★ 初級

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"
  }
}

識別子の規則

引数名・ブロックラベル・変数名などに使える「識別子」のルール:

コメント

# これが推奨スタイル(シェル風)
// これも書ける(C++ 風、ただし慣習的には # を使う)

/*
   複数行は
   /* */ で囲む
*/

文字列とヒアドキュメント

普通の文字列

name = "production"
path = "C:\\Users\\me"      # バックスラッシュは \\
note = "line1\nline2"        # \n で改行

ヒアドキュメント(複数行文字列)

user_data = <<EOT
#!/bin/bash
yum update -y
yum install -y nginx
systemctl enable nginx
systemctl start nginx
EOT

インデントを揃えたければ <<-EOT(ハイフン付き)。閉じタグの位置までの共通インデントが自動で除去されます。

user_data = <<-EOT
  #!/bin/bash
  yum update -y
  yum install -y nginx
EOT

${} 補間

文字列の中に変数や式の結果を埋め込む構文。Terraform で もっとも使う書き方の 1 つ

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.tfterraform { required_version, required_providers, backend }
providers.tfprovider "..." { ... }
variables.tfvariable "..." { ... }
locals.tflocals { ... }
main.tf主要な resource / data / module
outputs.tfoutput "..." { ... }