Skip to content

Commit 9b337df

Browse files
authored
fix(ecs): wrong ARN generated in Cluster.grantTaskProtection method (#36207)
The `Cluster.grantTaskProtection()` method is delegating to the method in the auto-generated `ClusterGrants` class. This class is generating policies with an incorrect ARN. It's using the cluster ARN (`:cluster/abc/*`) instead of the tasks ARN (`:task/abc/*`). Since the code generation mechanism doesn't provide any way of specifying a custom logic for the ARN generation, replace the auto-generated `ClusterGrants` with hand-written one, in which the ARN is computed by: ```ts private arnForTasks(keyPattern: string): string { return Stack.of(this.resource).formatArn({ service: 'ecs', resource: 'task', resourceName: `${this.resource.clusterRef.clusterName}/${keyPattern}`, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); } ``` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 4762f0e commit 9b337df

File tree

9 files changed

+93
-33
lines changed

9 files changed

+93
-33
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.cluster-grant-task-protection.js.snapshot/aws-ecs-integ.assets.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.cluster-grant-task-protection.js.snapshot/aws-ecs-integ.template.json

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,11 +423,21 @@
423423
"Fn::Join": [
424424
"",
425425
[
426+
"arn:",
426427
{
427-
"Fn::GetAtt": [
428-
"ClusterEB0386A7",
429-
"Arn"
430-
]
428+
"Ref": "AWS::Partition"
429+
},
430+
":ecs:",
431+
{
432+
"Ref": "AWS::Region"
433+
},
434+
":",
435+
{
436+
"Ref": "AWS::AccountId"
437+
},
438+
":task/",
439+
{
440+
"Ref": "ClusterEB0386A7"
431441
},
432442
"/*"
433443
]

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.cluster-grant-task-protection.js.snapshot/manifest.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.cluster-grant-task-protection.js.snapshot/tree.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/aws-cdk-lib/aws-ecs/grants.json

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* eslint-disable @stylistic/max-len, eol-last */
2+
import * as ecs from './ecs.generated';
3+
import { Grant, IGrantable } from '../../aws-iam';
4+
import { ArnFormat, Stack } from '../../core';
5+
6+
/**
7+
* Properties for ClusterGrants
8+
*/
9+
interface ClusterGrantsProps {
10+
/**
11+
* The resource on which actions will be allowed
12+
*/
13+
readonly resource: ecs.IClusterRef;
14+
}
15+
16+
/**
17+
* Collection of grant methods for a IClusterRef
18+
*/
19+
export class ClusterGrants {
20+
/**
21+
* Creates grants for ClusterGrants
22+
*/
23+
public static fromCluster(resource: ecs.IClusterRef): ClusterGrants {
24+
return new ClusterGrants({
25+
resource: resource,
26+
});
27+
}
28+
29+
protected readonly resource: ecs.IClusterRef;
30+
31+
private constructor(props: ClusterGrantsProps) {
32+
this.resource = props.resource;
33+
}
34+
35+
/**
36+
* Grants an ECS Task Protection API permission to the specified grantee.
37+
* This method provides a streamlined way to assign the 'ecs:UpdateTaskProtection'
38+
* permission, enabling the grantee to manage task protection in the ECS cluster.
39+
*/
40+
public taskProtection(grantee: IGrantable): Grant {
41+
const actions = ['ecs:UpdateTaskProtection'];
42+
return Grant.addToPrincipal({
43+
actions: actions,
44+
grantee: grantee,
45+
resourceArns: [this.arnForTasks('*')],
46+
});
47+
}
48+
49+
/**
50+
* Returns an ARN that represents all tasks within the cluster that match
51+
* the task pattern specified. To represent all tasks, specify ``"*"``.
52+
*
53+
* @param keyPattern Task id pattern
54+
*/
55+
private arnForTasks(keyPattern: string): string {
56+
return Stack.of(this.resource).formatArn({
57+
service: 'ecs',
58+
resource: 'task',
59+
resourceName: `${this.resource.clusterRef.clusterName}/${keyPattern}`,
60+
arnFormat: ArnFormat.SLASH_RESOURCE_NAME,
61+
});
62+
}
63+
}

packages/aws-cdk-lib/aws-ecs/lib/cluster.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Construct, IConstruct } from 'constructs';
22
import { BottleRocketImage, EcsOptimizedAmi } from './amis';
3+
import { ClusterGrants } from './cluster-grants';
34
import { InstanceDrainHook } from './drain-hook/instance-drain-hook';
45
import { ECSMetrics } from './ecs-canned-metrics.generated';
5-
import { ClusterGrants } from './ecs-grants.generated';
66
import {
77
CfnCluster,
88
CfnCapacityProvider,

packages/aws-cdk-lib/aws-ecs/lib/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export * from './container-definition';
88
export * from './container-image';
99
export * from './amis';
1010
export * from './cluster';
11+
export * from './cluster-grants';
1112
export * from './environment-file';
1213
export * from './credential-spec';
1314
export * from './firelens-log-router';
@@ -53,4 +54,3 @@ export * from './alternate-target-configuration';
5354
// AWS::ECS CloudFormation Resources:
5455
//
5556
export * from './ecs.generated';
56-
export * from './ecs-grants.generated';

packages/aws-cdk-lib/aws-ecs/test/cluster.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,12 +1323,14 @@ describe('cluster', () => {
13231323
'Fn::Join': [
13241324
'',
13251325
[
1326-
{
1327-
'Fn::GetAtt': [
1328-
'EcsCluster97242B84',
1329-
'Arn',
1330-
],
1331-
},
1326+
'arn:',
1327+
{ Ref: 'AWS::Partition' },
1328+
':ecs:',
1329+
{ Ref: 'AWS::Region' },
1330+
':',
1331+
{ Ref: 'AWS::AccountId' },
1332+
':task/',
1333+
{ Ref: 'EcsCluster97242B84' },
13321334
'/*',
13331335
],
13341336
],

0 commit comments

Comments
 (0)