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 d8761ff8e6e13..1f7f4d5428127 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 @@ -68,7 +68,7 @@ export interface ApplicationLoadBalancedServiceBaseProps { * @default HTTP. If a certificate is specified, the protocol will be * set by default to HTTPS. */ - readonly protocol?: ApplicationProtocol; + readonly protocol?: ApplicationProtocol; /** * The domain name for the service, e.g. "api.example.com." @@ -108,6 +108,13 @@ export interface ApplicationLoadBalancedServiceBaseProps { */ readonly loadBalancer?: ApplicationLoadBalancer; + /** + * Listener port of the application load balancer that will serve traffic to the service. + * + * @default 80 + */ + readonly listenerPort?: number; + /** * Specifies whether to propagate the tags from the task definition or the service to the tasks in the service. * Tags can only be propagated to the tasks within the service during service creation. @@ -273,17 +280,19 @@ export abstract class ApplicationLoadBalancedServiceBase extends cdk.Construct { this.loadBalancer = props.loadBalancer !== undefined ? props.loadBalancer : new ApplicationLoadBalancer(this, 'LB', lbProps); - const targetProps = { - port: 80 - }; - if (props.certificate !== undefined && props.protocol !== undefined && props.protocol !== ApplicationProtocol.HTTPS) { throw new Error('The HTTPS protocol must be used when a certificate is given'); } const protocol = props.protocol !== undefined ? props.protocol : (props.certificate ? ApplicationProtocol.HTTPS : ApplicationProtocol.HTTP); + const targetProps = { + port: props.listenerPort !== undefined ? props.listenerPort : 80, + protocol + }; + this.listener = this.loadBalancer.addListener('PublicListener', { protocol, + port: props.listenerPort, open: true }); this.targetGroup = this.listener.addTargets('ECS', targetProps); diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/base/network-load-balanced-service-base.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/base/network-load-balanced-service-base.ts index dd9a5818c7b1c..13f3a54aa1c7d 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/base/network-load-balanced-service-base.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/base/network-load-balanced-service-base.ts @@ -86,6 +86,13 @@ export interface NetworkLoadBalancedServiceBaseProps { */ readonly loadBalancer?: NetworkLoadBalancer; + /** + * Listener port of the network load balancer that will serve traffic to the service. + * + * @default 80 + */ + readonly listenerPort?: number; + /** * Specifies whether to propagate the tags from the task definition or the service to the tasks in the service. * Tags can only be propagated to the tasks within the service during service creation. @@ -245,11 +252,13 @@ export abstract class NetworkLoadBalancedServiceBase extends cdk.Construct { this.loadBalancer = props.loadBalancer !== undefined ? props.loadBalancer : new NetworkLoadBalancer(this, 'LB', lbProps); + const listenerPort = props.listenerPort !== undefined ? props.listenerPort : 80; + const targetProps = { - port: 80 + port: listenerPort }; - this.listener = this.loadBalancer.addListener('PublicListener', { port: 80 }); + this.listener = this.loadBalancer.addListener('PublicListener', { port: listenerPort }); this.targetGroup = this.listener.addTargets('ECS', targetProps); if (typeof props.domainName !== 'undefined') { diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.expected.json new file mode 100644 index 0000000000000..7ae1ae7e4ee78 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.expected.json @@ -0,0 +1,936 @@ +{ + "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/Vpc" + } + ] + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + } + ] + } + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ/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" + } + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ/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": "Name", + "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + } + ] + } + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ/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" + } + }, + "VpcPublicSubnet2NATGateway9182C01D": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet2EIP3C605A87", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ/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": "Name", + "Value": "aws-ecs-integ/Vpc/PrivateSubnet1" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ/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": "Name", + "Value": "aws-ecs-integ/Vpc/PrivateSubnet2" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableA678073B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-ecs-integ/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/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "ClusterEB0386A7": { + "Type": "AWS::ECS::Cluster" + }, + "FargateNlbServiceLBC7004B25": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "Scheme": "internet-facing", + "Subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "Type": "network" + }, + "DependsOn": [ + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet2DefaultRoute97F91067" + ] + }, + "FargateNlbServiceLBPublicListener91199F13": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "FargateNlbServiceLBPublicListenerECSGroup7501571D" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "FargateNlbServiceLBC7004B25" + }, + "Port": 2015, + "Protocol": "TCP" + } + }, + "FargateNlbServiceLBPublicListenerECSGroup7501571D": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 2015, + "Protocol": "TCP", + "TargetType": "ip", + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "FargateNlbServiceTaskDefTaskRoleD95D755C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "FargateNlbServiceTaskDef03021E9A": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "abiosoft/caddy", + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "FargateNlbServiceTaskDefwebLogGroup3547138D" + }, + "awslogs-stream-prefix": "FargateNlbService", + "awslogs-region": { + "Ref": "AWS::Region" + } + } + }, + "Name": "web", + "PortMappings": [ + { + "ContainerPort": 2015, + "Protocol": "tcp" + } + ] + } + ], + "Cpu": "256", + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "FargateNlbServiceTaskDefExecutionRole5E165F68", + "Arn" + ] + }, + "Family": "awsecsintegFargateNlbServiceTaskDef168F9D76", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "FargateNlbServiceTaskDefTaskRoleD95D755C", + "Arn" + ] + } + } + }, + "FargateNlbServiceTaskDefwebLogGroup3547138D": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "FargateNlbServiceTaskDefExecutionRole5E165F68": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "FargateNlbServiceTaskDefExecutionRoleDefaultPolicyC8326D5A": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "FargateNlbServiceTaskDefwebLogGroup3547138D", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "FargateNlbServiceTaskDefExecutionRoleDefaultPolicyC8326D5A", + "Roles": [ + { + "Ref": "FargateNlbServiceTaskDefExecutionRole5E165F68" + } + ] + } + }, + "FargateNlbService65A9DBF8": { + "Type": "AWS::ECS::Service", + "Properties": { + "TaskDefinition": { + "Ref": "FargateNlbServiceTaskDef03021E9A" + }, + "Cluster": { + "Ref": "ClusterEB0386A7" + }, + "DeploymentConfiguration": { + "MaximumPercent": 200, + "MinimumHealthyPercent": 50 + }, + "DesiredCount": 1, + "EnableECSManagedTags": false, + "HealthCheckGracePeriodSeconds": 60, + "LaunchType": "FARGATE", + "LoadBalancers": [ + { + "ContainerName": "web", + "ContainerPort": 2015, + "TargetGroupArn": { + "Ref": "FargateNlbServiceLBPublicListenerECSGroup7501571D" + } + } + ], + "NetworkConfiguration": { + "AwsvpcConfiguration": { + "AssignPublicIp": "DISABLED", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "FargateNlbServiceSecurityGroup4718761F", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + ] + } + } + }, + "DependsOn": [ + "FargateNlbServiceLBPublicListenerECSGroup7501571D", + "FargateNlbServiceLBPublicListener91199F13" + ] + }, + "FargateNlbServiceSecurityGroup4718761F": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-ecs-integ/FargateNlbService/Service/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "FargateAlbServiceLBA7128551": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "FargateAlbServiceLBSecurityGroupE10F3DF3", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "Type": "application" + }, + "DependsOn": [ + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet2DefaultRoute97F91067" + ] + }, + "FargateAlbServiceLBSecurityGroupE10F3DF3": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Automatically created Security Group for ELB awsecsintegFargateAlbServiceLBA9E1FE68", + "SecurityGroupIngress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow from anyone on port 2015", + "FromPort": 2015, + "IpProtocol": "tcp", + "ToPort": 2015 + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "FargateAlbServiceLBSecurityGrouptoawsecsintegFargateAlbServiceSecurityGroup0B11760820157EB4F873": { + "Type": "AWS::EC2::SecurityGroupEgress", + "Properties": { + "GroupId": { + "Fn::GetAtt": [ + "FargateAlbServiceLBSecurityGroupE10F3DF3", + "GroupId" + ] + }, + "IpProtocol": "tcp", + "Description": "Load balancer to target", + "DestinationSecurityGroupId": { + "Fn::GetAtt": [ + "FargateAlbServiceSecurityGroupF5AFFC6E", + "GroupId" + ] + }, + "FromPort": 2015, + "ToPort": 2015 + } + }, + "FargateAlbServiceLBPublicListener9C1349BE": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "FargateAlbServiceLBPublicListenerECSGroupB3826700" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "FargateAlbServiceLBA7128551" + }, + "Port": 2015, + "Protocol": "HTTP" + } + }, + "FargateAlbServiceLBPublicListenerECSGroupB3826700": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 2015, + "Protocol": "HTTP", + "TargetType": "ip", + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "FargateAlbServiceTaskDefTaskRoleC9259C01": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "FargateAlbServiceTaskDef291471C0": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "abiosoft/caddy", + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "FargateAlbServiceTaskDefwebLogGroup0BC14B46" + }, + "awslogs-stream-prefix": "FargateAlbService", + "awslogs-region": { + "Ref": "AWS::Region" + } + } + }, + "Name": "web", + "PortMappings": [ + { + "ContainerPort": 2015, + "Protocol": "tcp" + } + ] + } + ], + "Cpu": "256", + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "FargateAlbServiceTaskDefExecutionRole5FC6F0D2", + "Arn" + ] + }, + "Family": "awsecsintegFargateAlbServiceTaskDef1C0274E3", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "FargateAlbServiceTaskDefTaskRoleC9259C01", + "Arn" + ] + } + } + }, + "FargateAlbServiceTaskDefwebLogGroup0BC14B46": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "FargateAlbServiceTaskDefExecutionRole5FC6F0D2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "FargateAlbServiceTaskDefExecutionRoleDefaultPolicyD03CA136": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "FargateAlbServiceTaskDefwebLogGroup0BC14B46", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "FargateAlbServiceTaskDefExecutionRoleDefaultPolicyD03CA136", + "Roles": [ + { + "Ref": "FargateAlbServiceTaskDefExecutionRole5FC6F0D2" + } + ] + } + }, + "FargateAlbServiceB466E994": { + "Type": "AWS::ECS::Service", + "Properties": { + "TaskDefinition": { + "Ref": "FargateAlbServiceTaskDef291471C0" + }, + "Cluster": { + "Ref": "ClusterEB0386A7" + }, + "DeploymentConfiguration": { + "MaximumPercent": 200, + "MinimumHealthyPercent": 50 + }, + "DesiredCount": 1, + "EnableECSManagedTags": false, + "HealthCheckGracePeriodSeconds": 60, + "LaunchType": "FARGATE", + "LoadBalancers": [ + { + "ContainerName": "web", + "ContainerPort": 2015, + "TargetGroupArn": { + "Ref": "FargateAlbServiceLBPublicListenerECSGroupB3826700" + } + } + ], + "NetworkConfiguration": { + "AwsvpcConfiguration": { + "AssignPublicIp": "DISABLED", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "FargateAlbServiceSecurityGroupF5AFFC6E", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + ] + } + } + }, + "DependsOn": [ + "FargateAlbServiceLBPublicListenerECSGroupB3826700", + "FargateAlbServiceLBPublicListener9C1349BE" + ] + }, + "FargateAlbServiceSecurityGroupF5AFFC6E": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-ecs-integ/FargateAlbService/Service/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "FargateAlbServiceSecurityGroupfromawsecsintegFargateAlbServiceLBSecurityGroup2B85C6B72015203217AE": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "IpProtocol": "tcp", + "Description": "Load balancer to target", + "FromPort": 2015, + "GroupId": { + "Fn::GetAtt": [ + "FargateAlbServiceSecurityGroupF5AFFC6E", + "GroupId" + ] + }, + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "FargateAlbServiceLBSecurityGroupE10F3DF3", + "GroupId" + ] + }, + "ToPort": 2015 + } + } + }, + "Outputs": { + "FargateNlbServiceLoadBalancerDNS20395DB7": { + "Value": { + "Fn::GetAtt": [ + "FargateNlbServiceLBC7004B25", + "DNSName" + ] + } + }, + "FargateAlbServiceLoadBalancerDNSA91678BC": { + "Value": { + "Fn::GetAtt": [ + "FargateAlbServiceLBA7128551", + "DNSName" + ] + } + }, + "FargateAlbServiceServiceURL101F25CC": { + "Value": { + "Fn::Join": [ + "", + [ + "http://", + { + "Fn::GetAtt": [ + "FargateAlbServiceLBA7128551", + "DNSName" + ] + } + ] + ] + } + }, + "AlbDnsName": { + "Value": { + "Fn::GetAtt": [ + "FargateAlbServiceLBA7128551", + "DNSName" + ] + } + }, + "NlbDnsName": { + "Value": { + "Fn::GetAtt": [ + "FargateNlbServiceLBC7004B25", + "DNSName" + ] + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.ts new file mode 100644 index 0000000000000..55b803b0be1cb --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.ts @@ -0,0 +1,33 @@ +import ec2 = require('@aws-cdk/aws-ec2'); +import ecs = require('@aws-cdk/aws-ecs'); +import cdk = require('@aws-cdk/core'); +import ecsPatterns = require('../../lib'); + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-ecs-integ'); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2 }); + +const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); + +const fargateNlbService = new ecsPatterns.NetworkLoadBalancedFargateService(stack, "FargateNlbService", { + cluster, + listenerPort: 2015, + taskImageOptions: { + containerPort: 2015, + image: ecs.ContainerImage.fromRegistry('abiosoft/caddy') + }, +}); + +const fargateAlbService = new ecsPatterns.ApplicationLoadBalancedFargateService(stack, "FargateAlbService", { + cluster, + listenerPort: 2015, + taskImageOptions: { + containerPort: 2015, + image: ecs.ContainerImage.fromRegistry('abiosoft/caddy') + }, +}); + +new cdk.CfnOutput(stack, 'AlbDnsName', { value: fargateAlbService.loadBalancer.loadBalancerDnsName }); +new cdk.CfnOutput(stack, 'NlbDnsName', { value: fargateNlbService.loadBalancer.loadBalancerDnsName }); + +app.synth(); 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 e723a0f1c6959..8a80c866b6ac8 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 @@ -1,6 +1,7 @@ import { expect, haveResource, haveResourceLike, SynthUtils } from '@aws-cdk/assert'; import ec2 = require('@aws-cdk/aws-ec2'); import ecs = require('@aws-cdk/aws-ecs'); +import { ApplicationProtocol } from '@aws-cdk/aws-elasticloadbalancingv2'; import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/core'); import { Test } from 'nodeunit'; @@ -72,7 +73,7 @@ export = { // THEN const serviceTaskDefinition = SynthUtils.synthesize(stack).template.Resources.ServiceTaskDef1922A00F; - test.deepEqual(serviceTaskDefinition.Properties.ExecutionRoleArn, { 'Fn::GetAtt': [ 'ExecutionRole605A040B', 'Arn' ] }); + test.deepEqual(serviceTaskDefinition.Properties.ExecutionRoleArn, { 'Fn::GetAtt': ['ExecutionRole605A040B', 'Arn'] }); test.done(); }, @@ -100,7 +101,7 @@ export = { // THEN const serviceTaskDefinition = SynthUtils.synthesize(stack).template.Resources.ServiceTaskDef1922A00F; - test.deepEqual(serviceTaskDefinition.Properties.TaskRoleArn, { 'Fn::GetAtt': [ 'taskRoleTest9DA66B6E', 'Arn' ] }); + test.deepEqual(serviceTaskDefinition.Properties.TaskRoleArn, { 'Fn::GetAtt': ['taskRoleTest9DA66B6E', 'Arn'] }); test.done(); }, @@ -255,4 +256,159 @@ export = { test.done(); }, + 'setting NLB special listener port to create the listener'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); + + // WHEN + new ecsPatterns.NetworkLoadBalancedFargateService(stack, "FargateNlbService", { + cluster, + listenerPort: 2015, + taskImageOptions: { + containerPort: 2015, + image: ecs.ContainerImage.fromRegistry('abiosoft/caddy') + }, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::ElasticLoadBalancingV2::Listener', { + DefaultActions: [ + { + Type: "forward" + } + ], + Port: 2015, + Protocol: "TCP" + })); + + test.done(); + }, + 'setting ALB special listener port to create the listener'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); + + // WHEN + new ecsPatterns.ApplicationLoadBalancedFargateService(stack, "FargateAlbService", { + cluster, + listenerPort: 2015, + taskImageOptions: { + containerPort: 2015, + image: ecs.ContainerImage.fromRegistry('abiosoft/caddy') + }, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::ElasticLoadBalancingV2::Listener', { + DefaultActions: [ + { + Type: "forward" + } + ], + Port: 2015, + Protocol: "HTTP" + })); + + test.done(); + }, + + 'setting ALB HTTPS protocol to create the listener on 443'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); + + // WHEN + new ecsPatterns.ApplicationLoadBalancedFargateService(stack, "FargateAlbService", { + cluster, + protocol: ApplicationProtocol.HTTPS, + domainName: 'domain.com', + domainZone: { + hostedZoneId: 'fakeId', + zoneName: 'domain.com', + stack, + node: stack.node, + }, + taskImageOptions: { + containerPort: 2015, + image: ecs.ContainerImage.fromRegistry('abiosoft/caddy') + }, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::ElasticLoadBalancingV2::Listener', { + DefaultActions: [ + { + Type: "forward" + } + ], + Port: 443, + Protocol: "HTTPS" + })); + + test.done(); + }, + + 'setting ALB HTTP protocol to create the listener on 80'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); + + // WHEN + new ecsPatterns.ApplicationLoadBalancedFargateService(stack, "FargateAlbService", { + cluster, + protocol: ApplicationProtocol.HTTP, + taskImageOptions: { + containerPort: 2015, + image: ecs.ContainerImage.fromRegistry('abiosoft/caddy') + }, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::ElasticLoadBalancingV2::Listener', { + DefaultActions: [ + { + Type: "forward" + } + ], + Port: 80, + Protocol: "HTTP" + })); + + test.done(); + }, + + 'setting ALB without any protocol or listenerPort to create the listener on 80'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); + + // WHEN + new ecsPatterns.ApplicationLoadBalancedFargateService(stack, "FargateAlbService", { + cluster, + taskImageOptions: { + containerPort: 2015, + image: ecs.ContainerImage.fromRegistry('abiosoft/caddy') + }, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::ElasticLoadBalancingV2::Listener', { + DefaultActions: [ + { + Type: "forward" + } + ], + Port: 80, + Protocol: "HTTP" + })); + + test.done(); + }, + };