【保存版】terraform tfvarsの基礎から実践まで完全解説!7つの活用テクニック

tfvarsファイルとは?初心者でもわかる基礎知識

terraformにおける変数管理の重要性

Terraformでインフラをコード化する際、環境やプロジェクトごとに異なる設定値を柔軟に管理する必要があります。例えば、以下のような値は環境によって変化します:

  • インスタンスのサイズ(開発環境:t2.micro、本番環境:t2.large)
  • データベースの設定(開発環境:単一構成、本番環境:マルチAZ構成)
  • リソースのタグ(環境名、プロジェクト名など)

これらの値をハードコーディングすると、以下の問題が発生します:

  1. コードの再利用性が低下
  2. 設定変更時のリスク増大
  3. セキュリティ面での脆弱性

そこで、Terraformは変数機能を提供し、tfvarsファイルによる効率的な変数管理を実現しています。

tfvarsファイルが解決する3つの課題

  1. 環境分離の実現
  • 同じTerraformコードを異なる環境で再利用可能
  • 環境固有の設定値を明確に分離
  • 設定値の一元管理による保守性向上
# development.tfvars
environment = "dev"
instance_type = "t2.micro"
multi_az = false

# production.tfvars
environment = "prod"
instance_type = "t2.large"
multi_az = true
  1. セキュリティの向上
  • 機密情報(APIキー、パスワードなど)をコードから分離
  • アクセス制御の適用が容易
  • バージョン管理からの除外が可能
# secrets.tfvars
db_password = "your-secure-password"
api_key = "your-api-key"
  1. チーム開発の効率化
  • 設定値の標準化
  • レビュープロセスの簡素化
  • 変更履歴の追跡が容易

変数定義例:

# variables.tf
variable "environment" {
  type = string
  description = "Deployment environment (dev/stg/prod)"
}

variable "instance_type" {
  type = string
  description = "EC2 instance type"
}

variable "multi_az" {
  type = bool
  description = "Enable Multi-AZ deployment"
}

このように、tfvarsファイルは環境管理、セキュリティ、チーム開発の課題を効果的に解決し、Terraformプロジェクトの基盤として重要な役割を果たします。

tfvarsファイルの基本的な使い方・設定方法

tfvarsファイルの記述ルールと命名規則

tfvarsファイルは以下のルールに従って作成します:

# 基本的な変数定義
region = "ap-northeast-1"
instance_type = "t2.micro"

# リスト型の変数
availability_zones = ["ap-northeast-1a", "ap-northeast-1c"]

# マップ型の変数
tags = {
  Environment = "production"
  Project     = "example"
  Owner       = "team-infra"
}

命名規則のベストプラクティス:

  • デフォルト設定ファイル: terraform.tfvars
  • 環境別設定ファイル: 環境名.tfvars(例:dev.tfvars, prod.tfvars
  • 機密情報用ファイル: secrets.tfvars

変数定義ファイル(variables.tf)との関係性

variables.tfでの変数定義:

# 基本的な変数定義
variable "region" {
  type        = string
  description = "AWS region for deployment"
  default     = "ap-northeast-1"  # デフォルト値(オプション)
}

# 制約付き変数定義
variable "environment" {
  type        = string
  description = "Deployment environment"
  validation {
    condition     = contains(["dev", "stg", "prod"], var.environment)
    error_message = "Environment must be dev, stg, or prod."
  }
}

# 複合型の変数定義
variable "tags" {
  type = map(string)
  description = "Resource tags"
}

tfvarsファイルの適用方法:

  1. 自動読み込み
# terraform.tfvarsは自動的に読み込まれる
terraform plan
  1. コマンドラインでの指定
# 特定のtfvarsファイルを指定
terraform plan -var-file="prod.tfvars"

# 複数のtfvarsファイルを指定
terraform plan -var-file="prod.tfvars" -var-file="secrets.tfvars"
  1. 環境変数での指定
# 環境変数で上書き
export TF_VAR_region="us-west-2"
terraform plan

優先順位(上が優先):

  1. コマンドライン引数(-var, -var-file)
  2. *.auto.tfvars(アルファベット順)
  3. terraform.tfvars
  4. 環境変数(TF_VAR_*)
  5. variables.tfのdefault値

実践で使える7つの活用テクニック

環境ごとの設定値管理(dev/stg/prod)

# dev.tfvars
environment = "dev"
instance_config = {
  type = "t2.micro"
  count = 1
  monitoring = false
}

# prod.tfvars
environment = "prod"
instance_config = {
  type = "t2.large"
  count = 3
  monitoring = true
}

機密情報の安全な管理方法

# secrets.tfvars (gitignoreに追加)
db_credentials = {
  username = "admin"
  password = "secure-password"
}

# variables.tf
variable "db_credentials" {
  type = object({
    username = string
    password = string
  })
  sensitive = true  # 機密情報としてマーク
}

配列・マップ型変数の効率的な定義

# complex-values.tfvars
vpc_config = {
  subnets = {
    public = ["10.0.1.0/24", "10.0.2.0/24"]
    private = ["10.0.3.0/24", "10.0.4.0/24"]
  }
  routes = [
    {
      cidr = "0.0.0.0/0"
      gateway_id = "igw-123"
    },
    {
      cidr = "172.16.0.0/12"
      gateway_id = "vgw-456"
    }
  ]
}

条件分岐による柔軟な設定

# variables.tf
variable "environment" {}
variable "config" {}

# main.tf
locals {
  is_production = var.environment == "prod"
  instance_count = local.is_production ? var.config.prod_count : var.config.dev_count
}

# env_config.tfvars
config = {
  prod_count = 3
  dev_count = 1
}

変数の型による安全性向上

# variables.tf
variable "instance_type" {
  type = string
  validation {
    condition = can(regex("^t[23]\\.", var.instance_type))
    error_message = "Instance type must be t2.* or t3.*"
  }
}

variable "environment" {
  type = string
  validation {
    condition = contains(["dev", "stg", "prod"], var.environment)
    error_message = "Environment must be dev, stg, or prod."
  }
}

確実な値の効果的な使用方法

# backend.tfvars
backend_config = {
  bucket = "terraform-state"
  key    = "state/terraform.tfstate"
  region = "ap-northeast-1"
  encrypt = true
}

# main.tf
terraform {
  backend "s3" {}
}

# 実行時
terraform init -backend-config=backend.tfvars

モジュール間での変数共有テクニック

# modules/network/variables.tf
variable "vpc_config" {
  type = object({
    cidr_block = string
    subnet_configs = map(object({
      cidr = string
      az = string
    }))
  })
}

# project.tfvars
vpc_config = {
  cidr_block = "10.0.0.0/16"
  subnet_configs = {
    public-1 = {
      cidr = "10.0.1.0/24"
      az = "ap-northeast-1a"
    }
    private-1 = {
      cidr = "10.0.2.0/24"
      az = "ap-northeast-1c"
    }
  }
}

# main.tf
module "network" {
  source = "./modules/network"
  vpc_config = var.vpc_config
}

tfvarsファイルのセキュリティベストプラクティス

gitignoreでの管理方法

# .gitignore
*.tfvars
!example.tfvars
!terraform.tfvars

# 環境固有の設定
**/env/*.tfvars

# 機密情報
secrets.tfvars
credentials.tfvars

環境構成例:

project/
├── .gitignore
├── main.tf
├── variables.tf
├── terraform.tfvars      # 共通設定(バージョン管理対象)
├── example.tfvars        # サンプル設定(バージョン管理対象)
├── secrets.tfvars        # 機密情報(バージョン管理対象外)
└── env/
    ├── dev.tfvars       # 開発環境設定
    ├── stg.tfvars       # ステージング環境設定
    └── prod.tfvars      # 本番環境設定

暗号化による機密情報の保護

  1. AWS KMSを使用した暗号化
# KMS用のTerraform設定
resource "aws_kms_key" "terraform_key" {
  description = "KMS key for Terraform secrets"
  enable_key_rotation = true

  tags = {
    Environment = "shared"
    Purpose     = "terraform-secrets"
  }
}

# 暗号化されたシークレットの管理
data "aws_kms_secrets" "creds" {
  secret {
    name    = "db"
    payload = file("${path.module}/secrets/encrypted-db-creds.base64")
  }
}
  1. HashiCorp Vaultとの統合
provider "vault" {
  address = "https://vault.example.com:8200"
}

data "vault_generic_secret" "db_creds" {
  path = "secret/database/credentials"
}

locals {
  db_username = data.vault_generic_secret.db_creds.data["username"]
  db_password = data.vault_generic_secret.db_creds.data["password"]
}

アクセス制御と監査ログの設定

  1. AWS IAMポリシー例
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::terraform-state-bucket/tfvars/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/Team": "infrastructure"
        }
      }
    }
  ]
}
  1. CloudTrail監査設定
resource "aws_cloudtrail" "terraform_audit" {
  name                          = "terraform-tfvars-audit"
  s3_bucket_name               = aws_s3_bucket.audit_logs.id
  include_global_service_events = true
  is_multi_region_trail        = true

  event_selector {
    read_write_type           = "WriteOnly"
    include_management_events = true

    data_resource {
      type = "AWS::S3::Object"
      values = ["${aws_s3_bucket.tfvars_bucket.arn}/"]
    }
  }
}

セキュリティチェックリスト:

  • [ ] 機密情報を含むtfvarsファイルはgitignoreに追加
  • [ ] 暗号化メカニズムの導入(KMSまたはVault)
  • [ ] 最小権限原則に基づくIAMポリシーの設定
  • [ ] アクセスログの有効化と監査体制の確立
  • [ ] 定期的なシークレットローテーション
  • [ ] バックアップと復旧手順の確立

よくあるトラブルと解決方法

ファイル読み込みエラーの対処法

  1. ファイルパスの問題
Error: Failed to read variables file

解決方法:

# 相対パスの場合
terraform plan -var-file="../env/prod.tfvars"

# 絶対パスの場合
terraform plan -var-file="/path/to/prod.tfvars"
  1. 構文エラー
# 誤った記述
instance_type: "t2.micro"  # YAMLライクな構文

# 正しい記述
instance_type = "t2.micro"  # HCL構文

変数の型変換に関する問題解決

  1. 型の不一致
# variables.tf
variable "instance_count" {
  type = number
}

# prod.tfvars(エラー)
instance_count = "3"  # 文字列として指定

# prod.tfvars(正しい)
instance_count = 3    # 数値として指定
  1. 複合型のエラー
# variables.tf
variable "vpc_config" {
  type = object({
    cidr_block = string
    public_subnets = list(string)
  })
}

# 誤った指定
vpc_config = {
  cidr_block = "10.0.0.0/16"
  public_subnets = "10.0.1.0/24"  # 文字列を指定
}

# 正しい指定
vpc_config = {
  cidr_block = "10.0.0.0/16"
  public_subnets = ["10.0.1.0/24"]  # リストとして指定
}

複数環境でのコンフリクトの防止

  1. ワークスペースの活用
# 環境別のワークスペース作成
terraform workspace new dev
terraform workspace new prod

# ワークスペースの切り替え
terraform workspace select dev
terraform plan -var-file="dev.tfvars"
  1. バックエンド設定の分離
# backend.tf
terraform {
  backend "s3" {
    bucket = "terraform-state"
    key    = "${terraform.workspace}/terraform.tfstate"
    region = "ap-northeast-1"
    dynamodb_table = "terraform-locks"
  }
}

トラブルシューティングチェックリスト:

  1. tfvarsファイルの構文チェック
  • HCL形式の検証
  • クォートの使用確認
  • カンマの位置確認
  1. 変数型の確認
  • variables.tfでの型定義確認
  • tfvarsでの値の型確認
  • 必要な型変換の実施
  1. 環境分離の確認
  • ワークスペース設定
  • バックエンド構成
  • 状態ファイルの分離
  1. エラーメッセージの確認
   # デバッグモードでの実行
   TF_LOG=DEBUG terraform plan
  1. よくある解決方法
  • terraformの再初期化(terraform init)
  • プロバイダーのキャッシュクリア
  • ワークスペースの確認と切り替え
  • バックエンド設定の確認