BioErrorLog Tech Blog

試行錯誤の記録

Terraformにおける三項演算子の使い方

Terraformの三項演算子の使い方と、その使用例をまとめます。

はじめに

こんにちは、@bioerrorlogです。

三項演算子を活用すると、Terraformにおいても条件に応じた表現がシンプルに実現できます。

使用頻度も高く便利な機能なので、使い方を整理しておきます。


※作業バージョン

$ terraform --version
Terraform v1.2.6
on linux_amd64

Terraformで三項演算子

使い方

基本的な使い方はドキュメントの通りです:

condition ? true_val : false_val

conditionの位置にbool型の値を置き、それがtrueであれば一つ目の値true_valを、falseであれば二つ目の値false_valがreturnされます。

conditionの値は評価値がboolであればよいので、もちろん== / != 演算子や && / || 等も使うことができます。

またtrue_valfalse_valは同じ型である必要があります。
(cast可能なものはcastされます)

具体例

いくつか具体的な例を列挙します。

シンプルな例

true ? "true val" : "false val"
# "true val"

false ? "true val" : "false val"
# "false val"

条件演算子を組み合わせ

var.a == "" ? "default-a" : var.a

var.aが空文字""だった場合は"default-a"が、そうでない場合はvar.aをそのままreturnします。


0 <= var.i && var.i <= 5 ? "between 0-5" : "out of range"

&&演算子で複数条件を組み合わせた例です。
var.iが0以上5以下の場合は"between 0-5"を、そうでない場合は"out of range"を返します。

型がcastされる例

true ? 100 : "this is string"
# "100"

true ? true : "this is string"
# "true"

true ? null : "this is string"
# tostring(null)

"this is string"にあわせ、100numberではなくstringとして解釈されます。

trueも同様にstringとして解釈されます。

nulltostring(null)としてcastされています。

エラー: 異なる型を指定

Castできない型を指定すると、エラーになります。

例:numberとbool:

true ? 100 : true
╷
│ Error: Inconsistent conditional result types
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The true and false result expressions must have consistent types. The 'true' value is number, but the 'false' value is bool.


例:listとstring:

true ? [] : "this is stgin"
╷
│ Error: Inconsistent conditional result types
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The true and false result expressions must have consistent types. The 'true' value is tuple, but the 'false' value is string.

エラー: bool以外をconditionに指定

bool以外の値をconditionとして直接指定してしまうとエラーになります。

10 ? true : false
╷
│ Error: Incorrect condition type
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The condition expression must be of type bool.
"I am string" ? true : false
╷
│ Error: Incorrect condition type
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The condition expression must be of type bool.

活用事例:resource count

Terraformの三項演算子を活用する場面として最も代表的なのが、resourceを作成するか否かをcount句を使って制御するケースでしょう。

公式のAWS VPC moduleからコード例を抜粋します:

locals {
  # ~~中略~~
  create_vpc = var.create_vpc && var.putin_khuylo
}

# ~~中略~~

resource "aws_vpc" "this" {
  count = local.create_vpc ? 1 : 0

  cidr_block                       = var.cidr
  instance_tenancy                 = var.instance_tenancy
  enable_dns_hostnames             = var.enable_dns_hostnames
  enable_dns_support               = var.enable_dns_support
  enable_classiclink               = var.enable_classiclink
  enable_classiclink_dns_support   = var.enable_classiclink_dns_support
  assign_generated_ipv6_cidr_block = var.enable_ipv6

  tags = merge(
    { "Name" = var.name },
    var.tags,
    var.vpc_tags,
  )
}

count = local.create_vpc ? 1 : 0で、VPCを作成するか否かをmodule variablesに応じて制御しています。

活用事例:dynamic

パラメータを動的に定義するdynamic句と合わせるのも便利な利用法です。

同じくAWS VPC moduleからコード例を抜粋します:

  dynamic "destination_options" {
    for_each = var.flow_log_destination_type == "s3" ? [true] : []

    content {
      file_format                = var.flow_log_file_format
      hive_compatible_partitions = var.flow_log_hive_compatible_partitions
      per_hour_partition         = var.flow_log_per_hour_partition
    }
  }

for_each対象を三項演算子を使って条件分岐させています。

var.flow_log_destination_type == "s3"の結果がfalseの場合、for_each対象は空リスト[]となり、パラメータ"destination_options"は指定されません。

おわりに

Terraformにおける三項演算子の使い方とその具体例をまとめました。

Terraformには便利な機能が多くあるので、ぜひ活用してより良いIaCライフを送りたいものです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

参考

Conditional Expressions - Configuration Language | Terraform by HashiCorp

Operators - Configuration Language | Terraform by HashiCorp

Dynamic Blocks - Configuration Language | Terraform by HashiCorp

GitHub - terraform-aws-modules/terraform-aws-vpc: Terraform module which creates VPC resources on AWS 🇺🇦

GitHub - terraform-aws-modules/terraform-aws-eks: Terraform module to create an Elastic Kubernetes (EKS) cluster and associated resources 🇺🇦