For using AWS resources like S3 or DynamoDB in ECS containers, corresponding tasks should have necessary roles. However, usual AWS::IAM::Policy & AWS::IAM::Role combination that is sufficient for providing usual infrastructure priviledges will not be sufficient here, and there should also be a corresponding AWS::IAM::InstanceProfile.
This is explained in user guide. However, for me it was a little hard to figure out, and therefore wanted to document in case it will make someones life easier. To summarize, an application running in the ECS container is abstracted from underlying AWS by the virtualized operating system. Therefore, an additional step is needed to assign an AWS role and its associated permissions to make them available to applications. This is provided through AWS::IAM::InstanceProfile that is attached to the instance. The instance profile then will provide the role and its temporary credentials to an application that runs in the container. Then application in container will have the correspondingĀ temporary credentials to use in API calls to access resources.
For example, in order to provide programmatical access to S3 and DynamoDB to a container running in EC2 based ECS task, we can prepare role, profile and policy trio as;
ECSTaskRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'ecs.amazonaws.com' - 'ecs-tasks.amazonaws.com' Action: - 'sts:AssumeRole' Path: '/' RoleName: 'ECSInstanceRole' ECSTaskInstanceProfile: Type: 'AWS::IAM::InstanceProfile' Properties: Roles: - !Ref 'ECSTaskRole' ECSTaskPolicy: Type: AWS::IAM::Policy Properties: PolicyName: 'ECSTaskPolicy' PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'dynamodb:DescribeTable' - 'dynamodb:UpdateItem' - 'dynamodb:PutItem' - 'dynamodb:ListTables' - 'dynamodb:ListGlobalTables' - 's3:ListBucket' - 's3:PutObject' - 's3:CreateBucket' - 's3:ListAllMyBuckets' Resource: '*' Roles: - !Ref 'ECSTaskRole'
And use this role in corresponding task definition as;
TaskDefinition: Type: AWS::ECS::TaskDefinition DependsOn: VPC Properties: Family: 'ddgen' Cpu: '256' Memory: '512' TaskRoleArn: !Ref 'ECSTaskRole' RequiresCompatibilities: - EC2 ContainerDefinitions: - Name: !Ref AppName Image: docker.io/sifaserdarozen/ddgen:cloudformation Cpu: '256' PortMappings: - ContainerPort: 8080 HostPort: 8080 - ContainerPort: 443 HostPort: 443 Command: - './ddgen' - '--mirror' - '--useS3' - '--useDb' - '--ds' - '120' - '--dc' - '30' - '--nc' - '2' - '--sn' - 'ddgen' Memory: '512' Essential: true Tags: - Key: Name Value: !Ref 'EnvironmentName' service: Type: AWS::ECS::Service Properties: Cluster: !Ref Cluster DeploymentConfiguration: MaximumPercent: 200 MinimumHealthyPercent: 100 DesiredCount: 1 TaskDefinition: !Ref TaskDefinition ServiceName: ddgen
Corresponding code can be seen at DDGen repository.