Skip to content

Commit 9b1051f

Browse files
authored
feat(batch): add secrets props to job definition (#20871)
Add a secrets property to batch.JobDefinitionContainer. This interface is almost the same as ecs.ContainerDefinitionOptions. This is reopen PR of #19506 closes #10976 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent e274edc commit 9b1051f

File tree

11 files changed

+274
-7
lines changed

11 files changed

+274
-7
lines changed

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

+17
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,23 @@ new batch.JobDefinition(this, 'job-def', {
300300
});
301301
```
302302

303+
### Using the secret on secrets manager
304+
305+
You can set the environment variables from secrets manager.
306+
307+
```ts
308+
const dbSecret = new secretsmanager.Secret(this, 'secret');
309+
310+
new batch.JobDefinition(this, 'batch-job-def-secrets', {
311+
container: {
312+
image: ecs.EcrImage.fromRegistry('docker/whalesay'),
313+
secrets: {
314+
PASSWORD: ecs.Secret.fromSecretsManager(dbSecret, 'password'),
315+
},
316+
},
317+
});
318+
```
319+
303320
### Importing an existing Job Definition
304321

305322
#### From ARN

packages/@aws-cdk/aws-batch/lib/job-definition.ts

+23
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ export interface JobDefinitionContainer {
112112
*/
113113
readonly environment?: { [key: string]: string };
114114

115+
/**
116+
* The environment variables from secrets manager or ssm parameter store
117+
*
118+
* @default none
119+
*/
120+
readonly secrets?: { [key: string]: ecs.Secret };
121+
115122
/**
116123
* The image used to start a container.
117124
*/
@@ -453,6 +460,14 @@ export class JobDefinition extends Resource implements IJobDefinition {
453460
platformCapabilities: props.platformCapabilities ?? [PlatformCapabilities.EC2],
454461
});
455462

463+
// add read secrets permission to execution role
464+
if ( props.container.secrets && props.container.executionRole ) {
465+
const executionRole = props.container.executionRole;
466+
Object.values(props.container.secrets).forEach((secret) => {
467+
secret.grantRead(executionRole);
468+
});
469+
}
470+
456471
this.jobDefinitionArn = this.getResourceArnAttribute(jobDef.ref, {
457472
service: 'batch',
458473
resource: 'job-definition',
@@ -507,6 +522,14 @@ export class JobDefinition extends Resource implements IJobDefinition {
507522
return {
508523
command: container.command,
509524
environment: this.deserializeEnvVariables(container.environment),
525+
secrets: container.secrets
526+
? Object.entries(container.secrets).map(([key, value]) => {
527+
return {
528+
name: key,
529+
valueFrom: value.arn,
530+
};
531+
})
532+
: undefined,
510533
image: this.imageConfig.imageName,
511534
instanceType: container.instanceType && container.instanceType.toString(),
512535
jobRoleArn: container.jobRole && container.jobRole.roleArn,

packages/@aws-cdk/aws-batch/rosetta/default.ts-fixture

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Stack } from '@aws-cdk/core';
44
import * as ec2 from '@aws-cdk/aws-ec2';
55
import * as batch from '@aws-cdk/aws-batch';
66
import * as ecs from '@aws-cdk/aws-ecs';
7+
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
78

89
class Fixture extends Stack {
910
constructor(scope: Construct, id: string) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "20.0.0",
3+
"files": {
4+
"d3685c79f9ec67f5dd6fda839a136b079f201b3d72695fe0ea3b3788c3471cc8": {
5+
"source": {
6+
"path": "batch-stack.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "d3685c79f9ec67f5dd6fda839a136b079f201b3d72695fe0ea3b3788c3471cc8.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}

packages/@aws-cdk/aws-batch/test/batch.integ.snapshot/batch-stack.template.json

+42
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,14 @@
13651365
"UpdateReplacePolicy": "Retain",
13661366
"DeletionPolicy": "Retain"
13671367
},
1368+
"batchsecret7CD5E4C6": {
1369+
"Type": "AWS::SecretsManager::Secret",
1370+
"Properties": {
1371+
"GenerateSecretString": {}
1372+
},
1373+
"UpdateReplacePolicy": "Delete",
1374+
"DeletionPolicy": "Delete"
1375+
},
13681376
"batchjobdeffromecrE0E30DAD": {
13691377
"Type": "AWS::Batch::JobDefinition",
13701378
"Properties": {
@@ -1486,6 +1494,32 @@
14861494
}
14871495
}
14881496
},
1497+
"executionroleDefaultPolicy497F11A3": {
1498+
"Type": "AWS::IAM::Policy",
1499+
"Properties": {
1500+
"PolicyDocument": {
1501+
"Statement": [
1502+
{
1503+
"Action": [
1504+
"secretsmanager:DescribeSecret",
1505+
"secretsmanager:GetSecretValue"
1506+
],
1507+
"Effect": "Allow",
1508+
"Resource": {
1509+
"Ref": "batchsecret7CD5E4C6"
1510+
}
1511+
}
1512+
],
1513+
"Version": "2012-10-17"
1514+
},
1515+
"PolicyName": "executionroleDefaultPolicy497F11A3",
1516+
"Roles": [
1517+
{
1518+
"Ref": "executionroleD9A39BE6"
1519+
}
1520+
]
1521+
}
1522+
},
14891523
"batchjobdeffargate7FE30059": {
14901524
"Type": "AWS::Batch::JobDefinition",
14911525
"Properties": {
@@ -1509,6 +1543,14 @@
15091543
"Type": "MEMORY",
15101544
"Value": "512"
15111545
}
1546+
],
1547+
"Secrets": [
1548+
{
1549+
"Name": "SECRET",
1550+
"ValueFrom": {
1551+
"Ref": "batchsecret7CD5E4C6"
1552+
}
1553+
}
15121554
]
15131555
},
15141556
"PlatformCapabilities": [
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"version":"17.0.0"}
1+
{"version":"20.0.0"}

packages/@aws-cdk/aws-batch/test/batch.integ.snapshot/integ.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"version": "18.0.0",
2+
"version": "20.0.0",
33
"testCases": {
4-
"aws-batch/test/integ.batch": {
4+
"integ.batch": {
55
"stacks": [
66
"batch-stack"
77
],

packages/@aws-cdk/aws-batch/test/batch.integ.snapshot/manifest.json

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "17.0.0",
2+
"version": "20.0.0",
33
"artifacts": {
44
"Tree": {
55
"type": "cdk:tree",
@@ -285,6 +285,12 @@
285285
"data": "batchjobrepo4C508C51"
286286
}
287287
],
288+
"/batch-stack/batch-secret/Resource": [
289+
{
290+
"type": "aws:cdk:logicalId",
291+
"data": "batchsecret7CD5E4C6"
292+
}
293+
],
288294
"/batch-stack/batch-job-def-from-ecr/Resource": [
289295
{
290296
"type": "aws:cdk:logicalId",
@@ -303,6 +309,12 @@
303309
"data": "executionroleD9A39BE6"
304310
}
305311
],
312+
"/batch-stack/execution-role/DefaultPolicy/Resource": [
313+
{
314+
"type": "aws:cdk:logicalId",
315+
"data": "executionroleDefaultPolicy497F11A3"
316+
}
317+
],
306318
"/batch-stack/batch-job-def-fargate/Resource": [
307319
{
308320
"type": "aws:cdk:logicalId",

packages/@aws-cdk/aws-batch/test/batch.integ.snapshot/tree.json

+78-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"id": "Tree",
99
"path": "Tree",
1010
"constructInfo": {
11-
"fqn": "@aws-cdk/core.Construct",
12-
"version": "0.0.0"
11+
"fqn": "constructs.Construct",
12+
"version": "10.1.33"
1313
}
1414
},
1515
"batch-stack": {
@@ -1614,6 +1614,30 @@
16141614
"version": "0.0.0"
16151615
}
16161616
},
1617+
"batch-secret": {
1618+
"id": "batch-secret",
1619+
"path": "batch-stack/batch-secret",
1620+
"children": {
1621+
"Resource": {
1622+
"id": "Resource",
1623+
"path": "batch-stack/batch-secret/Resource",
1624+
"attributes": {
1625+
"aws:cdk:cloudformation:type": "AWS::SecretsManager::Secret",
1626+
"aws:cdk:cloudformation:props": {
1627+
"generateSecretString": {}
1628+
}
1629+
},
1630+
"constructInfo": {
1631+
"fqn": "@aws-cdk/aws-secretsmanager.CfnSecret",
1632+
"version": "0.0.0"
1633+
}
1634+
}
1635+
},
1636+
"constructInfo": {
1637+
"fqn": "@aws-cdk/aws-secretsmanager.Secret",
1638+
"version": "0.0.0"
1639+
}
1640+
},
16171641
"batch-job-def-from-ecr": {
16181642
"id": "batch-job-def-from-ecr",
16191643
"path": "batch-stack/batch-job-def-from-ecr",
@@ -1814,6 +1838,50 @@
18141838
"fqn": "@aws-cdk/aws-iam.CfnRole",
18151839
"version": "0.0.0"
18161840
}
1841+
},
1842+
"DefaultPolicy": {
1843+
"id": "DefaultPolicy",
1844+
"path": "batch-stack/execution-role/DefaultPolicy",
1845+
"children": {
1846+
"Resource": {
1847+
"id": "Resource",
1848+
"path": "batch-stack/execution-role/DefaultPolicy/Resource",
1849+
"attributes": {
1850+
"aws:cdk:cloudformation:type": "AWS::IAM::Policy",
1851+
"aws:cdk:cloudformation:props": {
1852+
"policyDocument": {
1853+
"Statement": [
1854+
{
1855+
"Action": [
1856+
"secretsmanager:DescribeSecret",
1857+
"secretsmanager:GetSecretValue"
1858+
],
1859+
"Effect": "Allow",
1860+
"Resource": {
1861+
"Ref": "batchsecret7CD5E4C6"
1862+
}
1863+
}
1864+
],
1865+
"Version": "2012-10-17"
1866+
},
1867+
"policyName": "executionroleDefaultPolicy497F11A3",
1868+
"roles": [
1869+
{
1870+
"Ref": "executionroleD9A39BE6"
1871+
}
1872+
]
1873+
}
1874+
},
1875+
"constructInfo": {
1876+
"fqn": "@aws-cdk/aws-iam.CfnPolicy",
1877+
"version": "0.0.0"
1878+
}
1879+
}
1880+
},
1881+
"constructInfo": {
1882+
"fqn": "@aws-cdk/aws-iam.Policy",
1883+
"version": "0.0.0"
1884+
}
18171885
}
18181886
},
18191887
"constructInfo": {
@@ -1849,6 +1917,14 @@
18491917
"aws:cdk:cloudformation:props": {
18501918
"type": "container",
18511919
"containerProperties": {
1920+
"secrets": [
1921+
{
1922+
"name": "SECRET",
1923+
"valueFrom": {
1924+
"Ref": "batchsecret7CD5E4C6"
1925+
}
1926+
}
1927+
],
18521928
"image": "docker/whalesay",
18531929
"executionRoleArn": {
18541930
"Fn::GetAtt": [

packages/@aws-cdk/aws-batch/test/integ.batch.ts

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as ec2 from '@aws-cdk/aws-ec2';
22
import * as ecr from '@aws-cdk/aws-ecr';
33
import * as ecs from '@aws-cdk/aws-ecs';
44
import * as iam from '@aws-cdk/aws-iam';
5+
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
56
import * as cdk from '@aws-cdk/core';
67
import * as batch from '../lib/';
78

@@ -93,6 +94,7 @@ new batch.JobQueue(stack, 'batch-job-fargate-queue', {
9394
});
9495

9596
const repo = new ecr.Repository(stack, 'batch-job-repo');
97+
const secret = new secretsmanager.Secret(stack, 'batch-secret');
9698

9799
new batch.JobDefinition(stack, 'batch-job-def-from-ecr', {
98100
container: {
@@ -115,5 +117,8 @@ new batch.JobDefinition(stack, 'batch-job-def-fargate', {
115117
container: {
116118
image: ecs.ContainerImage.fromRegistry('docker/whalesay'),
117119
executionRole,
120+
secrets: {
121+
SECRET: ecs.Secret.fromSecretsManager(secret),
122+
},
118123
},
119124
});

0 commit comments

Comments
 (0)