From 531bf3d55008af11739615f7cbd2b95ec16de0a6 Mon Sep 17 00:00:00 2001 From: Nitzan Raz Date: Tue, 10 Jan 2023 23:16:52 +0200 Subject: [PATCH] ECS: supporting x-aws-assign_public_ip Allowing users to choose whether their instances should get a public IP address or not. Defaulting to "no". Signed-off-by: Nitzan Raz --- ecs/cloudformation.go | 5 +- ecs/cloudformation_test.go | 11 + .../input/slightly-complex-service.yaml | 9 + .../simple-cloudformation-conversion.golden | 2 +- ...y-complex-cloudformation-conversion.golden | 320 ++++++++++++++++++ ecs/x.go | 1 + 6 files changed, 346 insertions(+), 2 deletions(-) create mode 100644 ecs/testdata/input/slightly-complex-service.yaml create mode 100644 ecs/testdata/slightly-complex-cloudformation-conversion.golden diff --git a/ecs/cloudformation.go b/ecs/cloudformation.go index 8b673510b..77700a07a 100644 --- a/ecs/cloudformation.go +++ b/ecs/cloudformation.go @@ -235,7 +235,10 @@ func (b *ecsAPIService) createService(project *types.Project, service types.Serv return err } - assignPublicIP := ecsapi.AssignPublicIpEnabled + assignPublicIP := "DISABLED" + if assignPublicIPSetting, ok := service.Extensions[extensionAssignPublicIP]; ok && assignPublicIPSetting.(bool) { + assignPublicIP = ecsapi.AssignPublicIpEnabled + } launchType := ecsapi.LaunchTypeFargate platformVersion := "1.4.0" // LATEST which is set to 1.3.0 (?) which doesn’t allow efs volumes. if requireEC2(service) { diff --git a/ecs/cloudformation_test.go b/ecs/cloudformation_test.go index a957a5bc7..5f086d20b 100644 --- a/ecs/cloudformation_test.go +++ b/ecs/cloudformation_test.go @@ -51,6 +51,17 @@ func TestSimpleConvert(t *testing.T) { golden.Assert(t, result, expected) } +func TestSlightlyComplexConvert(t *testing.T) { + bytes, err := ioutil.ReadFile("testdata/input/slightly-complex-service.yaml") + assert.NilError(t, err) + template := convertYaml(t, string(bytes), nil, useDefaultVPC) + resultAsJSON, err := marshall(template, "yaml") + assert.NilError(t, err) + result := fmt.Sprintf("%s\n", string(resultAsJSON)) + expected := "slightly-complex-cloudformation-conversion.golden" + golden.Assert(t, result, expected) +} + func TestLogging(t *testing.T) { template := convertYaml(t, ` services: diff --git a/ecs/testdata/input/slightly-complex-service.yaml b/ecs/testdata/input/slightly-complex-service.yaml new file mode 100644 index 000000000..5315d942c --- /dev/null +++ b/ecs/testdata/input/slightly-complex-service.yaml @@ -0,0 +1,9 @@ +services: + entrance: + image: nginx + ports: + - "80:80" + x-aws-assign_public_ip: true + + sensitive: + image: python diff --git a/ecs/testdata/simple-cloudformation-conversion.golden b/ecs/testdata/simple-cloudformation-conversion.golden index 7f82eb5f0..bddb0f8f6 100644 --- a/ecs/testdata/simple-cloudformation-conversion.golden +++ b/ecs/testdata/simple-cloudformation-conversion.golden @@ -81,7 +81,7 @@ Resources: Ref: SimpleTCP80TargetGroup NetworkConfiguration: AwsvpcConfiguration: - AssignPublicIp: ENABLED + AssignPublicIp: DISABLED SecurityGroups: - Ref: DefaultNetwork Subnets: diff --git a/ecs/testdata/slightly-complex-cloudformation-conversion.golden b/ecs/testdata/slightly-complex-cloudformation-conversion.golden new file mode 100644 index 000000000..0e0be1330 --- /dev/null +++ b/ecs/testdata/slightly-complex-cloudformation-conversion.golden @@ -0,0 +1,320 @@ +AWSTemplateFormatVersion: 2010-09-09 +Resources: + CloudMap: + Properties: + Description: Service Map for Docker Compose project TestSlightlyComplexConvert + Name: TestSlightlyComplexConvert.local + Vpc: vpc-123 + Type: AWS::ServiceDiscovery::PrivateDnsNamespace + Cluster: + Properties: + ClusterName: TestSlightlyComplexConvert + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + Type: AWS::ECS::Cluster + Default80Ingress: + Properties: + CidrIp: 0.0.0.0/0 + Description: entrance:80/tcp on default network + FromPort: 80 + GroupId: + Ref: DefaultNetwork + IpProtocol: TCP + ToPort: 80 + Type: AWS::EC2::SecurityGroupIngress + DefaultNetwork: + Properties: + GroupDescription: TestSlightlyComplexConvert Security Group for default network + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + - Key: com.docker.compose.network + Value: TestSlightlyComplexConvert_default + VpcId: vpc-123 + Type: AWS::EC2::SecurityGroup + DefaultNetworkIngress: + Properties: + Description: Allow communication within network default + GroupId: + Ref: DefaultNetwork + IpProtocol: "-1" + SourceSecurityGroupId: + Ref: DefaultNetwork + Type: AWS::EC2::SecurityGroupIngress + EntranceService: + DependsOn: + - EntranceTCP80Listener + Properties: + Cluster: + Fn::GetAtt: + - Cluster + - Arn + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 100 + DeploymentController: + Type: ECS + DesiredCount: 1 + LaunchType: FARGATE + LoadBalancers: + - ContainerName: entrance + ContainerPort: 80 + TargetGroupArn: + Ref: EntranceTCP80TargetGroup + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - Ref: DefaultNetwork + Subnets: + - subnet1 + - subnet2 + PlatformVersion: 1.4.0 + PropagateTags: SERVICE + SchedulingStrategy: REPLICA + ServiceRegistries: + - RegistryArn: + Fn::GetAtt: + - EntranceServiceDiscoveryEntry + - Arn + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + - Key: com.docker.compose.service + Value: entrance + TaskDefinition: + Ref: EntranceTaskDefinition + Type: AWS::ECS::Service + EntranceServiceDiscoveryEntry: + Properties: + Description: '"entrance" service discovery entry in Cloud Map' + DnsConfig: + DnsRecords: + - TTL: 60 + Type: A + RoutingPolicy: MULTIVALUE + HealthCheckCustomConfig: + FailureThreshold: 1 + Name: entrance + NamespaceId: + Ref: CloudMap + Type: AWS::ServiceDiscovery::Service + EntranceTCP80Listener: + Properties: + DefaultActions: + - ForwardConfig: + TargetGroups: + - TargetGroupArn: + Ref: EntranceTCP80TargetGroup + Type: forward + LoadBalancerArn: + Ref: LoadBalancer + Port: 80 + Protocol: HTTP + Type: AWS::ElasticLoadBalancingV2::Listener + EntranceTCP80TargetGroup: + Properties: + Port: 80 + Protocol: HTTP + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + TargetType: ip + VpcId: vpc-123 + Type: AWS::ElasticLoadBalancingV2::TargetGroup + EntranceTaskDefinition: + Properties: + ContainerDefinitions: + - Command: + - .compute.internal + - TestSlightlyComplexConvert.local + Essential: false + Image: docker/ecs-searchdomain-sidecar:1.0 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-group: + Ref: LogGroup + awslogs-region: + Ref: AWS::Region + awslogs-stream-prefix: TestSlightlyComplexConvert + Name: Entrance_ResolvConf_InitContainer + - DependsOn: + - Condition: SUCCESS + ContainerName: Entrance_ResolvConf_InitContainer + Essential: true + Image: nginx + LinuxParameters: {} + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-group: + Ref: LogGroup + awslogs-region: + Ref: AWS::Region + awslogs-stream-prefix: TestSlightlyComplexConvert + Name: entrance + PortMappings: + - ContainerPort: 80 + HostPort: 80 + Protocol: tcp + Cpu: "256" + ExecutionRoleArn: + Ref: EntranceTaskExecutionRole + Family: TestSlightlyComplexConvert-entrance + Memory: "512" + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Type: AWS::ECS::TaskDefinition + EntranceTaskExecutionRole: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Condition: {} + Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Version: 2012-10-17 + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy + - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + - Key: com.docker.compose.service + Value: entrance + Type: AWS::IAM::Role + LoadBalancer: + Properties: + Scheme: internet-facing + SecurityGroups: + - Ref: DefaultNetwork + Subnets: + - subnet1 + - subnet2 + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + Type: application + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + LogGroup: + Properties: + LogGroupName: /docker-compose/TestSlightlyComplexConvert + Type: AWS::Logs::LogGroup + SensitiveService: + Properties: + Cluster: + Fn::GetAtt: + - Cluster + - Arn + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 100 + DeploymentController: + Type: ECS + DesiredCount: 1 + LaunchType: FARGATE + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: DISABLED + SecurityGroups: + - Ref: DefaultNetwork + Subnets: + - subnet1 + - subnet2 + PlatformVersion: 1.4.0 + PropagateTags: SERVICE + SchedulingStrategy: REPLICA + ServiceRegistries: + - RegistryArn: + Fn::GetAtt: + - SensitiveServiceDiscoveryEntry + - Arn + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + - Key: com.docker.compose.service + Value: sensitive + TaskDefinition: + Ref: SensitiveTaskDefinition + Type: AWS::ECS::Service + SensitiveServiceDiscoveryEntry: + Properties: + Description: '"sensitive" service discovery entry in Cloud Map' + DnsConfig: + DnsRecords: + - TTL: 60 + Type: A + RoutingPolicy: MULTIVALUE + HealthCheckCustomConfig: + FailureThreshold: 1 + Name: sensitive + NamespaceId: + Ref: CloudMap + Type: AWS::ServiceDiscovery::Service + SensitiveTaskDefinition: + Properties: + ContainerDefinitions: + - Command: + - .compute.internal + - TestSlightlyComplexConvert.local + Essential: false + Image: docker/ecs-searchdomain-sidecar:1.0 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-group: + Ref: LogGroup + awslogs-region: + Ref: AWS::Region + awslogs-stream-prefix: TestSlightlyComplexConvert + Name: Sensitive_ResolvConf_InitContainer + - DependsOn: + - Condition: SUCCESS + ContainerName: Sensitive_ResolvConf_InitContainer + Essential: true + Image: python + LinuxParameters: {} + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-group: + Ref: LogGroup + awslogs-region: + Ref: AWS::Region + awslogs-stream-prefix: TestSlightlyComplexConvert + Name: sensitive + Cpu: "256" + ExecutionRoleArn: + Ref: SensitiveTaskExecutionRole + Family: TestSlightlyComplexConvert-sensitive + Memory: "512" + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Type: AWS::ECS::TaskDefinition + SensitiveTaskExecutionRole: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Condition: {} + Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Version: 2012-10-17 + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy + - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly + Tags: + - Key: com.docker.compose.project + Value: TestSlightlyComplexConvert + - Key: com.docker.compose.service + Value: sensitive + Type: AWS::IAM::Role + diff --git a/ecs/x.go b/ecs/x.go index f85cd3f22..69fd57bcb 100644 --- a/ecs/x.go +++ b/ecs/x.go @@ -31,4 +31,5 @@ const ( extensionManagedPolicies = "x-aws-policies" extensionAutoScaling = "x-aws-autoscaling" extensionCloudFormation = "x-aws-cloudformation" + extensionAssignPublicIP = "x-aws-assign_public_ip" )