Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Feature/aws ecs/add ability attaching policy for task role #1935

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/1935.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
plugin/aws: add ability to pass IAM Policy ARNs for attaching to task role
```
104 changes: 94 additions & 10 deletions builtin/aws/ecs/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,9 @@ func (p *Platform) Deploy(
return err
}

if p.config.TaskRoleName != "" {
taskRole, err = p.SetupTaskRole(ctx, s, log, sess, src)
if err != nil {
return err
}
taskRole, err = p.SetupTaskRole(ctx, s, log, sess, src)
if err != nil {
return err
}

logGroup, err = p.SetupLogs(ctx, s, log, sess)
Expand Down Expand Up @@ -438,20 +436,90 @@ func (p *Platform) SetupTaskRole(ctx context.Context, s LifecycleStatus, L hclog

roleName := p.config.TaskRoleName

if roleName == "" && p.config.TaskRolePolicyArns == nil {
return "", nil
}

if roleName == "" {
psihachina marked this conversation as resolved.
Show resolved Hide resolved
roleName = app.App + "-task-role"
}

// role names have to be 64 characters or less, and the client side doesn't validate this.
if len(roleName) > 64 {
roleName = roleName[:64]
L.Debug("using a shortened value for role name due to AWS's length limits", "roleName", roleName)
}

L.Debug("attempting to retrieve existing role", "role-name", roleName)

queryInput := &iam.GetRoleInput{
RoleName: aws.String(roleName),
}

getOut, err := svc.GetRole(queryInput)
var roleArn string

psihachina marked this conversation as resolved.
Show resolved Hide resolved
getOut, err := svc.GetRoleWithContext(ctx, queryInput)
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case "NoSuchEntity":
L.Debug("creating new role")
s.Status("Creating IAM role: %s", roleName)

input := &iam.CreateRoleInput{
AssumeRolePolicyDocument: aws.String(rolePolicy),
Path: aws.String("/"),
RoleName: aws.String(roleName),
}

result, err := svc.CreateRoleWithContext(ctx, input)
if err != nil {
return "", err
}

roleArn = *result.Role.Arn
default:
return "", err
}
} else {
return "", err
}
} else {
roleArn = *getOut.Role.Arn
}

listOut, err := svc.ListAttachedRolePoliciesWithContext(ctx, &iam.ListAttachedRolePoliciesInput{
RoleName: &roleName,
})

if err != nil {
s.Status("IAM role not found: %s", roleName)
return "", err
}

s.Status("Found task IAM role to use: %s", roleName)
return *getOut.Role.Arn, nil
for _, aPolicy := range p.config.TaskRolePolicyArns {
found := false
for _, policy := range listOut.AttachedPolicies {
if aPolicy == *policy.PolicyArn {
found = true
break
}
}

if !found {
_, err = svc.AttachRolePolicyWithContext(ctx, &iam.AttachRolePolicyInput{
PolicyArn: &aPolicy,
RoleName: &roleName,
})
if err != nil {
return "", err
}
}
}

L.Debug("attached task role policy")

s.Update("Created IAM role: %s", roleName)
return roleArn, nil
}

func (p *Platform) SetupExecutionRole(ctx context.Context, s LifecycleStatus, L hclog.Logger, sess *session.Session, app *component.Source) (string, error) {
Expand Down Expand Up @@ -1561,6 +1629,9 @@ type Config struct {
// Name of the execution task IAM Role to associate with the ECS Service
ExecutionRoleName string `hcl:"execution_role_name,optional"`

// IAM Policy ARNs for attaching to task role
TaskRolePolicyArns []string `hcl:"task_role_policy_arns,optional"`

// Name of the task IAM role to associate with the ECS service
TaskRoleName string `hcl:"task_role_name,optional"`

Expand Down Expand Up @@ -1660,7 +1731,20 @@ deploy {

doc.SetField(
"task_role_name",
"the name of the task IAM role to assign",
"the name of the task IAM role to assign.",
docs.Summary(
"If no role exists and a one or more task role policies are requested,",
"a role with this name will be created.",
),
)

doc.SetField(
"task_role_policy_arns",
"IAM Policy arns for attaching to the task role.",
docs.Summary(
"If no task role name is specified a task role with a default name",
"will be created for this app, and these policies will be attached.",
),
)

doc.SetField(
Expand Down
11 changes: 11 additions & 0 deletions website/content/partials/components/platform-aws-ecs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,20 @@ The VPC subnets to use for the application.

The name of the task IAM role to assign.

If no role exists and a one or more task role policies are requested, a role with this name will be created.

- Type: **string**
- **Optional**

#### task_role_policy_arns

IAM Policy arns for attaching to the task role.

If no task role name is specified a task role with a default name will be created for this app, and these policies will be attached.

- Type: **list of string**
- **Optional**

### Output Attributes

Output attributes can be used in your `waypoint.hcl` as [variables](/docs/waypoint-hcl/variables) via [`artifact`](/docs/waypoint-hcl/variables/artifact) or [`deploy`](/docs/waypoint-hcl/variables/deploy).
Expand Down