背景

terraformのmoduleを使用して複数のセキュリティグループを作ろうとしたらハマったので、記録に残す。

やりたいこと:inboudのIPアドレスを複数定義する

moduleを使用した以下の構成。引数に複数のIPアドレスをモジュールdbに渡す場合。

    ├── ./README.md
    ├── ./env
    │   ├── ./env/prod
    │   │   ├── ./env/prod/main.tf
    │   │   └── ./env/prod/variables.tf
    │   └── ./env/stag
    │       ├── ./env/stag/main.tf
    │       └── ./env/stag/variables.tf
    └── ./modules
        ├── ./modules/db
        │   └── ./modules/db/database.tf
        └── ./modules/network
            └── ./modules/network/network.tf

variables.tf

variables.tfには以下のようにmapで書く。省略しているが、localで記述している。

    ap = {
      server = {
        "01" = {
          ip_address = "aa.aa.aa.aa/32"
        }
        "02" = {
          ip_address = "bb.bb.bb.bb/32"
        }
        "03" = {
          ip_address = "cc.cc.cc.cc/32"
        }
      }
    }

main.tf

main.tfでmoduleで渡す際、以下のようにmapで定義する。不必要な箇所は省略。

    module "db" {
    source   = "../../modules/db"
    ap_list = local.ap
  }

database.tf

database.tfはmapで受け取って、aws_security_groupを作る。その後でaws_security_group_ruleを作り、適用していく。ポイントはfor_eachでmap内の要素を適応していくこと。

    variable "ap_list" {}

    # Security Group
    resource "aws_security_group" "public-db-sg" {
      name   = "${var.env}-public-db-sg"
      vpc_id = "${var.network.vpc-id}"
      tags = {
        Name = "public-db-sg"
      }
    }

    resource "aws_security_group_rule" "inbound_ap" {
      for_each = var.ap_list.server
      type        = "ingress"
      from_port   = 5432
      to_port     = 5432
      protocol    = "tcp"
      cidr_blocks = [
        "${var.ars_list.server[each.key].ip_address}"
      ]
      description = "ap-${each.key}"
      security_group_id = "${aws_security_group.public-db-sg.id}"
    }

参考資料

以下が参考になる。

Terraformで1つのセキュリティグループに複数のルールを設定する - Qiita