JSON設定ファイル(.tf.json)— HCLとの対応ガイド

1. 概要

  • TerraformのJSON設定ファイル(.tf.json)とは
  • HCLとJSONの対応関係
  • JSON設定が有効なユースケース
  • 注意点と制限

TerraformはHCL(HashiCorp Configuration Language)だけでなく、JSONでも設定を書けます。.tf.jsonという拡張子を使うと、Terraform が JSONファイルとして処理します。


2. HCLとJSONの対応

基本的な対応関係を確認します。

HCL(main.tf):

resource "aws_instance" "web" {
  ami           = "ami-0abc123456"
  instance_type = "t3.micro"

  tags = {
    Name        = "dev-web"
    Environment = "dev"
    ManagedBy   = "terraform"
  }
}

JSON(main.tf.json):

{
  "resource": {
    "aws_instance": {
      "web": {
        "ami": "ami-0abc123456",
        "instance_type": "t3.micro",
        "tags": {
          "Name": "dev-web",
          "Environment": "dev",
          "ManagedBy": "terraform"
        }
      }
    }
  }
}

3. JSON設定の全体例

{
  "terraform": {
    "required_version": ">= 1.9",
    "required_providers": {
      "aws": {
        "source": "hashicorp/aws",
        "version": "~> 5.0"
      }
    }
  },
  "provider": {
    "aws": {
      "region": "ap-northeast-1"
    }
  },
  "variable": {
    "environment": {
      "description": "環境名",
      "type": "string",
      "default": "dev"
    }
  },
  "data": {
    "aws_ami": {
      "amazon_linux_2023": {
        "most_recent": true,
        "owners": ["amazon"],
        "filter": [
          {
            "name": "name",
            "values": ["al2023-ami-*-x86_64"]
          }
        ]
      }
    }
  },
  "resource": {
    "aws_instance": {
      "web": {
        "ami": "${data.aws_ami.amazon_linux_2023.id}",
        "instance_type": "t3.micro",
        "root_block_device": {
          "volume_size": 20,
          "volume_type": "gp3",
          "encrypted": true
        },
        "tags": {
          "Name": "${var.environment}-web",
          "Environment": "${var.environment}",
          "ManagedBy": "terraform"
        }
      }
    }
  },
  "output": {
    "instance_id": {
      "value": "${aws_instance.web.id}",
      "description": "EC2インスタンスID"
    }
  }
}

4. JSON設定が有効なユースケース

プログラムからの設定生成: TerraformをCIパイプラインで動的に設定を生成する際、JSON はほぼすべてのプログラミング言語で簡単に生成・操作できます。

# Python でTerraform JSON設定を生成する例
import json

config = {
    "resource": {
        "aws_s3_bucket": {}
    }
}

environments = ["dev", "stg", "prd"]
for env in environments:
    config["resource"]["aws_s3_bucket"][f"{env}_data"] = {
        "bucket": f"{env}-myapp-data",
        "tags": {
            "Name": f"{env}-data",
            "Environment": env,
            "ManagedBy": "terraform"
        }
    }

with open("buckets.tf.json", "w") as f:
    json.dump(config, f, indent=2)

5. JSON特有の注意点

ブロックが複数ある場合はリストを使う:

{
  "resource": {
    "aws_security_group": {
      "web": {
        "name": "dev-web-sg",
        "vpc_id": "${aws_vpc.main.id}",
        "ingress": [
          {
            "from_port": 80,
            "to_port": 80,
            "protocol": "tcp",
            "cidr_blocks": ["0.0.0.0/0"]
          },
          {
            "from_port": 443,
            "to_port": 443,
            "protocol": "tcp",
            "cidr_blocks": ["0.0.0.0/0"]
          }
        ],
        "tags": {
          "Name": "dev-web-sg",
          "Environment": "dev",
          "ManagedBy": "terraform"
        }
      }
    }
  }
}

HCLのヒアドキュメント(<<-EOT)はJSONでは使えない — JSONの通常の文字列として書く必要があります。


6. HCLとJSONの混在

.tf.tf.jsonは同じディレクトリに混在できます。Terraformは両方を読み込んでマージします。

project/
├── main.tf           # HCL設定
├── variables.tf      # HCL変数
└── generated.tf.json # プログラムが生成したJSON設定

7. 関連記事


8. まとめ

  • .tf.json拡張子でJSON設定ファイルを使える
  • resource{ "resource": { "<type>": { "<name>": {...} } } }という構造
  • HCLのヒアドキュメントはJSON非対応
  • 繰り返しブロック(ingress等)はJSONの配列で表現する
  • プログラムからの設定生成・動的なCI/CDパイプラインでの活用に向いている
  • .tf.tf.jsonは同じディレクトリで混在可能

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/syntax/json