terraformterraform-provider-awsterraform0.12+terraform-template-file

Terraform -- Is possible take a value from a map and put this value inside to a local variable?


I am trying to take a value from a map and I need to put that value inside to a local variable, but I dont know How to do that, I need that because I created multiples lambdas, and some lambdas needs this resource "aws_lambda_permission" and ohters lambdas doesnt need that, I am using the value "method_path" from the map.

variables.tf

### Global variables ###
variable "stack_id" {
  type = string
}
variable "vpc_id" {
  type = string
}

### Lambda variables ###
variable "lambda_function" {
  type = map(object({
    memory_size = number
    runtime     = string
    handler     = string
    s3_key      = string
    role        = string
    layers      = optional(list(string))
    method_path = string
    env_key = map(any)

  }))
}

main.tf (lambdas)

locals {
  add_method_path = var.lambda_function.test-01.method_path
}

resource "aws_lambda_function" "lm" {
  for_each      = var.lambda_function_l3
  s3_bucket     = aws_s3_bucket.lm.id
  s3_key        = "code/${each.value.s3_key}"
  function_name = "lm-${var.stack_id}-${each.key}"
  role          = aws_iam_role.lm[each.value.role].arn
  handler       = "index.${each.value.handler}"
  runtime       = each.value.runtime
  memory_size   = each.value.memory_size
layers = each.value.layer1 == "null" ? null :aws_lambda_layer_version.lm[each.value.layer1].arn 
  depends_on = [ aws_lambda_layer_version.lm ]
  environment {
    variables = each.value.env_key
  }
  vpc_config {
    subnet_ids         = [local.subnet_private[0], local.subnet_private[5]]
    security_group_ids = ["sg-0591b309a73f15dd4"]
  }
}

resource "aws_lambda_permission" "lmp" {
  for_each = local.add_method_path != "false" ? var.lambda_function : {}
  //statement_id  = "AllowMyDemoAPIInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.lm[each.key].function_name
  principal     = "apigateway.amazonaws.com"

  # The /* part allows invocation from any stage, method and resource path
  # within API Gateway.
  source_arn = "${var.ag_id}/*${each.value.method_path}"

terraform.tfvars

lambda_function = {
  "test-01" = { memory_size = 512, runtime = "python3.9", handler = "lambda_handler", s3_key = "test_lm.zip", role = "s3_rw",method_path = "/POST/fincor/pucs/depurated/checks", layers = ["capa-openpyxl-s3fs-xlrd-fsspec"], env_key = { house = "car", test2 = "apple" } }
"test-02" = { memory_size = 1024, runtime = "python3.9", handler = "lambda_handler", s3_key = "test_lmv2.zip", role = "dba_r_sec_r", method_path = "false", layers = null, env_key = { window = "bread", test4 = "chicken" } }  
 


Solution

  • In case your main concern is iterating over the map, you should not even use a local variable

    In this case, your solution would be something like this in my opinion:

      for_each = { for key, value in var.lambda_function : key => value if value.method_path != "false" }
    

    Here, for_each is looping through the map var.lambda_function, and for each key-value pair, it is assigning the key to the key and the value to the value (key => value), but only if value.method_path does not equal false.

    Using this in your code will result in creating a resource for each of the map's key-value pairs, except when the value (which is an object) has false for the property method_path.