1. 概要
- Terraformの三項演算子(条件式)の基本構文
if文がない代わりに条件式を使うパターンcount・for_eachとの組み合わせ(オプションリソース)- よく使う実用パターン集
- ネストした条件式(注意点)
Terraformにはif文がなく、代わりに条件式(三項演算子)を使います。条件 ? 真の値 : 偽の値という構文で、環境やフラグに応じて設定値やリソース数を切り替えられます。
2. 基本構文
condition ? true_val : false_val
# condition: boolを返す式
# true_val: conditionがtrueのときに返す値
# false_val: conditionがfalseのときに返す値
⚠️ 型の制約(Result Types):
true_valとfalse_valは同じ型でなければなりません。異なる型が指定された場合、Terraformは自動型変換を試みます(例:数値は文字列に変換可能)が、変換できない場合はエラーになります。明示的に型変換関数(tostring()等)を使うことを推奨します。
# 数値→文字列への自動変換は動作する(ただし明示的な変換を推奨)
var.example ? 12 : "hello" # → "12"(数値が文字列に変換)
# 明示的に変換する推奨パターン
var.example ? tostring(12) : "hello"
# terraform consoleで確認
> var.environment == "prd" ? "t3.medium" : "t3.micro"
# var.environment = "prd" の場合: "t3.medium"
# var.environment = "dev" の場合: "t3.micro"
> true ? "yes" : "no"
"yes"
> 1 > 2 ? "big" : "small"
"small"
3. 基本的な使い方
環境によってインスタンスタイプを切り替える
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名(dev/stg/prd)"
type = string
default = "dev"
}
variable "enable_deletion_protection" {
description = "削除保護を有効にするか"
type = bool
default = false
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux_2023.id
# 本番はt3.medium、それ以外はt3.micro
instance_type = var.environment == "prd" ? "t3.medium" : "t3.micro"
root_block_device {
volume_size = var.environment == "prd" ? 100 : 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-app"
Environment = var.environment
ManagedBy = "terraform"
}
}
4. countと組み合わせてオプションリソースを作る
count = condition ? 1 : 0パターンは、フラグでリソースの作成有無を制御する定番手法です。
variable "create_bastion" {
description = "踏み台サーバーを作成するか"
type = bool
default = false
}
# create_bastionがtrueのときだけEC2を作成
resource "aws_instance" "bastion" {
count = var.create_bastion ? 1 : 0
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
tags = {
Name = "bastion"
Environment = var.environment
ManagedBy = "terraform"
}
}
# 条件付き作成したリソースの参照方法
output "bastion_ip" {
# count = 0の場合はnullを返す
value = var.create_bastion ? aws_instance.bastion[0].public_ip : null
}
5. for_eachと組み合わせる
locals {
environments = ["dev", "stg", "prd"]
# 本番環境のみencryption設定を変える
bucket_config = {
for env in local.environments :
env => {
versioning = env == "prd" ? true : false
lifecycle = env == "prd" ? 90 : 30
}
}
}
resource "aws_s3_bucket" "env" {
for_each = local.bucket_config
bucket = "myapp-${each.key}"
tags = {
Name = "myapp-${each.key}"
Environment = each.key
ManagedBy = "terraform"
}
}
resource "aws_s3_bucket_versioning" "env" {
for_each = local.bucket_config
bucket = aws_s3_bucket.env[each.key].id
versioning_configuration {
status = each.value.versioning ? "Enabled" : "Suspended"
}
}
6. 文字列内での条件式
locals {
# 文字列の一部に条件式を埋め込む
bucket_name = "myapp-${var.environment == "prd" ? "production" : var.environment}"
# CIDR範囲を環境で切り替える
vpc_cidr = var.environment == "prd" ? "10.1.0.0/16" : "10.0.0.0/16"
}
7. ネストした条件式(注意点)
複数の条件を組み合わせるとネストになりますが、可読性が下がるため注意が必要です。
# ❌ 3段ネストは読みにくい
instance_type = var.env == "prd" ? "t3.medium" : var.env == "stg" ? "t3.small" : "t3.micro"
# ✅ localsかlookupに切り出す
locals {
instance_type_map = {
dev = "t3.micro"
stg = "t3.small"
prd = "t3.medium"
}
instance_type = lookup(local.instance_type_map, var.environment, "t3.micro")
}
3種類以上の分岐が必要な場合は、lookup関数でmapから取り出す方が読みやすくなります。
8. よく使うパターン一覧
| パターン | コード |
|---|---|
| 値を切り替える | var.env == "prd" ? "t3.medium" : "t3.micro" |
| リソースを作る/作らない | count = var.create_resource ? 1 : 0 |
| null を使う | var.optional_value != null ? var.optional_value : "default" |
| bool → string | var.enabled ? "enabled" : "disabled" |
| 文字列に埋め込む | "prefix-${var.env == "prd" ? "prod" : var.env}" |
9. 関連記事
- countメタ引数の使い方 —
count = condition ? 1 : 0パターン - for_each — map/setで動的にリソースを作成するメタ引数 — 条件式との組み合わせ
- lookup関数の使い方 — 3種類以上の分岐に使う
- locals(ローカル値)の使い方 — 条件式をlocalsに切り出す
- for式 — リスト・mapを変換・フィルタリング
- 型システム入門 — string/number/bool/list/map/object
10. まとめ
- 構文:
condition ? true_val : false_val - TerraformにはIf文がない。代わりに条件式(三項演算子)を使う
count = var.flag ? 1 : 0でリソースの作成有無を制御する定番パターン- 3種類以上の分岐はネストが深くなるため、
lookup関数やmapで代替する localsに条件式を集めると、リソースブロックがシンプルになる
動作確認バージョン: Terraform >= 1.9 / AWS Provider ~> 5.0 公式ドキュメント: https://developer.hashicorp.com/terraform/language/expressions/conditionals