-
Notifications
You must be signed in to change notification settings - Fork 234
/
Copy pathlambdaEdge.ts
141 lines (125 loc) · 4.6 KB
/
lambdaEdge.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
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import * as aws from "@pulumi/aws";
import * as pulumi from "@pulumi/pulumi";
export interface LambdaEdgeArgs {
func: aws.lambda.Callback<any, any>;
funcDescription: string;
/**
* Set this to `true` if you do not want the component resources
* to have a prefix of the component name.
*
* This was added to support backwards compatibility with resources
* that were created prior to having the default naming strategy use
* this component's name as prefix for all resources. Any changes in names,
* after the fact will cause a replacement of all the resources,
* which will subsequently fail because a Lambda@Edge function cannot be
* deleted during a replacement.
*
* Lambda@Edge functions are automatically deleted by AWS when the
* last CloudFront Distribution association to it is removed.
*/
disableResourceNamePrefix?: boolean;
}
export class LambdaEdge extends pulumi.ComponentResource {
private args: LambdaEdgeArgs;
private readonly resourceNamesPrefix: string;
private role: aws.iam.Role;
private lambdaEdgeFunc: aws.lambda.CallbackFunction<any, any>;
constructor(name: string, args: LambdaEdgeArgs, opts: pulumi.ComponentResourceOptions) {
super("www-pulumi:infrastructure:LambdaEdge", name, undefined, opts);
const defaultRegion = aws.config.region;
if (defaultRegion !== aws.Region.USEast1 && !opts.providers && !opts.provider) {
throw new Error("Lambda@Edge must be deployed in us-east-1.");
}
if (!args.disableResourceNamePrefix) {
this.resourceNamesPrefix = `${name}-`;
} else {
this.resourceNamesPrefix = "";
}
this.args = args;
this.createIam();
this.createLambdaFunction();
super.registerOutputs({});
}
public getLambdaEdgeArn(): pulumi.Output<string> {
return pulumi.interpolate `${this.lambdaEdgeFunc.arn}:${this.lambdaEdgeFunc.version}`;
}
private createIam() {
this.role = new aws.iam.Role(
`${this.resourceNamesPrefix}lambdaEdgeRole`,
{
assumeRolePolicy: {
Statement: [{
Effect: "Allow",
Action: "sts:AssumeRole",
Principal: {
Service: [
"lambda.amazonaws.com",
"edgelambda.amazonaws.com",
],
},
}],
Version: "2012-10-17",
},
},
{
parent: this,
},
);
const rolePolicy = new aws.iam.RolePolicy(
`${this.resourceNamesPrefix}lambdaCloudWatchPolicy`,
{
role: this.role,
policy: {
Version: "2012-10-17",
Statement: [
{
Action: [
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:CreateLogGroup",
],
Effect: "Allow",
Resource: "*",
},
],
},
},
{
parent: this,
},
);
}
private createLambdaFunction() {
this.lambdaEdgeFunc = new aws.lambda.CallbackFunction(
`${this.resourceNamesPrefix}lambdaEdge`,
{
callback: this.args.func,
description: this.args.funcDescription,
// Minimum is 128MB.
memorySize: 128,
publish: true,
role: this.role,
runtime: aws.lambda.Runtime.NodeJS18dX,
// Note that Lambda@Edge functions have a different max timeout of 30 seconds
// than the regular Lambda functions.
timeout: 5,
},
{
parent: this,
},
);
// Grant permissions on the above Lambda function to the Lambda@Edge service.
const perm = new aws.lambda.Permission(
`${this.resourceNamesPrefix}getFuncPermission`,
{
action: "lambda:GetFunction",
principal: "edgelambda.amazonaws.com",
function: this.lambdaEdgeFunc,
},
{
parent: this,
},
);
}
}