1
1
import { Aws , CfnMapping , Fn , IResolveContext , Lazy , Stack , Token } from '@aws-cdk/core' ;
2
2
import { FactName , RegionInfo } from '@aws-cdk/region-info' ;
3
+ import { Construct } from 'constructs' ;
4
+ import { Architecture } from './architecture' ;
5
+ import { IFunction } from './function-base' ;
6
+
3
7
4
8
// This is the name of the mapping that will be added to the CloudFormation template, if a stack is region agnostic
5
9
const DEFAULT_MAPPING_PREFIX = 'LambdaInsightsVersions' ;
6
10
11
+ /**
12
+ * Config returned from {@link LambdaInsightsVersion._bind}
13
+ */
14
+ interface InsightsBindConfig {
15
+ /**
16
+ * ARN of the Lambda Insights Layer Version
17
+ */
18
+ readonly arn : string ;
19
+ }
20
+
7
21
// To add new versions, update fact-tables.ts `CLOUDWATCH_LAMBDA_INSIGHTS_ARNS` and create a new `public static readonly VERSION_A_B_C_D`
8
22
9
23
/**
@@ -31,6 +45,11 @@ export abstract class LambdaInsightsVersion {
31
45
*/
32
46
public static readonly VERSION_1_0_98_0 = LambdaInsightsVersion . fromInsightsVersion ( '1.0.98.0' ) ;
33
47
48
+ /**
49
+ * Version 1.0.119.0
50
+ */
51
+ public static readonly VERSION_1_0_119_0 = LambdaInsightsVersion . fromInsightsVersion ( '1.0.119.0' ) ;
52
+
34
53
/**
35
54
* Use the insights extension associated with the provided ARN. Make sure the ARN is associated
36
55
* with same region as your function
@@ -40,23 +59,35 @@ export abstract class LambdaInsightsVersion {
40
59
public static fromInsightVersionArn ( arn : string ) : LambdaInsightsVersion {
41
60
class InsightsArn extends LambdaInsightsVersion {
42
61
public readonly layerVersionArn = arn ;
62
+ public _bind ( _scope : Construct , _function : IFunction ) : InsightsBindConfig {
63
+ return { arn } ;
64
+ }
43
65
}
44
66
return new InsightsArn ( ) ;
45
67
}
46
68
47
69
// Use the verison to build the object. Not meant to be called by the user -- user should use e.g. VERSION_1_0_54_0
48
70
private static fromInsightsVersion ( insightsVersion : string ) : LambdaInsightsVersion {
49
71
50
- // Check if insights version is valid. This should only happen if one of the public static readonly versions are set incorrectly
51
- const versionExists = RegionInfo . regions . some ( regionInfo => regionInfo . cloudwatchLambdaInsightsArn ( insightsVersion ) ) ;
52
- if ( ! versionExists ) {
53
- throw new Error ( `Insights version ${ insightsVersion } does not exist.` ) ;
54
- }
55
-
56
72
class InsightsVersion extends LambdaInsightsVersion {
57
73
public readonly layerVersionArn = Lazy . uncachedString ( {
58
74
produce : ( context ) => getVersionArn ( context , insightsVersion ) ,
59
75
} ) ;
76
+
77
+ public _bind ( _scope : Construct , _function : IFunction ) : InsightsBindConfig {
78
+ const arch = _function . architecture ?. name ?? Architecture . X86_64 . name ;
79
+ // Check if insights version is valid. This should only happen if one of the public static readonly versions are set incorrectly
80
+ // or if the version is not available for the Lambda Architecture
81
+ const versionExists = RegionInfo . regions . some ( regionInfo => regionInfo . cloudwatchLambdaInsightsArn ( insightsVersion , arch ) ) ;
82
+ if ( ! versionExists ) {
83
+ throw new Error ( `Insights version ${ insightsVersion } does not exist.` ) ;
84
+ }
85
+ return {
86
+ arn : Lazy . uncachedString ( {
87
+ produce : ( context ) => getVersionArn ( context , insightsVersion , arch ) ,
88
+ } ) ,
89
+ } ;
90
+ }
60
91
}
61
92
return new InsightsVersion ( ) ;
62
93
}
@@ -65,6 +96,13 @@ export abstract class LambdaInsightsVersion {
65
96
* The arn of the Lambda Insights extension
66
97
*/
67
98
public readonly layerVersionArn : string = '' ;
99
+
100
+ /**
101
+ * Returns the arn of the Lambda Insights extension based on the
102
+ * Lambda architecture
103
+ * @internal
104
+ */
105
+ public abstract _bind ( _scope : Construct , _function : IFunction ) : InsightsBindConfig ;
68
106
}
69
107
70
108
/**
@@ -73,14 +111,15 @@ export abstract class LambdaInsightsVersion {
73
111
*
74
112
* This function is run on CDK synthesis.
75
113
*/
76
- function getVersionArn ( context : IResolveContext , insightsVersion : string ) : string {
114
+ function getVersionArn ( context : IResolveContext , insightsVersion : string , architecture ?: string ) : string {
77
115
78
116
const scopeStack = Stack . of ( context . scope ) ;
79
117
const region = scopeStack . region ;
118
+ const arch = architecture ?? Architecture . X86_64 . name ;
80
119
81
120
// Region is defined, look up the arn, or throw an error if the version isn't supported by a region
82
121
if ( region !== undefined && ! Token . isUnresolved ( region ) ) {
83
- const arn = RegionInfo . get ( region ) . cloudwatchLambdaInsightsArn ( insightsVersion ) ;
122
+ const arn = RegionInfo . get ( region ) . cloudwatchLambdaInsightsArn ( insightsVersion , arch ) ;
84
123
if ( arn === undefined ) {
85
124
throw new Error ( `Insights version ${ insightsVersion } is not supported in region ${ region } ` ) ;
86
125
}
@@ -116,19 +155,33 @@ function getVersionArn(context: IResolveContext, insightsVersion: string): strin
116
155
* -- {'arn': 'arn3'},
117
156
* - us-east-2
118
157
* -- {'arn': 'arn4'}
158
+ * LambdaInsightsVersions101190arm64 // a separate mapping version 1.0.119.0 arm64
159
+ * - us-east-1
160
+ * -- {'arn': 'arn3'},
161
+ * - us-east-2
162
+ * -- {'arn': 'arn4'}
119
163
*/
120
164
121
- const mapName = DEFAULT_MAPPING_PREFIX + insightsVersion . split ( '.' ) . join ( '' ) ;
165
+ let mapName = DEFAULT_MAPPING_PREFIX + insightsVersion . split ( '.' ) . join ( '' ) ;
166
+ // if the architecture is arm64 then append that to the end of the name
167
+ // this is so that we can have a separate mapping for x86 vs arm in scenarios
168
+ // where we have Lambda functions with both architectures in the same stack
169
+ if ( arch === Architecture . ARM_64 . name ) {
170
+ mapName += arch ;
171
+ }
122
172
const mapping : { [ k1 : string ] : { [ k2 : string ] : any } } = { } ;
123
- const region2arns = RegionInfo . regionMap ( FactName . cloudwatchLambdaInsightsVersion ( insightsVersion ) ) ;
173
+ const region2arns = RegionInfo . regionMap ( FactName . cloudwatchLambdaInsightsVersion ( insightsVersion , arch ) ) ;
124
174
for ( const [ reg , arn ] of Object . entries ( region2arns ) ) {
125
175
mapping [ reg ] = { arn } ;
126
176
}
127
177
128
178
// Only create a given mapping once. If another version of insights is used elsewhere, that mapping will also exist
129
179
if ( ! scopeStack . node . tryFindChild ( mapName ) ) {
130
- new CfnMapping ( scopeStack , mapName , { mapping } ) ;
180
+ // need to call findInMap here if we are going to set lazy=true, otherwise
181
+ // we get the informLazyUse info message
182
+ const map = new CfnMapping ( scopeStack , mapName , { mapping, lazy : true } ) ;
183
+ return map . findInMap ( Aws . REGION , 'arn' ) ;
131
184
}
132
185
// The ARN will be looked up at deployment time from the mapping we created
133
186
return Fn . findInMap ( mapName , Aws . REGION , 'arn' ) ;
134
- }
187
+ }
0 commit comments