-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
lambda-version.ts
175 lines (152 loc) · 5.34 KB
/
lambda-version.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import cloudwatch = require('@aws-cdk/aws-cloudwatch');
import { Construct, Fn } from '@aws-cdk/core';
import { Function } from './function';
import { IFunction, QualifiedFunctionBase } from './function-base';
import { CfnVersion } from './lambda.generated';
export interface IVersion extends IFunction {
/**
* The most recently deployed version of this function.
* @attribute
*/
readonly version: string;
/**
* The underlying AWS Lambda function.
*/
readonly lambda: IFunction;
}
/**
* Properties for a new Lambda version
*/
export interface VersionProps {
/**
* SHA256 of the version of the Lambda source code
*
* Specify to validate that you're deploying the right version.
*
* @default No validation is performed
*/
readonly codeSha256?: string;
/**
* Description of the version
*
* @default Description of the Lambda
*/
readonly description?: string;
/**
* Function to get the value of
*/
readonly lambda: IFunction;
}
export interface VersionAttributes {
/**
* The version.
*/
readonly version: string;
/**
* The lambda function.
*/
readonly lambda: IFunction;
}
/**
* A single newly-deployed version of a Lambda function.
*
* This object exists to--at deploy time--query the "then-current" version of
* the Lambda function that it refers to. This Version object can then be
* used in `Alias` to refer to a particular deployment of a Lambda.
*
* This means that for every new update you deploy to your Lambda (using the
* CDK and Aliases), you must always create a new Version object. In
* particular, it must have a different name, so that a new resource is
* created.
*
* If you want to ensure that you're associating the right version with
* the right deployment, specify the `codeSha256` property while
* creating the `Version.
*/
export class Version extends QualifiedFunctionBase implements IVersion {
/**
* Construct a Version object from a Version ARN.
*
* @param scope The cdk scope creating this resource
* @param id The cdk id of this resource
* @param versionArn The version ARN to create this version from
*/
public static fromVersionArn(scope: Construct, id: string, versionArn: string): IVersion {
const version = extractVersionFromArn(versionArn);
const lambda = Function.fromFunctionArn(scope, `${id}Function`, versionArn);
class Import extends QualifiedFunctionBase implements IVersion {
public readonly version = version;
public readonly lambda = lambda;
public readonly functionName = `${lambda.functionName}:${version}`;
public readonly functionArn = versionArn;
public readonly grantPrincipal = lambda.grantPrincipal;
public readonly role = lambda.role;
protected readonly canCreatePermissions = false;
}
return new Import(scope, id);
}
public static fromVersionAttributes(scope: Construct, id: string, attrs: VersionAttributes): IVersion {
class Import extends QualifiedFunctionBase implements IVersion {
public readonly version = attrs.version;
public readonly lambda = attrs.lambda;
public readonly functionName = `${attrs.lambda.functionName}:${attrs.version}`;
public readonly functionArn = `${attrs.lambda.functionArn}:${attrs.version}`;
public readonly grantPrincipal = attrs.lambda.grantPrincipal;
public readonly role = attrs.lambda.role;
protected readonly canCreatePermissions = false;
}
return new Import(scope, id);
}
public readonly version: string;
public readonly lambda: IFunction;
public readonly functionArn: string;
public readonly functionName: string;
protected readonly canCreatePermissions = true;
constructor(scope: Construct, id: string, props: VersionProps) {
super(scope, id);
this.lambda = props.lambda;
const version = new CfnVersion(this, 'Resource', {
codeSha256: props.codeSha256,
description: props.description,
functionName: props.lambda.functionName
});
this.version = version.attrVersion;
this.functionArn = version.ref;
this.functionName = `${this.lambda.functionName}:${this.version}`;
}
public get grantPrincipal() {
return this.lambda.grantPrincipal;
}
public get role() {
return this.lambda.role;
}
public metric(metricName: string, props: cloudwatch.MetricOptions = {}): cloudwatch.Metric {
// Metrics on Aliases need the "bare" function name, and the alias' ARN, this differes from the base behavior.
return super.metric(metricName, {
dimensions: {
FunctionName: this.lambda.functionName,
// construct the ARN from the underlying lambda so that alarms on an alias
// don't cause a circular dependency with CodeDeploy
// see: https://github.com/aws/aws-cdk/issues/2231
Resource: `${this.lambda.functionArn}:${this.version}`
},
...props
});
}
}
/**
* Given an opaque (token) ARN, returns a CloudFormation expression that extracts the version
* name from the ARN.
*
* Version ARNs look like this:
*
* arn:aws:lambda:region:account-id:function:function-name:version
*
* ..which means that in order to extract the `version` component from the ARN, we can
* split the ARN using ":" and select the component in index 7.
*
* @returns `FnSelect(7, FnSplit(':', arn))`
*/
function extractVersionFromArn(arn: string) {
return Fn.select(7, Fn.split(':', arn));
}