02. 基本構文
HCL の文法は驚くほどシンプルで、覚えるのは 2 種類だけ です。引数 (argument) と ブロック (block)。すべてはこの組み合わせ。
HCL は 2 種類の構造しかない
# これが「引数」(argument)
image_id = "ami-abc123"
# これが「ブロック」(block)
resource "aws_instance" "web" {
ami = "ami-abc123"
instance_type = "t3.micro"
}
引数は NAME = VALUE の代入。ブロックは TYPE [LABEL] [LABEL] { ... } の波カッコ構造。これだけで Terraform の設定全体が表現されます。
引数(argument)
引数は 名前 = 値 の形。値は文字列・数値・真偽値・リスト・マップ・オブジェクト・null など、第 4 章で詳しく扱う 型 に従います。
name = "my-app" # 文字列
count = 3 # 数値
enabled = true # 真偽値
zones = ["a", "b", "c"] # リスト
tags = { # マップ/オブジェクト
Env = "prod"
Team = "platform"
}
description = null # 値なし
ブロック(block)
ブロックは「何かのまとまり」を表します。以下、典型的なブロックの形を読み解きます。
resource "aws_instance" "web" {
ami = "ami-abc123"
instance_type = "t3.micro"
}
| 位置 | 意味 | 例 |
|---|---|---|
| ブロックタイプ | このブロックの種類 | resource |
| ラベル 1 | リソースタイプ(プロバイダが定義) | "aws_instance" |
| ラベル 2 | このリソースの呼び名(自分で決める) | "web" |
{ ... } | ボディ(中身は引数や入れ子ブロック) | ― |
ラベルの数や種類はブロックタイプによって決まっています。resource はラベル 2 つ、locals はラベル 0、provider はラベル 1。それぞれの章で出てきたら確認すれば OK。
入れ子ブロック
ブロックは中にさらにブロックを置けます。たとえば EC2 のルートディスク設定:
resource "aws_instance" "web" {
ami = "ami-abc123"
instance_type = "t3.micro"
root_block_device { # ← 入れ子ブロック
volume_size = 30
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "web"
}
}
識別子の規則
引数名・ブロックラベル・変数名などに使える「識別子」のルール:
- 使える文字: 英数字・アンダースコア(
_)・ハイフン(-) - 先頭は数字以外
- 大文字小文字を区別する
- 慣習: snake_case(
web_server、db_password)
コメント
# これが推奨スタイル(シェル風)
// これも書ける(C++ 風、ただし慣習的には # を使う)
/*
複数行は
/* */ で囲む
*/
文字列とヒアドキュメント
普通の文字列
# 普通の文字列リテラルは "..." で囲む。中でエスケープシーケンスが効く
name = "production"
path = "C:\\Users\\me" # バックスラッシュは \\ と書く(パス区切りで頻出)
note = "line1\nline2" # \n で改行コードを表現
ヒアドキュメント(複数行文字列)
# ヒアドキュメント = 複数行の文字列を改行を保ったまま書ける構文
# <<EOT で始まり、行頭の EOT で終わる("EOT" 部分は任意の識別子で OK)
user_data = <<EOT
#!/bin/bash
yum update -y
yum install -y nginx
systemctl enable nginx
systemctl start nginx
EOT
インデントを揃えたければ <<-EOT(ハイフン付き)。閉じタグの位置までの共通インデントが自動で除去されます。
# <<-EOT (ハイフン付き) は、共通インデントを自動で除去するヒアドキュメント
# 下の例だと先頭の「 」(2 スペース) が削除されて #!/bin/bash から始まる文字列になる
user_data = <<-EOT
#!/bin/bash
yum update -y
yum install -y nginx
EOT
${} 補間
文字列の中に変数や式の結果を埋め込む構文。Terraform で もっとも使う書き方の 1 つ。
# ${} 補間 = 文字列リテラル内に変数や式の結果を埋め込む構文
# 例: var.project = "myapp" のとき → "myapp-web" になる
name = "${var.project}-web" # 文字列の中に変数
# 任意の式(参照、関数呼び出し)を ${} の中に書ける
arn = "arn:aws:s3:::${var.bucket}/*"
# 値全体が 1 つの参照だけの時は、${} なしで生のまま書ける(こちらが推奨)
arn = aws_s3_bucket.this.arn # ${aws_s3_bucket.this.arn} と同じ意味
スタイル
Terraform 0.12 以降は 「文字列の合成が必要な時だけ
${} を使う」 のが推奨です。name = "${var.x}" のように単独で使うのは冗長で、警告も出ます。
ファイル分割は機能でなく役割で
Terraform は同じディレクトリの .tf をすべてマージして 1 つの構成として読みます。なので分割は完全に 読みやすさのため。慣習的なファイル名:
| ファイル | 中身 |
|---|---|
terraform.tf | terraform { required_version, required_providers, backend } |
providers.tf | provider "..." { ... } |
variables.tf | variable "..." { ... } |
locals.tf | locals { ... } |
main.tf | 主要な resource / data / module |
outputs.tf | output "..." { ... } |