tail -f /dev/null

産まれたばかりの仔羊. If you haven't had any obstacles lately, you're not challenging. be the worst.

Terraform: flatten を利用した tfvars の nest 構造

ALB Listener 1つにつき, 複数の Listener Rule と Target Group が紐づく (今回は Listener Rule と Target Group は 1:1 な前提で書いている). その為 nest した tfvars を定義し list の list を作り, flatten した map を生成するようにした.

flatten() は list を受け取り, 要素を flat にして sequential に書き換えるものである. 非常に使いづらい.

env

terraform ver. 0.12.28

tf file

locals {
  listener_rule_map = flatten([
    for listener_key, listener in var.alb_listener : [
      for key, listener_rule in listener.listener_rules : {
        listener_key      = listener_key
        listener_rule_key = key
        type              = "${listener_rule.action.type}"
        value             = "${listener_rule.condition.host_header.value}"
      }
    ]
  ])
}

resource "aws_alb_listener" "alb_listener" {
  for_each          = var.alb_listener
  load_balancer_arn = aws_alb.alb[each.key].arn
  port              = ...

  default_action {
    type = each.value.default_action.type
    ...
  }
}

resource "aws_alb_listener_rule" "alb_listener_rule" {
  for_each = {
    for l in local.listener_rule_map : "${l.listener_rule_key}" => l
  }
  listener_arn = aws_alb_listener.alb_listener[each.value.listener_key].arn

  action {
    target_group_arn = aws_alb_target_group.alb_target_group[each.value.listener_rule_key].arn
    type = ...
  }
}

resource "aws_alb_target_group" "alb_target_group" {
  for_each             = var.alb_target_group
  name                 = each.key
  port                 = each.value.port
  protocol             = ...
}

tfvars file

alb_listener = {
  listener_001 = {
    port            = "443"
    protocol        = ...

    default_action = {
      type = "fixed-response"
      fixed_response = {
        content_type = "text/plain"
        message_body = ...
      }
    }
    listener_rules = {
      target-001 = {
        action = {
          type = ...
        }
      }
      target-002 = {
        action = {
          type = ...
        }
      }
    }
  }
  listener_002 = {
    port            = "80"
    protocol        = "HTTP"
    ssl_policy      = ""
    certificate_arn = ""

    default_action = {
      type = ...
    }
    listener_rules = {
      target-003 = {
        action = {
          type = ...
        }
      }
      target-004 = {
        action = {
          type = ...
        }
      }
    }
  }
}

alb_target_group = {
  target-001 = {
    port                 = 80
    protocol             = ...
    health_check = {
      interval            = ...
    }
  }
  target-002 = {
    port                 = 8080
    protocol             = ...
    deregistration_delay = 300
    health_check = {
      interval            = ...
    }
  }
  target-003 = {
    port                 = 80
    protocol             = ...
    health_check = {
      interval            = ...
    }
  }
  target-004 = {
    port                 = 8080
    protocol             = ...
    health_check = {
      interval            = ...
    }
  }
}

listener_rule_map の中身は次のようになっている.

listener_rule_map = [
  {
    "listener_key" = "listener_001"
    "listener_rule_key" = "target-002"
    "type" = ...
  },
  {
    "listener_key" = "listener_001"
    "listener_rule_key" = "target-001"
    "type" = ...
  {
    "listener_key" = "listener_002"
    "listener_rule_key" = "target-004"
    "type" = ...
  },
  {
    "listener_key" = "listener_002"
    "listener_rule_key" = "target-003"
    "type" = ...
  },
]