Skip to content

Commit 9f1696b

Browse files
author
Alexander Schueren
authored
chore(ci): add canary to layer deployment (#1593)
1 parent 863edc8 commit 9f1696b

File tree

5 files changed

+113
-18
lines changed

5 files changed

+113
-18
lines changed

Diff for: .github/scripts/setup_tmp_layer_files.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ npm init -y
66
npm i \
77
@aws-lambda-powertools/logger@$VERSION \
88
@aws-lambda-powertools/metrics@$VERSION \
9-
@aws-lambda-powertools/tracer@$VERSION
9+
@aws-lambda-powertools/tracer@$VERSION \
10+
@aws-lambda-powertools/parameters@$VERSION
1011
rm -rf node_modules/@types \
1112
package.json \
1213
package-lock.json

Diff for: .github/workflows/reusable_deploy_layer_stack.yml

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ jobs:
9494
path: ./cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting.
9595
if-no-files-found: error
9696
retention-days: 1
97+
- name: CDK deploy canary
98+
run: npm run cdk -w layer -- deploy --app cdk.out --context region=${{ matrix.region }} 'CanaryStack' --require-approval never --verbose --outputs-file cdk-outputs.json
9799
update_layer_arn_docs:
98100
needs: deploy-cdk-stack
99101
permissions:

Diff for: layers/bin/layers.ts

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import 'source-map-support/register';
33
import { App } from 'aws-cdk-lib';
44
import { LayerPublisherStack } from '../src/layer-publisher-stack';
5+
import { CanaryStack } from 'layers/src/canary-stack';
56

67
const SSM_PARAM_LAYER_ARN = '/layers/powertools-layer-arn';
78

@@ -12,3 +13,9 @@ new LayerPublisherStack(app, 'LayerPublisherStack', {
1213
layerName: 'AWSLambdaPowertoolsTypeScript',
1314
ssmParameterLayerArn: SSM_PARAM_LAYER_ARN,
1415
});
16+
17+
new CanaryStack(app, 'CanaryStack', {
18+
powertoolsPackageVersion: app.node.tryGetContext('PowertoolsPackageVersion'),
19+
ssmParameterLayerArn: SSM_PARAM_LAYER_ARN,
20+
layerName: 'AWSLambdaPowertoolsCanaryTypeScript',
21+
});

Diff for: layers/src/canary-stack.ts

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { CustomResource, Duration, Stack, StackProps } from 'aws-cdk-lib';
2+
import { Construct } from 'constructs';
3+
import { LayerVersion, Runtime } from 'aws-cdk-lib/aws-lambda';
4+
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
5+
import { v4 } from 'uuid';
6+
import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';
7+
import { Provider } from 'aws-cdk-lib/custom-resources';
8+
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
9+
import path from 'path';
10+
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
11+
12+
export interface CanaryStackProps extends StackProps {
13+
readonly layerName: string;
14+
readonly powertoolsPackageVersion: string;
15+
readonly ssmParameterLayerArn: string;
16+
}
17+
18+
export class CanaryStack extends Stack {
19+
public constructor(scope: Construct, id: string, props: CanaryStackProps) {
20+
super(scope, id, props);
21+
const { layerName, powertoolsPackageVersion } = props;
22+
23+
const suffix = v4().substring(0, 5);
24+
25+
const layerArn = StringParameter.fromStringParameterAttributes(
26+
this,
27+
'LayerArn',
28+
{
29+
parameterName: props.ssmParameterLayerArn,
30+
}
31+
).stringValue;
32+
33+
// lambda function
34+
const layer = [
35+
LayerVersion.fromLayerVersionArn(this, 'powertools-layer', layerArn),
36+
];
37+
38+
const canaryFunction = new NodejsFunction(this, 'CanaryFunction', {
39+
entry: path.join(
40+
__dirname,
41+
'../tests/e2e/layerPublisher.class.test.functionCode.ts'
42+
),
43+
handler: 'handler',
44+
runtime: Runtime.NODEJS_18_X,
45+
functionName: `canary-${suffix}`,
46+
timeout: Duration.seconds(30),
47+
bundling: {
48+
externalModules: [
49+
// don't package these modules, we want to pull them from the layer
50+
'aws-sdk',
51+
'@aws-lambda-powertools/logger',
52+
'@aws-lambda-powertools/metrics',
53+
'@aws-lambda-powertools/tracer',
54+
'@aws-lambda-powertools/parameters',
55+
'@aws-lambda-powertools/commons',
56+
],
57+
},
58+
environment: {
59+
POWERTOOLS_SERVICE_NAME: 'canary',
60+
POWERTOOLS_PACKAGE_VERSION: powertoolsPackageVersion,
61+
POWERTOOLS_LAYER_NAME: layerName,
62+
SSM_PARAMETER_LAYER_ARN: props.ssmParameterLayerArn,
63+
},
64+
layers: layer,
65+
logRetention: RetentionDays.ONE_DAY,
66+
});
67+
68+
canaryFunction.addToRolePolicy(
69+
new PolicyStatement({
70+
actions: ['ssm:GetParameter'],
71+
resources: ['*'],
72+
effect: Effect.ALLOW,
73+
})
74+
);
75+
76+
// use custom resource to trigger the lambda function during the CFN deployment
77+
const provider = new Provider(this, 'CanaryCustomResourceProvider', {
78+
onEventHandler: canaryFunction,
79+
logRetention: RetentionDays.ONE_DAY,
80+
});
81+
82+
// random suffix forces recreation of the custom resource otherwise the custom resource will be reused from prevous deployment
83+
new CustomResource(this, `CanaryCustomResource${suffix}`, {
84+
serviceToken: provider.serviceToken,
85+
});
86+
}
87+
}

Diff for: layers/tests/e2e/layerPublisher.class.test.functionCode.ts

+15-17
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,31 @@ import { readFileSync } from 'node:fs';
22
import { Logger } from '@aws-lambda-powertools/logger';
33
import { Metrics } from '@aws-lambda-powertools/metrics';
44
import { Tracer } from '@aws-lambda-powertools/tracer';
5+
import { SSMProvider } from '@aws-lambda-powertools/parameters/ssm';
56

67
const logger = new Logger({
78
logLevel: 'DEBUG',
89
});
910
const metrics = new Metrics();
1011
const tracer = new Tracer();
12+
new SSMProvider();
1113

1214
export const handler = (): void => {
1315
// Check that the packages version matches the expected one
14-
try {
15-
const packageJSON = JSON.parse(
16-
readFileSync(
17-
'/opt/nodejs/node_modules/@aws-lambda-powertools/logger/package.json',
18-
{
19-
encoding: 'utf8',
20-
flag: 'r',
21-
}
22-
)
23-
);
16+
const packageJSON = JSON.parse(
17+
readFileSync(
18+
'/opt/nodejs/node_modules/@aws-lambda-powertools/logger/package.json',
19+
{
20+
encoding: 'utf8',
21+
flag: 'r',
22+
}
23+
)
24+
);
2425

25-
if (packageJSON.version != process.env.POWERTOOLS_PACKAGE_VERSION) {
26-
throw new Error(
27-
`Package version mismatch: ${packageJSON.version} != ${process.env.POWERTOOLS_PACKAGE_VERSION}`
28-
);
29-
}
30-
} catch (error) {
31-
console.error(error);
26+
if (packageJSON.version != process.env.POWERTOOLS_PACKAGE_VERSION) {
27+
throw new Error(
28+
`Package version mismatch: ${packageJSON.version} != ${process.env.POWERTOOLS_PACKAGE_VERSION}`
29+
);
3230
}
3331

3432
// Check that the logger is working

0 commit comments

Comments
 (0)