Skip to content

Commit 30e2233

Browse files
authored
feat(lambda-python): support setting environment vars for bundling (#18635)
While using the Python Lambda with Code Artifact, discovered that Code Artifact was still inaccessible because bundling occurs at _run_ time, which can only access env vars, not build args. This is not a security issue because bundled output doesn't contain any of the secret values. **Note:** Without this, using Code Artifact (or any other private packaging for Python Lambdas) is currently broken. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent e64de67 commit 30e2233

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

packages/@aws-cdk/aws-lambda-python/README.md

+27-2
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,34 @@ new lambda.PythonFunction(this, 'function', {
167167
entry,
168168
runtime: Runtime.PYTHON_3_8,
169169
bundling: {
170-
buildArgs: { PIP_INDEX_URL: indexUrl },
170+
environment: { PIP_INDEX_URL: indexUrl },
171171
},
172172
});
173173
```
174174

175-
This type of an example should work for `pip` and `poetry` based dependencies, but will not work for `pipenv`.
175+
The index URL or the token are only used during bundling and thus not included in the final asset. Setting only environment variable for `PIP_INDEX_URL` or `PIP_EXTRA_INDEX_URL` should work for accesing private Python repositories with `pip`, `pipenv` and `poetry` based dependencies.
176+
177+
If you also want to use the Code Artifact repo for building the base Docker image for bundling, use `buildArgs`. However, note that setting custom build args for bundling will force the base bundling image to be rebuilt every time (i.e. skip the Docker cache). Build args can be customized as:
178+
179+
```ts
180+
import { execSync } from 'child_process';
181+
182+
const entry = '/path/to/function';
183+
const image = DockerImage.fromBuild(entry);
184+
185+
const domain = 'my-domain';
186+
const domainOwner = '111122223333';
187+
const repoName = 'my_repo';
188+
const region = 'us-east-1';
189+
const codeArtifactAuthToken = execSync(`aws codeartifact get-authorization-token --domain ${domain} --domain-owner ${domainOwner} --query authorizationToken --output text`).toString().trim();
190+
191+
const indexUrl = `https://aws:${codeArtifactAuthToken}@${domain}-${domainOwner}.d.codeartifact.${region}.amazonaws.com/pypi/${repoName}/simple/`;
192+
193+
new lambda.PythonFunction(this, 'function', {
194+
entry,
195+
runtime: Runtime.PYTHON_3_8,
196+
bundling: {
197+
buildArgs: { PIP_INDEX_URL: indexUrl },
198+
},
199+
});
200+
```

packages/@aws-cdk/aws-lambda-python/lib/bundling.ts

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export class Bundling implements CdkBundlingOptions {
5151

5252
public readonly image: DockerImage;
5353
public readonly command: string[];
54+
public readonly environment?: { [key: string]: string };
5455

5556
constructor(props: BundlingProps) {
5657
const {
@@ -78,6 +79,7 @@ export class Bundling implements CdkBundlingOptions {
7879
});
7980
this.image = image ?? defaultImage;
8081
this.command = ['bash', '-c', chain(bundlingCommands)];
82+
this.environment = props.environment;
8183
}
8284

8385
private createBundlingCommand(options: BundlingCommandOptions): string[] {

packages/@aws-cdk/aws-lambda-python/lib/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ export interface BundlingOptions {
3030
*/
3131
readonly buildArgs?: { [key: string]: string };
3232

33+
/**
34+
* Environment variables defined when bundling runs.
35+
*
36+
* @default - no environment variables are defined.
37+
*/
38+
readonly environment?: { [key: string]: string; };
39+
3340
/**
3441
* Determines how asset hash is calculated. Assets will get rebuild and
3542
* uploaded only if their hash has changed.

packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts

+19
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,22 @@ test('Bundling with custom build args', () => {
229229
}),
230230
}));
231231
});
232+
233+
test('Bundling with custom environment vars`', () => {
234+
const entry = path.join(__dirname, 'lambda-handler');
235+
Bundling.bundle({
236+
entry: entry,
237+
runtime: Runtime.PYTHON_3_7,
238+
environment: {
239+
KEY: 'value',
240+
},
241+
});
242+
243+
expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({
244+
bundling: expect.objectContaining({
245+
environment: {
246+
KEY: 'value',
247+
},
248+
}),
249+
}));
250+
});

0 commit comments

Comments
 (0)