From 7aa2f4a2dd0c42e91361893d4a5b790cba033531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Fri, 30 Sep 2022 10:27:36 +0200 Subject: [PATCH 01/12] feat(python)!: add support for v2 layer Changes to v1 layer: * remove python 3.6 support * aggregated all extra dependencies in "extras" group * removed unecessary files from Lambda Layer to reduce size BREAKING CHANGE: dropped python 3.6 support --- layer/Python/Dockerfile | 19 ++++++++++++------- src/lambda-powertools-layer.ts | 10 +++++----- test/lambda-powertools-python-layer.test.ts | 15 +++++++-------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/layer/Python/Dockerfile b/layer/Python/Dockerfile index f488f00..6f65802 100644 --- a/layer/Python/Dockerfile +++ b/layer/Python/Dockerfile @@ -1,19 +1,24 @@ FROM public.ecr.aws/lambda/python:3.8 - - ARG PACKAGE_SUFFIX='' USER root WORKDIR /tmp - -# PACKAGE_SUFFIX = '[pydantic]==1.23.0' -# PACKAGE_SUFFIX = '[pydantic]' +# PACKAGE_SUFFIX = '[extras]==1.23.0' +# PACKAGE_SUFFIX = '[extras]' # PACKAGE_SUFFIX = '=='1.23.0' # PACKAGE_SUFFIX = '' - RUN yum update -y && yum install -y zip unzip wget tar gzip -RUN pip install -t /asset/python aws-lambda-powertools$PACKAGE_SUFFIX \ No newline at end of file +RUN pip install -t /asset/python aws-lambda-powertools$PACKAGE_SUFFIX + +# Removing nonessential files +RUN cd /asset && \ + rm -rf python/boto* && \ + find python -name '*.so' -type f -exec strip "{}" \; && \ + find python -wholename "*/tests/*" -type f -delete && \ + find python -regex '^.*\(__pycache__\|\.py[co]\)$' -delete && \ + zip -r9 aws-lambda-powertools.zip ./python && \ + rm -rf ./python \ No newline at end of file diff --git a/src/lambda-powertools-layer.ts b/src/lambda-powertools-layer.ts index d9e362f..c7b46ca 100644 --- a/src/lambda-powertools-layer.ts +++ b/src/lambda-powertools-layer.ts @@ -10,8 +10,9 @@ export interface PowertoolsLayerProps { * The powertools package version from pypi repository. */ readonly version?: string; + /** - * A flag for the pydantic extras dependency, used for parsing. + * A flag for the extras dependencies (pydantic, aws-xray-sdk, etc.) * This will increase the size of the layer significantly. If you don't use parsing, ignore it. */ readonly includeExtras?: boolean; @@ -36,7 +37,7 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { * There are multiple combinations between version and extras package that results in different suffix for the installation. * With and without version, with and without extras flag. * We construct one suffix here because it is easier to do in code than inside the Dockerfile with bash commands. - * For example, if we set extras=true and version=1.22.0 we get '[pydantic]==1.22.0'. + * For example, if we set extras=true and version=1.22.0 we get '[extras]==1.22.0'. * */ static constructBuildArgs( @@ -48,7 +49,7 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { switch (runtimeFamily) { case lambda.RuntimeFamily.PYTHON: if (includeExtras) { - suffix = '[pydantic]'; + suffix = '[extras]'; } if (version) { suffix = `${suffix}==${version}`; @@ -84,7 +85,7 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { license: 'MIT-0', compatibleRuntimes: getRuntimesFromRuntimeFamily(runtimeFamily), description: `Lambda Powertools for ${languageName}${ - props?.includeExtras ? ' with Pydantic' : '' + props?.includeExtras ? ' with Extras' : '' } ${props?.version ? `version ${props?.version}` : 'latest version'}`.trim(), }); } @@ -94,7 +95,6 @@ function getRuntimesFromRuntimeFamily(runtimeFamily: lambda.RuntimeFamily): lamb switch (runtimeFamily) { case lambda.RuntimeFamily.PYTHON: return [ - lambda.Runtime.PYTHON_3_6, lambda.Runtime.PYTHON_3_7, lambda.Runtime.PYTHON_3_8, lambda.Runtime.PYTHON_3_9, diff --git a/test/lambda-powertools-python-layer.test.ts b/test/lambda-powertools-python-layer.test.ts index 6ea4d04..52ec3f3 100644 --- a/test/lambda-powertools-python-layer.test.ts +++ b/test/lambda-powertools-python-layer.test.ts @@ -23,7 +23,6 @@ describe('with no configuration the construct', () => { test('matches the python 3.x runtimes', () => { template.hasResourceProperties('AWS::Lambda::LayerVersion', { CompatibleRuntimes: [ - 'python3.6', 'python3.7', 'python3.8', 'python3.9', @@ -73,34 +72,34 @@ describe('with version configuration the construct', () => { }); Template.fromStack(stack).hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for Python with Pydantic version 1.22.0', + Description: 'Lambda Powertools for Python with Extras version 1.22.0', }); }); - test('synthesizes with pyndatic and latest version', () => { + test('synthesizes with extras and latest version', () => { const stack = new Stack(); new LambdaPowertoolsLayer(stack, 'LayerExtrasNoVersion', { includeExtras: true, }); Template.fromStack(stack).hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for Python with Pydantic latest version', + Description: 'Lambda Powertools for Python with Extras latest version', }); }); }); describe('construct build args for Dockerfile', () => { - test('returns pydantic and version', () => { + test('returns extras and version', () => { const args = LambdaPowertoolsLayer.constructBuildArgs(RuntimeFamily.PYTHON, true, '1.21.0'); - expect(args).toEqual('[pydantic]==1.21.0'); + expect(args).toEqual('[extras]==1.21.0'); }); - test('returns only pydantic when no version provided', () => { + test('returns only extras when no version provided', () => { const args = LambdaPowertoolsLayer.constructBuildArgs(RuntimeFamily.PYTHON, true, undefined); - expect(args).toEqual('[pydantic]'); + expect(args).toEqual('[extras]'); }); test('returns only version when no extras flag provided', () => { From 50bde69279971b4ac21b8524692ed963862505fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Fri, 30 Sep 2022 10:57:54 +0200 Subject: [PATCH 02/12] feat: add architecture option to generate layers for ARM64 --- .projen/deps.json | 4 ++-- .projenrc.js | 2 +- package.json | 4 ++-- src/lambda-powertools-layer.ts | 21 +++++++++++++++++++++ test/lambda-powertools-python-layer.test.ts | 17 ++++++++++++++++- yarn.lock | 12 ++++++------ 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/.projen/deps.json b/.projen/deps.json index e4c4705..fc3a24e 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -27,7 +27,7 @@ }, { "name": "aws-cdk-lib", - "version": "2.24.1", + "version": "2.44.0", "type": "build" }, { @@ -107,7 +107,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.24.1", + "version": "^2.44.0", "type": "peer" }, { diff --git a/.projenrc.js b/.projenrc.js index 9606100..1a1f3a6 100644 --- a/.projenrc.js +++ b/.projenrc.js @@ -4,7 +4,7 @@ const project = new awscdk.AwsCdkConstructLibrary({ authorUrl: 'https://aws.amazon.com', authorOrganization: true, keywords: ['aws', 'cdk', 'powertools', 'python', 'layer', 'lambda', 'devax', 'typescript', 'nodejs'], - cdkVersion: '2.24.1', + cdkVersion: '2.44.0', defaultReleaseBranch: 'main', majorVersion: 2, name: 'cdk-aws-lambda-powertools-layer', diff --git a/package.json b/package.json index b91aabc..9151d12 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@types/prettier": "2.6.0", "@typescript-eslint/eslint-plugin": "^5", "@typescript-eslint/parser": "^5", - "aws-cdk-lib": "2.24.1", + "aws-cdk-lib": "2.44.0", "constructs": "10.0.5", "eslint": "^8", "eslint-import-resolver-node": "^0.3.6", @@ -62,7 +62,7 @@ "typescript": "^4.8.2" }, "peerDependencies": { - "aws-cdk-lib": "^2.24.1", + "aws-cdk-lib": "^2.44.0", "constructs": "^10.0.5" }, "keywords": [ diff --git a/src/lambda-powertools-layer.ts b/src/lambda-powertools-layer.ts index c7b46ca..414bd05 100644 --- a/src/lambda-powertools-layer.ts +++ b/src/lambda-powertools-layer.ts @@ -1,5 +1,6 @@ import * as path from 'path'; import { aws_lambda as lambda } from 'aws-cdk-lib'; +import { Architecture } from 'aws-cdk-lib/aws-lambda'; import { Construct } from 'constructs'; /** @@ -26,6 +27,11 @@ export interface PowertoolsLayerProps { * the runtime of the layer */ readonly runtimeFamily?: lambda.RuntimeFamily; + + /** + * The compatible architectures for the layer + */ + readonly compatibleArchitectures?: lambda.Architecture[]; } /** @@ -70,6 +76,8 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { const runtimeFamily = props?.runtimeFamily ?? lambda.RuntimeFamily.PYTHON; const languageName = getLanguageNameFromRuntimeFamily(runtimeFamily); const dockerFilePath = path.join(__dirname, `../layer/${languageName}`); + const compatibleArchitectures = props?.compatibleArchitectures ?? [lambda.Architecture.X86_64]; + console.log(`path ${dockerFilePath}`); super(scope, id, { code: lambda.Code.fromDockerBuild(dockerFilePath, { @@ -80,10 +88,12 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { props?.version, ), }, + platform: getPlatformNameFromArchitectures(compatibleArchitectures), }), layerVersionName: props?.layerVersionName ? props?.layerVersionName : undefined, license: 'MIT-0', compatibleRuntimes: getRuntimesFromRuntimeFamily(runtimeFamily), + compatibleArchitectures, description: `Lambda Powertools for ${languageName}${ props?.includeExtras ? ' with Extras' : '' } ${props?.version ? `version ${props?.version}` : 'latest version'}`.trim(), @@ -120,3 +130,14 @@ function getLanguageNameFromRuntimeFamily(runtimeFamily: lambda.RuntimeFamily): return 'Unknown'; } } + +function getPlatformNameFromArchitectures(architectures: lambda.Architecture[]): string { + if (architectures.length == 1) { + return architectures[0].dockerPlatform; + } else { + // if we have multiple architectures, we default to x86_64, hoping for the + // layer not to have any architecture specific code or at least contain + // binary code for all architectures + return Architecture.X86_64.dockerPlatform; + } +} \ No newline at end of file diff --git a/test/lambda-powertools-python-layer.test.ts b/test/lambda-powertools-python-layer.test.ts index 52ec3f3..5ff635d 100644 --- a/test/lambda-powertools-python-layer.test.ts +++ b/test/lambda-powertools-python-layer.test.ts @@ -1,6 +1,6 @@ import { Stack } from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; -import { RuntimeFamily } from 'aws-cdk-lib/aws-lambda'; +import { Architecture, RuntimeFamily } from 'aws-cdk-lib/aws-lambda'; import { LambdaPowertoolsLayer } from '../src'; @@ -31,6 +31,21 @@ describe('with no configuration the construct', () => { }); }); +describe('with arm64 architecture', () => { + const stack = new Stack(); + new LambdaPowertoolsLayer(stack, 'PowertoolsLayer', { + runtimeFamily: RuntimeFamily.PYTHON, + compatibleArchitectures: [Architecture.ARM_64], + }); + const template = Template.fromStack(stack); + test('synthesizes successfully', () => { + template.hasResourceProperties('AWS::Lambda::LayerVersion', { + Description: 'Lambda Powertools for Python latest version', + CompatibleArchitectures: ['arm64'], + }); + }); +}); + describe('for layerVersionName configuraiton the construct', () => { test('synthisizes to a layer with provided name', () => { const stack = new Stack(); diff --git a/yarn.lock b/yarn.lock index 6c775d4..4ab41d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1220,16 +1220,16 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -aws-cdk-lib@2.24.1: - version "2.24.1" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.24.1.tgz#197d10216b384850c01205acc8e4818838964302" - integrity sha512-xGeEX+9wPGppSiIUdf/JTLMmqMikGhlSi7bjijl3lwncZtySkdjX0j+W2A1fuKp0S8Yd2axkwVkltIMxzNH/gw== +aws-cdk-lib@2.44.0: + version "2.44.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.44.0.tgz#e6157df7a72b8d1a4528f6fb9f9b0ed7aa404bcc" + integrity sha512-h0lCcS3t2TPF5FIpkA7OcE2t4vChtz/FGcZ5jVaORj21quiUz84eOhGk2BeRoKqfSp1Zqu2QxQUk6p6YpAOrRA== dependencies: "@balena/dockerignore" "^1.0.2" case "1.6.3" fs-extra "^9.1.0" ignore "^5.2.0" - jsonschema "^1.4.0" + jsonschema "^1.4.1" minimatch "^3.1.2" punycode "^2.1.1" semver "^7.3.7" @@ -3993,7 +3993,7 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -jsonschema@^1.4.0: +jsonschema@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== From 43b53cc7f01fd55ff1936a7c08aa5d22bbb12baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Fri, 30 Sep 2022 11:13:58 +0200 Subject: [PATCH 03/12] chore(docs): update API --- API.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/API.md b/API.md index 503bf10..2e26260 100644 --- a/API.md +++ b/API.md @@ -95,13 +95,26 @@ const powertoolsLayerProps: PowertoolsLayerProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | -| [`includeExtras`](#cdkawslambdapowertoolslayerpowertoolslayerpropspropertyincludeextras) | `boolean` | A flag for the pydantic extras dependency, used for parsing. | +| [`compatibleArchitectures`](#cdkawslambdapowertoolslayerpowertoolslayerpropspropertycompatiblearchitectures) | [`aws-cdk-lib.aws_lambda.Architecture`](#aws-cdk-lib.aws_lambda.Architecture)[] | The compatible architectures for the layer. | +| [`includeExtras`](#cdkawslambdapowertoolslayerpowertoolslayerpropspropertyincludeextras) | `boolean` | A flag for the extras dependencies (pydantic, aws-xray-sdk, etc.) This will increase the size of the layer significantly. If you don't use parsing, ignore it. | | [`layerVersionName`](#cdkawslambdapowertoolslayerpowertoolslayerpropspropertylayerversionname) | `string` | the name of the layer, will be randomised if empty. | | [`runtimeFamily`](#cdkawslambdapowertoolslayerpowertoolslayerpropspropertyruntimefamily) | [`aws-cdk-lib.aws_lambda.RuntimeFamily`](#aws-cdk-lib.aws_lambda.RuntimeFamily) | the runtime of the layer. | | [`version`](#cdkawslambdapowertoolslayerpowertoolslayerpropspropertyversion) | `string` | The powertools package version from pypi repository. | --- +##### `compatibleArchitectures`Optional + +```typescript +public readonly compatibleArchitectures: Architecture[]; +``` + +- *Type:* [`aws-cdk-lib.aws_lambda.Architecture`](#aws-cdk-lib.aws_lambda.Architecture)[] + +The compatible architectures for the layer. + +--- + ##### `includeExtras`Optional ```typescript @@ -110,9 +123,7 @@ public readonly includeExtras: boolean; - *Type:* `boolean` -A flag for the pydantic extras dependency, used for parsing. - -This will increase the size of the layer significantly. If you don't use parsing, ignore it. +A flag for the extras dependencies (pydantic, aws-xray-sdk, etc.) This will increase the size of the layer significantly. If you don't use parsing, ignore it. --- From d69fb03e901845e7fa5946ecae375068676c2989 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Mon, 3 Oct 2022 11:18:59 +0200 Subject: [PATCH 04/12] chore: apply suggestions from code review Co-authored-by: Heitor Lessa --- layer/Python/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/layer/Python/Dockerfile b/layer/Python/Dockerfile index 6f65802..bf22a77 100644 --- a/layer/Python/Dockerfile +++ b/layer/Python/Dockerfile @@ -17,6 +17,7 @@ RUN pip install -t /asset/python aws-lambda-powertools$PACKAGE_SUFFIX # Removing nonessential files RUN cd /asset && \ rm -rf python/boto* && \ + # remove debugging symbols find python -name '*.so' -type f -exec strip "{}" \; && \ find python -wholename "*/tests/*" -type f -delete && \ find python -regex '^.*\(__pycache__\|\.py[co]\)$' -delete && \ From 898cae5f7db93efe8cd5c205dc0997c3ee4cbe39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Mon, 3 Oct 2022 11:20:19 +0200 Subject: [PATCH 05/12] chore: document python Dockerfile --- layer/Python/Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/layer/Python/Dockerfile b/layer/Python/Dockerfile index bf22a77..ddf66d1 100644 --- a/layer/Python/Dockerfile +++ b/layer/Python/Dockerfile @@ -16,10 +16,15 @@ RUN pip install -t /asset/python aws-lambda-powertools$PACKAGE_SUFFIX # Removing nonessential files RUN cd /asset && \ + # remove boto3 and botocore (already available in Lambda Runtime) rm -rf python/boto* && \ # remove debugging symbols find python -name '*.so' -type f -exec strip "{}" \; && \ + # remove tests find python -wholename "*/tests/*" -type f -delete && \ + # remove python bytecode find python -regex '^.*\(__pycache__\|\.py[co]\)$' -delete && \ + # zip layer zip -r9 aws-lambda-powertools.zip ./python && \ + # delete original rm -rf ./python \ No newline at end of file From 3e11dbc8623538d7ede766978da84993d2bdca9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Mon, 3 Oct 2022 11:37:43 +0200 Subject: [PATCH 06/12] chore: rename extras poetry group to all --- layer/Python/Dockerfile | 6 +++--- src/lambda-powertools-layer.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/layer/Python/Dockerfile b/layer/Python/Dockerfile index ddf66d1..c931872 100644 --- a/layer/Python/Dockerfile +++ b/layer/Python/Dockerfile @@ -5,9 +5,9 @@ ARG PACKAGE_SUFFIX='' USER root WORKDIR /tmp -# PACKAGE_SUFFIX = '[extras]==1.23.0' -# PACKAGE_SUFFIX = '[extras]' -# PACKAGE_SUFFIX = '=='1.23.0' +# PACKAGE_SUFFIX = '[all]==2.0.0' +# PACKAGE_SUFFIX = '[all]' +# PACKAGE_SUFFIX = '=='2.0.0' # PACKAGE_SUFFIX = '' RUN yum update -y && yum install -y zip unzip wget tar gzip diff --git a/src/lambda-powertools-layer.ts b/src/lambda-powertools-layer.ts index 414bd05..18bd52f 100644 --- a/src/lambda-powertools-layer.ts +++ b/src/lambda-powertools-layer.ts @@ -55,7 +55,7 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { switch (runtimeFamily) { case lambda.RuntimeFamily.PYTHON: if (includeExtras) { - suffix = '[extras]'; + suffix = '[all]'; } if (version) { suffix = `${suffix}==${version}`; From a3a0f177d0aa9aa2c9aeac38057829d7af61c9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Mon, 3 Oct 2022 11:44:53 +0200 Subject: [PATCH 07/12] fix: tests --- test/lambda-powertools-python-layer.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lambda-powertools-python-layer.test.ts b/test/lambda-powertools-python-layer.test.ts index 5ff635d..307c572 100644 --- a/test/lambda-powertools-python-layer.test.ts +++ b/test/lambda-powertools-python-layer.test.ts @@ -108,13 +108,13 @@ describe('construct build args for Dockerfile', () => { test('returns extras and version', () => { const args = LambdaPowertoolsLayer.constructBuildArgs(RuntimeFamily.PYTHON, true, '1.21.0'); - expect(args).toEqual('[extras]==1.21.0'); + expect(args).toEqual('[all]==1.21.0'); }); test('returns only extras when no version provided', () => { const args = LambdaPowertoolsLayer.constructBuildArgs(RuntimeFamily.PYTHON, true, undefined); - expect(args).toEqual('[extras]'); + expect(args).toEqual('[all]'); }); test('returns only version when no extras flag provided', () => { From f2b8803ea11112b7a56dd84b0bf77be0637a0917 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Mon, 3 Oct 2022 14:49:30 +0200 Subject: [PATCH 08/12] chore: apply feedback from code review Co-authored-by: Heitor Lessa --- src/lambda-powertools-layer.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lambda-powertools-layer.ts b/src/lambda-powertools-layer.ts index 18bd52f..079653f 100644 --- a/src/lambda-powertools-layer.ts +++ b/src/lambda-powertools-layer.ts @@ -43,7 +43,7 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { * There are multiple combinations between version and extras package that results in different suffix for the installation. * With and without version, with and without extras flag. * We construct one suffix here because it is easier to do in code than inside the Dockerfile with bash commands. - * For example, if we set extras=true and version=1.22.0 we get '[extras]==1.22.0'. + * For example, if we set `includeExtras=true` and `version=1.22.0` we get '[all]==1.22.0'. * */ static constructBuildArgs( @@ -88,7 +88,8 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { props?.version, ), }, - platform: getPlatformNameFromArchitectures(compatibleArchitectures), + // supports cross-platform docker build + platform: getDockerPlatformNameFromArchitectures(compatibleArchitectures), }), layerVersionName: props?.layerVersionName ? props?.layerVersionName : undefined, license: 'MIT-0', @@ -131,7 +132,7 @@ function getLanguageNameFromRuntimeFamily(runtimeFamily: lambda.RuntimeFamily): } } -function getPlatformNameFromArchitectures(architectures: lambda.Architecture[]): string { +function getDockerPlatformNameFromArchitectures(architectures: lambda.Architecture[]): string { if (architectures.length == 1) { return architectures[0].dockerPlatform; } else { From 907939d3f14893b8e0eb46f4f42c2d5e3d2fc327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Mon, 3 Oct 2022 15:29:31 +0200 Subject: [PATCH 09/12] chore: addressed code review feedback --- layer/Python/Dockerfile | 8 ++------ src/lambda-powertools-layer.ts | 4 ++-- test/lambda-powertools-python-layer.test.ts | 10 +++++----- test/lambda-powertools-typescript-layer.test.ts | 4 ++-- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/layer/Python/Dockerfile b/layer/Python/Dockerfile index c931872..fa1e512 100644 --- a/layer/Python/Dockerfile +++ b/layer/Python/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /tmp # PACKAGE_SUFFIX = '=='2.0.0' # PACKAGE_SUFFIX = '' -RUN yum update -y && yum install -y zip unzip wget tar gzip +RUN yum update -y && yum install -y zip unzip wget tar gzip binutils RUN pip install -t /asset/python aws-lambda-powertools$PACKAGE_SUFFIX @@ -23,8 +23,4 @@ RUN cd /asset && \ # remove tests find python -wholename "*/tests/*" -type f -delete && \ # remove python bytecode - find python -regex '^.*\(__pycache__\|\.py[co]\)$' -delete && \ - # zip layer - zip -r9 aws-lambda-powertools.zip ./python && \ - # delete original - rm -rf ./python \ No newline at end of file + find python -regex '^.*\(__pycache__\|\.py[co]\)$' -delete \ No newline at end of file diff --git a/src/lambda-powertools-layer.ts b/src/lambda-powertools-layer.ts index 079653f..085f3d8 100644 --- a/src/lambda-powertools-layer.ts +++ b/src/lambda-powertools-layer.ts @@ -95,8 +95,8 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { license: 'MIT-0', compatibleRuntimes: getRuntimesFromRuntimeFamily(runtimeFamily), compatibleArchitectures, - description: `Lambda Powertools for ${languageName}${ - props?.includeExtras ? ' with Extras' : '' + description: `Lambda Powertools for ${languageName} [${compatibleArchitectures.map(x => x.name).join(', ')}]${ + props?.includeExtras ? ' with extra dependencies' : '' } ${props?.version ? `version ${props?.version}` : 'latest version'}`.trim(), }); } diff --git a/test/lambda-powertools-python-layer.test.ts b/test/lambda-powertools-python-layer.test.ts index 307c572..b629098 100644 --- a/test/lambda-powertools-python-layer.test.ts +++ b/test/lambda-powertools-python-layer.test.ts @@ -10,7 +10,7 @@ describe('with no configuration the construct', () => { const template = Template.fromStack(stack); test('synthesizes successfully', () => { template.hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for Python latest version', + Description: 'Lambda Powertools for Python [x86_64] latest version', }); }); @@ -40,7 +40,7 @@ describe('with arm64 architecture', () => { const template = Template.fromStack(stack); test('synthesizes successfully', () => { template.hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for Python latest version', + Description: 'Lambda Powertools for Python [arm64] latest version', CompatibleArchitectures: ['arm64'], }); }); @@ -68,7 +68,7 @@ describe('with version configuration the construct', () => { Template.fromStack(stack).hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for Python version 1.21.0', + Description: 'Lambda Powertools for Python [x86_64] version 1.21.0', }); }); @@ -87,7 +87,7 @@ describe('with version configuration the construct', () => { }); Template.fromStack(stack).hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for Python with Extras version 1.22.0', + Description: 'Lambda Powertools for Python [x86_64] with extra dependencies version 1.22.0', }); }); @@ -99,7 +99,7 @@ describe('with version configuration the construct', () => { }); Template.fromStack(stack).hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for Python with Extras latest version', + Description: 'Lambda Powertools for Python [x86_64] with extra dependencies latest version', }); }); }); diff --git a/test/lambda-powertools-typescript-layer.test.ts b/test/lambda-powertools-typescript-layer.test.ts index 7ce9c5b..1b3dfa3 100644 --- a/test/lambda-powertools-typescript-layer.test.ts +++ b/test/lambda-powertools-typescript-layer.test.ts @@ -12,7 +12,7 @@ describe('with minimal configuration the construct', () => { const template = Template.fromStack(stack); test('synthesizes successfully', () => { template.hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: 'Lambda Powertools for TypeScript latest version', + Description: 'Lambda Powertools for TypeScript [x86_64] latest version', }); }); @@ -57,7 +57,7 @@ describe('with version configuration the construct', () => { Template.fromStack(stack).hasResourceProperties('AWS::Lambda::LayerVersion', { - Description: `Lambda Powertools for TypeScript version ${version}`, + Description: `Lambda Powertools for TypeScript [x86_64] version ${version}`, }); }); From 0fbd446d4fcae0ddd62d3dfbe6b6f8f920c41c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Mon, 3 Oct 2022 15:31:43 +0200 Subject: [PATCH 10/12] chore: add documentation to getDockerPlatformNameFromArchitectures --- src/lambda-powertools-layer.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lambda-powertools-layer.ts b/src/lambda-powertools-layer.ts index 085f3d8..a278720 100644 --- a/src/lambda-powertools-layer.ts +++ b/src/lambda-powertools-layer.ts @@ -132,6 +132,8 @@ function getLanguageNameFromRuntimeFamily(runtimeFamily: lambda.RuntimeFamily): } } +// Docker expects a single string for the --platform option. +// getDockerPlatformNameFromArchitectures converts the Architecture enum to a string. function getDockerPlatformNameFromArchitectures(architectures: lambda.Architecture[]): string { if (architectures.length == 1) { return architectures[0].dockerPlatform; From 96839c0d64dfbbe3bef93d79509618c33fbfa6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Fonseca?= Date: Mon, 3 Oct 2022 16:22:51 +0200 Subject: [PATCH 11/12] chore: remove more dependencies from the python layer --- layer/Python/Dockerfile | 2 ++ src/lambda-powertools-layer.ts | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/layer/Python/Dockerfile b/layer/Python/Dockerfile index fa1e512..32db134 100644 --- a/layer/Python/Dockerfile +++ b/layer/Python/Dockerfile @@ -18,6 +18,8 @@ RUN pip install -t /asset/python aws-lambda-powertools$PACKAGE_SUFFIX RUN cd /asset && \ # remove boto3 and botocore (already available in Lambda Runtime) rm -rf python/boto* && \ + # remove boto3 dependencies + rm -rf python/s3transfer* python/*dateutil* python/urllib3* && \ # remove debugging symbols find python -name '*.so' -type f -exec strip "{}" \; && \ # remove tests diff --git a/src/lambda-powertools-layer.ts b/src/lambda-powertools-layer.ts index a278720..a7d060d 100644 --- a/src/lambda-powertools-layer.ts +++ b/src/lambda-powertools-layer.ts @@ -77,6 +77,7 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { const languageName = getLanguageNameFromRuntimeFamily(runtimeFamily); const dockerFilePath = path.join(__dirname, `../layer/${languageName}`); const compatibleArchitectures = props?.compatibleArchitectures ?? [lambda.Architecture.X86_64]; + const compatibleArchitecturesDescription = compatibleArchitectures.map((arch) => arch.name).join(', '); console.log(`path ${dockerFilePath}`); super(scope, id, { @@ -95,7 +96,7 @@ export class LambdaPowertoolsLayer extends lambda.LayerVersion { license: 'MIT-0', compatibleRuntimes: getRuntimesFromRuntimeFamily(runtimeFamily), compatibleArchitectures, - description: `Lambda Powertools for ${languageName} [${compatibleArchitectures.map(x => x.name).join(', ')}]${ + description: `Lambda Powertools for ${languageName} [${compatibleArchitecturesDescription}]${ props?.includeExtras ? ' with extra dependencies' : '' } ${props?.version ? `version ${props?.version}` : 'latest version'}`.trim(), }); From 4bc80e86922850d570ff684fa6309da15702b4b5 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Mon, 3 Oct 2022 16:51:27 +0200 Subject: [PATCH 12/12] chore(deps): remove six boto dep --- layer/Python/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layer/Python/Dockerfile b/layer/Python/Dockerfile index 32db134..682c596 100644 --- a/layer/Python/Dockerfile +++ b/layer/Python/Dockerfile @@ -19,7 +19,7 @@ RUN cd /asset && \ # remove boto3 and botocore (already available in Lambda Runtime) rm -rf python/boto* && \ # remove boto3 dependencies - rm -rf python/s3transfer* python/*dateutil* python/urllib3* && \ + rm -rf python/s3transfer* python/*dateutil* python/urllib3* python/six* && \ # remove debugging symbols find python -name '*.so' -type f -exec strip "{}" \; && \ # remove tests