LoginSignup
2
1

Local Valueとfor_eachを使ってリソース定義を楽したい

Posted at

tl;dr

Local Valueで定義したいリソースのパラメータを事前に用意し、 for_each でそれを読み込むとresource定義はひとつで済むので便利。

まえがき

terraformでリソースを定義するとき、名前や保持期間など、一部パラメータが違うだけのほとんど同じリソースを複数定義することがあります。
AWSで言うと、たとえばElastic Container RegistryやCloudwatch Logsのロググループなどが該当します。

これらのリソースを一個一個定義するのもいいのですが、時には短く書きたい場合もあります。
そんなときに便利な、Local Valuefor_each について紹介します。

やってみる

キーだけを参照するシンプルな例

まずは実際のコードを例示します。
以下のコードは、Elastic Container Registryのリポジトリを for_each で定義するものです。

まずは、Local Valueとしてリソースごとに変更させたいもののリストを定義します。
今回はリポジトリ名のみを可変にしたいので、aws_ecr_repository.repositories という名前の list(string) 型の変数として定義します。

locals.tf
locals {
  aws_ecr_repository = {
    repositories = [
      "php",
      "nginx",
    ]
  }
}

その後、リソースを定義する時に、リソースの中でfor_eachを使います。

ecr.tf
# リストを元にリソースを作成する
resource "aws_ecr_repository" "repositories" {
  for_each = toset(local.aws_ecr_repository.repositories) # aws_ecr_repository.repositories の数だけリソースを定義する

  name = each.key # repositoriesのキー(php, nginx)が参照される
  image_tag_mutability = "MUTABLE"
}

これをapplyすると、aws_ecr_repository.repositories[] が定義されます。
他のリソースから特定のリポジトリを参照したい場合は、aws_ecr_repository.repositories[リストのキー] で参照できます。
上記のサンプルコードだと、aws_ecr_repository.repositories["php"], aws_ecr_repository.repositories["nginx"] のようにします。

キー・バリューを活用する例

先ほどの例では、シンプルに名前のリストを作ってそのぶんだけリソースを作る、というものでした。
実際には、リソースごとに微妙に変えたい値があるケースもあります。
そうした場合、下記のようにkey-valueの形式を使って、可変したい値を含めたLocal Valueを定義すると便利です。

CloudflareのDNSレコードを定義するコードで例示します。

まずは、このようにLocal Valueを定義します。

locals.tf
locals {
  records = {
    "example.com" = { value = "example.com", comment = "hoge", proxied = false }
    "www"         = { value = "example.com", comment = "piyo", proxied = true }
  }
}

そして、以下のようにkeyに加えてvalueも参照します。

cname.tf
# CNAME Records
resource "cloudflare_record" "cname" {
  for_each = local.records

  zone_id         = var.cloudflare_zone_id
  name            = each.key # "example.com", "www" が参照される
  comment         = each.value.comment
  type            = "CNAME"
  value           = each.value.value
  proxied         = each.value.proxied
  allow_overwrite = false
}

DNSのTTLや向き先、ログの保持期間など、リソースごとのちょっとした差分についてもLocal Valueを使うことで吸収し for_each で楽してリソース定義することができます。

まとめ

こうした for_each を使った書き方を使うことで、同じようなリソースの定義が楽になります。
また、嬉しい副作用として、localsを見ればそのtfファイルで何を定義しているかがすぐにわかるようにもなります。

使ったことがなければ、一度試してみることをおすすめします。

(もちろん、複雑な差分がある場合には素直に個別にresourceブロックを記述することをおすすめします。あくまでシンプルな差分で使うのがよさそうです!)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1