Skip to content

Commit 6d091c2

Browse files
authored
feat(ecs): support version stages and ids for Secrets (#18174)
Adds a new `Secret.fromSecretsManagerVersion` method that allows a stage or id to be provided. It will then be added to the secret string handed over to ECS. fixes #18123 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 0ef6527 commit 6d091c2

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

packages/@aws-cdk/aws-ecs/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ const newContainer = taskDefinition.addContainer('container', {
427427
secrets: { // Retrieved from AWS Secrets Manager or AWS Systems Manager Parameter Store at container start-up.
428428
SECRET: ecs.Secret.fromSecretsManager(secret),
429429
DB_PASSWORD: ecs.Secret.fromSecretsManager(dbSecret, 'password'), // Reference a specific JSON field, (requires platform version 1.4.0 or later for Fargate tasks)
430+
API_KEY: ecs.Secret.fromSecretsManagerVersion(secret, { versionId: '12345' }, 'apiKey'), // Reference a specific version of the secret by its version id or version stage (requires platform version 1.4.0 or later for Fargate tasks)
430431
PARAMETER: ecs.Secret.fromSsmParameter(parameter),
431432
},
432433
});

packages/@aws-cdk/aws-ecs/lib/container-definition.ts

+37
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ import { LogDriver, LogDriverConfig } from './log-drivers/log-driver';
1414
// eslint-disable-next-line no-duplicate-imports, import/order
1515
import { Construct as CoreConstruct } from '@aws-cdk/core';
1616

17+
/**
18+
* Specify the secret's version id or version stage
19+
*/
20+
export interface SecretVersionInfo {
21+
/**
22+
* version id of the secret
23+
*
24+
* @default - use default version id
25+
*/
26+
readonly versionId?: string;
27+
/**
28+
* version stage of the secret
29+
*
30+
* @default - use default version stage
31+
*/
32+
readonly versionStage?: string;
33+
}
34+
1735
/**
1836
* A secret environment variable.
1937
*/
@@ -47,6 +65,25 @@ export abstract class Secret {
4765
};
4866
}
4967

68+
/**
69+
* Creates a environment variable value from a secret stored in AWS Secrets
70+
* Manager.
71+
*
72+
* @param secret the secret stored in AWS Secrets Manager
73+
* @param versionInfo the version information to reference the secret
74+
* @param field the name of the field with the value that you want to set as
75+
* the environment variable value. Only values in JSON format are supported.
76+
* If you do not specify a JSON field, then the full content of the secret is
77+
* used.
78+
*/
79+
public static fromSecretsManagerVersion(secret: secretsmanager.ISecret, versionInfo: SecretVersionInfo, field?: string): Secret {
80+
return {
81+
arn: `${secret.secretArn}:${field ?? ''}:${versionInfo.versionStage ?? ''}:${versionInfo.versionId ?? ''}`,
82+
hasField: !!field,
83+
grantRead: grantee => secret.grantRead(grantee),
84+
};
85+
}
86+
5087
/**
5188
* The ARN of the secret
5289
*/

packages/@aws-cdk/aws-ecs/test/container-definition.test.ts

+60
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,8 @@ describe('container definition', () => {
12611261
secrets: {
12621262
SECRET: ecs.Secret.fromSecretsManager(secret),
12631263
PARAMETER: ecs.Secret.fromSsmParameter(parameter),
1264+
SECRET_ID: ecs.Secret.fromSecretsManagerVersion(secret, { versionId: 'version-id' }),
1265+
SECRET_STAGE: ecs.Secret.fromSecretsManagerVersion(secret, { versionStage: 'version-stage' }),
12641266
},
12651267
});
12661268

@@ -1298,6 +1300,34 @@ describe('container definition', () => {
12981300
],
12991301
},
13001302
},
1303+
{
1304+
Name: 'SECRET_ID',
1305+
ValueFrom: {
1306+
'Fn::Join': [
1307+
'',
1308+
[
1309+
{
1310+
Ref: 'SecretA720EF05',
1311+
},
1312+
':::version-id',
1313+
],
1314+
],
1315+
},
1316+
},
1317+
{
1318+
Name: 'SECRET_STAGE',
1319+
ValueFrom: {
1320+
'Fn::Join': [
1321+
'',
1322+
[
1323+
{
1324+
Ref: 'SecretA720EF05',
1325+
},
1326+
'::version-stage:',
1327+
],
1328+
],
1329+
},
1330+
},
13011331
],
13021332
}),
13031333
],
@@ -1405,6 +1435,8 @@ describe('container definition', () => {
14051435
memoryLimitMiB: 1024,
14061436
secrets: {
14071437
SECRET_KEY: ecs.Secret.fromSecretsManager(secret, 'specificKey'),
1438+
SECRET_KEY_ID: ecs.Secret.fromSecretsManagerVersion(secret, { versionId: 'version-id' }, 'specificKey'),
1439+
SECRET_KEY_STAGE: ecs.Secret.fromSecretsManagerVersion(secret, { versionStage: 'version-stage' }, 'specificKey'),
14081440
},
14091441
});
14101442

@@ -1427,6 +1459,34 @@ describe('container definition', () => {
14271459
],
14281460
},
14291461
},
1462+
{
1463+
Name: 'SECRET_KEY_ID',
1464+
ValueFrom: {
1465+
'Fn::Join': [
1466+
'',
1467+
[
1468+
{
1469+
Ref: 'SecretA720EF05',
1470+
},
1471+
':specificKey::version-id',
1472+
],
1473+
],
1474+
},
1475+
},
1476+
{
1477+
Name: 'SECRET_KEY_STAGE',
1478+
ValueFrom: {
1479+
'Fn::Join': [
1480+
'',
1481+
[
1482+
{
1483+
Ref: 'SecretA720EF05',
1484+
},
1485+
':specificKey:version-stage:',
1486+
],
1487+
],
1488+
},
1489+
},
14301490
],
14311491
}),
14321492
],

0 commit comments

Comments
 (0)