-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdispatcher.tf
More file actions
87 lines (76 loc) · 3.6 KB
/
Copy pathdispatcher.tf
File metadata and controls
87 lines (76 loc) · 3.6 KB
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
###############################################################################
# Dispatcher Lambda. A terraform_data build step produces the zip (handler.py +
# arm64 pyjwt/cryptography wheels) before the function is created/updated.
###############################################################################
locals {
# The build writes this zip and the function reads it, so the path is shared
# (there is no resource attribute to reference for it).
dispatcher_zip = "${path.module}/.terraform-build/dispatcher.zip"
# Hash the SOURCE inputs (which exist at plan time), never the built artifact.
# This is stable at plan, avoids the first-apply "file does not exist" error,
# and changes (=> redeploy) only when the code, deps, or build script change.
dispatcher_source_hash = base64sha256(join("", [
filesha256("${path.module}/dispatcher/handler.py"),
filesha256("${path.module}/dispatcher/requirements.txt"),
filesha256("${path.module}/scripts/build-dispatcher.sh"),
]))
}
resource "terraform_data" "dispatcher_build" {
triggers_replace = local.dispatcher_source_hash
provisioner "local-exec" {
command = "bash ${path.module}/scripts/build-dispatcher.sh"
environment = {
SRC_DIR = "${path.module}/dispatcher"
BUILD_DIR = "${path.module}/.terraform-build/dispatcher"
ZIP_PATH = local.dispatcher_zip
REQUIREMENTS = "${path.module}/dispatcher/requirements.txt"
PY_VERSION = "3.13"
}
}
}
resource "aws_cloudwatch_log_group" "dispatcher" {
name = "/aws/lambda/${var.name_prefix}-dispatcher"
retention_in_days = var.log_retention_days
tags = local.tags
}
resource "aws_lambda_function" "dispatcher" {
function_name = "${var.name_prefix}-dispatcher"
role = aws_iam_role.dispatcher.arn
filename = local.dispatcher_zip
# Synthetic provider-only trigger; does not need to equal the real CodeSha256.
# Source-derived so it is known at plan and redeploys on any code/dep change.
source_code_hash = local.dispatcher_source_hash
runtime = "python3.13"
architectures = ["arm64"]
handler = "handler.handler"
timeout = var.dispatcher_timeout
memory_size = var.dispatcher_memory_size
# handler.py reads AWS_REGION from the runtime, so it is intentionally absent
# here (it is a reserved key Lambda rejects).
environment {
variables = {
IMAGE_ARN = awscc_lambda_microvm_image.runner.image_arn
# Empty => the dispatcher resolves the latest ACTIVE version at runtime (so a
# rebuilt image is picked up with no redeploy and no two-apply lag). A non-null
# var.image_version pins it. Deliberately NOT wired to the awscc computed
# `latest_active_image_version` - that lags a plan behind on updates.
IMAGE_VERSION = var.image_version != null ? var.image_version : ""
EXEC_ROLE_ARN = aws_iam_role.exec.arn
EGRESS_CONNECTOR = "arn:aws:lambda:${local.region}:aws:network-connector:aws-network-connector:INTERNET_EGRESS"
MAX_DURATION = tostring(var.max_duration_seconds)
LOG_GROUP = aws_cloudwatch_log_group.runner.name
PARAM_NAME = aws_ssm_parameter.dispatcher.name
REQUIRED_LABELS = join(",", var.required_labels)
RUNNER_LABELS = join(",", var.runner_labels)
GH_API_URL = var.github_api_url
}
}
# No attribute links the build to the function, so depend explicitly: the zip
# must exist before the create/update within one apply.
depends_on = [
terraform_data.dispatcher_build,
aws_iam_role_policy.dispatcher,
aws_cloudwatch_log_group.dispatcher,
]
tags = local.tags
}