Skip to content

Commit

Permalink
chore: Add wildcard revision to imported taskdefinition. Fixes aws#30390
Browse files Browse the repository at this point in the history
  • Loading branch information
Joerg Woehrle committed Jun 7, 2024
1 parent 8f4d4d7 commit 3ac633e
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
10 changes: 9 additions & 1 deletion packages/aws-cdk-lib/aws-events-targets/lib/ecs-task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,18 @@ export class EcsTask implements events.IRuleTarget {
}

private createEventRolePolicyStatements(): iam.PolicyStatement[] {
// check if there is a taskdefinition revision (arn will end with : followed by digits) included in the arn already
let needsRevisionWildcard = false;
if ( !cdk.Token.isUnresolved(this.taskDefinition.taskDefinitionArn)) {
const revisionAtEndPattern = /:[0-9]+$/;
const hasRevision = revisionAtEndPattern.test(this.taskDefinition.taskDefinitionArn);
needsRevisionWildcard = !hasRevision;
}

const policyStatements = [
new iam.PolicyStatement({
actions: ['ecs:RunTask'],
resources: [this.taskDefinition.taskDefinitionArn],
resources: [`${this.taskDefinition.taskDefinitionArn}${needsRevisionWildcard ? ':*' : ''}`],
conditions: {
ArnEquals: { 'ecs:cluster': this.cluster.clusterArn },
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as iam from '../../../aws-iam';
import * as sqs from '../../../aws-sqs';
import * as cdk from '../../../core';
import * as targets from '../../lib';
import { EcsTask } from '../../lib';

let stack: cdk.Stack;
let vpc: ec2.Vpc;
Expand Down Expand Up @@ -1095,3 +1096,100 @@ test.each([
],
});
});

test('Non-imported TaskDefinition role is targeting by Ref', () => {
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef');
taskDefinition.addContainer('TheContainer', {
image: ecs.ContainerImage.fromRegistry('henk'),
});

const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.rate(cdk.Duration.hours(1)),
});

rule.addTarget(
new EcsTask({
cluster: cluster,
taskDefinition: taskDefinition,
}),
);

const policyMatch = Match.objectLike({
PolicyDocument: {
Statement: Match.arrayWith([
Match.objectLike({
Action: 'ecs:RunTask',
Resource: {
Ref: 'TaskDef54694570',
},
}),
]),
},
});
const template = Template.fromStack(stack);
template.hasResource('AWS::IAM::Policy', { Properties: policyMatch });
});

test('Imported task definition without revision adds wildcard to policy resource', () => {
const taskDefinition = ecs.FargateTaskDefinition.fromFargateTaskDefinitionAttributes(stack, 'TaskDefImport', {
taskDefinitionArn: 'arn:aws:ecs:us-west-2:012345678901:task-definition/MyTask',
taskRole: iam.Role.fromRoleArn(stack, 'RoleImport', 'arn:aws:iam::012345678901:role/MyTaskRole'),
networkMode: ecs.NetworkMode.AWS_VPC,
});

const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.rate(cdk.Duration.hours(1)),
});

rule.addTarget(
new EcsTask({
cluster: cluster,
taskDefinition: taskDefinition,
}),
);

const policyMatch = Match.objectLike({
PolicyDocument: {
Statement: Match.arrayWith([
Match.objectLike({
Action: 'ecs:RunTask',
Resource: `${taskDefinition.taskDefinitionArn}:*`,
}),
]),
},
});
const template = Template.fromStack(stack);
template.hasResource('AWS::IAM::Policy', { Properties: policyMatch });
});

test('Imported task definition with revision uses original arn for policy resource', () => {
const taskDefinition = ecs.FargateTaskDefinition.fromFargateTaskDefinitionAttributes(stack, 'TaskDefImport', {
taskDefinitionArn: 'arn:aws:ecs:us-west-2:012345678901:task-definition/MyTask:1',
taskRole: iam.Role.fromRoleArn(stack, 'RoleImport', 'arn:aws:iam::012345678901:role/MyTaskRole'),
networkMode: ecs.NetworkMode.AWS_VPC,
});

const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.rate(cdk.Duration.hours(1)),
});

rule.addTarget(
new EcsTask({
cluster: cluster,
taskDefinition: taskDefinition,
}),
);

const policyMatch = Match.objectLike({
PolicyDocument: {
Statement: Match.arrayWith([
Match.objectLike({
Action: 'ecs:RunTask',
Resource: taskDefinition.taskDefinitionArn,
}),
]),
},
});
const template = Template.fromStack(stack);
template.hasResource('AWS::IAM::Policy', { Properties: policyMatch });
});

0 comments on commit 3ac633e

Please sign in to comment.