-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Hi there,
First of all, thank you for building SST — I currently have several projects running in production using sst/sst. I’m now trying to adopt more native SST components beyond the lower-level Pulumi ones. I really enjoy working with sst.aws.Service, and I’m trying to better understand the design decisions around local development for ECS-based services.
Context
I’m using sst.aws.Service() to deploy ECS services on AWS. When running sst dev, the workflow still creates or references an ECS cluster in AWS, because the Service constructor requires a cluster to be provided via args.cluster.
From what I’ve been able to observe, there doesn’t seem to be an alternative way to run local development without also provisioning (or referencing) an ECS cluster in AWS — even though this is only for local development. In production, of course, requiring a real cluster makes complete sense.
Why I’m confused about needing a cluster up front
Looking at the constructor implementation, it appears that the Service exits early when running in dev mode:
constructor(
name: string,
args: ServiceArgs,
opts: ComponentResourceOptions = {},
) {
super(__pulumiType, name, args, opts);
this._name = name;
const self = this;
const clusterArn = args.cluster.nodes.cluster.arn;
const clusterName = args.cluster.nodes.cluster.name;
const region = getRegionOutput({}, opts).name;
const dev = normalizeDev();
const wait = output(args.wait ?? false);
const architecture = normalizeArchitecture(args);
const cpu = normalizeCpu(args);
const memory = normalizeMemory(cpu, args);
const storage = normalizeStorage(args);
const containers = normalizeContainers("service", args, name, architecture);
const lbArgs = normalizeLoadBalancer();
const scaling = normalizeScaling();
const capacity = normalizeCapacity();
const vpc = normalizeVpc();
const taskRole = createTaskRole(name, args, opts, self, !!dev);
this.dev = !!dev;
this.cloudmapNamespace = vpc.cloudmapNamespaceName;
this.taskRole = taskRole;
if (dev) {
this.devUrl = !lbArgs ? undefined : dev.url;
registerReceiver();
return;
}
[...]
}Because the if (dev) { ... return; } branch exits relatively early, I’m trying to understand why a fully defined ECS cluster is still required upfront, along with all the associated normalization logic.
Observations
- Many of the normalization steps (region, VPC, load balancer, CPU/memory, etc.) are clearly necessary for a real ECS deployment.
- However, for local development, it seems that several of these validations could potentially be skipped or deferred.
- Requiring an ECS cluster during
sst devincreases the initial startup time and can introduce unnecessary AWS cost if clusters are kept running only for development purposes.
Questions
-
Is it intentional that
sst.aws.Servicerequires a real ECS cluster even when running indevmode? -
Is there an architectural reason why cluster-related normalization must happen before the early
devreturn? -
Is there any plan to introduce something like:
- a lightweight or mocked
ClusterArgsfordev, or - an extension of
Clusterwith explicitdev-only capabilities (similar in spirit to how EKS local workflows are handled)?
- a lightweight or mocked
If this behavior is by design, I’d really appreciate any insight into the rationale behind it, or pointers to documentation or code paths that explain the constraints.
Thanks again for the project, and happy New Year! 🎉