Reputation: 11
I'm trying to dynamically set the contents of a dictionary within a resource. In my case I want to set per Lambda specific environment variables. I really don't want to modify the local.lambda structure in any way, but I can't quite work out the syntax to iterate over the local.lambda dictionary, lookup the extra vars and then their values dynamically. Any ideas on how I can achieve this?
Here's my locals data
locals {
lambdas = {
func1 = "myfunc-${local.env}"
func2 = "myfunc-${local.env}"
func3 = "myfunc-${local.env}"
}
envvars = {
myenv1 = "apple"
myenv2 = "pear"
myenv3 = "orange"
}
extra_envvars = {
myenv4 = "lettuce"
myenv5 = "carrot"
myenv6 = "turnip"
}
assign_extra_vars = {
func1 = [ myenv4, myenv5 ]
func3 = [ myenv6 ]
}
}
Here's my Terraform resource with a little block of pseudo code which hopefully explain what I'm trying to achieve better than my broken Terraform.
resource "aws_lambda_function" "task" {
for_each = local.lambdas
environment" {
// Pseudo code
my_extra = map {}
for env_var in local.assign_extra_vars[each.key] : {
my_extra[env_var] = lookup(local.extra_envvars, env_var, "")
}
// end pseudo code
variables = merge(envvars, my_extra)
}
}
Thanks in advance for any reply.
Upvotes: 0
Views: 2348
Reputation: 4837
With a tiny bit of restructuring of your locals
this can be achieved:
locals {
env = "dev"
lambdas = {
func1 = "myfunc1-${local.env}"
func2 = "myfunc2-${local.env}"
func3 = "myfunc3-${local.env}"
}
envvars = {
myenv1 = "apple"
myenv2 = "pear"
myenv3 = "orange"
}
extra_envvars = {
func1 = {
myenv4 = "lettuce"
myenv5 = "carrot"
}
func3 = {
myenv6 = "turnip"
}
}
}
So extra_envvars
is now a lookup map by function.
Now your Lambda function becomes this:
resource "aws_lambda_function" "task" {
for_each = local.lambdas
function_name = each.value
role = aws_iam_role.iam_for_lambda.arn
handler = "test.test"
runtime = "nodejs12.x"
environment {
variables = merge(local.envvars, lookup(local.extra_envvars, each.key, {}))
}
}
I've filled handler
and runtime
with dummy content, and for the sake of completeness this is how aws_iam_role.iam_for_lambda
looks like:
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
Upvotes: 0