mcpField
T
terraform-style-guide

terraform-style-guide

github.com/midudevクラウド・DevOps7.0k57 回インストール1 週間前に更新
リポジトリ

terraform-style-guide について

HashiCorpの規約に沿ってTerraformコードを作成・保守するためのスタイルガイドです。ファイル構成、書式、命名、変数、バージョン制約、レビュー項目を説明します。

主な機能

  1. 01標準的なTerraformファイル構成
  2. 02書式とブロック順序の指針
  3. 03リソースと変数の命名規則
  4. 04変数と出力の説明要件
  5. 05バージョン固定とstateファイル保護
  6. 06コミット前の検証チェックリスト

活用シーン

  1. 01一貫したTerraformプロジェクト構成の作成
  2. 02生成されたインフラ設定のレビュー
  3. 03Terraform変更のコミット準備
  4. 04スタイル規約に沿った設定確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/midudev/autoskills --skill terraform-style-guide

インストール後、Claude Code で/terraform-style-guideを入力して読み込まれたか確認します。

同梱ファイルSECURITY.md

詳細

Terraform スタイルガイド

HashiCorp の公式スタイル規約とベストプラクティスに従って Terraform コードを生成・保守します。

参考資料: HashiCorp Terraform Style Guide

コード生成戦略

Terraform コードを生成する際は、次の手順に従います。

  1. プロバイダーの設定とバージョン制約から始めます
  2. 依存するリソースより先にデータソースを作成します
  3. 依存関係の順序に従ってリソースを構築します
  4. 主要なリソース属性の出力を追加します
  5. 設定可能な値にはすべて変数を使用します

ファイル構成

ファイル用途
terraform.tfTerraform とプロバイダーのバージョン要件
providers.tfプロバイダーの設定
main.tf主要なリソースとデータソース
variables.tf入力変数の宣言(アルファベット順)
outputs.tf出力値の宣言(アルファベット順)
locals.tfローカル値の宣言
構成例
# terraform.tf
terraform {
  required_version = ">= 1.14"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

# variables.tf
variable "environment" {
  description = "Target deployment environment"
  type        = string

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

# locals.tf
locals {
  common_tags = {
    Environment = var.environment
    ManagedBy   = "Terraform"
  }
}

# main.tf
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true

  tags = merge(local.common_tags, {
    Name = "${var.project_name}-${var.environment}-vpc"
  })
}

# outputs.tf
output "vpc_id" {
  description = "ID of the created VPC"
  value       = aws_vpc.main.id
}

コードの書式設定

インデントと位置合わせ
  • ネストの各レベルで半角スペース 2 つを使用します(タブは使用しません)
  • 連続する引数の等号の位置を揃えます
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = "subnet-12345678"

  tags = {
    Name        = "web-server"
    Environment = "production"
  }
}
ブロックの構成

引数をブロックより先に記述し、メタ引数を最初に配置します。

resource "aws_instance" "example" {
  # Meta-arguments
  count = 3

  # Arguments
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  # Blocks
  root_block_device {
    volume_size = 20
  }

  # Lifecycle last
  lifecycle {
    create_before_destroy = true
  }
}

命名規則

  • すべての名前に小文字とアンダースコアを使用します
  • リソースタイプを含めず、内容を具体的に表す名詞を使用します
  • 具体的で意味のある名前を付けます
  • リソース名は複数形ではなく単数形にします
  • 具体的でわかりやすい名前が不要、または使用できないリソースでは、インスタンスが 1 つだけ存在することを条件に、既定で main を使用します
# Bad
resource "aws_instance" "webAPI-aws-instance" {}
resource "aws_instance" "web_apis" {}
variable "name" {}

# Good
resource "aws_instance" "web_api" {}
resource "aws_vpc" "main" {}
variable "application_name" {}

変数

すべての変数には type と description を指定します。

variable "instance_type" {
  description = "EC2 instance type for the web server"
  type        = string
  default     = "t2.micro"

  validation {
    condition     = contains(["t2.micro", "t2.small", "t2.medium"], var.instance_type)
    error_message = "Instance type must be t2.micro, t2.small, or t2.medium."
  }
}

variable "database_password" {
  description = "Password for the database admin user"
  type        = string
  sensitive   = true
}

出力

すべての出力には description を指定します。

output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.web.id
}

output "database_password" {
  description = "Database administrator password"
  value       = aws_db_instance.main.password
  sensitive   = true
}

動的なリソース作成

count より for_each を優先する
# Bad - count for multiple resources
resource "aws_instance" "web" {
  count = var.instance_count
  tags  = { Name = "web-${count.index}" }
}

# Good - for_each with named instances
variable "instance_names" {
  type    = set(string)
  default = ["web-1", "web-2", "web-3"]
}

resource "aws_instance" "web" {
  for_each = var.instance_names
  tags     = { Name = each.key }
}
条件付き作成には count を使用する
resource "aws_cloudwatch_metric_alarm" "cpu" {
  count = var.enable_monitoring ? 1 : 0

  alarm_name = "high-cpu-usage"
  threshold  = 80
}

セキュリティのベストプラクティス

SECURITY.md を参照してください。リソースの暗号化、状態ファイルへの機密データの保存防止、安全な設定に関するガイダンスが記載されています。

バージョンの固定

terraform {
  required_version = ">= 1.14"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

依存関係ロックファイルまたは設定で使用する他のモジュールによる制約がない限り、各プロバイダーの最新メジャーバージョンと、Terraform の最新マイナーバージョンを使用します。

バージョン制約の演算子:

  • = 1.0.0 - 完全一致
  • >= 1.0.0 - 以上
  • ~> 1.0 - 最も右のコンポーネントの増加を許可
  • >= 1.0, < 2.0 - バージョン範囲

プロバイダーの設定

provider "aws" {
  region = "us-west-2"

  default_tags {
    tags = {
      ManagedBy = "Terraform"
      Project   = var.project_name
    }
  }
}

# Aliased provider for multi-region
provider "aws" {
  alias  = "east"
  region = "us-east-1"
}

バージョン管理

コミットしないもの:

  • terraform.tfstate、terraform.tfstate.backup
  • .terraform/ ディレクトリ
  • *.tfplan
  • 機密データを含む .tfvars ファイル

必ずコミットするもの:

  • すべての .tf 設定ファイル
  • .terraform.lock.hcl(依存関係ロックファイル)

検証ツール

コミット前に実行します。

terraform fmt -recursive
terraform validate

その他のツール:

  • tflint - リントとベストプラクティスの確認
  • checkov / tfsec - セキュリティスキャン

コードレビューのチェックリスト

  • terraform fmt でコードをフォーマット済み
  • terraform validate で設定を検証済み
  • 標準の構成に従ってファイルを整理済み
  • すべての変数に型と説明を指定済み
  • すべての出力に説明を指定済み
  • リソース名にアンダースコアを含む説明的な名詞を使用済み
  • バージョン制約を明示的に固定済み
  • 機密値に sensitive = true を指定済み
  • ハードコードされた認証情報やシークレットがない
  • セキュリティのベストプラクティスを適用済み

参考資料:HashiCorp Terraform Style Guide

コメント