Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 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
Expand Down
62 changes: 60 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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" {
Expand Down Expand Up @@ -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
# 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

# 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
]
}
}
13 changes: 13 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <<EOS
Map of environment variable names to ARNs of AWS Secret Manager secrets.

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 function to read the secret values.
EOS
}

variable "source_dir" {
type = string
default = null
Expand Down