Skip to content

Commit

Permalink
fix(ecs): allow passing execution role to imported TaskDefinitions (#…
Browse files Browse the repository at this point in the history
…24987)

See #24984 for details.

TLDR; there's not a way currently exposed to define the `executionRole` on an imported `TaskDefinition`. This change allows optionally passing an `executionRole`.

Fixes issue #24984.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
blimmer authored Apr 18, 2023
1 parent 2d4a60d commit 0d156a8
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 2 deletions.
10 changes: 10 additions & 0 deletions packages/aws-cdk-lib/aws-ecs/lib/base/_imported-task-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ export interface ImportedTaskDefinitionProps {
* @default Permissions cannot be granted to the imported task.
*/
readonly taskRole?: IRole;

/**
* The IAM role that grants containers and Fargate agents permission to make AWS API calls on your behalf.
*
* Some tasks do not have an execution role.
*
* @default - undefined
*/
readonly executionRole?: IRole;
}

/**
Expand Down Expand Up @@ -70,6 +79,7 @@ export class ImportedTaskDefinition extends Resource implements IEc2TaskDefiniti

this.compatibility = props.compatibility ?? Compatibility.EC2_AND_FARGATE;
this.taskDefinitionArn = props.taskDefinitionArn;
this.executionRole = props.executionRole;
this._taskRole = props.taskRole;
this._networkMode = props.networkMode;
}
Expand Down
10 changes: 10 additions & 0 deletions packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ export interface CommonTaskDefinitionAttributes {
* @default Permissions cannot be granted to the imported task.
*/
readonly taskRole?: iam.IRole;

/**
* The IAM role that grants containers and Fargate agents permission to make AWS API calls on your behalf.
*
* Some tasks do not have an execution role.
*
* @default - undefined
*/
readonly executionRole?: iam.IRole;
}

/**
Expand Down Expand Up @@ -317,6 +326,7 @@ export class TaskDefinition extends TaskDefinitionBase {
compatibility: attrs.compatibility,
networkMode: attrs.networkMode,
taskRole: attrs.taskRole,
executionRole: attrs.executionRole,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export class Ec2TaskDefinition extends TaskDefinition implements IEc2TaskDefinit
compatibility: Compatibility.EC2,
networkMode: attrs.networkMode,
taskRole: attrs.taskRole,
executionRole: attrs.executionRole,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export class ExternalTaskDefinition extends TaskDefinition implements IExternalT
compatibility: Compatibility.EXTERNAL,
networkMode: attrs.networkMode,
taskRole: attrs.taskRole,
executionRole: attrs.executionRole,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export class FargateTaskDefinition extends TaskDefinition implements IFargateTas
compatibility: Compatibility.FARGATE,
networkMode: attrs.networkMode,
taskRole: attrs.taskRole,
executionRole: attrs.executionRole,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1201,12 +1201,16 @@ describe('ec2 task definition', () => {
const expectTaskRole = new iam.Role(stack, 'TaskRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const expectExecutionRole = new iam.Role(stack, 'ExecutionRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});

// WHEN
const taskDefinition = ecs.Ec2TaskDefinition.fromEc2TaskDefinitionAttributes(stack, 'TD_ID', {
taskDefinitionArn: expectTaskDefinitionArn,
networkMode: expectNetworkMode,
taskRole: expectTaskRole,
executionRole: expectExecutionRole,
});

// THEN
Expand All @@ -1216,6 +1220,7 @@ describe('ec2 task definition', () => {
expect(taskDefinition.isFargateCompatible).toBeFalsy();
expect(taskDefinition.networkMode).toBe(expectNetworkMode);
expect(taskDefinition.taskRole).toBe(expectTaskRole);
expect(taskDefinition.executionRole).toEqual(expectExecutionRole);
});

test('returns an Ec2 TaskDefinition that will throw an error when trying to access its yet to defined networkMode', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,4 +617,33 @@ describe('external task definition', () => {
deviceType: 'eia2.medium',
})).toThrow('Cannot use inference accelerators on tasks that run on External service');
});

test('can import an External Task Definition using attributes', () => {
// GIVEN
const stack = new cdk.Stack();
const expectTaskDefinitionArn = 'TD_ARN';
const expectCompatibility = ecs.Compatibility.EXTERNAL;
const expectNetworkMode = ecs.NetworkMode.AWS_VPC;
const expectTaskRole = new iam.Role(stack, 'TaskRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const expectExecutionRole = new iam.Role(stack, 'ExecutionRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});

// WHEN
const taskDefinition = ecs.ExternalTaskDefinition.fromExternalTaskDefinitionAttributes(stack, 'TD_ID', {
taskDefinitionArn: expectTaskDefinitionArn,
networkMode: expectNetworkMode,
taskRole: expectTaskRole,
executionRole: expectExecutionRole,
});

// THEN
expect(taskDefinition.taskDefinitionArn).toEqual(expectTaskDefinitionArn);
expect(taskDefinition.compatibility).toEqual(expectCompatibility);
expect(taskDefinition.executionRole).toEqual(expectExecutionRole);
expect(taskDefinition.networkMode).toEqual(expectNetworkMode);
expect(taskDefinition.taskRole).toEqual(expectTaskRole);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,16 @@ describe('fargate task definition', () => {
const expectTaskRole = new iam.Role(stack, 'TaskRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const expectExecutionRole = new iam.Role(stack, 'ExecutionRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});

// WHEN
const taskDefinition = ecs.FargateTaskDefinition.fromFargateTaskDefinitionAttributes(stack, 'TD_ID', {
taskDefinitionArn: expectTaskDefinitionArn,
networkMode: expectNetworkMode,
taskRole: expectTaskRole,
executionRole: expectExecutionRole,
});

// THEN
Expand All @@ -205,6 +209,7 @@ describe('fargate task definition', () => {
expect(taskDefinition.isEc2Compatible).toEqual(false);
expect(taskDefinition.networkMode).toEqual(expectNetworkMode);
expect(taskDefinition.taskRole).toEqual(expectTaskRole);
expect(taskDefinition.executionRole).toEqual(expectExecutionRole);


});
Expand Down Expand Up @@ -380,4 +385,4 @@ describe('fargate task definition', () => {
});

});
});
});
6 changes: 5 additions & 1 deletion packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,19 +303,23 @@ describe('task definition', () => {
const expectTaskRole = new iam.Role(stack, 'TaskRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const expectExecutionRole = new iam.Role(stack, 'ExecutionRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});

// WHEN
const taskDefinition = ecs.TaskDefinition.fromTaskDefinitionAttributes(stack, 'TD_ID', {
taskDefinitionArn: expectTaskDefinitionArn,
compatibility: expectCompatibility,
networkMode: expectNetworkMode,
taskRole: expectTaskRole,
executionRole: expectExecutionRole,
});

// THEN
expect(taskDefinition.taskDefinitionArn).toEqual(expectTaskDefinitionArn);
expect(taskDefinition.compatibility).toEqual(expectCompatibility);
expect(taskDefinition.executionRole).toEqual(undefined);
expect(taskDefinition.executionRole).toEqual(expectExecutionRole);
expect(taskDefinition.networkMode).toEqual(expectNetworkMode);
expect(taskDefinition.taskRole).toEqual(expectTaskRole);

Expand Down

0 comments on commit 0d156a8

Please sign in to comment.