From d853ae8eafb9cbffd51f0dfced6e1470e7927d83 Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Wed, 5 Aug 2026 12:18:30 -0400 Subject: [PATCH] fix(iac): ship lambda zips via s3 for hcp plan/apply split HCP plan and apply workers do not share disk; carry archive bytes in the plan with content_base64 and add IAM depends_on before function create. --- terraform/artifacts.tf | 37 +++++++++++++++++++++++++++++++++++++ terraform/lambda.tf | 23 ++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 terraform/artifacts.tf diff --git a/terraform/artifacts.tf b/terraform/artifacts.tf new file mode 100644 index 0000000..c6874f0 --- /dev/null +++ b/terraform/artifacts.tf @@ -0,0 +1,37 @@ +# HCP plan and apply run on separate workers. archive_file paths from plan are +# not on the apply worker, so zip bytes are carried in the plan via +# content_base64 and uploaded to S3 at apply time for Lambda to consume. + +resource "aws_s3_bucket" "artifacts" { + bucket = "afi-backup-monitor-artifacts-${local.account_id}" +} + +resource "aws_s3_bucket_public_access_block" "artifacts" { + bucket = aws_s3_bucket.artifacts.id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} + +resource "aws_s3_object" "shared_layer" { + bucket = aws_s3_bucket.artifacts.id + key = "afi-shared-layer.zip" + content_base64 = filebase64(data.archive_file.shared_layer.output_path) + source_hash = data.archive_file.shared_layer.output_base64sha256 +} + +resource "aws_s3_object" "auto_protect" { + bucket = aws_s3_bucket.artifacts.id + key = "afi-auto-protect.zip" + content_base64 = filebase64(data.archive_file.auto_protect.output_path) + source_hash = data.archive_file.auto_protect.output_base64sha256 +} + +resource "aws_s3_object" "health_digest" { + bucket = aws_s3_bucket.artifacts.id + key = "afi-health-digest.zip" + content_base64 = filebase64(data.archive_file.health_digest.output_path) + source_hash = data.archive_file.health_digest.output_base64sha256 +} diff --git a/terraform/lambda.tf b/terraform/lambda.tf index 39978cf..05a7b09 100644 --- a/terraform/lambda.tf +++ b/terraform/lambda.tf @@ -21,10 +21,13 @@ data "archive_file" "health_digest" { resource "aws_lambda_layer_version" "shared" { layer_name = "afi-shared" description = "Shared Afi API client and utilities" - filename = data.archive_file.shared_layer.output_path + s3_bucket = aws_s3_bucket.artifacts.id + s3_key = aws_s3_object.shared_layer.key source_code_hash = data.archive_file.shared_layer.output_base64sha256 compatible_runtimes = ["python3.12"] compatible_architectures = ["arm64"] + + depends_on = [aws_s3_object.shared_layer] } resource "aws_lambda_function" "auto_protect" { @@ -36,7 +39,8 @@ resource "aws_lambda_function" "auto_protect" { memory_size = 256 timeout = 120 - filename = data.archive_file.auto_protect.output_path + s3_bucket = aws_s3_bucket.artifacts.id + s3_key = aws_s3_object.auto_protect.key source_code_hash = data.archive_file.auto_protect.output_base64sha256 layers = [aws_lambda_layer_version.shared.arn] @@ -46,6 +50,12 @@ resource "aws_lambda_function" "auto_protect" { AFI_POLICY_ID = var.afi_policy_id }) } + + depends_on = [ + aws_s3_object.auto_protect, + aws_iam_role_policy_attachment.auto_protect_basic, + aws_iam_role_policy.auto_protect_secrets, + ] } resource "aws_lambda_function" "health_digest" { @@ -57,7 +67,8 @@ resource "aws_lambda_function" "health_digest" { memory_size = 256 timeout = 120 - filename = data.archive_file.health_digest.output_path + s3_bucket = aws_s3_bucket.artifacts.id + s3_key = aws_s3_object.health_digest.key source_code_hash = data.archive_file.health_digest.output_base64sha256 layers = [aws_lambda_layer_version.shared.arn] @@ -65,4 +76,10 @@ resource "aws_lambda_function" "health_digest" { environment { variables = local.common_env } + + depends_on = [ + aws_s3_object.health_digest, + aws_iam_role_policy_attachment.health_digest_basic, + aws_iam_role_policy.health_digest_secrets, + ] }