Project: KICS (Provisioning / Security & Compliance)
File: 6c131358-c54d-419b-9dd6-1f7dd41d180c.md

title: ECS Cluster Not Encrypted At Rest hide: toc: true navigation: true <style> .highlight .hll { background-color: #ff171742; } .md-content { max-width: 1100px; margin: 0 auto; } </style> Query id: 6c131358-c54d-419b-9dd6-1f7dd41d180c Query name: ECS Cluster Not Encrypted At Rest Platform: CloudFormation Severity: <span style="color:#bb2124">High</span> Category: Encryption URL: Ensure that AWS ECS clusters are encrypted. Data encryption at rest, prevents unauthorized users from accessing sensitive data on your AWS ECS clusters and associated cache storage systems.<br> ```yaml title="Positive test num. 1 - yaml file" hl_lines="37" Resources: cluster: Type: AWS::ECS::Cluster taskdefinition: Type: AWS::ECS::TaskDefinition Properties: ContainerDefinitions: Name: !Ref AppName MountPoints: SourceVolume: my-vol ContainerPath: /var/www/my-vol Image: amazon/amazon-ecs-sample Cpu: '10' PortMappings: ContainerPort: !Ref AppContainerPort HostPort: !Ref AppHostPort EntryPoint: /usr/sbin/apache2 '-D' FOREGROUND Memory: '500' Essential: true Name: busybox Image: busybox Cpu: '10' EntryPoint: sh '-c' Memory: '500' Command: >- /bin/sh -c "while true; do /bin/date > /var/www/my-vol/date; sleep 1; done" Essential: false VolumesFrom: SourceContainer: !Ref AppName Volumes: Host: SourcePath: /var/lib/docker/vfs/dir/ Name: my-vol EFSVolumeConfiguration: TransitEncryption: DISABLED TransitEncryptionPort: 8080 service: Type: AWS::ECS::Service Properties: Cluster: !Ref cluster DeploymentConfiguration: MaximumPercent: 200 MinimumHealthyPercent: 100 DesiredCount: 0 HealthCheckGracePeriodSeconds: !Ref HealthCheckGracePeriodSeconds LoadBalancers: ContainerName: !Ref AppName ContainerPort: !Ref AppContainerPort LoadBalancerName: !Ref elb PlacementStrategies: Type: binpack Field: memory Type: spread Field: host PlacementConstraints: Type: memberOf Expression: 'attribute:ecs.availability-zone != us-east-1d' Type: distinctInstance TaskDefinition: !Ref taskdefinition ServiceName: !Ref ServiceName Role: !Ref Role elb: Type: AWS::ElasticLoadBalancing::LoadBalancer Properties: LoadBalancerName: !Ref LoadBalancerName Listeners: InstancePort: !Ref AppHostPort LoadBalancerPort: '80' Protocol: HTTP Subnets: !Ref Subnet1 DependsOn: GatewayAttachment VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/24 Subnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.0.0/25 InternetGateway: Type: AWS::EC2::InternetGateway GatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2008-10-17 Statement: Sid: '' Effect: Allow Principal: Service: ecs.amazonaws.com Action: 'sts:AssumeRole' ManagedPolicyArns: 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole' ``` ```yaml title="Positive test num. 2 - yaml file" hl_lines="26" Resources: cluster: Type: AWS::ECS::Cluster service: Type: AWS::ECS::Service Properties: Cluster: !Ref cluster DeploymentConfiguration: MaximumPercent: 200 MinimumHealthyPercent: 100 DesiredCount: 0 HealthCheckGracePeriodSeconds: !Ref HealthCheckGracePeriodSeconds LoadBalancers: ContainerName: !Ref AppName ContainerPort: !Ref AppContainerPort LoadBalancerName: !Ref elb PlacementStrategies: Type: binpack Field: memory Type: spread Field: host PlacementConstraints: Type: memberOf Expression: 'attribute:ecs.availability-zone != us-east-1d' Type: distinctInstance TaskDefinition: !Ref taskdefinition1 ServiceName: !Ref ServiceName Role: !Ref Role elb: Type: AWS::ElasticLoadBalancing::LoadBalancer Properties: LoadBalancerName: !Ref LoadBalancerName Listeners: InstancePort: !Ref AppHostPort LoadBalancerPort: '80' Protocol: HTTP Subnets: !Ref Subnet1 DependsOn: GatewayAttachment VPC2: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/24 Subnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.0.0/25 InternetGateway: Type: AWS::EC2::InternetGateway GatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2008-10-17 Statement: Sid: '' Effect: Allow Principal: Service: ecs.amazonaws.com Action: 'sts:AssumeRole' ManagedPolicyArns: 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole' ``` ```json title="Positive test num. 3 - json file" hl_lines="122" { "Resources": { "cluster": { "Type": "AWS::ECS::Cluster" }, "service": { "Type": "AWS::ECS::Service", "Properties": { "LoadBalancers": [ { "ContainerName": "AppName", "ContainerPort": "AppContainerPort", "LoadBalancerName": "elb" } ], "PlacementStrategies": [ { "Type": "binpack", "Field": "memory" }, { "Type": "spread", "Field": "host" } ], "PlacementConstraints": [ { "Expression":

!= us-east-1d", "Type": "memberOf" }, { "Type": "distinctInstance" } ], "Role": "Role", "DeploymentConfiguration": { "MaximumPercent": 200, "MinimumHealthyPercent": 100 }, "DesiredCount": 0, "TaskDefinition": "taskdefinition", "ServiceName": "ServiceName", "Cluster": "cluster", "HealthCheckGracePeriodSeconds": "HealthCheckGracePeriodSeconds" } }, "elb": { "DependsOn": "GatewayAttachment", "Type": "AWS::ElasticLoadBalancing::LoadBalancer", "Properties": { "LoadBalancerName": "LoadBalancerName", "Listeners": [ { "LoadBalancerPort": "80", "Protocol": "HTTP", "InstancePort": "AppHostPort" } ], "Subnets": [ "Subnet1" ] } }, "InternetGateway": { "Type": "AWS::EC2::InternetGateway" }, "GatewayAttachment": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": "VPC", "InternetGatewayId": "InternetGateway" } }, "taskdefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ { "Essential": true, "Name": "AppName", "MountPoints": [ { "SourceVolume": "my-vol", "ContainerPath": "/var/www/my-vol" } ], "Image": "amazon/amazon-ecs-sample", "Cpu": "10", "PortMappings": [ { "ContainerPort": "AppContainerPort", "HostPort": "AppHostPort" } ], "EntryPoint": [ "/usr/sbin/apache2", "-D", "FOREGROUND" ], "Memory": "500" }, { "Memory": "500", "Command": [ "/bin/sh -c \"while true; do /bin/date \u003e /var/www/my-vol/date; sleep 1; done\"" ], "Essential": false, "VolumesFrom": [ { "SourceContainer": "AppName" } ], "Name": "busybox", "Image": "busybox", "Cpu": "10", "EntryPoint": [ "sh", "-c" ] } ], "Volumes": [ { "Host": { "SourcePath": "/var/lib/docker/vfs/dir/" }, "Name": "my-vol", "EFSVolumeConfiguration": { "TransitEncryption": "DISABLED", "TransitEncryptionPort": 8080 } } ] } }, "VPC": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.0.0.0/24" } }, "Subnet1": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": "VPC", "CidrBlock": "10.0.0.0/25" } }, "Role": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2008-10-17T00:00:00Z", "Statement": [ { "Principal": { "Service": "ecs.amazonaws.com" }, "Action": "sts:AssumeRole", "Sid": "", "Effect": "Allow" } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole" ] } } } } ``` <details><summary>Positive test num. 4 - json file</summary> ```json hl_lines="54" { "Resources": { "InternetGateway": { "Type": "AWS::EC2::InternetGateway" }, "GatewayAttachment": { "Properties": { "InternetGatewayId": "InternetGateway", "VpcId": "VPC" }, "Type": "AWS::EC2::VPCGatewayAttachment" }, "Role": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ecs.amazonaws.com" }, "Action": "sts:AssumeRole" } ], "Version": "2008-10-17T00:00:00Z" }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole" ] } }, "cluster": { "Type": "AWS::ECS::Cluster" }, "service": { "Type": "AWS::ECS::Service", "Properties": { "PlacementConstraints": [ { "Type": "memberOf", "Expression": "attribute:ecs.availability-zone != us-east-1d" }, { "Type": "distinctInstance" } ], "ServiceName": "ServiceName", "Role": "Role", "Cluster": "cluster", "DesiredCount": 0, "HealthCheckGracePeriodSeconds": "HealthCheckGracePeriodSeconds", "TaskDefinition": "taskdefinition1", "DeploymentConfiguration": { "MaximumPercent": 200, "MinimumHealthyPercent": 100 }, "LoadBalancers": [ { "ContainerName": "AppName", "ContainerPort": "AppContainerPort", "LoadBalancerName": "elb" } ], "PlacementStrategies": [ { "Type": "binpack", "Field": "memory" }, { "Type": "spread", "Field": "host" } ] } }, "elb": { "Type": "AWS::ElasticLoadBalancing::LoadBalancer", "Properties": { "LoadBalancerName": "LoadBalancerName", "Listeners": [ { "LoadBalancerPort": "80", "Protocol": "HTTP", "InstancePort": "AppHostPort" } ], "Subnets": [ "Subnet1" ] }, "DependsOn": "GatewayAttachment" }, "VPC2": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.0.0.0/24" } }, "Subnet1": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": "VPC", "CidrBlock": "10.0.0.0/25" } } } } ``` </details> ```yaml title="Negative test

1 - yaml file" AWSTemplateFormatVersion: 2010-09-09 Description: Creating ECS service Parameters: AppName: Type: String Description: Name of app requiring ELB exposure Default: simple-app AppContainerPort: Type: Number Description: Container port of app requiring ELB exposure Default: '80' AppHostPort: Type: Number Description: Host port of app requiring ELB exposure Default: '80' ServiceName: Type: String LoadBalancerName: Type: String HealthCheckGracePeriodSeconds: Type: String Resources: cluster: Type: AWS::ECS::Cluster taskdefinition: Type: AWS::ECS::TaskDefinition Properties: ContainerDefinitions: Name: !Ref AppName MountPoints: SourceVolume: my-vol ContainerPath: /var/www/my-vol Image: amazon/amazon-ecs-sample Cpu: '10' PortMappings: ContainerPort: !Ref AppContainerPort HostPort: !Ref AppHostPort EntryPoint: /usr/sbin/apache2 '-D' FOREGROUND Memory: '500' Essential: true Name: busybox Image: busybox Cpu: '10' EntryPoint: sh '-c' Memory: '500' Command: >- /bin/sh -c "while true; do /bin/date > /var/www/my-vol/date; sleep 1; done" Essential: false VolumesFrom: SourceContainer: !Ref AppName Volumes: Host: SourcePath: /var/lib/docker/vfs/dir/ Name: my-vol EFSVolumeConfiguration: TransitEncryption: ENABLED TransitEncryptionPort: 8080 service: Type: AWS::ECS::Service Properties: Cluster: !Ref cluster DeploymentConfiguration: MaximumPercent: 200 MinimumHealthyPercent: 100 DesiredCount: 0 HealthCheckGracePeriodSeconds: !Ref HealthCheckGracePeriodSeconds LoadBalancers: ContainerName: !Ref AppName ContainerPort: !Ref AppContainerPort LoadBalancerName: !Ref elb PlacementStrategies: Type: binpack Field: memory Type: spread Field: host PlacementConstraints: Type: memberOf Expression: 'attribute:ecs.availability-zone != us-east-1d' Type: distinctInstance TaskDefinition: !Ref taskdefinition ServiceName: !Ref ServiceName Role: !Ref Role elb: Type: AWS::ElasticLoadBalancing::LoadBalancer Properties: LoadBalancerName: !Ref LoadBalancerName Listeners: InstancePort: !Ref AppHostPort LoadBalancerPort: '80' Protocol: HTTP Subnets: !Ref Subnet1 DependsOn: GatewayAttachment VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/24 Subnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.0.0/25 InternetGateway: Type: AWS::EC2::InternetGateway GatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2008-10-17 Statement: Sid: '' Effect: Allow Principal: Service: ecs.amazonaws.com Action: 'sts:AssumeRole' ManagedPolicyArns: 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole' Outputs: Cluster: Value: !Ref cluster ``` ```json title="Negative test num. 2 - json file" { "AWSTemplateFormatVersion": "2010-09-09T00:00:00Z", "Description": "Creating ECS service", "Parameters": { "HealthCheckGracePeriodSeconds": { "Type": "String" }, "AppName": { "Type": "String", "Description": "Name of app requiring ELB exposure", "Default": "simple-app" }, "AppContainerPort": { "Type": "Number", "Description": "Container port of app requiring ELB exposure", "Default": "80" }, "AppHostPort": { "Type": "Number", "Description": "Host port of app requiring ELB exposure", "Default": "80" }, "ServiceName": { "Type": "String" }, "LoadBalancerName": { "Type": "String" } }, "Resources": { "InternetGateway": { "Type": "AWS::EC2::InternetGateway" }, "GatewayAttachment": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "InternetGatewayId": "InternetGateway", "VpcId": "VPC" } }, "Role": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2008-10-17T00:00:00Z", "Statement": [ { "Action": "sts:AssumeRole", "Sid": "", "Effect": "Allow", "Principal": { "Service": "ecs.amazonaws.com" } } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole" ] } }, "cluster": { "Type": "AWS::ECS::Cluster" }, "service": { "Type": "AWS::ECS::Service", "Properties": { "DeploymentConfiguration": { "MaximumPercent": 200, "MinimumHealthyPercent": 100 }, "TaskDefinition": "taskdefinition", "Role": "Role", "LoadBalancers": [ { "ContainerName": "AppName", "ContainerPort": "AppContainerPort", "LoadBalancerName": "elb" } ], "PlacementStrategies": [ { "Type": "binpack", "Field": "memory" }, { "Type": "spread", "Field": "host" } ], "PlacementConstraints": [ { "Type": "memberOf", "Expression": "attribute:ecs.availability-zone != us-east-1d" }, { "Type": "distinctInstance" } ], "ServiceName": "ServiceName", "Cluster": "cluster", "DesiredCount": 0, "HealthCheckGracePeriodSeconds": "HealthCheckGracePeriodSeconds" } }, "elb": { "Type": "AWS::ElasticLoadBalancing::LoadBalancer", "Properties": { "Subnets": [ "Subnet1" ], "LoadBalancerName": "LoadBalancerName", "Listeners": [ { "LoadBalancerPort": "80", "Protocol": "HTTP", "InstancePort": "AppHostPort" } ] }, "DependsOn": "GatewayAttachment" }, "VPC": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.0.0.0/24" } }, "Subnet1": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.0.0/25", "VpcId": "VPC" } }, "taskdefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ { "Image": "amazon/amazon-ecs-sample", "Cpu": "10", "PortMappings": [ { "HostPort": "AppHostPort", "ContainerPort": "AppContainerPort" } ], "EntryPoint": [ "/usr/sbin/apache2", "-D", "FOREGROUND" ], "Memory": "500", "Essential": true, "Name": "AppName", "MountPoints": [ { "SourceVolume": "my-vol", "ContainerPath": "/var/www/my-vol" } ] }, { "Cpu": "10", "EntryPoint": [ "sh", "-c" ], "Memory": "500", "Command": [ "/bin/sh -c \"while true; do /bin/date \u003e /var/www/my-vol/date; sleep 1; done\"" ], "Essential": false, "VolumesFrom": [ { "SourceContainer": "AppName" } ], "Name": "busybox", "Image": "busybox" } ], "Volumes": [ { "Host":