最近の記事

環境間でパラメータ値が異なる場合にvariableブロックを使用する

ルール

Use variable blocks when parameter values differ between environments (e.g., production → CPU 4096, development → CPU 1024).

(環境間でパラメータ値が異なる場合にvariableブロックを使用する(例: 本番環境 → CPU 4096、開発環境 → CPU 1024))

解説

生成AIはvariable blocksを必要もなく使いたがる傾向があるため、濫用を禁止しています。しかし全く使わないとそれはそれでおかしなコードができあがるため、利用して良いケースを明示しています。

サンプルコード

# variables.tf
variable "cpu_units" {
  type        = number
  description = "CPU units for ECS task"
}

Infrastructure 開発ガイドライン Coding Standards

variableブロックに型定義を含める

ルール

Include type definitions in variable blocks.

(variableブロックに型定義を含める)

解説

AWSの推奨に従っています。

変数に型を明示することで誤った値の代入を防ぐ他、変数の性格を推測しやすくなります。

サンプルコード

# variables.tf
variable "environment" {
  type        = string
  description = "Environment name"
}

variable "instance_count" {
  type        = number
  description = "Number of instances to create"
}

参考リンク

Infrastructure 開発ガイドライン Coding Standards

環境間で同一の値には変数ブロックを使用しない

ルール

Do not use variable blocks for values that remain the same across environments.

(環境間で同一の値には変数ブロックを使用しない)

解説

生成AIはvariable blocksを必要もなく使いたがる傾向があるため、濫用を禁止しています。

サンプルコード

# 全環境で同じ値は直接記述
resource "aws_ecs_task_definition" "main" {
  family                   = "api"
  network_mode             = "awsvpc"  # 全環境で同じ
  requires_compatibilities = ["FARGATE"]  # 全環境で同じ

  # 環境ごとに異なる値のみ変数化
  cpu    = var.cpu_size
  memory = var.memory_size
}

Infrastructure 開発ガイドライン Coding Standards

変数ブロックは厳密に必要な場合のみ使用する

ルール

Do not use variable blocks unless strictly necessary. They may be used only when there are actual parameter differences between environments (e.g., development vs. production).

(変数ブロックは厳密に必要な場合のみ使用する。環境間で実際にパラメータ差異がある場合(例:開発環境と本番環境)にのみ使用可能)

解説

生成AIはvariable blocksを必要もなく使いたがる傾向があるため、濫用を禁止しています。

ただし環境ごとに異なる値(CPUサイズ、インスタンス数など)を表現するためには必要ですから、全面禁止にはしていません。

サンプルコード

# 開発環境と本番環境でCPUサイズが異なる場合のみ変数化
variable "cpu_size" {
  type        = number
  description = "ECS task CPU size"
}

resource "aws_ecs_task_definition" "main" {
  family = "api"
  cpu    = var.cpu_size  # 環境により 512 または 2048
  memory = 1024

  # その他の固定値は直接記述
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
}

Infrastructure 開発ガイドライン Coding Standards

variableとoutputブロックにdescriptionを含める

ルール

Include descriptions in variable and output blocks.

(variableとoutputブロックにdescriptionを含めること)

解説

変数と出力値に説明を付けることで、各パラメータの目的を誤解しづらくなります。人間も助かりますが、なによりAIの助けになります。

サンプルコード

# variables.tf
variable "instance_type" {
  type        = string
  description = "EC2 instance type for application servers"
}

参考リンク

Infrastructure 開発ガイドライン Coding Standards

variableブロックにdefault値を設定しない

ルール

Do not set default values in variable blocks.

(variableブロックにdefault値を設定しない)

解説

デフォルト値があると設定漏れに気づかずに意図しない値でインフラが構築されることがあります。

ほんの少し楽をしようとして事故を起こすのは割に合わないため、全面的に禁止しています。

サンプルコード

# variables.tf (良い例)
variable "instance_type" {
  type        = string
  description = "EC2 instance type"
  # defaultは設定しない
}

Infrastructure 開発ガイドライン Coding Standards

variableブロックの属性順序を統一する

ルール

The order of variable block attributes should be as follows: 1. Type, 2. Description, 3. Default (optional), 4. Sensitive (optional), 5. Validation blocks

(variableブロックの属性順序は次の通り: 1. type、2. description、3. default(オプション)、4. sensitive(オプション)、5. validationブロック)

解説

HashiCorp公式の推奨に従っています。

統一された記述順序は可読性を向上させます。

サンプルコード

variable "instance_type" {
  type        = string
  description = "EC2インスタンスタイプ"
  default     = "t3.micro"

  validation {
    condition     = can(regex("^t3\\.", var.instance_type))
    error_message = "インスタンスタイプはt3系を指定してください"
  }
}

variable "db_password" {
  type        = string
  description = "データベースパスワード"
  sensitive   = true
}

参考リンク

Infrastructure 開発ガイドライン Coding Standards

リソースブロック属性の順序を統一する

ルール

The order of resource block attributes should be as follows: 1. If present, The count or for_each meta-argument, 2. Resource-specific non-block parameters, 3. Resource-specific block parameters, 4. If required, a lifecycle block, 5. If required, the depends_on parameter. No other constraints apply.

(リソースブロック属性の順序は以下の通りとする:1. 存在する場合、countまたはfor_eachメタ引数、2. リソース固有の非ブロックパラメータ、3. リソース固有のブロックパラメータ、4. 必要な場合、lifecycleブロック、5. 必要な場合、depends_onパラメータ。その他の制約は適用しない)

解説

Terraform公式スタイルガイドに従っています。

決めの問題ですが、ある程度フォーマットされているだけでも読みやすさが上がります。

サンプルコード

resource "aws_instance" "web" {
  # 1. メタ引数
  count = var.instance_count

  # 2. 非ブロックパラメータ
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t4g.micro"
  subnet_id     = aws_subnet.main.id

  # 3. ブロックパラメータ
  tags = {
    Name = "web-server-${count.index}"
  }

  # 4. lifecycle
  lifecycle {
    create_before_destroy = true
  }

  # 5. depends_on
  depends_on = [aws_security_group.web]
}

参考リンク

Infrastructure 開発ガイドライン Coding Standards

出力ブロックで変数ブロックを参照しない

ルール

Do not reference variable blocks as values in output blocks.

(出力ブロックで変数ブロックを参照しない)

解説

AWSの推奨に従っています。

出力ブロックに変数をそのまま格納するのは無駄ですから普通しないと思いますが、念のため残しています。

サンプルコード(悪い例)

variable "name" {
  description = "Resource name"
  type = string
}

output "name" {
  description = "Name of Resource"
  value       = var.name
}

参考リンク

Infrastructure 開発ガイドライン Coding Standards

他モジュールの呼び出しはmain.tfに定義する

ルール

Define calls to other modules in main.tf.

(他モジュールの呼び出しはmain.tfに定義する)

解説

AWSの推奨に従っています。

モジュール呼び出しは必ずmain.tfにある、とわかっていれば、モジュールの呼び出し部分を迷わず見つけることが可能です。

サンプルコード

# main.tf
module "networking" {
  source = "./modules/networking"
  vpc_cidr = var.vpc_cidr
}

module "database" {
  source = "./modules/database"
  vpc_id = module.networking.vpc_id
  db_subnet_ids = module.networking.private_subnet_ids
}

module "application" {
  source = "./modules/application"
  vpc_id = module.networking.vpc_id
  db_endpoint = module.database.endpoint
}

参考リンク

Infrastructure 開発ガイドライン Coding Standards