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): allow asset bundling on docker remote host / docker in docker #23576

Merged
merged 41 commits into from Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
fabddf0
WIP docker bundle with cp
webratz Dec 23, 2022
025e8d9
wip mv
webratz Dec 23, 2022
c2e10b8
adjust cp command
webratz Jan 2, 2023
815edab
Merge branch 'aws:main' into main
webratz Jan 2, 2023
2f71a5b
Merge branch 'main' of https://github.com/webratz/aws-cdk
webratz Jan 3, 2023
8cb6259
fix missing path to copy out
webratz Jan 3, 2023
c006750
slight cleanup and first failed tests
webratz Jan 4, 2023
ac327d0
add basic integration test and pass through config from python lambda
webratz Jan 4, 2023
6fb1dd2
Merge branch 'aws:main' into main
webratz Jan 4, 2023
fd367ef
move to own class and cleanup
webratz Jan 5, 2023
26c1d10
add tests
webratz Jan 5, 2023
87e7a2a
add to all lambda implementations
webratz Jan 5, 2023
dca7457
fix import order
webratz Jan 5, 2023
e804023
add readme
webratz Jan 5, 2023
e667436
add import to readme
webratz Jan 9, 2023
13cba32
Update packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts
webratz Jan 20, 2023
1ca8496
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 20, 2023
813c8b7
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 20, 2023
871da21
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 20, 2023
ed23041
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 20, 2023
6bc93e1
address first MR comments
webratz Jan 20, 2023
7b3798e
fix readme
webratz Jan 20, 2023
d94e232
Merge branch 'main' into webratz/main
mrgrain Jan 20, 2023
54b3a80
WIP: restructure
webratz Jan 20, 2023
5c98592
WIP separate bundling
webratz Jan 23, 2023
056f48b
Merge branch 'main' into main
webratz Jan 23, 2023
ace87a4
move classes to private
webratz Jan 23, 2023
7be1cc5
Update packages/@aws-cdk/core/test/docker-stub-cp.sh
webratz Jan 25, 2023
fa11118
Update packages/@aws-cdk/core/test/bundling.test.ts
webratz Jan 25, 2023
381e5bf
Update packages/@aws-cdk/core/lib/private/asset-staging.ts
webratz Jan 25, 2023
5a9b75e
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 25, 2023
8640305
allow use of different stub files
webratz Jan 25, 2023
4750a5f
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 25, 2023
27026e5
change naming
webratz Jan 25, 2023
974762a
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 25, 2023
2890d54
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 25, 2023
325fdbb
Update packages/@aws-cdk/core/lib/bundling.ts
webratz Jan 25, 2023
6590681
remaining name fixes
webratz Jan 26, 2023
4ecaf47
cleanup
webratz Jan 26, 2023
cb54c28
Merge branch 'main' into webratz/main
mrgrain Jan 26, 2023
c4b09ee
Merge branch 'main' into main
mergify[bot] Jan 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-lambda-go/README.md
Expand Up @@ -284,3 +284,17 @@ and Go only includes dependencies that are used in the executable. So in this ca
if `cmd/api` used the `auth` & `middleware` packages, but `cmd/anotherApi` did not, then
an update to `auth` or `middleware` would only trigger an update to the `cmd/api` Lambda
Function.

## Docker based bundling in complex Docker configurations

By default the input and output of Docker based bundling is handled via bind mounts.
In situtations where this does not work, like Docker-in-Docker setups or when using a remote Docker socket, you can configure an alternative, but slower, variant that also works in these situations.

```ts
new go.GoFunction(this, 'GoFunction', {
entry: 'app/cmd/api',
bundling: {
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
},
});
```
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-lambda-go/lib/bundling.ts
Expand Up @@ -60,6 +60,12 @@ export interface BundlingProps extends BundlingOptions {
* The system architecture of the lambda function
*/
readonly architecture: Architecture;

/**
* Which option to use to copy the source files to the docker container and output files back
* @default - BundlingFileAccess.BIND_MOUNT
*/
readonly bundlingFileAccess?: cdk.BundlingFileAccess;
}

/**
Expand All @@ -85,6 +91,7 @@ export class Bundling implements cdk.BundlingOptions {
user: bundling.user,
securityOpt: bundling.securityOpt,
network: bundling.network,
bundlingFileAccess: bundling.bundlingFileAccess,
},
});
}
Expand All @@ -107,6 +114,7 @@ export class Bundling implements cdk.BundlingOptions {
public readonly user?: string;
public readonly securityOpt?: string;
public readonly network?: string;
public readonly bundlingFileAccess?: cdk.BundlingFileAccess;

private readonly relativeEntryPath: string;

Expand Down Expand Up @@ -154,6 +162,7 @@ export class Bundling implements cdk.BundlingOptions {
this.user = props.user;
this.securityOpt = props.securityOpt;
this.network = props.network;
this.bundlingFileAccess = props.bundlingFileAccess;

// Local bundling
if (!props.forcedDockerBundling) { // only if Docker is not forced
Expand Down
8 changes: 7 additions & 1 deletion packages/@aws-cdk/aws-lambda-go/lib/types.ts
@@ -1,4 +1,4 @@
import { AssetHashType, DockerImage, DockerRunOptions } from '@aws-cdk/core';
import { AssetHashType, BundlingFileAccess, DockerImage, DockerRunOptions } from '@aws-cdk/core';

/**
* Bundling options
Expand Down Expand Up @@ -111,6 +111,12 @@ export interface BundlingOptions extends DockerRunOptions {
* @default - Direct access
*/
readonly goProxies?: string[];

/**
* Which option to use to copy the source files to the docker container and output files back
* @default - BundlingFileAccess.BIND_MOUNT
*/
readonly bundlingFileAccess?: BundlingFileAccess;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-lambda-go/rosetta/default.ts-fixture
@@ -1,6 +1,6 @@
// Fixture with packages imported, but nothing else
import { Construct } from 'constructs';
import { DockerImage, Stack } from '@aws-cdk/core';
import { DockerImage, Stack, BundlingFileAccess } from '@aws-cdk/core';
import * as go from '@aws-cdk/aws-lambda-go';

class Fixture extends Stack {
Expand Down
20 changes: 19 additions & 1 deletion packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts
Expand Up @@ -2,7 +2,7 @@ import * as child_process from 'child_process';
import * as os from 'os';
import * as path from 'path';
import { Architecture, Code, Runtime } from '@aws-cdk/aws-lambda';
import { AssetHashType, DockerImage } from '@aws-cdk/core';
import { AssetHashType, BundlingFileAccess, DockerImage } from '@aws-cdk/core';
import { Bundling } from '../lib/bundling';
import * as util from '../lib/util';

Expand Down Expand Up @@ -461,3 +461,21 @@ test('Custom bundling network', () => {
}),
});
});

test('Custom bundling file copy variant', () => {
Bundling.bundle({
entry,
moduleDir,
runtime: Runtime.GO_1_X,
architecture: Architecture.X86_64,
forcedDockerBundling: true,
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
});

expect(Code.fromAsset).toHaveBeenCalledWith('/project', {
assetHashType: AssetHashType.OUTPUT,
bundling: expect.objectContaining({
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
}),
});
});
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/README.md
Expand Up @@ -337,3 +337,16 @@ new nodejs.NodejsFunction(this, 'my-handler', {

If you chose to customize the hash, you will need to make sure it is updated every time the asset
changes, or otherwise it is possible that some deployments will not be invalidated.

## Docker based bundling in complex Docker configurations

By default the input and output of Docker based bundling is handled via bind mounts.
In situtations where this does not work, like Docker-in-Docker setups or when using a remote Docker socket, you can configure an alternative, but slower, variant that also works in these situations.

```ts
new nodejs.NodejsFunction(this, 'my-handler', {
bundling: {
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
},
});
```
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
Expand Up @@ -43,6 +43,11 @@ export interface BundlingProps extends BundlingOptions {
*/
readonly preCompilation?: boolean

/**
* Which option to use to copy the source files to the docker container and output files back
* @default - BundlingFileAccess.BIND_MOUNT
*/
readonly bundlingFileAccess?: cdk.BundlingFileAccess;
}

/**
Expand Down Expand Up @@ -83,6 +88,7 @@ export class Bundling implements cdk.BundlingOptions {
public readonly securityOpt?: string;
public readonly network?: string;
public readonly local?: cdk.ILocalBundling;
public readonly bundlingFileAccess?: cdk.BundlingFileAccess;

private readonly projectRoot: string;
private readonly relativeEntryPath: string;
Expand Down Expand Up @@ -154,6 +160,7 @@ export class Bundling implements cdk.BundlingOptions {
this.user = props.user;
this.securityOpt = props.securityOpt;
this.network = props.network;
this.bundlingFileAccess = props.bundlingFileAccess;

// Local bundling
if (!props.forceDockerBundling) { // only if Docker is not forced
Expand Down
8 changes: 7 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
@@ -1,4 +1,4 @@
import { DockerImage, DockerRunOptions } from '@aws-cdk/core';
import { BundlingFileAccess, DockerImage, DockerRunOptions } from '@aws-cdk/core';

/**
* Bundling options
Expand Down Expand Up @@ -301,6 +301,12 @@ export interface BundlingOptions extends DockerRunOptions {
* @default - no code is injected
*/
readonly inject?: string[]

/**
* Which option to use to copy the source files to the docker container and output files back
* @default - BundlingFileAccess.BIND_MOUNT
*/
readonly bundlingFileAccess?: BundlingFileAccess;
}

/**
Expand Down
@@ -1,6 +1,6 @@
// Fixture with packages imported, but nothing else
import { Construct } from 'constructs';
import { DockerImage, Stack } from '@aws-cdk/core';
import { DockerImage, Stack, BundlingFileAccess } from '@aws-cdk/core';
import * as nodejs from '@aws-cdk/aws-lambda-nodejs';

class Fixture extends Stack {
Expand Down
21 changes: 20 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
Expand Up @@ -2,7 +2,7 @@ import * as child_process from 'child_process';
import * as os from 'os';
import * as path from 'path';
import { Architecture, Code, Runtime, RuntimeFamily } from '@aws-cdk/aws-lambda';
import { AssetHashType, DockerImage } from '@aws-cdk/core';
import { AssetHashType, BundlingFileAccess, DockerImage } from '@aws-cdk/core';
import { version as delayVersion } from 'delay/package.json';
import { Bundling } from '../lib/bundling';
import { PackageInstallation } from '../lib/package-installation';
Expand Down Expand Up @@ -826,3 +826,22 @@ test('Custom bundling network', () => {
}),
});
});

test('Custom bundling file copy variant', () => {
Bundling.bundle({
entry,
projectRoot,
depsLockFilePath,
runtime: Runtime.NODEJS_14_X,
architecture: Architecture.X86_64,
forceDockerBundling: true,
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
});

expect(Code.fromAsset).toHaveBeenCalledWith('/project', {
assetHashType: AssetHashType.OUTPUT,
bundling: expect.objectContaining({
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
}),
});
});
17 changes: 17 additions & 0 deletions packages/@aws-cdk/aws-lambda-python/README.md
Expand Up @@ -252,3 +252,20 @@ an array of commands to run. Commands are chained with `&&`.

The commands will run in the environment in which bundling occurs: inside the
container for Docker bundling or on the host OS for local bundling.

## Docker based bundling in complex Docker configurations

By default the input and output of Docker based bundling is handled via bind mounts.
In situtations where this does not work, like Docker-in-Docker setups or when using a remote Docker socket, you can configure an alternative, but slower, variant that also works in these situations.

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

new python.PythonFunction(this, 'function', {
entry,
runtime: Runtime.PYTHON_3_8,
bundling: {
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
},
});
```
10 changes: 9 additions & 1 deletion packages/@aws-cdk/aws-lambda-python/lib/bundling.ts
@@ -1,6 +1,6 @@
import * as path from 'path';
import { Architecture, AssetCode, Code, Runtime } from '@aws-cdk/aws-lambda';
import { AssetStaging, BundlingOptions as CdkBundlingOptions, DockerImage, DockerVolume } from '@aws-cdk/core';
import { AssetStaging, BundlingFileAccess, BundlingOptions as CdkBundlingOptions, DockerImage, DockerVolume } from '@aws-cdk/core';
import { Packaging, DependenciesFile } from './packaging';
import { BundlingOptions, ICommandHooks } from './types';

Expand Down Expand Up @@ -41,6 +41,12 @@ export interface BundlingProps extends BundlingOptions {
* @default - Does not skip bundling
*/
readonly skip?: boolean;

/**
* Which option to use to copy the source files to the docker container and output files back
* @default - BundlingFileAccess.BIND_MOUNT
*/
bundlingFileAccess?: BundlingFileAccess
}

/**
Expand All @@ -66,6 +72,7 @@ export class Bundling implements CdkBundlingOptions {
public readonly user?: string;
public readonly securityOpt?: string;
public readonly network?: string;
public readonly bundlingFileAccess?: BundlingFileAccess;

constructor(props: BundlingProps) {
const {
Expand Down Expand Up @@ -104,6 +111,7 @@ export class Bundling implements CdkBundlingOptions {
this.user = props.user;
this.securityOpt = props.securityOpt;
this.network = props.network;
this.bundlingFileAccess = props.bundlingFileAccess;
}

private createBundlingCommand(options: BundlingCommandOptions): string[] {
Expand Down
8 changes: 7 additions & 1 deletion packages/@aws-cdk/aws-lambda-python/lib/types.ts
@@ -1,4 +1,4 @@
import { AssetHashType, DockerImage, DockerRunOptions } from '@aws-cdk/core';
import { AssetHashType, BundlingFileAccess, DockerImage, DockerRunOptions } from '@aws-cdk/core';


/**
Expand Down Expand Up @@ -86,6 +86,12 @@ export interface BundlingOptions extends DockerRunOptions {
* @default - do not run additional commands
*/
readonly commandHooks?: ICommandHooks;

/**
* Which option to use to copy the source files to the docker container and output files back
* @default - BundlingFileAccess.BIND_MOUNT
*/
readonly bundlingFileAccess?: BundlingFileAccess;
}

/**
Expand Down
@@ -1,6 +1,6 @@
// Fixture with packages imported, but nothing else
import { Construct } from 'constructs';
import { DockerImage, Stack } from '@aws-cdk/core';
import { DockerImage, Stack, BundlingFileAccess } from '@aws-cdk/core';
import { Runtime } from '@aws-cdk/aws-lambda';
import * as python from '@aws-cdk/aws-lambda-python';

Expand Down
18 changes: 17 additions & 1 deletion packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts
@@ -1,7 +1,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { Architecture, Code, Runtime } from '@aws-cdk/aws-lambda';
import { DockerImage } from '@aws-cdk/core';
import { BundlingFileAccess, DockerImage } from '@aws-cdk/core';
import { Bundling } from '../lib/bundling';

jest.spyOn(Code, 'fromAsset');
Expand Down Expand Up @@ -374,6 +374,22 @@ test('Bundling with custom network', () => {
}));
});

test('Bundling with docker copy variant', () => {
const entry = path.join(__dirname, 'lambda-handler');
Bundling.bundle({
entry: entry,
runtime: Runtime.PYTHON_3_7,
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,

});

expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({
bundling: expect.objectContaining({
bundlingFileAccess: BundlingFileAccess.VOLUME_COPY,
}),
}));
});

test('Do not build docker image when skipping bundling', () => {
const entry = path.join(__dirname, 'lambda-handler');
Bundling.bundle({
Expand Down