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

feat(core): add volumes-from option to docker run command for bundling #21660

Closed
wants to merge 13 commits into from
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-lambda-python/README.md
Expand Up @@ -145,6 +145,18 @@ new python.PythonFunction(this, 'function', {
});
```

You can also pass additional options to configure Docker for situations where the docker daemon is not running in the same system as you are bundling from.

```ts
const entry = '/path/to/function';

new python.PythonFunction(this, 'function', {
entry,
runtime: Runtime.PYTHON_3_8,
bundling: { volumesFrom: process.env.HOSTNAME },
});
```

## Custom Bundling with Code Artifact

To use a Code Artifact PyPI repo, the `PIP_INDEX_URL` for bundling the function can be customized (requires AWS CLI in the build environment):
Expand Down
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-lambda-python/lib/bundling.ts
Expand Up @@ -35,6 +35,13 @@ export interface BundlingProps extends BundlingOptions {
*/
readonly architecture?: Architecture;

/**
* Where to mount the specified volumes from
* Docker [volumes-from option](https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from)
* @default - no volumes-from options
*/
readonly volumesFrom?: string;

/**
* Whether or not the bundling process should be skipped
*
Expand All @@ -59,6 +66,7 @@ export class Bundling implements CdkBundlingOptions {
public readonly image: DockerImage;
public readonly command: string[];
public readonly environment?: { [key: string]: string };
public readonly volumesFrom?: string | undefined;

constructor(props: BundlingProps) {
const {
Expand Down Expand Up @@ -88,6 +96,7 @@ export class Bundling implements CdkBundlingOptions {
});
this.command = ['bash', '-c', chain(bundlingCommands)];
this.environment = props.environment;
this.volumesFrom = props.volumesFrom;
}

private createBundlingCommand(options: BundlingCommandOptions): string[] {
Expand Down
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-lambda-python/lib/types.ts
Expand Up @@ -86,4 +86,11 @@ export interface BundlingOptions {
* @default - Based on `assetHashType`
*/
readonly assetHash?: string;

/**
* Where to mount the specified volumes from
* Docker [volumes-from option](https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from)
* @default - no volumes-from options
*/
readonly volumesFrom?: string;
}
15 changes: 15 additions & 0 deletions packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts
Expand Up @@ -278,6 +278,21 @@ test('Bundling with custom environment vars`', () => {
}));
});

test('Bundling with custom volumes', () => {
const entry = path.join(__dirname, 'lambda-handler');
Bundling.bundle({
entry: entry,
runtime: Runtime.PYTHON_3_7,
volumesFrom: process.env.HOSTNAME,
});

expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({
bundling: expect.objectContaining({
volumesFrom: process.env.HOSTNAME,
}),
}));
});

test('Do not build docker image when skipping bundling', () => {
const entry = path.join(__dirname, 'lambda-handler');
Bundling.bundle({
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/core/lib/asset-staging.ts
Expand Up @@ -469,6 +469,7 @@ export class AssetStaging extends Construct {
entrypoint: options.entrypoint,
workingDirectory: options.workingDirectory ?? AssetStaging.BUNDLING_INPUT_DIR,
securityOpt: options.securityOpt ?? '',
volumesFrom: options.volumesFrom,
});
}
} catch (err) {
Expand Down
17 changes: 17 additions & 0 deletions packages/@aws-cdk/core/lib/bundling.ts
Expand Up @@ -43,6 +43,13 @@ export interface BundlingOptions {
*/
readonly volumes?: DockerVolume[];

/**
* Where to mount the specified volumes from
* Docker [volumes-from option](https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from)
* @default - no volumes-from options
*/
readonly volumesFrom?: string;

/**
* The environment variables to pass to the Docker container.
*
Expand Down Expand Up @@ -210,6 +217,9 @@ export class BundlingDockerImage {
...options.user
? ['-u', options.user]
: [],
...options.volumesFrom
? ['--volumes-from', options.volumesFrom]
: [],
...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}:${isSeLinux() ? 'z,' : ''}${v.consistency ?? DockerVolumeConsistency.DELEGATED}`])),
...flatten(Object.entries(environment).map(([k, v]) => ['--env', `${k}=${v}`])),
...options.workingDirectory
Expand Down Expand Up @@ -441,6 +451,13 @@ export interface DockerRunOptions {
*/
readonly volumes?: DockerVolume[];

/**
* Where to mount the specified volumes from
* Docker [volumes-from option](https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from)
* @default - no volumes-from options
*/
readonly volumesFrom?: string;

/**
* The environment variables to pass to the container.
*
Expand Down