Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(batch): Allow ECS JobDefinition Containers to pass Secrets as Environment Variables & Enable Kubernetes Secret Volumes #26126

Merged
merged 5 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions packages/@aws-cdk/aws-batch-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,29 @@ jobDefn.container.addVolume(batch.EcsVolume.efs({
}));
```

### Secrets

You can expose SecretsManager Secret ARNs to your container as environment variables.
The following example defines the `MY_SECRET_ENV_VAR` environment variable that contains the
ARN of the Secret defined by `mySecret`:

```ts
import * as cdk from 'aws-cdk-lib';

declare const mySecret: secretsmanager.ISecret;

const jobDefn = new batch.EcsJobDefinition(this, 'JobDefn', {
container: new batch.EcsEc2ContainerDefinition(this, 'containerDefn', {
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/amazonlinux/amazonlinux:latest'),
memory: cdk.Size.mebibytes(2048),
cpu: 256,
secrets: {
MY_SECRET_ENV_VAR: mySecret,
}
}),
});
```

### Running Kubernetes Workflows

Batch also supports running workflows on EKS. The following example creates a `JobDefinition` that runs on EKS:
Expand Down
18 changes: 10 additions & 8 deletions packages/@aws-cdk/aws-batch-alpha/lib/ecs-container-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,13 +342,14 @@ export interface IEcsContainerDefinition extends IConstruct {
readonly readonlyRootFilesystem?: boolean;

/**
* The secrets for the container. Can be referenced in your job definition.
* A map from environment variable names to the secrets for the container. Allows your job definitions
* to reference the secret by the environment variable name defined in this property.
*
* @see https://docs.aws.amazon.com/batch/latest/userguide/specifying-sensitive-data.html
*
* @default - no secrets
*/
readonly secrets?: secretsmanager.ISecret[];
readonly secrets?: { [envVarName: string]: secretsmanager.ISecret };

/**
* The user name to use inside the container
Expand Down Expand Up @@ -458,13 +459,14 @@ export interface EcsContainerDefinitionProps {
readonly readonlyRootFilesystem?: boolean;

/**
* The secrets for the container. Can be referenced in your job definition.
* A map from environment variable names to the secrets for the container. Allows your job definitions
* to reference the secret by the environment variable name defined in this property.
*
* @see https://docs.aws.amazon.com/batch/latest/userguide/specifying-sensitive-data.html
*
* @default - no secrets
*/
readonly secrets?: secretsmanager.ISecret[];
readonly secrets?: { [envVarName: string]: secretsmanager.ISecret };

/**
* The user name to use inside the container
Expand Down Expand Up @@ -495,7 +497,7 @@ abstract class EcsContainerDefinitionBase extends Construct implements IEcsConta
public readonly linuxParameters?: LinuxParameters;
public readonly logDriverConfig?: ecs.LogDriverConfig;
public readonly readonlyRootFilesystem?: boolean;
public readonly secrets?: secretsmanager.ISecret[];
public readonly secrets?: { [envVarName: string]: secretsmanager.ISecret };
public readonly user?: string;
public readonly volumes: EcsVolume[];

Expand Down Expand Up @@ -553,12 +555,12 @@ abstract class EcsContainerDefinitionBase extends Construct implements IEcsConta
logConfiguration: this.logDriverConfig,
readonlyRootFilesystem: this.readonlyRootFilesystem,
resourceRequirements: this._renderResourceRequirements(),
secrets: this.secrets?.map((secret) => {
secrets: this.secrets ? Object.entries(this.secrets).map(([name, secret]) => {
return {
name: secret.secretName,
name,
valueFrom: secret.secretArn,
};
}),
}) : undefined,
mountPoints: Lazy.any({
produce: () => {
if (this.volumes.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,9 +647,9 @@ export interface EksVolumeOptions {
readonly name: string;

/**
* The path on the container where the container is mounted.
* The path on the container where the volume is mounted.
*
* @default - the container is not mounted
* @default - the volume is not mounted
*/
readonly mountPath?: string;

Expand Down Expand Up @@ -902,7 +902,7 @@ export class SecretPathVolume extends EksVolume {
constructor(options: SecretPathVolumeOptions) {
super(options);
this.secretName = options.secretName;
this.optional = options.optional;
this.optional = options.optional ?? true;
}
}

Expand Down
3 changes: 1 addition & 2 deletions packages/@aws-cdk/aws-batch-alpha/lib/eks-job-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,13 @@ export class EksJobDefinition extends JobDefinitionBase implements IEksJobDefini
};
}
if (SecretPathVolume.isSecretPathVolume(volume)) {
/*return {
return {
name: volume.name,
secret: {
optional: volume.optional,
secretName: volume.secretName,
},
};
*/
}

throw new Error('unknown volume type');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,9 @@ describe.each([EcsEc2ContainerDefinition, EcsFargateContainerDefinition])('%p',
new EcsJobDefinition(stack, 'ECSJobDefn', {
container: new ContainerDefinition(stack, 'EcsContainer', {
...defaultContainerProps,
secrets: [
new Secret(stack, 'testSecret'),
],
secrets: {
envName: new Secret(stack, 'testSecret'),
},
}),
});

Expand All @@ -268,59 +268,7 @@ describe.each([EcsEc2ContainerDefinition, EcsFargateContainerDefinition])('%p',
...pascalCaseExpectedProps.ContainerProperties,
Secrets: [
{
Name: {
'Fn::Join': [
'-',
[
{
'Fn::Select': [
0,
{
'Fn::Split': [
'-',
{
'Fn::Select': [
6,
{
'Fn::Split': [
':',
{
Ref: 'testSecretB96AD12C',
},
],
},
],
},
],
},
],
},
{
'Fn::Select': [
1,
{
'Fn::Split': [
'-',
{
'Fn::Select': [
6,
{
'Fn::Split': [
':',
{
Ref: 'testSecretB96AD12C',
},
],
},
],
},
],
},
],
},
],
],
},
Name: 'envName',
ValueFrom: { Ref: 'testSecretB96AD12C' },
},
],
Expand Down
Loading