From 40bf8f6302cebdd15c939bb4bdf4024ea675d0ed Mon Sep 17 00:00:00 2001 From: jtsaito Date: Wed, 22 Sep 2021 11:49:22 +0200 Subject: [PATCH 1/6] Add support for secret environment variable --- CHANGELOG.md | 5 +++++ main.tf | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-- variables.tf | 13 +++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b155594..418ffe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,13 @@ ## v1.1.0 - [Add layers attribute](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/7) +- [Add secret environment variables attribute](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/8) ## v1.0.0 - [Initial version](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/1) + +## v1.1.0 + +- [Added support for secret environment variables](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/6) diff --git a/main.tf b/main.tf index 85581d6..e814c3e 100644 --- a/main.tf +++ b/main.tf @@ -13,7 +13,7 @@ resource "aws_lambda_function" "this" { role = aws_iam_role.this.arn dynamic "environment" { - for_each = var.environment_variables != null ? [{ variables = var.environment_variables }] : [] + for_each = local.environment_variables != null ? [{ variables = local.environment_variables }] : [] content { variables = environment.value.variables @@ -25,7 +25,10 @@ resource "aws_lambda_function" "this" { tags = var.tags - depends_on = [aws_cloudwatch_log_group.this] + depends_on = [ + aws_cloudwatch_log_group.this, + null_resource.watch_iam_role_policy_secretsmanager_get_secret_value, + ] } data "archive_file" "this" { @@ -80,3 +83,58 @@ data "aws_iam_policy_document" "cloudwatch-log-group" { resources = ["${aws_cloudwatch_log_group.this.arn}:*"] } } + + +# Secret environment variables + +locals { + environment_variables = merge(var.environment_variables, local.secret_environment_variables) + + secret_environment_variables = { + for k, v in var.secret_environment_variables : join("", [k, "_SECRET_ARN"]) => v + } +} + +resource "aws_iam_role_policy" "secretsmanager-get-secret-value" { + count = length(var.secret_environment_variables) > 0 ? 1 : 0 + + name = "secretsmanager-get-secret-value-${md5(data.aws_iam_policy_document.secretsmanager-get-secret-value[count.index].json)}" + role = aws_iam_role.this.name + policy = data.aws_iam_policy_document.secretsmanager-get-secret-value[count.index].json + + lifecycle { + create_before_destroy = true + } +} + +# Whenever a change is made to the secrets, the role policy must be updated +# first, then we need to wait for a few seconds and only then update the lambda function itself. +# Waiting is necessary because otherwise the during initialization of the lambda function the +# secrets-fetcher wrapper will not yet have the permissions for fetching the secret values. +resource "null_resource" "watch_iam_role_policy_secretsmanager_get_secret_value" { + count = length(var.secret_environment_variables) > 0 ? 1 : 0 + + # null_resource is replaced every time the policy changes + triggers = { + secretsmanager_get_secret_value_policy = aws_iam_role_policy.secretsmanager-get-secret-value[count.index].policy + } + + provisioner "local-exec" { + command = "sleep 15" + } +} + +data "aws_iam_policy_document" "secretsmanager-get-secret-value" { + count = length(var.secret_environment_variables) > 0 ? 1 : 0 + + statement { + actions = ["secretsmanager:GetSecretValue"] + + # select secret arns and cut off trailing json keys + # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data-secrets.html + resources = [ + for k, extended_secret_arn in local.secret_environment_variables : + join(":", slice(split(":", extended_secret_arn), 0, 7)) if length(regexall("_SECRET_ARN$", k)) == 1 + ] + } +} diff --git a/variables.tf b/variables.tf index 4e594a6..9b01365 100644 --- a/variables.tf +++ b/variables.tf @@ -65,6 +65,19 @@ variable "runtime" { description = "The identifier of the Lambda function [runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)." } +variable "secret_environment_variables" { + type = map(string) + default = {} + + description = < Date: Wed, 22 Sep 2021 12:06:03 +0200 Subject: [PATCH 2/6] Update main.tf Co-authored-by: Jan Sebastian Siwy --- main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index e814c3e..cb9a24c 100644 --- a/main.tf +++ b/main.tf @@ -109,8 +109,8 @@ resource "aws_iam_role_policy" "secretsmanager-get-secret-value" { # Whenever a change is made to the secrets, the role policy must be updated # first, then we need to wait for a few seconds and only then update the lambda function itself. -# Waiting is necessary because otherwise the during initialization of the lambda function the -# secrets-fetcher wrapper will not yet have the permissions for fetching the secret values. +# Waiting is necessary because otherwise the during initialization of the lambda function +# it will not yet have the permissions for fetching the secret values. resource "null_resource" "watch_iam_role_policy_secretsmanager_get_secret_value" { count = length(var.secret_environment_variables) > 0 ? 1 : 0 From f1ca2a4254e341385ea134298a702101b3af34d8 Mon Sep 17 00:00:00 2001 From: Jahn Saito Date: Wed, 22 Sep 2021 12:06:19 +0200 Subject: [PATCH 3/6] Update variables.tf Co-authored-by: Jan Sebastian Siwy --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 710e36f..583de27 100644 --- a/variables.tf +++ b/variables.tf @@ -72,7 +72,7 @@ variable "secret_environment_variables" { description = < Date: Wed, 22 Sep 2021 12:06:24 +0200 Subject: [PATCH 4/6] Update variables.tf Co-authored-by: Jan Sebastian Siwy --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 583de27..c6ca953 100644 --- a/variables.tf +++ b/variables.tf @@ -74,7 +74,7 @@ Map of environment variables' names to ARNs of AWS Secret Manager secrets. If co Each ARN will be passed as environment variable to the lambda function with the key's name extended by suffix _SECRET_ARN. When initializing the Lambda run time environment, the Lambda function or a [wrapper script](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-modify.html#runtime-wrapper) can look up the secret value. -Permission will be added allowing the lambda to read the secret values. +Permission will be added allowing the Lambda function to read the secret values. EOS } From db171a78041b0ebf91f1992ecc99590fbcdcfbff Mon Sep 17 00:00:00 2001 From: jtsaito Date: Wed, 22 Sep 2021 12:07:15 +0200 Subject: [PATCH 5/6] Remove duplication from change log --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 418ffe4..df7eff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,3 @@ ## v1.0.0 - [Initial version](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/1) - -## v1.1.0 - -- [Added support for secret environment variables](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/6) From d4d8fa761ce03f07a11d4c9a41ba489482ab4442 Mon Sep 17 00:00:00 2001 From: Jahn Saito Date: Wed, 22 Sep 2021 12:08:03 +0200 Subject: [PATCH 6/6] Update variables.tf Co-authored-by: Jan Sebastian Siwy --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index c6ca953..6deb4a6 100644 --- a/variables.tf +++ b/variables.tf @@ -70,7 +70,7 @@ variable "secret_environment_variables" { default = {} description = <