Skip to content

Commit 5dae7b0

Browse files
authored
Merge pull request #59 from hablutzel1/eventbridge-warmer
Introduce a Lambda function warmer to mitigate cold starts
2 parents e96c396 + a2b665b commit 5dae7b0

6 files changed

Lines changed: 125 additions & 14 deletions

File tree

configure.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,7 @@ def main(raw_args=None):
144144
# Iterate through the different regions specified and produce an output file for each region.
145145
for region in config['perspectives']:
146146
aws_perspective_tf_region = aws_perspective_tf.replace("{{region}}", region)
147-
148-
# Replace the deployment id.
149-
aws_perspective_tf_region = aws_perspective_tf_region.replace("{{deployment-id}}", str(deployment_id))
147+
150148
# Construct the default CAA domain list.
151149
default_caa_domains_list = "|".join(config['caa-domains'])
152150
aws_perspective_tf_region = aws_perspective_tf_region.replace("{{default-caa-domains}}", f"\"{default_caa_domains_list}\"")

open-tofu/aws-perspective.tf.template

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Each layer must be created in the region of the functions.
22
resource "aws_lambda_layer_version" "python3_open_mpic_layer_{{region}}" {
33
filename = "../layer/python3_layer_content.zip"
4-
layer_name = "python3_open_mpic_layer_{{region}}_{{deployment-id}}"
4+
layer_name = "python3_open_mpic_layer_{{region}}_${local.deployment_id}"
55
source_code_hash = "${filebase64sha256("../layer/python3_layer_content.zip")}"
66
compatible_runtimes = ["python3.11"]
77
provider = aws.{{region}}
@@ -197,7 +197,7 @@ resource "aws_route53_resolver_dnssec_config" "dnssec_config_{{region}}" {
197197

198198
resource "aws_lambda_function" "mpic_dcv_checker_lambda_{{region}}" {
199199
filename = "../{{source-path}}/mpic_dcv_checker_lambda/mpic_dcv_checker_lambda.zip"
200-
function_name = "open_mpic_dcv_checker_lambda_{{region}}_{{deployment-id}}"
200+
function_name = "open_mpic_dcv_checker_lambda_{{region}}_${local.deployment_id}"
201201
role = aws_iam_role.open_mpic_lambda_role.arn
202202
depends_on = [
203203
aws_iam_role.open_mpic_lambda_role,
@@ -228,7 +228,7 @@ resource "aws_lambda_function" "mpic_dcv_checker_lambda_{{region}}" {
228228

229229
resource "aws_lambda_function" "mpic_caa_checker_lambda_{{region}}" {
230230
filename = "../{{source-path}}/mpic_caa_checker_lambda/mpic_caa_checker_lambda.zip"
231-
function_name = "open_mpic_caa_checker_lambda_{{region}}_{{deployment-id}}"
231+
function_name = "open_mpic_caa_checker_lambda_{{region}}_${local.deployment_id}"
232232
role = aws_iam_role.open_mpic_lambda_role.arn
233233
depends_on = [
234234
aws_iam_role.open_mpic_lambda_role,

open-tofu/eventbridge_warmer.tf

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
resource "aws_scheduler_schedule" "open_mpic_warmer_schedule" {
2+
for_each = {
3+
for k, v in {
4+
# TODO instead of using valid MPIC requests, evaluate to modify the coordinator Lambda to receive an especial parameter to trigger the warmup of all the perspectives. That would simplify things by requiring a single warmer, instead of two, as now.
5+
caa = {
6+
check_type = "caa"
7+
domain_or_ip_target = "invalid"
8+
orchestration_parameters = {
9+
perspective_count = length(keys(local.perspectives))
10+
}
11+
}
12+
dcv = {
13+
check_type = "dcv"
14+
domain_or_ip_target = "invalid"
15+
dcv_check_parameters = {
16+
validation_method = "dns-change"
17+
dns_record_type = "TXT"
18+
challenge_value = "dummy"
19+
}
20+
orchestration_parameters = {
21+
perspective_count = length(keys(local.perspectives))
22+
}
23+
}
24+
} : k => v if var.eventbridge_warmer_enabled
25+
}
26+
name = "open-mpic-${each.key}-warmer-schedule-${local.deployment_id}"
27+
group_name = "default"
28+
29+
flexible_time_window {
30+
mode = "OFF"
31+
}
32+
33+
schedule_expression = "rate(5 minutes)"
34+
35+
target {
36+
arn = aws_lambda_function.mpic_coordinator_lambda.arn
37+
role_arn = aws_iam_role.open_mpic_warmer_role[0].arn
38+
input = jsonencode({
39+
resource = "/dummy",
40+
path = "/dummy",
41+
httpMethod = "POST",
42+
headers = {},
43+
multiValueHeaders = {},
44+
requestContext = {
45+
accountId = "dummy",
46+
apiId = "dummy",
47+
stage = "dummy",
48+
protocol = "dummy",
49+
identity = {
50+
sourceIp = "0.0.0.0"
51+
},
52+
requestId = "dummy",
53+
requestTime = "dummy",
54+
requestTimeEpoch = 0,
55+
resourcePath = "dummy",
56+
httpMethod = "POST",
57+
path = "dummy"
58+
},
59+
body = jsonencode(each.value)
60+
})
61+
}
62+
}
63+
64+
resource "aws_iam_role" "open_mpic_warmer_role" {
65+
count = var.eventbridge_warmer_enabled ? 1 : 0
66+
name = "open-mpic-warmer-role-${local.deployment_id}"
67+
68+
assume_role_policy = <<EOF
69+
{
70+
"Version": "2012-10-17",
71+
"Statement": [
72+
{
73+
"Action": "sts:AssumeRole",
74+
"Principal": {
75+
"Service": "scheduler.amazonaws.com"
76+
},
77+
"Effect": "Allow"
78+
}
79+
]
80+
}
81+
EOF
82+
}
83+
84+
resource "aws_iam_role_policy" "open_mpic_warmer_role_policy" {
85+
count = var.eventbridge_warmer_enabled ? 1 : 0
86+
name = "open-mpic-warmer-role-policy-${local.deployment_id}"
87+
role = aws_iam_role.open_mpic_warmer_role[0].name
88+
policy = <<EOF
89+
{
90+
"Version": "2012-10-17",
91+
"Statement": [
92+
{
93+
"Action": "lambda:InvokeFunction",
94+
"Resource": [
95+
"${aws_lambda_function.mpic_coordinator_lambda.arn}"
96+
],
97+
"Effect": "Allow"
98+
}
99+
]
100+
}
101+
EOF
102+
}

open-tofu/main.tf.template

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,30 @@ provider "aws" {
44
profile = "default"
55
}
66

7+
locals {
8+
deployment_id = {{deployment-id}}
9+
perspectives = {{perspectives}}
10+
}
11+
712
# Python open-mpic layer (contains third party libraries)
813
resource "aws_lambda_layer_version" "python3_open_mpic_layer" {
914
filename = "../layer/python3_layer_content.zip"
10-
layer_name = "python3_open_mpic_layer_{{deployment-id}}"
15+
layer_name = "python3_open_mpic_layer_${local.deployment_id}"
1116
source_code_hash = "${filebase64sha256("../layer/python3_layer_content.zip")}"
1217
compatible_runtimes = ["python3.11"]
1318
}
1419

1520
# Mpic Coordinator layer for the mpic coordinator lambda (contains supporting first-party source code)
1621
resource "aws_lambda_layer_version" "mpic_coordinator_layer" {
1722
filename = "../layer/mpic_coordinator_layer_content.zip"
18-
layer_name = "mpic_coordinator_layer_{{deployment-id}}"
23+
layer_name = "mpic_coordinator_layer_${local.deployment_id}"
1924
source_code_hash = "${filebase64sha256("../layer/mpic_coordinator_layer_content.zip")}"
2025
compatible_runtimes = ["python3.11"]
2126
}
2227

2328
# Provide an IAM role for the functions to run under.
2429
resource "aws_iam_role" "open_mpic_lambda_role" {
25-
name = "open-mpic-lambda-role-{{deployment-id}}"
30+
name = "open-mpic-lambda-role-${local.deployment_id}"
2631

2732
assume_role_policy = <<EOF
2833
{
@@ -67,7 +72,7 @@ resource "aws_iam_role_policy_attachment" "invoke-lambda-policy-attach" {
6772
# Init the mpic coordinator lambda.
6873
resource "aws_lambda_function" "mpic_coordinator_lambda" {
6974
filename = "../{{source-path}}/mpic_coordinator_lambda/mpic_coordinator_lambda.zip"
70-
function_name = "open_mpic_lambda_coordinator_{{deployment-id}}"
75+
function_name = "open_mpic_lambda_coordinator_${local.deployment_id}"
7176
role = aws_iam_role.open_mpic_lambda_role.arn
7277
handler = "mpic_coordinator_lambda_function.lambda_handler"
7378
source_code_hash = filebase64sha256("../{{source-path}}/mpic_coordinator_lambda/mpic_coordinator_lambda.zip")
@@ -81,7 +86,7 @@ resource "aws_lambda_function" "mpic_coordinator_lambda" {
8186
]
8287
environment {
8388
variables = {
84-
perspectives = jsonencode({{perspectives}})
89+
perspectives = jsonencode(local.perspectives)
8590
default_perspective_count = {{default-perspective-count}}
8691
hash_secret = {{hash-secret}}
8792
{{absolute-max-attempts-with-key}}
@@ -91,7 +96,7 @@ resource "aws_lambda_function" "mpic_coordinator_lambda" {
9196
}
9297

9398
resource "aws_api_gateway_rest_api" "open_mpic_api" {
94-
name = "open-mpic-api-{{deployment-id}}"
99+
name = "open-mpic-api-${local.deployment_id}"
95100
description = "Open MPIC API Gateway"
96101
endpoint_configuration {
97102
types = ["EDGE"]
@@ -121,7 +126,7 @@ resource "aws_lambda_permission" "lambda_permission_api" {
121126

122127
# Set up the API key for the API.
123128
resource "aws_api_gateway_api_key" "open_mpic" {
124-
name = "open_mpic-{{deployment-id}}"
129+
name = "open_mpic-${local.deployment_id}"
125130
}
126131

127132
resource "aws_api_gateway_usage_plan_key" "prod_usage_key" {

open-tofu/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ variable "perspective_memory_size" {
1515
description = "MPIC Perspective Lambda Function Memory"
1616
default = 256
1717
}
18+
19+
variable "eventbridge_warmer_enabled" {
20+
type = bool
21+
description = "Enable EventBridge warmer to try to keep Lambda functions warm. See https://aws.amazon.com/pt/blogs/compute/operating-lambda-performance-optimization-part-1/, \"Understanding how functions warmers work\""
22+
default = false
23+
}

src/aws_lambda_mpic/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.0.5"
1+
__version__ = "1.0.6"

0 commit comments

Comments
 (0)