From 0d310c621274ebc2a7fcd4abc46ffdc65680d4c5 Mon Sep 17 00:00:00 2001 From: Saami Rahman Date: Tue, 17 Mar 2026 12:51:18 -0400 Subject: [PATCH 1/2] remove http dependency --- README.md | 4 +- data.tf | 27 +-------- main.tf | 8 ++- tests/create_api_key_secret_flag.tftest.hcl | 36 +----------- tests/forwarder_version_tag.tftest.hcl | 61 +++++---------------- variables.tf | 24 +++++++- 6 files changed, 48 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index d92096a..6c97058 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,8 @@ For complete usage examples demonstrating different configuration scenarios, see | timeout | Timeout in seconds | `number` | `120` | | reserved_concurrency | Reserved concurrency | `string` | `null` | | log_retention_in_days | CloudWatch log retention | `number` | `90` | -| layer_version | Version of the Datadog Forwarder Lambda layer | `string` | `"latest"` | -| layer_arn | Custom layer ARN (optional) | `string` | `null` | +| layer_version | Version of the Datadog Forwarder Lambda layer. Required when `layer_arn` is not provided. `"latest"` is not supported. | `string` | `null` | +| layer_arn | Custom layer ARN. Required when `layer_version` is not provided. | `string` | `null` | | existing_iam_role_arn | ARN of existing IAM role to use for the Lambda function. When using an existing role, you must provide either `dd_api_key_secret_arn` or `dd_api_key_ssm_parameter_name`, and you are responsible for ensuring the role has the necessary permissions for any resources the module creates. See [Using an Existing IAM Role](#using-an-existing-iam-role) for details. | `string` | `null` | | tags | Resource tags | `map(string)` | `{}` | diff --git a/data.tf b/data.tf index dcd1bed..2a68ed3 100644 --- a/data.tf +++ b/data.tf @@ -3,25 +3,10 @@ data "aws_caller_identity" "current" {} data "aws_region" "current" {} data "aws_partition" "current" {} -# Fetch version mapping from public S3 bucket -data "http" "forwarder_versions" { - url = "https://datadog-opensource-asset-versions.s3.us-east-1.amazonaws.com/forwarder/versions.json" -} - # Local values locals { - # Parse version mapping from S3 - version_data = jsondecode(data.http.forwarder_versions.response_body) - - # Determine layer version: use latest or specified version - layer_version = var.layer_version == "latest" ? local.version_data.latest.layer_version : var.layer_version - - # Determine forwarder version: use latest or lookup in mappings - forwarder_version = ( - var.layer_version == "latest" - ? local.version_data.latest.forwarder_version - : lookup(local.version_data.mappings, var.layer_version, null) - ) + # Determine layer version from explicit input or layer ARN + layer_version = var.layer_version != null ? var.layer_version : regex("[0-9]+$", var.layer_arn) # Determine if we need to create an S3 bucket for caching and failed events storage create_s3_bucket = (coalesce(var.dd_fetch_log_group_tags, false) || coalesce(var.dd_fetch_lambda_tags, false) || coalesce(var.dd_fetch_s3_tags, false) || coalesce(var.dd_store_failed_events, false)) && var.dd_forwarder_existing_bucket_name == null @@ -54,13 +39,7 @@ locals { var.dd_api_key_secret_arn ) : null - # Merge dd_forwarder_version tag with user-provided tags (only when version is known) - tags_with_version = merge( - var.tags, - local.forwarder_version != null ? { - dd_forwarder_version = local.forwarder_version - } : {} - ) + tags_with_version = var.tags } # Deprecation warnings for conflicting API key configurations. diff --git a/main.tf b/main.tf index 6a04bf2..1befaec 100644 --- a/main.tf +++ b/main.tf @@ -1,3 +1,9 @@ +provider "aws" { + region = "eu-west-1" + + allowed_account_ids = ["888322182566"] +} + # IAM role and policies for the Forwarder Lambda module "iam" { count = var.existing_iam_role_arn == null ? 1 : 0 @@ -198,7 +204,7 @@ resource "aws_lambda_function" "forwarder" { description = "Pushes logs, metrics and traces from AWS to Datadog." role = local.iam_role_arn handler = "lambda_function.lambda_handler" - runtime = var.layer_version == "latest" ? "python3.14" : (can(tonumber(var.layer_version)) && tonumber(var.layer_version) >= 94 ? "python3.14" : "python3.13") + runtime = can(tonumber(local.layer_version)) && tonumber(local.layer_version) >= 94 ? "python3.14" : "python3.13" architectures = ["arm64"] memory_size = var.memory_size timeout = var.timeout diff --git a/tests/create_api_key_secret_flag.tftest.hcl b/tests/create_api_key_secret_flag.tftest.hcl index 2953a22..3d0c63b 100644 --- a/tests/create_api_key_secret_flag.tftest.hcl +++ b/tests/create_api_key_secret_flag.tftest.hcl @@ -28,6 +28,7 @@ mock_provider "aws" { variables { dd_site = "datadoghq.com" region = "us-east-1" + layer_version = "92" } # ───────────────────────────────────────────────────────────────────────────── @@ -41,13 +42,6 @@ run "explicit_false_with_secret_arn" { create_dd_api_key_secret = false } - override_data { - target = data.http.forwarder_versions - values = { - response_body = "{\"latest\":{\"layer_version\":\"92\",\"forwarder_version\":\"5.1.0\"},\"mappings\":{}}" - } - } - assert { condition = length(aws_secretsmanager_secret.dd_api_key_secret) == 0 error_message = "No secret should be created when create_dd_api_key_secret=false" @@ -70,13 +64,6 @@ run "explicit_false_with_ssm_parameter" { create_dd_api_key_secret = false } - override_data { - target = data.http.forwarder_versions - values = { - response_body = "{\"latest\":{\"layer_version\":\"92\",\"forwarder_version\":\"5.1.0\"},\"mappings\":{}}" - } - } - assert { condition = length(aws_secretsmanager_secret.dd_api_key_secret) == 0 error_message = "No secret should be created when using SSM parameter with flag=false" @@ -94,13 +81,6 @@ run "explicit_true_creates_secret" { create_dd_api_key_secret = true } - override_data { - target = data.http.forwarder_versions - values = { - response_body = "{\"latest\":{\"layer_version\":\"92\",\"forwarder_version\":\"5.1.0\"},\"mappings\":{}}" - } - } - assert { condition = length(aws_secretsmanager_secret.dd_api_key_secret) == 1 error_message = "Secret should be created when create_dd_api_key_secret=true and dd_api_key is set" @@ -118,13 +98,6 @@ run "null_flag_auto_creates_secret_from_api_key" { # create_dd_api_key_secret not set (null/default) } - override_data { - target = data.http.forwarder_versions - values = { - response_body = "{\"latest\":{\"layer_version\":\"92\",\"forwarder_version\":\"5.1.0\"},\"mappings\":{}}" - } - } - assert { condition = length(aws_secretsmanager_secret.dd_api_key_secret) == 1 error_message = "Secret should be auto-created when dd_api_key is provided and flag is null" @@ -139,13 +112,6 @@ run "null_flag_auto_skips_secret_with_external_arn" { # create_dd_api_key_secret not set (null/default) } - override_data { - target = data.http.forwarder_versions - values = { - response_body = "{\"latest\":{\"layer_version\":\"92\",\"forwarder_version\":\"5.1.0\"},\"mappings\":{}}" - } - } - assert { condition = length(aws_secretsmanager_secret.dd_api_key_secret) == 0 error_message = "Secret should NOT be auto-created when dd_api_key_secret_arn is provided" diff --git a/tests/forwarder_version_tag.tftest.hcl b/tests/forwarder_version_tag.tftest.hcl index e224195..1251a1d 100644 --- a/tests/forwarder_version_tag.tftest.hcl +++ b/tests/forwarder_version_tag.tftest.hcl @@ -1,4 +1,4 @@ -# Test the dd_forwarder_version tag functionality +# Test explicit layer version configuration mock_provider "aws" { mock_data "aws_caller_identity" { defaults = { @@ -20,62 +20,35 @@ mock_provider "aws" { } variables { - dd_api_key = "test-api-key-value" - dd_site = "datadoghq.com" + dd_api_key = "test-api-key-value" + dd_site = "datadoghq.com" + layer_version = "92" } -# Test with layer_version = "latest" (default) -run "version_tag_with_latest" { +run "explicit_layer_version" { command = plan - # Lambda should have dd_forwarder_version tag assert { - condition = contains(keys(aws_lambda_function.forwarder.tags), "dd_forwarder_version") - error_message = "Lambda function should have dd_forwarder_version tag" - } - - # Tag should be a semantic version (e.g., "5.1.0") - assert { - condition = can(regex("^[0-9]+\\.[0-9]+\\.[0-9]+", aws_lambda_function.forwarder.tags["dd_forwarder_version"])) - error_message = "dd_forwarder_version tag should be a semantic version (e.g., 5.1.0)" - } - - # Verify local.forwarder_version is set - assert { - condition = local.forwarder_version != null - error_message = "local.forwarder_version should be set when using latest" + condition = can(regex(":92$", aws_lambda_function.forwarder.layers[0])) + error_message = "Lambda layer ARN should end with :92" } } -# Test with specific layer_version -run "version_tag_with_specific_layer" { +run "custom_layer_arn" { command = plan variables { - layer_version = "92" - } - - # Lambda should have dd_forwarder_version tag - assert { - condition = contains(keys(aws_lambda_function.forwarder.tags), "dd_forwarder_version") - error_message = "Lambda function should have dd_forwarder_version tag when using specific layer version" + layer_version = null + layer_arn = "arn:aws:lambda:us-east-1:464622532012:layer:Datadog-Forwarder:94" } - # Tag should be a semantic version assert { - condition = can(regex("^[0-9]+\\.[0-9]+\\.[0-9]+", aws_lambda_function.forwarder.tags["dd_forwarder_version"])) - error_message = "dd_forwarder_version tag should be a semantic version" - } - - # Layer ARN should use the specified version - assert { - condition = can(regex(":92$", aws_lambda_function.forwarder.layers[0])) - error_message = "Lambda layer ARN should end with :92" + condition = aws_lambda_function.forwarder.runtime == "python3.14" + error_message = "Lambda runtime should be python3.14 for layer version 94" } } -# Test that user tags are preserved alongside dd_forwarder_version -run "version_tag_with_user_tags" { +run "user_tags_are_preserved" { command = plan variables { @@ -85,7 +58,6 @@ run "version_tag_with_user_tags" { } } - # User tags should be present assert { condition = aws_lambda_function.forwarder.tags["Environment"] == "test" error_message = "User-provided Environment tag should be preserved" @@ -95,11 +67,4 @@ run "version_tag_with_user_tags" { condition = aws_lambda_function.forwarder.tags["Team"] == "platform" error_message = "User-provided Team tag should be preserved" } - - # dd_forwarder_version should also be present - assert { - condition = contains(keys(aws_lambda_function.forwarder.tags), "dd_forwarder_version") - error_message = "dd_forwarder_version tag should be added alongside user tags" - } } - diff --git a/variables.tf b/variables.tf index 0008c1e..a6be411 100644 --- a/variables.tf +++ b/variables.tf @@ -177,14 +177,34 @@ variable "log_retention_in_days" { variable "layer_version" { type = string - default = "latest" - description = "Version of the Datadog Forwarder Lambda layer. Use 'latest' to automatically fetch the latest version from GitHub releases or specify a version like '89'." + default = null + description = "Version of the Datadog Forwarder Lambda layer. Specify an explicit version like '89' when layer_arn is not provided." + + validation { + condition = var.layer_version == null || var.layer_version != "latest" + error_message = "layer_version no longer supports 'latest'. Specify an explicit layer version or set layer_arn." + } + + validation { + condition = var.layer_version == null || can(regex("^[0-9]+$", var.layer_version)) + error_message = "layer_version must be a numeric string like '89'." + } + + validation { + condition = var.layer_version != null || var.layer_arn != null + error_message = "You must specify either layer_version or layer_arn." + } } variable "layer_arn" { type = string default = null description = "ARN for the layer containing the forwarder code. If empty, the script will use the version of the layer the forwarder was published with." + + validation { + condition = var.layer_arn == null || can(regex("^arn:.*:lambda:.*:layer:.*:[0-9]+$", var.layer_arn)) + error_message = "layer_arn must be a valid Lambda layer ARN ending in a numeric version." + } } # Datadog configuration From e6dd16f5fcd72a3cd216728be52866f9bad1da86 Mon Sep 17 00:00:00 2001 From: Saami Rahman Date: Wed, 18 Mar 2026 12:52:00 -0400 Subject: [PATCH 2/2] remove region --- main.tf | 6 ------ 1 file changed, 6 deletions(-) diff --git a/main.tf b/main.tf index 1befaec..ed8156d 100644 --- a/main.tf +++ b/main.tf @@ -1,9 +1,3 @@ -provider "aws" { - region = "eu-west-1" - - allowed_account_ids = ["888322182566"] -} - # IAM role and policies for the Forwarder Lambda module "iam" { count = var.existing_iam_role_arn == null ? 1 : 0