GeekFactory

int128.hatenablog.com

TerraformでIPアドレスリストをCIDRリストに変換する

Terraformの小ネタです.プライベートサブネットからInternet facing ALBへのアクセスを許可するため,NATゲートウェイグローバルIPアドレスをセキュリティグループに追加する必要がありました.Terraformの aws_security_group_rule にはIPアドレスではなくCIDRのリストを指定する必要があります.IPアドレスリストをCIDRリストに変換するにはどう書けばよいのか試行錯誤したのでメモを残しておきます.

Terraform v0.12を前提とします.

TL;DR

resource "aws_security_group_rule" "allow_from_natgw" {
  cidr_blocks = [for ip in ips : "${ip}/32"]
}

解説

terraform-aws-vpc モジュールを利用して,パブリック/プライベートサブネット構成を作成します.

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "2.9.0"

  enable_nat_gateway   = true
  # 中略
}

セキュリティグループを作成するには aws_security_group リソースを利用します.

resource "aws_security_group" "alb_foo" {
  name        = "alb-foo"
  vpc_id      = module.vpc.vpc_id
}

セキュリティグループにルールを追加するには aws_security_group_rule リソースを利用します.

resource "aws_security_group_rule" "alb_foo_from_natgw" {
  description       = "Allow from NAT Gateway"
  security_group_id = aws_security_group.alb_foo.id
  type              = "ingress"
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
  cidr_blocks       = [for ip in module.vpc.nat_public_ips : "${ip}/32"]
}

Terraform v0.12から for Expressions が利用できます.例えば,NATゲートウェイグローバルIPアドレス["1.2.3.4", "5.6.7.8"] の場合は以下のように展開されます.

  cidr_blocks = ["1.2.3.4/32", "5.6.7.8/32"]

もっと簡潔な書き方があったらぜひ教えてください!