简体   繁体   中英

Terraform Argument Block as a List of Maps

I am trying to pick up both elements in my query_string tuple. However, only the last element is being picked up. Below, is my test/main.tf file:

terraform {
  required_version = ">= 0.13.0"

  required_providers {
    aws = ">= 3.58"
  }
}

provider "aws" {
  region = "us-east-1"
}

module "test_module" {
  source = "../"

  lb = [
    {
      name                       = "lb-name"
      enable_deletion_protection = true
      internal                   = false
      load_balancer_type         = "application"

      lb_listener = [
        {
          port       = "8080"
          protocol   = "HTTP"
          ssl_policy = "ELBSecurityPolicy-2016-08"

          default_action = {
            type  = "redirect"
            order = 1

            redirect = {
              status_code = "HTTP_302"
            }
          }

          lb_listener_rule = [
            {
              action = {
                type = "fixed-response"

                fixed_response = {
                  content_type = "text/plain"
                  message_body = "This is a message body."
                }
              }

              condition = {
                query_string = [
                  {
                    key   = "health"
                    value = "check"
                  },
                  {
                    value = "bar"
                  }
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}

Here is my lb.tf file:

variable "lb" {
  description = <<DESCRIPTION
  The AWS Elastic Load Balancing v2 module.
  DESCRIPTION
  type    = any
  default = []
}

locals {
  lb_listener_flat_list = flatten([
    for lb in var.lb : [
      for lb_listener in lookup(lb, "lb_listener", []) : {
        lb_name                          = lb.name
        lb_listener_load_balancer_arn    = aws_lb.lb[lb.name].arn
        lb_listener_port                 = lookup(lb, "load_balancer_type", "application") != "gateway" ? lookup(lb_listener, "port", null) : null
        lb_listener_protocol             = lookup(lb, "load_balancer_type", "application") != "gateway" || lookup(lb, "ip_address_type", null) != "dualstack" ? lookup(lb_listener, "protocol", null) : null
        lb_listener_ssl_policy           = lookup(lb_listener, "protocol", null) != "HTTPS" || lookup(lb_listener, "protocol", null) != "TLS" ? lb_listener.ssl_policy : lookup(lb_listener, "ssl_policy", null)
        lb_listener_default_action_type  = lb_listener.default_action.type
        lb_listener_default_action_order = lookup(lb_listener.default_action, "order", null)

        lb_listener_default_action_redirect = lookup(lb_listener.default_action, "redirect", {}) != {} ? {
          lb_listener_default_action_redirect_status_code = lb_listener.default_action.redirect.status_code
        } : null
      }
    ]
  ])

  lb_listener_rule_flat_list = flatten([
    for lb in var.lb : [
      for lb_listener in lookup(lb, "lb_listener", []) : [
        for lb_listener_rule in lookup(lb_listener, "lb_listener_rule", []) : [
          # I've recently added the line below in an attempte to loop through the list of maps for query_string
          for index in range(length(lookup(lb_listener_rule.condition, "query_string", []))) : {
            lb_name                       = lb.name
            lb_listener_rule_index        = index
            lb_listener_rule_listener_arn = aws_lb_listener.lb_listener[lb.name].arn
            lb_listener_rule_action_type  = lb_listener_rule.action.type

            lb_listener_rule_action_fixed_response = lookup(lb_listener_rule.action, "fixed_response", {}) != {} ? {
              lb_listener_rule_action_fixed_response_content_type = lb_listener_rule.action.fixed_response.content_type
              lb_listener_rule_action_fixed_response_message_body = lookup(lb_listener_rule.action.fixed_response, "message_body", null)
            } : null

            lb_listener_rule_condition_query_string = lookup(lb_listener_rule.condition, "query_string", {}) != {} ? {
              lb_listener_rule_condition_query_string_key   = lookup(lb_listener_rule.condition.query_string[index], "key", null)
              lb_listener_rule_condition_query_string_value = lb_listener_rule.condition.query_string[index].value
            } : null
          }
        ]
      ]
    ]
  ])

  lb_map               = { for lb in var.lb : lb.name => lb }
  lb_listener_map      = { for lb_listener in local.lb_listener_flat_list : lb_listener.lb_name => lb_listener }
  lb_listener_rule_map = { for lb_listener_rule in local.lb_listener_rule_flat_list : "${lb_listener_rule.lb_name}-[${lb_listener_rule.lb_listener_rule_index}]" => lb_listener_rule }
}

resource "aws_lb_listener" "lb_listener" {
  for_each          = local.lb_listener_map
  load_balancer_arn = each.value.lb_listener_load_balancer_arn
  port              = each.value.lb_listener_port
  protocol          = each.value.lb_listener_protocol
  ssl_policy        = each.value.lb_listener_ssl_policy

  default_action {
    type  = each.value.lb_listener_default_action_type
    order = each.value.lb_listener_default_action_order

    dynamic "redirect" {
      for_each = each.value.lb_listener_default_action_redirect != null ? [{}] : []
      content {
        status_code = each.value.lb_listener_default_action_redirect.lb_listener_default_action_redirect_status_code
      }
    }
  }
}

resource "aws_lb_listener_rule" "lb_listener_rule" {
  for_each     = local.lb_listener_rule_map
  listener_arn = each.value.lb_listener_rule_listener_arn

  action {
    type = each.value.lb_listener_rule_action_type

    dynamic "fixed_response" {
      for_each = each.value.lb_listener_rule_action_fixed_response != null ? [{}] : []
      content {
        content_type = each.value.lb_listener_rule_action_fixed_response.lb_listener_rule_action_fixed_response_content_type
        message_body = each.value.lb_listener_rule_action_fixed_response.lb_listener_rule_action_fixed_response_message_body
      }
    }
  }

  condition {
    dynamic "query_string" {
      for_each = each.value.lb_listener_rule_condition_query_string != null ? [{}] : []
      content {
        key   = each.value.lb_listener_rule_condition_query_string.lb_listener_rule_condition_query_string_key
        value = each.value.lb_listener_rule_condition_query_string.lb_listener_rule_condition_query_string_value
      }
    }
  }
}

resource "aws_lb" "lb" {
  for_each                   = local.lb_map
  name                       = lookup(each.value, "name", null)
  enable_deletion_protection = lookup(each.value, "enable_deletion_protection", null)
  internal                   = lookup(each.value, "internal", null)
  ip_address_type            = lookup(each.value, "ip_address_type", null)
  load_balancer_type         = lookup(each.value, "load_balancer_type", null)
}

Here is how the condition block looks when I run a terraform plan :

condition {
  query_string {
    value = "bar"
  }
}

Here is how I would like the condition block to look:

condition {
  query_string {
    key   = "health"
    value = "check"
  }

  query_string {
    value = "bar"
  }
}

Your code, as complex as it is creates the two query_string correctly :

在此处输入图像描述

The code, in the form posted in the question has number of issues and it will not work. But then as you wrote that "My original files are very long. ", I guess that your real code actually works. Thus I only focused on its verification , rather then fixing all possible errors as I don't know what is your factual code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM