Skip to content

Commit

Permalink
constructs/Service - add ability to use existing Cluster (#3692)
Browse files Browse the repository at this point in the history
* constructs/Service - add ability to use existing Cluster

* added cluster test for constructs/Service

* cleanup

* Move cluster to cdk.cluster

* Sync

---------

Co-authored-by: Frank <frank@sst.dev>
  • Loading branch information
zxan1285 and fwang committed Mar 14, 2024
1 parent df8866b commit 533caae
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 13 deletions.
6 changes: 6 additions & 0 deletions .changeset/rotten-plants-yell.md
@@ -0,0 +1,6 @@
---
"sst": patch
"@sst/docs": patch
---

Service: support using existing ECS Cluster
45 changes: 33 additions & 12 deletions packages/sst/src/constructs/Service.ts
Expand Up @@ -63,6 +63,7 @@ import {
FargateService,
FargateTaskDefinition,
FargateServiceProps,
ICluster,
} from "aws-cdk-lib/aws-ecs";
import { LogGroup, LogRetention, RetentionDays } from "aws-cdk-lib/aws-logs";
import { Platform } from "aws-cdk-lib/aws-ecr-assets";
Expand Down Expand Up @@ -563,7 +564,22 @@ export interface ServiceProps {
image?: ContainerDefinitionOptions["image"];
};
/**
* Runs codebuild job in the specified VPC. Note this will only work once deployed.
* Create the service in an existing ECS cluster.
*
* @example
* ```js
* import { Cluster } from "aws-cdk-lib/aws-ecs";
*
* {
* cdk: {
* cluster: Cluster.fromClusterArn(stack, "Cluster", "arn:aws:ecs:us-east-1:123456789012:cluster/my-cluster"),
* }
* }
* ```
*/
cluster?: ICluster;
/**
* Create the service in the specified VPC. Note this will only work once deployed.
*
* @example
* ```js
Expand Down Expand Up @@ -608,7 +624,7 @@ export class Service extends Construct implements SSTConstruct {
private doNotDeploy: boolean;
private devFunction?: Function;
private vpc?: IVpc;
private cluster?: Cluster;
private cluster?: ICluster;
private container?: ContainerDefinition;
private taskDefinition?: FargateTaskDefinition;
private service?: FargateService;
Expand Down Expand Up @@ -646,8 +662,8 @@ export class Service extends Construct implements SSTConstruct {

// Create ECS cluster
const vpc = this.createVpc();
const { cluster, container, taskDefinition, service } =
this.createService(vpc);
const cluster = this.createCluster(vpc);
const { container, taskDefinition, service } = this.createService(cluster);
const { alb, target } = this.createLoadBalancer(vpc, service);
this.createAutoScaling(service, target);
this.alb = alb;
Expand Down Expand Up @@ -929,26 +945,31 @@ export class Service extends Construct implements SSTConstruct {
);
}

private createService(vpc: IVpc) {
private createCluster(vpc: IVpc) {
if (this.props.cdk?.cluster) return this.props.cdk.cluster;

const app = this.node.root as App;
const clusterName = app.logicalPrefixedName(this.node.id);
return new Cluster(this, "Cluster", {
clusterName,
vpc,
});
}

private createService(cluster: ICluster) {
const { architecture, cpu, memory, storage, port, logRetention, cdk } =
this.props;
const app = this.node.root as App;
const clusterName = app.logicalPrefixedName(this.node.id);

const logGroup = new LogRetention(this, "LogRetention", {
logGroupName: `/sst/service/${clusterName}`,
logGroupName: `/sst/service/${cluster.clusterName}`,
retention:
RetentionDays[logRetention.toUpperCase() as keyof typeof RetentionDays],
logRetentionRetryOptions: {
maxRetries: 100,
},
});

const cluster = new Cluster(this, "Cluster", {
clusterName,
vpc,
});

const ephemeralStorageGiB = toCdkSize(storage).toGibibytes();
const taskDefinition = new FargateTaskDefinition(this, `TaskDefinition`, {
// @ts-expect-error
Expand Down
20 changes: 19 additions & 1 deletion packages/sst/test/constructs/Service.test.ts
@@ -1,6 +1,6 @@
import { test, expect, beforeAll, vi } from "vitest";
import { HostedZone } from "aws-cdk-lib/aws-route53";
import { ContainerImage } from "aws-cdk-lib/aws-ecs";
import { ContainerImage, Cluster } from "aws-cdk-lib/aws-ecs";
import {
countResources,
countResourcesLike,
Expand Down Expand Up @@ -493,6 +493,24 @@ test("environment", async () => {
});
});

test("cdk.cluster", async () => {
const app = await createApp();
const stack = new Stack(app, "stack");
const cluster = new Cluster(stack, "custom-cluster-id", {
clusterName: "custom-cluster",
});

new Service(stack, "Service", {
port: 3000,
cdk: { cluster },
});

countResources(stack, "AWS::ECS::Cluster", 1);
hasResource(stack, "AWS::ECS::Cluster", {
ClusterName: "custom-cluster",
});
});

test("cdk.fargateService", async () => {
const { stack } = await createService({
cdk: {
Expand Down
20 changes: 20 additions & 0 deletions www/docs/constructs/Service.about.md
Expand Up @@ -423,3 +423,23 @@ new Service(stack, "MyService", {
},
});
```
### Using an existing Cluster
```js
import { Cluster } from "aws-cdk-lib/aws-ecs";

const cluster = new Cluster(stack, "SharedCluster");

new Service(stack, "MyServiceA", {
path: "./service-a",
port: 3000,
cdk: { cluster },
});

new Service(stack, "MyServiceB", {
path: "./service-b",
port: 3000,
cdk: { cluster },
});
```
1 change: 1 addition & 0 deletions www/generate.mjs
Expand Up @@ -28,6 +28,7 @@ const CDK_DOCS_MAP = {
FargateServiceProps: "aws_ecs",
FargateTaskDefinition: "aws_ecs",
FunctionUrlOptions: "aws_lambda",
ICluster: "aws_ecs",
LogGroup: "aws_logs",
LogGroupProps: "aws_logs",
ILogGroup: "aws_logs",
Expand Down

0 comments on commit 533caae

Please sign in to comment.