Skip to content

Commit 62f1eaa

Browse files
authored
Merge pull request #8 from babbel/lambda-secrets
Add support for secret environment variable
2 parents 71f37ec + d4d8fa7 commit 62f1eaa

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## v1.1.0
44
- [Add layers attribute](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/7)
5+
- [Add secret environment variables attribute](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/8)
56

67

78
## v1.0.0

main.tf

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ resource "aws_lambda_function" "this" {
1313
role = aws_iam_role.this.arn
1414

1515
dynamic "environment" {
16-
for_each = var.environment_variables != null ? [{ variables = var.environment_variables }] : []
16+
for_each = local.environment_variables != null ? [{ variables = local.environment_variables }] : []
1717

1818
content {
1919
variables = environment.value.variables
@@ -25,7 +25,10 @@ resource "aws_lambda_function" "this" {
2525

2626
tags = var.tags
2727

28-
depends_on = [aws_cloudwatch_log_group.this]
28+
depends_on = [
29+
aws_cloudwatch_log_group.this,
30+
null_resource.watch_iam_role_policy_secretsmanager_get_secret_value,
31+
]
2932
}
3033

3134
data "archive_file" "this" {
@@ -80,3 +83,58 @@ data "aws_iam_policy_document" "cloudwatch-log-group" {
8083
resources = ["${aws_cloudwatch_log_group.this.arn}:*"]
8184
}
8285
}
86+
87+
88+
# Secret environment variables
89+
90+
locals {
91+
environment_variables = merge(var.environment_variables, local.secret_environment_variables)
92+
93+
secret_environment_variables = {
94+
for k, v in var.secret_environment_variables : join("", [k, "_SECRET_ARN"]) => v
95+
}
96+
}
97+
98+
resource "aws_iam_role_policy" "secretsmanager-get-secret-value" {
99+
count = length(var.secret_environment_variables) > 0 ? 1 : 0
100+
101+
name = "secretsmanager-get-secret-value-${md5(data.aws_iam_policy_document.secretsmanager-get-secret-value[count.index].json)}"
102+
role = aws_iam_role.this.name
103+
policy = data.aws_iam_policy_document.secretsmanager-get-secret-value[count.index].json
104+
105+
lifecycle {
106+
create_before_destroy = true
107+
}
108+
}
109+
110+
# Whenever a change is made to the secrets, the role policy must be updated
111+
# first, then we need to wait for a few seconds and only then update the lambda function itself.
112+
# Waiting is necessary because otherwise the during initialization of the lambda function
113+
# it will not yet have the permissions for fetching the secret values.
114+
resource "null_resource" "watch_iam_role_policy_secretsmanager_get_secret_value" {
115+
count = length(var.secret_environment_variables) > 0 ? 1 : 0
116+
117+
# null_resource is replaced every time the policy changes
118+
triggers = {
119+
secretsmanager_get_secret_value_policy = aws_iam_role_policy.secretsmanager-get-secret-value[count.index].policy
120+
}
121+
122+
provisioner "local-exec" {
123+
command = "sleep 15"
124+
}
125+
}
126+
127+
data "aws_iam_policy_document" "secretsmanager-get-secret-value" {
128+
count = length(var.secret_environment_variables) > 0 ? 1 : 0
129+
130+
statement {
131+
actions = ["secretsmanager:GetSecretValue"]
132+
133+
# select secret arns and cut off trailing json keys
134+
# https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data-secrets.html
135+
resources = [
136+
for k, extended_secret_arn in local.secret_environment_variables :
137+
join(":", slice(split(":", extended_secret_arn), 0, 7)) if length(regexall("_SECRET_ARN$", k)) == 1
138+
]
139+
}
140+
}

variables.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ variable "runtime" {
6565
description = "The identifier of the Lambda function [runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)."
6666
}
6767

68+
variable "secret_environment_variables" {
69+
type = map(string)
70+
default = {}
71+
72+
description = <<EOS
73+
Map of environment variable names to ARNs of AWS Secret Manager secrets.
74+
75+
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.
76+
77+
Permission will be added allowing the Lambda function to read the secret values.
78+
EOS
79+
}
80+
6881
variable "source_dir" {
6982
type = string
7083
default = null

0 commit comments

Comments
 (0)