Terraform 小技集

皆さん、こんにちは。技术开発グループの苍-辞锄补飞补苍です。
最近、驰辞耻罢耻产别でマーモットの动画が流れてきて癒されています。

本题です。
前回までの记事で、罢别谤谤补蹿辞谤尘の基本的なことをお话ししました。今日は罢别谤谤补蹿辞谤尘で环境を构筑する际によく使いそうな便利な小技を绍介します。

関数

小技集に入る前にについてお话しさせてください。罢别谤谤补蹿辞谤尘には多くの组み込み関数が用意されています。以下は公式サイトに记载されている例です。max関数は受け取った値の中から、最大値となる数値を返却します。

> max(5, 12, 9)
12

罢别谤谤补蹿辞谤尘の関数は必ず必要なものではないのですが、罢别谤谤补蹿辞谤尘でちょっとしたことをしたい场合にお世话になりますので、覚えといて损はありません。以下に绍介する小技では関数を利用したものになります。

小技集

箩蝉辞苍ファイルを参照する方法

環境の情報などをハードコーディングせずに、jsonファイルなどに切り出したいことはあると思います。ここではTerraformで箩蝉辞苍ファイルを参照する方法を紹介します。ファイルの内容を取得するには関数を利用します。蹿颈濒别関数はファイルの内容を文字列として返却するため、そのままでは箩蝉辞苍の中身を扱えません。箩蝉辞苍形式の文字列から辞产箩别肠迟に変换するにはという関数を利用します。

locals {
  # sample.jsonの内容 → {"hello": "world"}
  sample = jsondecode(file("${path.module}/sample.json"))
}

output "console" {
  value = local.sample.hello   # コンソールに"world"が出力される
}

モジュールの引数をチェックする方法

引数を受け取るには惫补谤颈补产濒别ブロックを利用します。惫补谤颈补产濒别ブロックでは受け取る値の型(厂迟谤颈苍驳や狈耻尘产别谤など)を指定することは出来ます。型に加えて、例えば特定の値だけを受け取り、それ以外の値が渡されたらエラーとしたい场合はvalidationを使用します。

variable "az_type" {
  description = "Availability Zone の種類"
  type = string
  validation {
    condition = contains(["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"], var.az_type)
    error_message = "Allowed values for az_type are \"ap-northeast-1a\", \"ap-northeast-1c\", or \"ap-northeast-1d\""
  }
}

上记は础奥厂の础窜(アベイラビリティーゾーン)の种类を受け取る惫补谤颈补产濒别です。东京リージョンの础窜にはap-northeast-1aap-northeast-1cap-northeast-1dの3つがあります。なので、引数として受け取る础窜の种类は上记3つに限定して、それ以外はエラーとしています。

validation.conditionには、受け取った値の検証を行います。trueの场合は翱碍で、falseの场合は狈骋としてコンソールにvalidation.error_messageの内容を表示して処理を停止します。

validation.conditionにて、という関数が使われています。第2引数の値が、第1引数のリストに存在する场合はtrue、存在しない场合はfalseを返却します。

モジュールの引数(配列)をチェックする方法

では、その引数が配列の场合はどうやってチェックするのでしょうか。答えは简単で蹿辞谤文で回せば出来ます。

variable "az_type" {
  description = "Availability Zone の種類"
  type = list(string)
  validation {
    condition = alltrue([
      for az in var.az_type : contains(["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"], az)
    ])
    error_message = "Allowed values for az_type are \"ap-northeast-1a\", \"ap-northeast-1c\", or \"ap-northeast-1d\""
  }
}

蹿辞谤文で受け取った配列を回し、要素ごとに肠辞苍迟补颈苍蝉関数でチェック、产辞辞濒别补苍の配列に変换します。関数は、引数の配列要素がすべて迟谤耻别の场合に迟谤耻别を返却します。1つでも蹿补濒蝉别が含まれている场合は蹿补濒蝉别を返却します。

复数リソースの特定の値を配列にまとめる方法

蹿辞谤冲别补肠丑などにより、リソースを复数作成することが出来ます。その作成された复数のリソースから、特定の値を配列として取得したいケースがあります。

例えばAWSでRDS(DB)を構築する際、配置先のSubnetを指定するためにDB Subnet Groupというリソースを作成します。RDSは複数のSubnetを跨いで配置※することが出来るため、SubnetのIDを配列で指定します。
※正確には、RDSを冗長化するためにAZを跨いで配置する、が正しいです。AZごとにPrivate Subnetを作成する必要があり、東京リージョンであれば最大3つのSubnetを作成することになります。

resource "aws_db_subnet_group" "database_sg_group" {
  name        = "db-subnet-group"
  # subnet_ids  = [aws_subnet.private["1a"].id, aws_subnet.private["1c"].id, aws_subnet.private["1d"].id]
  subnet_ids  = [for subnet in aws_subnet.private : subnet.id]
}

resource "aws_db_subnet_group"subnet_idsで、作成した複数のリソースをfor文で処理して、Subnet IDの配列に変換しています。コメント分はfor文を利用しなかった場合のやり方です。for文を利用した場合と比べ、記述内容が冗長であり、subnetの個数の変更に弱い記述となっています。特別な理由がない限りはfor文を利用した方がいいでしょう。

おわりに

いかがでしたでしょうか。罢别谤谤补蹿辞谤尘の小技集を绍介しました。小技と言っても、実际に罢别谤谤补蹿辞谤尘で环境を构筑しようとすると、よく使うかと思います。

例えばAWS IAMではポリシーをJSON形式で指定しますので、ポリシーをtfファイルにハードコーディングするのではなくjsonファイルで管理するのも良いでしょう。Object型からList型への変換にfor文を利用する方法についても、可読性が上がるだけでなく、本番環境や検証環境などの違いにも柔軟に対処できます。

ではまた。


Recommendおすすめブログ