2

In AWS CDK v2 the ECS TaskDefinition L2 construct has an optional property TaskRole if not specified CDK default behavior is to create a task role. However I do not want a task role set for this resource, it is not actually required in AWS - the Task Definition can function without this property. How can i manage that in CDK? I can't see any way to unset that task role or not have it generated in the first place. Do I need to step back to the L1 construct for this? My configuration:

taskDefinition := awsecs.NewEc2TaskDefinition(stack, jsii.String(deploymentEnv+service.Tag+"TaskDef"), &awsecs.Ec2TaskDefinitionProps{
            Family:      jsii.String(deploymentEnv + service.Tag), 
            NetworkMode: awsecs.NetworkMode_BRIDGE,
            //TaskRole: what can i do here to fix this
            Volumes: &[]*awsecs.Volume{
                &efs_shared_volume,
            },
        })
fedonev
  • 20,327
  • 2
  • 25
  • 34
Trevor Griffiths
  • 383
  • 3
  • 12

2 Answers2

3

In the CDK, it's necessary because the L2 construct implements the Grantable interface, and its methods depend on the existence of the role. Technically, you can override almost any property on any node which would allow you to get this effect, but that may result in difficult to track errors down the road.

Additionally, if no role is specified for a task definition, your tasks inherit permissions from the EC2 instance role in the cluster, which is almost certainly not a behavior you want. If that is the behavior you want, you're better off explicitly defining the role to be the same as the role used in the EC2 cluster.

Alternatively, if your intention is to make your tasks have no permissions, your best bet is to either stick with the default behavior or explicitly define a role with no attached policies then (optionally) pass the object returned by the .withoutPolicyUpdates on the role object to prevent it from being updated by grants.

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
  description: 'Empty ECS task role with no permissions',
});

// ...

taskDefinition := awsecs.NewEc2TaskDefinition(stack, jsii.String(deploymentEnv+service.Tag+"TaskDef"), &awsecs.Ec2TaskDefinitionProps{
            // ...
            TaskRole: role.withoutPolicyUpdates(),
            // ...
            },
        })
sytech
  • 29,298
  • 3
  • 45
  • 86
2

You can remove arbitrary child constructs by ID, using the tryRemoveChild escape hatch method:

// remove the role
taskDefinition.Node().TryRemoveChild(jsii.String("TaskRole"))

// remove the reference to the role
t := taskDefinition.Node().DefaultChild().(awsecs.CfnTaskDefinition)
t.AddPropertyDeletionOverride(jsii.String("TaskRoleArn"))

The trick is identifying the construct ID. You sometimes need to look for it in the source code.

fedonev
  • 20,327
  • 2
  • 25
  • 34
  • Is there a minimally painful way to do this in Go? Go has the issue of not easily being able to read json objects unless you marshall them into a struct - in which case you'd have to go to the trouble of defining the whole Cfn L1 construct as a struct - which in this case is a lot of work. – Trevor Griffiths Jan 19 '23 at 16:35
  • @TrevorGriffiths I am not sure what your question is. – fedonev Jan 19 '23 at 16:59
  • sorry i was not clear. It does look like go supports this directly as you said. I had been reading other docs like: https://www.go-on-aws.com/infrastructure-as-go/cdk-go/escape-hatches/modify_cfn/ which seem to indicate that the escape hatches are messy in go. I think they still might be if you need to modify not remove... – Trevor Griffiths Jan 20 '23 at 14:55
  • 1
    @TrevorGriffiths No worries, glad to help! I did test the code in the answer before posting. It produces the expected result, removing the role from the template. – fedonev Jan 20 '23 at 15:07
  • actually revisiting this i have noticed an issue. The escape hatch is successful at having CDK remove the role it generates, However, the container definition within the task definition still references the role that was removed and thus fails validation. I'm struggling to find a way to remove TaskRoleArn from the Container Definition. `Stack Deployments Failed: ValidationError: Template error: instance of Fn::GetAtt references undefined resource TaskDefTaskRole7E740C5E` – Trevor Griffiths Feb 10 '23 at 15:09
  • 1
    @TrevorGriffiths The edited answer's code nows also shows how to remove the reference to the role. – fedonev Feb 10 '23 at 16:27
  • that does it! you are a super hero. – Trevor Griffiths Feb 10 '23 at 19:44