From 0f6e2daa248aed9300f5b6c3019cdcb168ee4951 Mon Sep 17 00:00:00 2001 From: Thorsten Hoeger Date: Fri, 20 Nov 2020 20:34:09 +0100 Subject: [PATCH] feat(ecs): allow HTTPS connections from LB to task (#11381) If you need or want to encrypt traffic between the load balancer and the ECS task you need to set the protocol of the target group to `HTTPS`. This PR adds a new property to specify this. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ecs-patterns/README.md | 2 + .../application-load-balanced-service-base.ts | 15 ++++++-- .../test.load-balanced-fargate-service.ts | 37 +++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-ecs-patterns/README.md b/packages/@aws-cdk/aws-ecs-patterns/README.md index 57905649401cd..df15fed648e21 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/README.md +++ b/packages/@aws-cdk/aws-ecs-patterns/README.md @@ -68,6 +68,8 @@ By setting `redirectHTTP` to true, CDK will automatically create a listener on p If you specify the option `recordType` you can decide if you want the construct to use CNAME or Route53-Aliases as record sets. +If you need to encrypt the traffic between the load balancer and the ECS tasks, you can set the `targetProtocol` to `HTTPS`. + Additionally, if more than one application target group are needed, instantiate one of the following: * `ApplicationMultipleTargetGroupsEc2Service` diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/base/application-load-balanced-service-base.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/base/application-load-balanced-service-base.ts index 24e2aa98fd430..e9dd04e494b82 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/base/application-load-balanced-service-base.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/base/application-load-balanced-service-base.ts @@ -3,7 +3,7 @@ import { IVpc } from '@aws-cdk/aws-ec2'; import { AwsLogDriver, BaseService, CloudMapOptions, Cluster, ContainerImage, ICluster, LogDriver, PropagatedTagSource, Secret } from '@aws-cdk/aws-ecs'; import { ApplicationListener, ApplicationLoadBalancer, ApplicationProtocol, ApplicationTargetGroup, - IApplicationLoadBalancer, ListenerCertificate, ListenerAction, + IApplicationLoadBalancer, ListenerCertificate, ListenerAction, AddApplicationTargetsProps, } from '@aws-cdk/aws-elasticloadbalancingv2'; import { IRole } from '@aws-cdk/aws-iam'; import { ARecord, IHostedZone, RecordTarget, CnameRecord } from '@aws-cdk/aws-route53'; @@ -88,6 +88,15 @@ export interface ApplicationLoadBalancedServiceBaseProps { */ readonly certificate?: ICertificate; + /** + * The protocol for connections from the load balancer to the ECS tasks. + * The default target port is determined from the protocol (port 80 for + * HTTP, port 443 for HTTPS). + * + * @default HTTP. + */ + readonly targetProtocol?: ApplicationProtocol; + /** * The protocol for connections from clients to the load balancer. * The load balancer port is determined from the protocol (port 80 for @@ -369,8 +378,8 @@ export abstract class ApplicationLoadBalancedServiceBase extends cdk.Construct { throw new Error('The HTTPS protocol must be used when redirecting HTTP traffic'); } - const targetProps = { - port: 80, + const targetProps: AddApplicationTargetsProps = { + protocol: props.targetProtocol ?? ApplicationProtocol.HTTP, }; this.listener = loadBalancer.addListener('PublicListener', { diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/test.load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/test.load-balanced-fargate-service.ts index 4c8152482ed06..0f6be905dca30 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/test.load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/test.load-balanced-fargate-service.ts @@ -229,6 +229,43 @@ export = { test.done(); }, + 'target group uses HTTP/80 as default'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'Service', { + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + }, + }); + // THEN + expect(stack).to(haveResourceLike('AWS::ElasticLoadBalancingV2::TargetGroup', { + Port: 80, + Protocol: 'HTTP', + })); + test.done(); + }, + + 'target group uses HTTPS/443 when configured'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'Service', { + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + }, + targetProtocol: ApplicationProtocol.HTTPS, + }); + // THEN + expect(stack).to(haveResourceLike('AWS::ElasticLoadBalancingV2::TargetGroup', { + Port: 443, + Protocol: 'HTTPS', + })); + test.done(); + }, + 'setting platform version'(test: Test) { // GIVEN const stack = new cdk.Stack();