mcpField
T
terraform-style-guide

terraform-style-guide

github.com/hashicorpクラウド・DevOps90912.7k 回インストール今日更新
リポジトリ

terraform-style-guide について

terraform-style-guide は、HashiCorp の規約に沿った Terraform 設定の生成と保守を支援するスキルです。ファイル構成、書式、命名、検証やセキュリティの実践方法を Terraform の作成者向けにまとめています。

主な機能

  1. 01Terraform の標準ファイル構成
  2. 02書式と命名の規約
  3. 03変数と出力の要件
  4. 04リソース作成の指針
  5. 05バージョンとセキュリティの指針
  6. 06検証とレビューのチェックリスト

活用シーン

  1. 01Terraform 設定の書き始め
  2. 02コミット前の Terraform コード確認
  3. 03リソース名と変数名の統一

インストール

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

$npx skills add https://github.com/hashicorp/agent-skills --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

コメント