Merge pull request #595 from docker/IAM

Distinguish TaskExecutionRole and TaskRole
This commit is contained in:
Guillaume Tardif 2020-09-09 11:37:22 +02:00 committed by GitHub
commit eaabee12e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 30 deletions

View File

@ -159,12 +159,14 @@ func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Templat
return nil, err return nil, err
} }
taskExecutionRole, err := createTaskExecutionRole(service, err, definition, template) taskExecutionRole := createTaskExecutionRole(service, definition, template)
if err != nil {
return template, err
}
definition.ExecutionRoleArn = cloudformation.Ref(taskExecutionRole) definition.ExecutionRoleArn = cloudformation.Ref(taskExecutionRole)
taskRole := createTaskRole(service, template)
if taskRole != "" {
definition.TaskRoleArn = cloudformation.Ref(taskRole)
}
taskDefinition := fmt.Sprintf("%sTaskDefinition", normalizeResourceName(service.Name)) taskDefinition := fmt.Sprintf("%sTaskDefinition", normalizeResourceName(service.Name))
template.Resources[taskDefinition] = definition template.Resources[taskDefinition] = definition
@ -459,40 +461,43 @@ func createServiceRegistry(service types.ServiceConfig, template *cloudformation
return serviceRegistry return serviceRegistry
} }
func createTaskExecutionRole(service types.ServiceConfig, err error, definition *ecs.TaskDefinition, template *cloudformation.Template) (string, error) { func createTaskExecutionRole(service types.ServiceConfig, definition *ecs.TaskDefinition, template *cloudformation.Template) string {
taskExecutionRole := fmt.Sprintf("%sTaskExecutionRole", normalizeResourceName(service.Name)) taskExecutionRole := fmt.Sprintf("%sTaskExecutionRole", normalizeResourceName(service.Name))
policy := getPolicy(definition) policies := createPolicies(service, definition)
if err != nil { template.Resources[taskExecutionRole] = &iam.Role{
return taskExecutionRole, err AssumeRolePolicyDocument: assumeRolePolicyDocument,
} Policies: policies,
rolePolicies := []iam.Role_Policy{} ManagedPolicyArns: []string{
if policy != nil { ecsTaskExecutionPolicy,
rolePolicies = append(rolePolicies, iam.Role_Policy{ ecrReadOnlyPolicy,
PolicyDocument: policy, },
PolicyName: fmt.Sprintf("%sGrantAccessToSecrets", service.Name),
})
} }
return taskExecutionRole
}
func createTaskRole(service types.ServiceConfig, template *cloudformation.Template) string {
taskRole := fmt.Sprintf("%sTaskRole", normalizeResourceName(service.Name))
rolePolicies := []iam.Role_Policy{}
if roles, ok := service.Extensions[extensionRole]; ok { if roles, ok := service.Extensions[extensionRole]; ok {
rolePolicies = append(rolePolicies, iam.Role_Policy{ rolePolicies = append(rolePolicies, iam.Role_Policy{
PolicyDocument: roles, PolicyDocument: roles,
}) })
} }
managedPolicies := []string{ managedPolicies := []string{}
ecsTaskExecutionPolicy,
ecrReadOnlyPolicy,
}
if v, ok := service.Extensions[extensionManagedPolicies]; ok { if v, ok := service.Extensions[extensionManagedPolicies]; ok {
for _, s := range v.([]interface{}) { for _, s := range v.([]interface{}) {
managedPolicies = append(managedPolicies, s.(string)) managedPolicies = append(managedPolicies, s.(string))
} }
} }
template.Resources[taskExecutionRole] = &iam.Role{ if len(rolePolicies) == 0 && len(managedPolicies) == 0 {
return ""
}
template.Resources[taskRole] = &iam.Role{
AssumeRolePolicyDocument: assumeRolePolicyDocument, AssumeRolePolicyDocument: assumeRolePolicyDocument,
Policies: rolePolicies, Policies: rolePolicies,
ManagedPolicyArns: managedPolicies, ManagedPolicyArns: managedPolicies,
} }
return taskExecutionRole, nil return taskRole
} }
func createCluster(project *types.Project, template *cloudformation.Template) string { func createCluster(project *types.Project, template *cloudformation.Template) string {
@ -582,7 +587,7 @@ func normalizeResourceName(s string) string {
return strings.Title(regexp.MustCompile("[^a-zA-Z0-9]+").ReplaceAllString(s, "")) return strings.Title(regexp.MustCompile("[^a-zA-Z0-9]+").ReplaceAllString(s, ""))
} }
func getPolicy(taskDef *ecs.TaskDefinition) *PolicyDocument { func createPolicies(service types.ServiceConfig, taskDef *ecs.TaskDefinition) []iam.Role_Policy {
arns := []string{} arns := []string{}
for _, container := range taskDef.ContainerDefinitions { for _, container := range taskDef.ContainerDefinitions {
if container.RepositoryCredentials != nil { if container.RepositoryCredentials != nil {
@ -596,13 +601,19 @@ func getPolicy(taskDef *ecs.TaskDefinition) *PolicyDocument {
} }
if len(arns) > 0 { if len(arns) > 0 {
return &PolicyDocument{ return []iam.Role_Policy{
{
PolicyDocument: &PolicyDocument{
Statement: []PolicyStatement{ Statement: []PolicyStatement{
{ {
Effect: "Allow", Effect: "Allow",
Action: []string{actionGetSecretValue, actionGetParameters, actionDecrypt}, Action: []string{actionGetSecretValue, actionGetParameters, actionDecrypt},
Resource: arns, Resource: arns,
}}, },
},
},
PolicyName: fmt.Sprintf("%sGrantAccessToSecrets", service.Name),
},
} }
} }
return nil return nil

View File

@ -99,7 +99,7 @@ func TestCompose(t *testing.T) {
}) })
t.Run("compose ls", func(t *testing.T) { t.Run("compose ls", func(t *testing.T) {
res := c.RunDockerCmd("compose", "ls") res := c.RunDockerCmd("compose", "ls", "--project-name", stack)
lines := strings.Split(strings.TrimSpace(res.Stdout()), "\n") lines := strings.Split(strings.TrimSpace(res.Stdout()), "\n")
assert.Equal(t, 2, len(lines)) assert.Equal(t, 2, len(lines))