ECS cluster not encrypted at rest
This product is not supported for your selected
Datadog site. (
).
Id: 6c131358-c54d-419b-9dd6-1f7dd41d180c
Cloud Provider: AWS
Platform: CloudFormation
Severity: High
Category: Encryption
Learn More
Description
Amazon EFS transit encryption must be enabled for Amazon ECS task definitions that mount EFS volumes. This protects data in transit between containers and the EFS file system from interception or tampering and can help meet common compliance requirements.
In CloudFormation, inspect the AWS::ECS::Service resource’s TaskDefinition reference. Then verify the referenced AWS::ECS::TaskDefinition resource has Properties.Volumes[].EFSVolumeConfiguration.TransitEncryption set to ENABLED. Resources will be flagged if the referenced task definition is missing, or if any volume has TransitEncryption set to DISABLED or is not defined. Secure example task definition configuration:
MyTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: app
Image: my-image
Volumes:
- Name: efsVolume
EFSVolumeConfiguration:
FileSystemId: fs-0123456789abcdef0
TransitEncryption: ENABLED
Compliant Code Examples
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
{
"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": {
"SourcePath": "/var/lib/docker/vfs/dir/"
},
"Name": "my-vol",
"EFSVolumeConfiguration": {
"TransitEncryption": "ENABLED",
"TransitEncryptionPort": 8080
}
}
]
}
}
},
"Outputs": {
"Cluster": {
"Value": "cluster"
}
}
}
Non-Compliant Code Examples
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'
{
"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": "attribute:ecs.availability-zone != 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"
]
}
}
}
}
{
"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"
}
}
}
}