使えると便利なTerraformのメタ引数と組み込み関数

Tech

2022.6.13

Topics

こんにちは、tkgです。

Terraformではリソース定義以外にも様々な関数や特殊な引数があります。
今回は、利用できると表現の幅が広がりそうだなと思うメタ引数と組み込み関数について理解を深めて行きたいと思います。

データ型の種別

まず、普段利用するデータ型についておさらいです。

  • string
    「”」で囲まれた任意の文字列。通常の文字列として扱われる。

  • number
    数値型。整数および小数の値が両方利用可能。「”」 で囲まれていない数値。

  • bool
    true もしくは false のフラグ管理向け。

  • list
    [“a”, “b”] のような配列要素で利用。

  • map
    下記のような、key:value型の要素を扱う時に利用。

{
    a = "hoge"
    b = "fuga"
}

今回は、上記の list および map を利用するものを紹介します。

メタ引数

メタ引数 (Meta-Argument)とは、resourceやmodule定義自体の動作を変更させるメタ的な引数です。

for_each

前回の記事ですこし利用していましたが、Terraformのresource定義やmoduleで利用できる引数になります。
map形式での値を受付け、key:value の数だけ繰り返し生成されます。
受け付けた値は、${each.key}でkeyが、 ${each.value}でvalueが参照可能な為、全く同じものを生成するのではなく、異なる名前や設定を行うことも可能です。

前回の引用ですが、下記のような形で一つの定義で複数台のリソースを定義可能です。


locals {
    multiple_instances = {
        01 = {
          availability_zone = element(module.vpc.azs, 0)
          subnet_id         = element(module.vpc.private_subnets, 0)
        }
        02 = {
          availability_zone = element(module.vpc.azs, 1)
          subnet_id         = element(module.vpc.private_subnets, 1)
        }
    }
}
 
module "ec2" {
    source  = "terraform-aws-modules/ec2-instance/aws"
    version = "4.0.0"
    for_each = local.multiple_instances
 
    name = "${local.name_prefix}-ec2-${each.key}"
 
    ami                    = "ami-0123c868871eaa6e5"
    instance_type          = "t3.micro"
    availability_zone      = each.value.availability_zone
    subnet_id              = each.value.subnet_id
 
    vpc_security_group_ids = [module.sg-local-http.security_group_id]
 
    root_block_device = [
        {
          encrypted   = true
          volume_type = "gp3"
          throughput  = 125
          volume_size = 10
        }
    ]
}

上記の場合ですと、local変数に定義したmultiple_instancesの中に01および02の設定が定義されています。
each.keyでサーバ固有の名前を設定し、each.key.availability_zoneeach.value.subnet_id でAZやサブネットを参照、設定させる内容となっています。

count

こちらもループ処理のメタ引数となります。
詳しい内容は Cold-Airflowさんの記事がありますので割愛しますが、同一設定で複数のリソースを作成する場合などに利用可能です。

組み込み関数

Terraform上には利用できる値の変換や結合ができる多数の関数があります。
今回はその中の4つを確認していきます。

element

こちらはlist要素の中身を参照するために利用する関数です。
element(list, 要素の番号) の書式で設定し、指定したlistの要素を返します。

前述のfor_eachなどで動的に作成されたlistの一部を呼び出したい時などに活用できます。

▼terraform console上での動作例

> module.vpc.public_subnets
[
  "subnet-xxxxxxxxxxxxxxxxx",
  "subnet-yyyyyyyyyyyyyyyyy",
]
→ list要素を返す変数

>
> element(module.vpc.public_subnets, 1)
"subnet-yyyyyyyyyyyyyyyyy"
→ "1"の要素が抜き出せたことを確認

>

lookup

lookup関数はmap要素内のkeyと一致するvalueを返す関数です。
指定したkeyが無い場合はdefault値を返します。
lookup(map要素, key, default)

▼動作例

> lookup(local.multiple_instances,2,"other")
{
  "availability_zone" = "ap-northeast-1c"
  "subnet_id" = "subnet-yyyyyyyyyyyyyyyyy"
}
>
> lookup(local.multiple_instances,3,"other")
"other"
>

keys

こちらは、map要素内のkey-value の keyをlist形式で返す関数です。
keys(map要素)の書式で記述します。

▼動作例

> keys(local.multiple_instances)
[
  "1",
  "2",
]
>

values

こちらは先程のkeysと逆に valueを返す関数です。
同様に、values(map要素) の書式で記述します。

▼動作例

> values(local.multiple_instances)
[
  {
    "availability_zone" = "ap-northeast-1a"
    "subnet_id" = "subnet-0b883b97a65c8a914"
  },
  {
    "availability_zone" = "ap-northeast-1c"
    "subnet_id" = "subnet-0189eba49ec2b6fbe"
  },
]
>

所感

key-value、list等それぞれの記述に対する定義などが無いとコードが逆に読みづらくなってしまうものですが、うまく利用できるとコードの圧縮や可読性の向上に繋がります。
前回紹介したTerraform AWS Moduleでも多く利用されており、それらのコードの仕組みを理解する上でも重要です。
紹介した機能はそれぞれ実運用で利用しやすい特性をもっていますので、ぜひお持ちのコードに実装してみてください。

その他にも多くのメタ引数関数がありますので、興味がある方は公式ドキュメントをご参照ください。

tkg

2016年入社のインフラエンジニアです。 写真が趣味。防湿庫からはレンズが生え、押入れには機材が生えます。 2D/3DCG方面に触れていた時期もありました。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら