zaki work log

作業ログやら生活ログやらなんやら

[Terraform] Data Sourcesを使った対象リージョンのAZの実行時取得

指定のリージョンにおけるアベイラビリティゾーンは何があるか?のように、自分が実装する内容でなくAWS(プロバイダ)の情報を取得したい場合は、データソースを使うことで情報参照ができる。

developer.hashicorp.com

アベイラビリティゾーンを参照するためのデータソースはaws_availability_zoneが用意されており、簡単なコードで実現できる。

registry.terraform.io

before (AZをハードコーディング)

2つのサブネットをそれぞれ別のAZとしたい場合、ハードコーディングするとこんな感じ。

resource "aws_subnet" "example_subnet1" {
  vpc_id            = aws_vpc.example_vpc.id
  cidr_block        = "10.89.1.0/24"
  availability_zone = "ap-southeast-2a"

  tags = {
    Name = "example_subnet1"
  }
}

resource "aws_subnet" "example_subnet2" {
  vpc_id            = aws_vpc.example_vpc.id
  cidr_block        = "10.89.2.0/24"
  availability_zone = "ap-southeast-2b"

  tags = {
    Name = "example_subnet2"
  }
}

after (データソースを使ったAZの取得)

前述のハードコーディングの場合、リージョンをap-southeast-2から変更したい場合に、AZの指定の箇所も修正が必要になるのでまったくスマートではない。
そこで使用するのがデータソースで、これを使うことで「現在のリージョンで定義されているAZを実行時に取得」することができる。

data "aws_availability_zones" "available" {
  state = "available"
}

resource "aws_subnet" "example_subnet1" {
  vpc_id            = aws_vpc.example_vpc.id
  cidr_block        = "10.89.1.0/24"
  availability_zone = data.aws_availability_zones.available.names[0]

  tags = {
    Name = "example_subnet1"
  }
}

resource "aws_subnet" "example_subnet2" {
  vpc_id            = aws_vpc.example_vpc.id
  cidr_block        = "10.89.2.0/24"
  availability_zone = data.aws_availability_zones.available.names[1]

  tags = {
    Name = "example_subnet2"
  }
}

このコードでplanすると以下のように自動でAZの値が取れていることが確認できる。

  # aws_subnet.example_subnet1 will be created
  + resource "aws_subnet" "example_subnet1" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-southeast-2a"
      + availability_zone_id                           = (known after apply)

[...]

  # aws_subnet.example_subnet2 will be created
  + resource "aws_subnet" "example_subnet2" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-southeast-2b"
      + availability_zone_id                           = (known after apply)

[...]

CFnの場合

CloudFormationの場合はこんな感じのはず (YAML)

  ExampleSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs '' ]

※ ちなみに今、他の人が実装したCFnのコードを微修正して実装してたシステムを最近Terraformに置き換えを進めてるところで、CFn自体はまったく理解してないというのが現状


zaki-hmkc.hatenablog.com