03. 値(variable / local / output)
Terraform の「値」には 3 つの場所 があります。variable は外から受け取る値、local は中で計算する値、output は外に返す値。役割をちゃんと分けると、コードがぐっと読みやすくなります。
3 種類の使い分け
| 役割 | 参照する書き方 | 使う場面 | |
|---|---|---|---|
| variable | 外から受け取る入力 | var.NAME | 環境ごとに変えたい値(リージョン、サイズ) |
| local | 内部で計算する中間値 | local.NAME | 長い式の名前付け、共通タグ |
| output | 外に出す結果 | (モジュールから親へ) | VPC ID を別モジュールに渡す等 |
variable(入力)
variable "region" {
type = string
description = "AWS リージョン"
default = "ap-northeast-1"
}
variable "instance_type" {
type = string
default = "t3.micro"
}
variable "subnet_cidrs" {
type = list(string)
default = ["10.0.1.0/24", "10.0.2.0/24"]
}
variable "tags" {
type = map(string)
default = {
Project = "hcl-guide"
Env = "dev"
}
}
variable の主要属性
| 属性 | 意味 |
|---|---|
type | 受け付ける型(次章)。型を書くとミス値で弾かれる |
default | 省略時の値。書かないと「必須入力」 |
description | 説明。terraform plan やドキュメント生成で使われる |
sensitive | true で plan/apply 出力にマスク表示 |
nullable | false で null 不可(デフォルト true) |
validation | 値の妥当性チェック(後述) |
variable に値を渡す方法と優先順位
同じ変数に複数の経路から値が来ると、下に行くほど強い(後から上書き)。
- variable の
default(最弱) - 環境変数
TF_VAR_NAME terraform.tfvarsterraform.tfvars.json*.auto.tfvars/*.auto.tfvars.json(辞書順に)- CLI の
-var-file/-var(最強)
tfvars ファイルの書き方
# terraform.tfvars
region = "us-east-1"
instance_type = "t3.small"
subnet_cidrs = ["10.10.1.0/24", "10.10.2.0/24"]
# 環境ごとの tfvars を CLI で指定
terraform apply -var-file=envs/prd/terraform.tfvars
# ピンポイントで上書き
terraform apply -var="instance_type=t3.large"
# 環境変数で渡す(自動化で便利)
export TF_VAR_region=ap-northeast-1
terraform apply
validation で値を検証する
受け取った値が「想定外」で apply が走ってしまう前に、validation で止められます。
variable "environment" {
type = string
description = "環境名"
validation {
condition = contains(["dev", "stg", "prd"], var.environment)
error_message = "environment は dev / stg / prd のいずれかにしてください。"
}
}
variable "vpc_cidr" {
type = string
validation {
condition = can(cidrnetmask(var.vpc_cidr))
error_message = "vpc_cidr は有効な CIDR でなければなりません(例: 10.0.0.0/16)。"
}
}
locals(内部計算)
locals は「式の結果に名前を付ける」場所。同じ式を 3 か所で使うなら local にまとめると変更が 1 か所で済みます。
locals {
name_prefix = "${var.project}-${var.environment}"
is_prod = var.environment == "prd"
common_tags = {
Project = var.project
Env = var.environment
ManagedBy = "Terraform"
}
}
resource "aws_s3_bucket" "logs" {
bucket = "${local.name_prefix}-logs"
tags = local.common_tags
}
resource "aws_s3_bucket" "data" {
bucket = "${local.name_prefix}-data"
tags = local.common_tags
}
注意
ブロック名は
locals(複数形)ですが、参照は local.NAME(単数形)です。間違えやすいポイント。
output(出力)
「root モジュール」(プロジェクト直下)の output は terraform apply の最後に CLI に表示されます。「子モジュール」の output は親から module.NAME.OUTPUT で参照できます。
output "vpc_id" {
description = "作成した VPC の ID"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
value = [for s in aws_subnet.public : s.id]
}
# 機密値は sensitive = true でマスク
output "db_password" {
value = random_password.db.result
sensitive = true
}
子モジュールの出力を親で使う
# 親 (root)
module "network" {
source = "./modules/network"
cidr = "10.0.0.0/16"
}
resource "aws_instance" "web" {
subnet_id = module.network.public_subnet_ids[0] # ← 子の output を参照
# ...
}