From c6e4964c98de2c95254dc14fc2b2dc11a0c44a8b Mon Sep 17 00:00:00 2001 From: Eduardo Lopez <252504+tapichu@users.noreply.github.com> Date: Mon, 20 Dec 2021 11:24:00 -0800 Subject: [PATCH] Add ephemeral storage support to aws-ecs-patterns Fargate supports a new ephemeral storage option, to request up to 200 GiB of task storage. Support for it was added to aws-ecs but not to aws-ecs-patterns. This change adds support for ephemeral storage, so the following patterns can take advantage of it: * Application load balanced fargate service * Application multiple target groups fargate service * Network load balanced fargate service * Network multiple target groups fargate service * Queue processing fargate service * Scheduled fargate task Closes #18105 Signed-off-by: Eduardo Lopez <252504+tapichu@users.noreply.github.com> --- packages/@aws-cdk/aws-ecs-patterns/README.md | 140 +++ ...plication-load-balanced-fargate-service.ts | 12 + ...-multiple-target-groups-fargate-service.ts | 12 + .../network-load-balanced-fargate-service.ts | 12 + ...-multiple-target-groups-fargate-service.ts | 12 + .../queue-processing-fargate-service.ts | 12 + .../lib/fargate/scheduled-fargate-task.ts | 12 + ...vice-https-ephemeral-storage.expected.json | 778 ++++++++++++++++ ...fargate-service-https-ephemeral-storage.ts | 32 + ...te-service-ephemeral-storage.expected.json | 844 ++++++++++++++++++ ...ssing-fargate-service-ephemeral-storage.ts | 22 + ...e-task-ephemeral-storage.lit.expected.json | 510 +++++++++++ ...uled-fargate-task-ephemeral-storage.lit.ts | 35 + .../load-balanced-fargate-service-v2.test.ts | 8 + .../load-balanced-fargate-service.test.ts | 34 + .../queue-processing-fargate-service.test.ts | 4 + .../fargate/scheduled-fargate-task.test.ts | 4 + 17 files changed, 2483 insertions(+) create mode 100644 packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.expected.json create mode 100644 packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.ts create mode 100644 packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.expected.json create mode 100644 packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.ts create mode 100644 packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.expected.json create mode 100644 packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.ts diff --git a/packages/@aws-cdk/aws-ecs-patterns/README.md b/packages/@aws-cdk/aws-ecs-patterns/README.md index 386682e0b75d9..b41cad376ab50 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/README.md +++ b/packages/@aws-cdk/aws-ecs-patterns/README.md @@ -76,6 +76,25 @@ If you need to encrypt the traffic between the load balancer and the ECS tasks, Additionally, if more than one application target group are needed, instantiate one of the following: +On Fargate Platform Version 1.4.0 or later, you may specify up to 200GiB of [ephemeral storage](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html#fargate-task-storage-pv14): + +```ts +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { + cluster, + memoryLimitMiB: 1024, + cpu: 512, + ephemeralStorageGiB: 100, + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + }, +}); + +loadBalancedFargateService.targetGroup.configureHealthCheck({ + path: "/custom-health-path", +}); +``` + * `ApplicationMultipleTargetGroupsEc2Service` ```ts @@ -125,6 +144,32 @@ const loadBalancedFargateService = new ecsPatterns.ApplicationMultipleTargetGrou }); ``` +On Fargate Platform Version 1.4.0 or later, you may specify up to 200GiB of [ephemeral storage](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html#fargate-task-storage-pv14): + +```ts +// One application load balancer with one listener and two target groups. +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationMultipleTargetGroupsFargateService(this, 'Service', { + cluster, + memoryLimitMiB: 1024, + cpu: 512, + ephemeralStorageGiB: 100, + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + }, + targetGroups: [ + { + containerPort: 80, + }, + { + containerPort: 90, + pathPattern: 'a/b/c', + priority: 10, + }, + ], +}); +``` + ## Network Load Balanced Services To define an Amazon ECS service that is behind a network load balancer, instantiate one of the following: @@ -169,6 +214,21 @@ If you specify the option `recordType` you can decide if you want the construct Additionally, if more than one network target group is needed, instantiate one of the following: +On Fargate Platform Version 1.4.0 or later, you may specify up to 200GiB of [ephemeral storage](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html#fargate-task-storage-pv14): + +```ts +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.NetworkLoadBalancedFargateService(this, 'Service', { + cluster, + memoryLimitMiB: 1024, + cpu: 512, + ephemeralStorageGiB: 100, + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + }, +}); +``` + * NetworkMultipleTargetGroupsEc2Service ```ts @@ -253,6 +313,49 @@ const loadBalancedFargateService = new ecsPatterns.NetworkMultipleTargetGroupsFa }); ``` +On Fargate Platform Version 1.4.0 or later, you may specify up to 200GiB of [ephemeral storage](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html#fargate-task-storage-pv14): + +```ts +// Two network load balancers, each with their own listener and target group. +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.NetworkMultipleTargetGroupsFargateService(this, 'Service', { + cluster, + memoryLimitMiB: 512, + ephemeralStorageGiB: 100, + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + }, + loadBalancers: [ + { + name: 'lb1', + listeners: [ + { + name: 'listener1', + }, + ], + }, + { + name: 'lb2', + listeners: [ + { + name: 'listener2', + }, + ], + }, + ], + targetGroups: [ + { + containerPort: 80, + listener: 'listener1', + }, + { + containerPort: 90, + listener: 'listener2', + }, + ], +}); +``` + ## Queue Processing Services To define a service that creates a queue and reads from that queue, instantiate one of the following: @@ -299,6 +402,27 @@ const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateServ when queue not provided by user, CDK will create a primary queue and a dead letter queue with default redrive policy and attach permission to the task to be able to access the primary queue. +On Fargate Platform Version 1.4.0 or later, you may specify up to 200GiB of [ephemeral storage](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html#fargate-task-storage-pv14): + +```ts +declare const cluster: ecs.Cluster; +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { + cluster, + memoryLimitMiB: 512, + ephemeralStorageGiB: 100, + image: ecs.ContainerImage.fromRegistry('test'), + command: ["-c", "4", "amazon.com"], + enableLogging: false, + desiredTaskCount: 2, + environment: { + TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value", + TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value", + }, + maxScalingCapacity: 5, + containerName: 'test', +}); +``` + ## Scheduled Tasks To define a task that runs periodically, there are 2 options: @@ -336,6 +460,22 @@ const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'Schedul }); ``` +On Fargate Platform Version 1.4.0 or later, you may specify up to 200GiB of [ephemeral storage](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html#fargate-task-storage-pv14): + +```ts +declare const cluster: ecs.Cluster; +const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'ScheduledFargateTask', { + cluster, + scheduledFargateTaskImageOptions: { + image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), + memoryLimitMiB: 512, + ephemeralStorageGiB: 100, + }, + schedule: appscaling.Schedule.expression('rate(1 minute)'), + platformVersion: ecs.FargatePlatformVersion.LATEST, +}); +``` + ## Additional Examples In addition to using the constructs, users can also add logic to customize these constructs: diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts index 81f243f4a6fa6..f260c6dd09e95 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts @@ -60,6 +60,17 @@ export interface ApplicationLoadBalancedFargateServiceProps extends ApplicationL */ readonly memoryLimitMiB?: number; + /** + * The amount (in GiB) of ephemeral storage to be allocated to the task. The maximum supported value is 200 GiB. + * + * NOTE: This parameter is only supported for tasks hosted on AWS Fargate using platform version 1.4.0 or later. + * + * This default is set in the underlying FargateTaskDefinition construct. + * + * @default 20 + */ + readonly ephemeralStorageGiB?: number; + /** * Determines whether the service will be assigned a public IP address. * @@ -129,6 +140,7 @@ export class ApplicationLoadBalancedFargateService extends ApplicationLoadBalanc this.taskDefinition = new FargateTaskDefinition(this, 'TaskDef', { memoryLimitMiB: props.memoryLimitMiB, cpu: props.cpu, + ephemeralStorageGiB: props.ephemeralStorageGiB, executionRole: taskImageOptions.executionRole, taskRole: taskImageOptions.taskRole, family: taskImageOptions.family, diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-multiple-target-groups-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-multiple-target-groups-fargate-service.ts index 8052e0483b16a..8ab9b12d71056 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-multiple-target-groups-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-multiple-target-groups-fargate-service.ts @@ -64,6 +64,17 @@ export interface ApplicationMultipleTargetGroupsFargateServiceProps extends Appl */ readonly memoryLimitMiB?: number; + /** + * The amount (in GiB) of ephemeral storage to be allocated to the task. The maximum supported value is 200 GiB. + * + * NOTE: This parameter is only supported for tasks hosted on AWS Fargate using platform version 1.4.0 or later. + * + * This default is set in the underlying FargateTaskDefinition construct. + * + * @default 20 + */ + readonly ephemeralStorageGiB?: number; + /** * Determines whether the service will be assigned a public IP address. * @@ -125,6 +136,7 @@ export class ApplicationMultipleTargetGroupsFargateService extends ApplicationMu this.taskDefinition = new FargateTaskDefinition(this, 'TaskDef', { memoryLimitMiB: props.memoryLimitMiB, cpu: props.cpu, + ephemeralStorageGiB: props.ephemeralStorageGiB, executionRole: taskImageOptions.executionRole, taskRole: taskImageOptions.taskRole, family: taskImageOptions.family, diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts index 9095be5cf2cd1..292ef7df104e0 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts @@ -60,6 +60,17 @@ export interface NetworkLoadBalancedFargateServiceProps extends NetworkLoadBalan */ readonly memoryLimitMiB?: number; + /** + * The amount (in GiB) of ephemeral storage to be allocated to the task. The maximum supported value is 200 GiB. + * + * NOTE: This parameter is only supported for tasks hosted on AWS Fargate using platform version 1.4.0 or later. + * + * This default is set in the underlying FargateTaskDefinition construct. + * + * @default 20 + */ + readonly ephemeralStorageGiB?: number; + /** * Determines whether the service will be assigned a public IP address. * @@ -118,6 +129,7 @@ export class NetworkLoadBalancedFargateService extends NetworkLoadBalancedServic this.taskDefinition = new FargateTaskDefinition(this, 'TaskDef', { memoryLimitMiB: props.memoryLimitMiB, cpu: props.cpu, + ephemeralStorageGiB: props.ephemeralStorageGiB, executionRole: taskImageOptions.executionRole, taskRole: taskImageOptions.taskRole, family: taskImageOptions.family, diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-multiple-target-groups-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-multiple-target-groups-fargate-service.ts index 1a185f642a558..fe44894605d10 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-multiple-target-groups-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/network-multiple-target-groups-fargate-service.ts @@ -64,6 +64,17 @@ export interface NetworkMultipleTargetGroupsFargateServiceProps extends NetworkM */ readonly memoryLimitMiB?: number; + /** + * The amount (in GiB) of ephemeral storage to be allocated to the task. The maximum supported value is 200 GiB. + * + * NOTE: This parameter is only supported for tasks hosted on AWS Fargate using platform version 1.4.0 or later. + * + * This default is set in the underlying FargateTaskDefinition construct. + * + * @default 20 + */ + readonly ephemeralStorageGiB?: number; + /** * Determines whether the service will be assigned a public IP address. * @@ -125,6 +136,7 @@ export class NetworkMultipleTargetGroupsFargateService extends NetworkMultipleTa this.taskDefinition = new FargateTaskDefinition(this, 'TaskDef', { memoryLimitMiB: props.memoryLimitMiB, cpu: props.cpu, + ephemeralStorageGiB: props.ephemeralStorageGiB, executionRole: taskImageOptions.executionRole, taskRole: taskImageOptions.taskRole, family: taskImageOptions.family, diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts index 033d19dc39612..5539b31456513 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts @@ -51,6 +51,17 @@ export interface QueueProcessingFargateServiceProps extends QueueProcessingServi */ readonly memoryLimitMiB?: number; + /** + * The amount (in GiB) of ephemeral storage to be allocated to the task. The maximum supported value is 200 GiB. + * + * NOTE: This parameter is only supported for tasks hosted on AWS Fargate using platform version 1.4.0 or later. + * + * This default is set in the underlying FargateTaskDefinition construct. + * + * @default 20 + */ + readonly ephemeralStorageGiB?: number; + /** * The platform version on which to run your service. * @@ -116,6 +127,7 @@ export class QueueProcessingFargateService extends QueueProcessingServiceBase { this.taskDefinition = new FargateTaskDefinition(this, 'QueueProcessingTaskDef', { memoryLimitMiB: props.memoryLimitMiB || 512, cpu: props.cpu || 256, + ephemeralStorageGiB: props.ephemeralStorageGiB, family: props.family, }); diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/scheduled-fargate-task.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/scheduled-fargate-task.ts index 7a5a018920e7a..f9d407bdb9d30 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/scheduled-fargate-task.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/scheduled-fargate-task.ts @@ -69,6 +69,17 @@ export interface ScheduledFargateTaskImageOptions extends ScheduledTaskImageProp * @default 512 */ readonly memoryLimitMiB?: number; + + /** + * The amount (in GiB) of ephemeral storage to be allocated to the task. The maximum supported value is 200 GiB. + * + * NOTE: This parameter is only supported for tasks hosted on AWS Fargate using platform version 1.4.0 or later. + * + * This default is set in the underlying FargateTaskDefinition construct. + * + * @default 20 + */ + readonly ephemeralStorageGiB?: number; } /** @@ -114,6 +125,7 @@ export class ScheduledFargateTask extends ScheduledTaskBase { this.taskDefinition = new FargateTaskDefinition(this, 'ScheduledTaskDef', { memoryLimitMiB: taskImageOptions.memoryLimitMiB || 512, cpu: taskImageOptions.cpu || 256, + ephemeralStorageGiB: taskImageOptions.ephemeralStorageGiB, }); this.taskDefinition.addContainer('ScheduledContainer', { image: taskImageOptions.image, diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.expected.json new file mode 100644 index 0000000000000..7e2e1e4766c80 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.expected.json @@ -0,0 +1,778 @@ +{ + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc" + } + ] + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet1EIPD7E02669": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet2Subnet691E08A3": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.64.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + } + }, + "VpcPublicSubnet2DefaultRoute97F91067": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet2EIP3C605A87": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2NATGateway9182C01D": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet2EIP3C605A87", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPrivateSubnet1Subnet536B997A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcPrivateSubnet2Subnet3788AAA1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.192.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableA678073B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + } + }, + "VpcPrivateSubnet2DefaultRoute060D2087": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet2NATGateway9182C01D" + } + } + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ-alb-fg-https-es/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "ClusterEB0386A7": { + "Type": "AWS::ECS::Cluster" + }, + "myServiceLB168895E1": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "myServiceLBSecurityGroupFE0ED608", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "Type": "application" + }, + "DependsOn": [ + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet2DefaultRoute97F91067" + ] + }, + "myServiceLBSecurityGroupFE0ED608": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Automatically created Security Group for ELB awsecsintegalbfghttpsesmyServiceLBFD892FD6", + "SecurityGroupIngress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow from anyone on port 443", + "FromPort": 443, + "IpProtocol": "tcp", + "ToPort": 443 + }, + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow from anyone on port 80", + "FromPort": 80, + "IpProtocol": "tcp", + "ToPort": 80 + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "myServiceLBSecurityGrouptoawsecsintegalbfghttpsesmyServiceSecurityGroup1CE5D8538016761582": { + "Type": "AWS::EC2::SecurityGroupEgress", + "Properties": { + "GroupId": { + "Fn::GetAtt": [ + "myServiceLBSecurityGroupFE0ED608", + "GroupId" + ] + }, + "IpProtocol": "tcp", + "Description": "Load balancer to target", + "DestinationSecurityGroupId": { + "Fn::GetAtt": [ + "myServiceSecurityGroupC3B9D4E0", + "GroupId" + ] + }, + "FromPort": 80, + "ToPort": 80 + } + }, + "myServiceLBPublicListenerC78AE8A0": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "myServiceLBPublicListenerECSGroup17E9BBC1" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "myServiceLB168895E1" + }, + "Certificates": [ + { + "CertificateArn": { + "Ref": "myServiceCertificate152F9DDA" + } + } + ], + "Port": 443, + "Protocol": "HTTPS" + } + }, + "myServiceLBPublicListenerECSGroup17E9BBC1": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 80, + "Protocol": "HTTP", + "TargetGroupAttributes": [ + { + "Key": "stickiness.enabled", + "Value": "false" + } + ], + "TargetType": "ip", + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "myServiceLBPublicRedirectListener0EEF9DCA": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "RedirectConfig": { + "Port": "443", + "Protocol": "HTTPS", + "StatusCode": "HTTP_301" + }, + "Type": "redirect" + } + ], + "LoadBalancerArn": { + "Ref": "myServiceLB168895E1" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "myServiceCertificate152F9DDA": { + "Type": "AWS::CertificateManager::Certificate", + "Properties": { + "DomainName": "test.example.com", + "DomainValidationOptions": [ + { + "DomainName": "test.example.com", + "HostedZoneId": "fakeId" + } + ], + "ValidationMethod": "DNS" + } + }, + "myServiceDNSD76FB53A": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "Name": "test.example.com.", + "Type": "A", + "AliasTarget": { + "DNSName": { + "Fn::Join": [ + "", + [ + "dualstack.", + { + "Fn::GetAtt": [ + "myServiceLB168895E1", + "DNSName" + ] + } + ] + ] + }, + "HostedZoneId": { + "Fn::GetAtt": [ + "myServiceLB168895E1", + "CanonicalHostedZoneID" + ] + } + }, + "HostedZoneId": "fakeId" + } + }, + "myServiceTaskDefTaskRole1C1DE6CC": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "myServiceTaskDef7FB8322A": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "amazon/amazon-ecs-sample", + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "myServiceTaskDefwebLogGroupA1767F2C" + }, + "awslogs-stream-prefix": "myService", + "awslogs-region": { + "Ref": "AWS::Region" + } + } + }, + "Name": "web", + "PortMappings": [ + { + "ContainerPort": 80, + "Protocol": "tcp" + } + ] + } + ], + "Cpu": "256", + "EphemeralStorage": { + "SizeInGiB": 50 + }, + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "myServiceTaskDefExecutionRole618CD311", + "Arn" + ] + }, + "Family": "awsecsintegalbfghttpsesmyServiceTaskDef1739C0F8", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "myServiceTaskDefTaskRole1C1DE6CC", + "Arn" + ] + } + } + }, + "myServiceTaskDefwebLogGroupA1767F2C": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "myServiceTaskDefExecutionRole618CD311": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "myServiceTaskDefExecutionRoleDefaultPolicyBDAEC571": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "myServiceTaskDefwebLogGroupA1767F2C", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "myServiceTaskDefExecutionRoleDefaultPolicyBDAEC571", + "Roles": [ + { + "Ref": "myServiceTaskDefExecutionRole618CD311" + } + ] + } + }, + "myServiceB0B6FAA0": { + "Type": "AWS::ECS::Service", + "Properties": { + "Cluster": { + "Ref": "ClusterEB0386A7" + }, + "DeploymentConfiguration": { + "MaximumPercent": 200, + "MinimumHealthyPercent": 50 + }, + "EnableECSManagedTags": true, + "HealthCheckGracePeriodSeconds": 60, + "LaunchType": "FARGATE", + "LoadBalancers": [ + { + "ContainerName": "web", + "ContainerPort": 80, + "TargetGroupArn": { + "Ref": "myServiceLBPublicListenerECSGroup17E9BBC1" + } + } + ], + "NetworkConfiguration": { + "AwsvpcConfiguration": { + "AssignPublicIp": "DISABLED", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "myServiceSecurityGroupC3B9D4E0", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + ] + } + }, + "TaskDefinition": { + "Ref": "myServiceTaskDef7FB8322A" + } + }, + "DependsOn": [ + "myServiceLBPublicListenerECSGroup17E9BBC1", + "myServiceLBPublicListenerC78AE8A0" + ] + }, + "myServiceSecurityGroupC3B9D4E0": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-ecs-integ-alb-fg-https-es/myService/Service/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "myServiceSecurityGroupfromawsecsintegalbfghttpsesmyServiceLBSecurityGroup7B6C458C80E1BD5E7A": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "IpProtocol": "tcp", + "Description": "Load balancer to target", + "FromPort": 80, + "GroupId": { + "Fn::GetAtt": [ + "myServiceSecurityGroupC3B9D4E0", + "GroupId" + ] + }, + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "myServiceLBSecurityGroupFE0ED608", + "GroupId" + ] + }, + "ToPort": 80 + } + } + }, + "Outputs": { + "myServiceLoadBalancerDNS3A083E9F": { + "Value": { + "Fn::GetAtt": [ + "myServiceLB168895E1", + "DNSName" + ] + } + }, + "myServiceServiceURL1258C56B": { + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Ref": "myServiceDNSD76FB53A" + } + ] + ] + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.ts new file mode 100644 index 0000000000000..b8b94d54a940d --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https-ephemeral-storage.ts @@ -0,0 +1,32 @@ +import { Vpc } from '@aws-cdk/aws-ec2'; +import { Cluster, ContainerImage } from '@aws-cdk/aws-ecs'; +import { ApplicationProtocol } from '@aws-cdk/aws-elasticloadbalancingv2'; +import * as route53 from '@aws-cdk/aws-route53'; +import { App, Stack } from '@aws-cdk/core'; + +import { ApplicationLoadBalancedFargateService } from '../../lib'; + +const app = new App(); +const stack = new Stack(app, 'aws-ecs-integ-alb-fg-https-es'); +const vpc = new Vpc(stack, 'Vpc', { maxAzs: 2 }); +const cluster = new Cluster(stack, 'Cluster', { vpc }); + +// Loadbalancer with HTTPS +new ApplicationLoadBalancedFargateService(stack, 'myService', { + cluster, + memoryLimitMiB: 512, + ephemeralStorageGiB: 50, + taskImageOptions: { + image: ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), + }, + protocol: ApplicationProtocol.HTTPS, + enableECSManagedTags: true, + domainName: 'test.example.com', + domainZone: route53.HostedZone.fromHostedZoneAttributes(stack, 'HostedZone', { + hostedZoneId: 'fakeId', + zoneName: 'example.com.', + }), + redirectHTTP: true, +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.expected.json new file mode 100644 index 0000000000000..f1577d375e115 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.expected.json @@ -0,0 +1,844 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.64.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet2EIP4947BC00": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.192.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-patterns-queue-es/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "QueueProcessingServiceEcsProcessingDeadLetterQueueD47A7C6B": { + "Type": "AWS::SQS::Queue", + "Properties": { + "MessageRetentionPeriod": 1209600 + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "QueueProcessingServiceEcsProcessingQueue552F0B37": { + "Type": "AWS::SQS::Queue", + "Properties": { + "RedrivePolicy": { + "deadLetterTargetArn": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingDeadLetterQueueD47A7C6B", + "Arn" + ] + }, + "maxReceiveCount": 3 + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "QueueProcessingServiceQueueProcessingTaskDefTaskRole782B79A6": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "QueueProcessingServiceQueueProcessingTaskDefTaskRoleDefaultPolicyAE808B19": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sqs:ReceiveMessage", + "sqs:ChangeMessageVisibility", + "sqs:GetQueueUrl", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingQueue552F0B37", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "QueueProcessingServiceQueueProcessingTaskDefTaskRoleDefaultPolicyAE808B19", + "Roles": [ + { + "Ref": "QueueProcessingServiceQueueProcessingTaskDefTaskRole782B79A6" + } + ] + } + }, + "QueueProcessingServiceQueueProcessingTaskDef4982F68B": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Environment": [ + { + "Name": "QUEUE_NAME", + "Value": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingQueue552F0B37", + "QueueName" + ] + } + } + ], + "Essential": true, + "Image": { + "Fn::Join": [ + "", + [ + { + "Ref": "AWS::AccountId" + }, + ".dkr.ecr.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/aws-cdk/assets:d6b024485c22795b5f5379edcd5cd6485f5bec6eb80bd072b20526f8eb2e0c64" + ] + ] + }, + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "QueueProcessingServiceQueueProcessingTaskDefQueueProcessingContainerLogGroupCC92448A" + }, + "awslogs-stream-prefix": "QueueProcessingService", + "awslogs-region": { + "Ref": "AWS::Region" + } + } + }, + "Name": "QueueProcessingContainer" + } + ], + "Cpu": "256", + "EphemeralStorage": { + "SizeInGiB": 50 + }, + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "QueueProcessingServiceQueueProcessingTaskDefExecutionRole37838985", + "Arn" + ] + }, + "Family": "awsecspatternsqueueesQueueProcessingServiceQueueProcessingTaskDef80674093", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "QueueProcessingServiceQueueProcessingTaskDefTaskRole782B79A6", + "Arn" + ] + } + } + }, + "QueueProcessingServiceQueueProcessingTaskDefQueueProcessingContainerLogGroupCC92448A": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "QueueProcessingServiceQueueProcessingTaskDefExecutionRole37838985": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "QueueProcessingServiceQueueProcessingTaskDefExecutionRoleDefaultPolicyA83D332D": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ecr:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":repository/aws-cdk/assets" + ] + ] + } + }, + { + "Action": "ecr:GetAuthorizationToken", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "QueueProcessingServiceQueueProcessingTaskDefQueueProcessingContainerLogGroupCC92448A", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "QueueProcessingServiceQueueProcessingTaskDefExecutionRoleDefaultPolicyA83D332D", + "Roles": [ + { + "Ref": "QueueProcessingServiceQueueProcessingTaskDefExecutionRole37838985" + } + ] + } + }, + "QueueProcessingServiceQueueProcessingFargateService0340DB9F": { + "Type": "AWS::ECS::Service", + "Properties": { + "Cluster": { + "Ref": "EcsDefaultClusterMnL3mNNYNVPC9C1EC7A3" + }, + "DeploymentConfiguration": { + "MaximumPercent": 200, + "MinimumHealthyPercent": 50 + }, + "EnableECSManagedTags": false, + "LaunchType": "FARGATE", + "NetworkConfiguration": { + "AwsvpcConfiguration": { + "AssignPublicIp": "DISABLED", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "QueueProcessingServiceQueueProcessingFargateServiceSecurityGroup8FDF413D", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + } + }, + "TaskDefinition": { + "Ref": "QueueProcessingServiceQueueProcessingTaskDef4982F68B" + } + } + }, + "QueueProcessingServiceQueueProcessingFargateServiceSecurityGroup8FDF413D": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-ecs-patterns-queue-es/QueueProcessingService/QueueProcessingFargateService/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetA9D54444": { + "Type": "AWS::ApplicationAutoScaling::ScalableTarget", + "Properties": { + "MaxCapacity": 2, + "MinCapacity": 0, + "ResourceId": { + "Fn::Join": [ + "", + [ + "service/", + { + "Ref": "EcsDefaultClusterMnL3mNNYNVPC9C1EC7A3" + }, + "/", + { + "Fn::GetAtt": [ + "QueueProcessingServiceQueueProcessingFargateService0340DB9F", + "Name" + ] + } + ] + ] + }, + "RoleARN": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService" + ] + ] + }, + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs" + } + }, + "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetCpuScaling330150E9": { + "Type": "AWS::ApplicationAutoScaling::ScalingPolicy", + "Properties": { + "PolicyName": "awsecspatternsqueueesQueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetCpuScaling83DE8898", + "PolicyType": "TargetTrackingScaling", + "ScalingTargetId": { + "Ref": "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetA9D54444" + }, + "TargetTrackingScalingPolicyConfiguration": { + "PredefinedMetricSpecification": { + "PredefinedMetricType": "ECSServiceAverageCPUUtilization" + }, + "TargetValue": 50 + } + } + }, + "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingLowerPolicy332E2644": { + "Type": "AWS::ApplicationAutoScaling::ScalingPolicy", + "Properties": { + "PolicyName": "awsecspatternsqueueesQueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingLowerPolicyE9AD74AB", + "PolicyType": "StepScaling", + "ScalingTargetId": { + "Ref": "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetA9D54444" + }, + "StepScalingPolicyConfiguration": { + "AdjustmentType": "ChangeInCapacity", + "MetricAggregationType": "Maximum", + "StepAdjustments": [ + { + "MetricIntervalUpperBound": 0, + "ScalingAdjustment": -1 + } + ] + } + } + }, + "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingLowerAlarm20C30A06": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "LessThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmActions": [ + { + "Ref": "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingLowerPolicy332E2644" + } + ], + "AlarmDescription": "Lower threshold scaling alarm", + "Dimensions": [ + { + "Name": "QueueName", + "Value": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingQueue552F0B37", + "QueueName" + ] + } + } + ], + "MetricName": "ApproximateNumberOfMessagesVisible", + "Namespace": "AWS/SQS", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 0 + } + }, + "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingUpperPolicy84DD739A": { + "Type": "AWS::ApplicationAutoScaling::ScalingPolicy", + "Properties": { + "PolicyName": "awsecspatternsqueueesQueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingUpperPolicyDEC4E27C", + "PolicyType": "StepScaling", + "ScalingTargetId": { + "Ref": "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetA9D54444" + }, + "StepScalingPolicyConfiguration": { + "AdjustmentType": "ChangeInCapacity", + "MetricAggregationType": "Maximum", + "StepAdjustments": [ + { + "MetricIntervalLowerBound": 0, + "MetricIntervalUpperBound": 400, + "ScalingAdjustment": 1 + }, + { + "MetricIntervalLowerBound": 400, + "ScalingAdjustment": 5 + } + ] + } + } + }, + "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingUpperAlarm2660BEDF": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmActions": [ + { + "Ref": "QueueProcessingServiceQueueProcessingFargateServiceTaskCountTargetQueueMessagesVisibleScalingUpperPolicy84DD739A" + } + ], + "AlarmDescription": "Upper threshold scaling alarm", + "Dimensions": [ + { + "Name": "QueueName", + "Value": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingQueue552F0B37", + "QueueName" + ] + } + } + ], + "MetricName": "ApproximateNumberOfMessagesVisible", + "Namespace": "AWS/SQS", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 100 + } + }, + "EcsDefaultClusterMnL3mNNYNVPC9C1EC7A3": { + "Type": "AWS::ECS::Cluster" + } + }, + "Outputs": { + "QueueProcessingServiceSQSDeadLetterQueueE9058015": { + "Value": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingDeadLetterQueueD47A7C6B", + "QueueName" + ] + } + }, + "QueueProcessingServiceSQSDeadLetterQueueArnF7C6D3A8": { + "Value": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingDeadLetterQueueD47A7C6B", + "Arn" + ] + } + }, + "QueueProcessingServiceSQSQueue1AD9CD9C": { + "Value": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingQueue552F0B37", + "QueueName" + ] + } + }, + "QueueProcessingServiceSQSQueueArn8C4AE4AE": { + "Value": { + "Fn::GetAtt": [ + "QueueProcessingServiceEcsProcessingQueue552F0B37", + "Arn" + ] + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.ts new file mode 100644 index 0000000000000..0a76859399aa6 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.queue-processing-fargate-service-ephemeral-storage.ts @@ -0,0 +1,22 @@ +import * as path from 'path'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; +import { App, Stack } from '@aws-cdk/core'; + +import { QueueProcessingFargateService } from '../../lib'; + +const app = new App(); +const stack = new Stack(app, 'aws-ecs-patterns-queue-es'); +const vpc = new ec2.Vpc(stack, 'VPC', { + maxAzs: 2, +}); + +new QueueProcessingFargateService(stack, 'QueueProcessingService', { + vpc, + memoryLimitMiB: 512, + ephemeralStorageGiB: 50, + image: new ecs.AssetImage(path.join(__dirname, '..', 'sqs-reader')), + minScalingCapacity: 0, +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.expected.json new file mode 100644 index 0000000000000..fcce4f839ec83 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.expected.json @@ -0,0 +1,510 @@ +{ + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc" + } + ] + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/17", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet1EIPD7E02669": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1Subnet536B997A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/17", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-fargate-integ-es/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "FargateCluster7CCD5F93": { + "Type": "AWS::ECS::Cluster" + }, + "ScheduledFargateTaskScheduledEventRule2B79E34F": { + "Type": "AWS::Events::Rule", + "Properties": { + "ScheduleExpression": "rate(2 minutes)", + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Fn::GetAtt": [ + "FargateCluster7CCD5F93", + "Arn" + ] + }, + "EcsParameters": { + "LaunchType": "FARGATE", + "NetworkConfiguration": { + "AwsVpcConfiguration": { + "AssignPublicIp": "DISABLED", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "ScheduledFargateTaskScheduledTaskDefSecurityGroupE075BC19", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + ] + } + }, + "TaskCount": 2, + "TaskDefinitionArn": { + "Ref": "ScheduledFargateTaskScheduledTaskDef521FA675" + } + }, + "Id": "Target0", + "Input": "{}", + "RoleArn": { + "Fn::GetAtt": [ + "ScheduledFargateTaskScheduledTaskDefEventsRole6CE19522", + "Arn" + ] + } + } + ] + } + }, + "ScheduledFargateTaskScheduledTaskDefTaskRoleD0FF16AD": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ScheduledFargateTaskScheduledTaskDef521FA675": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Environment": [ + { + "Name": "TRIGGER", + "Value": "CloudWatch Events" + } + ], + "Essential": true, + "Image": { + "Fn::Join": [ + "", + [ + { + "Ref": "AWS::AccountId" + }, + ".dkr.ecr.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/aws-cdk/assets:8c1d9ca9f5d37b1c4870c13a9f855301bb42c1848dbcdd5edc8fe2c6c7261d48" + ] + ] + }, + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "ScheduledFargateTaskScheduledTaskDefScheduledContainerLogGroup4134B16C" + }, + "awslogs-stream-prefix": "ScheduledFargateTask", + "awslogs-region": { + "Ref": "AWS::Region" + } + } + }, + "Name": "ScheduledContainer" + } + ], + "Cpu": "256", + "EphemeralStorage": { + "SizeInGiB": 50 + }, + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "ScheduledFargateTaskScheduledTaskDefExecutionRoleD37356D5", + "Arn" + ] + }, + "Family": "awsfargateintegesScheduledFargateTaskScheduledTaskDefDF68AAD9", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "ScheduledFargateTaskScheduledTaskDefTaskRoleD0FF16AD", + "Arn" + ] + } + } + }, + "ScheduledFargateTaskScheduledTaskDefScheduledContainerLogGroup4134B16C": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "ScheduledFargateTaskScheduledTaskDefExecutionRoleD37356D5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ScheduledFargateTaskScheduledTaskDefExecutionRoleDefaultPolicy3E3AEE49": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ecr:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":repository/aws-cdk/assets" + ] + ] + } + }, + { + "Action": "ecr:GetAuthorizationToken", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "ScheduledFargateTaskScheduledTaskDefScheduledContainerLogGroup4134B16C", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ScheduledFargateTaskScheduledTaskDefExecutionRoleDefaultPolicy3E3AEE49", + "Roles": [ + { + "Ref": "ScheduledFargateTaskScheduledTaskDefExecutionRoleD37356D5" + } + ] + } + }, + "ScheduledFargateTaskScheduledTaskDefEventsRole6CE19522": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ScheduledFargateTaskScheduledTaskDefEventsRoleDefaultPolicy4903ED72": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "ecs:RunTask", + "Condition": { + "ArnEquals": { + "ecs:cluster": { + "Fn::GetAtt": [ + "FargateCluster7CCD5F93", + "Arn" + ] + } + } + }, + "Effect": "Allow", + "Resource": { + "Ref": "ScheduledFargateTaskScheduledTaskDef521FA675" + } + }, + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "ScheduledFargateTaskScheduledTaskDefExecutionRoleD37356D5", + "Arn" + ] + } + }, + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "ScheduledFargateTaskScheduledTaskDefTaskRoleD0FF16AD", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ScheduledFargateTaskScheduledTaskDefEventsRoleDefaultPolicy4903ED72", + "Roles": [ + { + "Ref": "ScheduledFargateTaskScheduledTaskDefEventsRole6CE19522" + } + ] + } + }, + "ScheduledFargateTaskScheduledTaskDefSecurityGroupE075BC19": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-fargate-integ-es/ScheduledFargateTask/ScheduledTaskDef/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.ts new file mode 100644 index 0000000000000..4283b9e131583 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.scheduled-fargate-task-ephemeral-storage.lit.ts @@ -0,0 +1,35 @@ +import * as path from 'path'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as events from '@aws-cdk/aws-events'; +import * as cdk from '@aws-cdk/core'; + +import { ScheduledFargateTask } from '../../lib'; + +const app = new cdk.App(); + +class EventStack extends cdk.Stack { + constructor(scope: cdk.App, id: string) { + super(scope, id); + + const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 1 }); + const cluster = new ecs.Cluster(this, 'FargateCluster', { vpc }); + + // Create the scheduled task + new ScheduledFargateTask(this, 'ScheduledFargateTask', { + cluster, + scheduledFargateTaskImageOptions: { + image: new ecs.AssetImage(path.join(__dirname, '..', 'demo-image')), + memoryLimitMiB: 512, + cpu: 256, + ephemeralStorageGiB: 50, + environment: { TRIGGER: 'CloudWatch Events' }, + }, + desiredTaskCount: 2, + schedule: events.Schedule.rate(cdk.Duration.minutes(2)), + }); + } +} + +new EventStack(app, 'aws-fargate-integ-es'); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service-v2.test.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service-v2.test.ts index 902d5412ee8bf..83e4dfe6de12b 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service-v2.test.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service-v2.test.ts @@ -115,6 +115,7 @@ describe('When Application Load Balancer', () => { cpu: 256, assignPublicIp: true, memoryLimitMiB: 512, + ephemeralStorageGiB: 100, desiredCount: 3, enableECSManagedTags: true, healthCheckGracePeriod: Duration.millis(2000), @@ -235,6 +236,9 @@ describe('When Application Load Balancer', () => { }, Family: 'Ec2TaskDef', Memory: '512', + EphemeralStorage: { + SizeInGiB: 100, + }, NetworkMode: 'awsvpc', RequiresCompatibilities: [ 'FARGATE', @@ -484,6 +488,7 @@ describe('When Network Load Balancer', () => { cpu: 256, assignPublicIp: true, memoryLimitMiB: 512, + ephemeralStorageGiB: 100, desiredCount: 3, enableECSManagedTags: true, healthCheckGracePeriod: Duration.millis(2000), @@ -599,6 +604,9 @@ describe('When Network Load Balancer', () => { }, Family: 'Ec2TaskDef', Memory: '512', + EphemeralStorage: { + SizeInGiB: 100, + }, NetworkMode: 'awsvpc', RequiresCompatibilities: [ 'FARGATE', diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts index 0f4c0ab29ba86..1af50c33eeb64 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts @@ -316,6 +316,40 @@ test('setting platform version', () => { }); }); +test('setting ephemeral storage on NLB Fargate Service', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new ecsPatterns.NetworkLoadBalancedFargateService(stack, 'Service', { + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + }, + ephemeralStorageGiB: 100, + }); + + // THEN + const serviceTaskDefinition = SynthUtils.synthesize(stack).template.Resources.ServiceTaskDef1922A00F; + expect(serviceTaskDefinition.Properties.EphemeralStorage).toEqual({ SizeInGiB: 100 }); +}); + +test('setting ephemeral storage on ALB Fargate Service', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'Service', { + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + }, + ephemeralStorageGiB: 100, + }); + + // THEN + const serviceTaskDefinition = SynthUtils.synthesize(stack).template.Resources.ServiceTaskDef1922A00F; + expect(serviceTaskDefinition.Properties.EphemeralStorage).toEqual({ SizeInGiB: 100 }); +}); + test('test load balanced service with family defined', () => { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/queue-processing-fargate-service.test.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/queue-processing-fargate-service.test.ts index 6f91b633d1249..2cec423901c7e 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/queue-processing-fargate-service.test.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/queue-processing-fargate-service.test.ts @@ -350,6 +350,7 @@ testDeprecated('test Fargate queue worker service construct - with optional prop new ecsPatterns.QueueProcessingFargateService(stack, 'Service', { cluster, memoryLimitMiB: 512, + ephemeralStorageGiB: 100, image: ecs.ContainerImage.fromRegistry('test'), command: ['-c', '4', 'amazon.com'], enableLogging: false, @@ -419,6 +420,9 @@ testDeprecated('test Fargate queue worker service construct - with optional prop Image: 'test', }, ], + EphemeralStorage: { + SizeInGiB: 100, + }, Family: 'fargate-task-family', }); }); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts index 5d37bba01af2f..781201ccd96bc 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts @@ -92,6 +92,7 @@ test('Can create a scheduled Fargate Task - with optional props', () => { image: ecs.ContainerImage.fromRegistry('henk'), memoryLimitMiB: 512, cpu: 2, + ephemeralStorageGiB: 100, environment: { TRIGGER: 'CloudWatch Events' }, }, desiredTaskCount: 2, @@ -162,6 +163,9 @@ test('Can create a scheduled Fargate Task - with optional props', () => { Name: 'ScheduledContainer', }, ], + EphemeralStorage: { + SizeInGiB: 100, + }, }); });