★★★ 上級

13. check と precondition / postcondition

「想定外の値で apply された」「作ったあとに API レスポンスが期待と違う」を plan の段階で止める 仕組み。Terraform 1.5+ で本格化したアサーション機能。

3 つのアサーション

Terraform で「条件を満たしているか確認する」場所は 3 種類:

場所タイミング失敗したら
variable.validation変数受け取り時plan エラー
lifecycle.preconditionresource の plan 直前plan エラー
lifecycle.postconditionresource の apply 後apply エラー
check ブロックplan / apply の最後(独立)warning(停止せず)

variable validation(おさらい)

03 章で扱った変数の値検証:

variable "environment" {
  type = string
  validation {
    condition     = contains(["dev", "stg", "prd"], var.environment)
    error_message = "environment は dev / stg / prd のいずれか。"
  }
}

lifecycle.precondition

「このリソースを作る前に、これが満たされていなければ止めて」を書く。複数 resource をまたいだチェックに有用。

data "aws_ami" "al2023" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.al2023.id
  instance_type = "t3.micro"

  lifecycle {
    precondition {
      condition     = data.aws_ami.al2023.architecture == "x86_64"
      error_message = "x86_64 アーキテクチャの AMI を使ってください。"
    }
    precondition {
      condition     = var.environment != "prd" || var.instance_type != "t3.micro"
      error_message = "prd 環境で t3.micro は使用禁止。"
    }
  }
}

lifecycle.postcondition

「作った直後に self. でこれが期待通りか確認して」

resource "aws_instance" "web" {
  ami                    = data.aws_ami.al2023.id
  instance_type          = "t3.micro"
  associate_public_ip_address = true

  lifecycle {
    postcondition {
      condition     = self.public_dns != ""
      error_message = "Public DNS が割り当てられていません。"
    }
  }
}

resource "aws_lb" "main" {
  # ...
  lifecycle {
    postcondition {
      condition     = self.dns_name != null && length(self.dns_name) > 0
      error_message = "ALB の DNS 名が取得できませんでした。"
    }
  }
}

check ブロック(1.5+)

Terraform 1.5 で追加。resource とは独立した独自のチェック。失敗しても apply は止まらず 警告として表示。継続的な健全性チェック向け。

check "site_is_up" {
  data "http" "site" {
    url = "https://${var.domain_name}"
  }

  assert {
    condition     = data.http.site.status_code == 200
    error_message = "サイトが 200 を返しません: ${data.http.site.status_code}"
  }
}

check "cert_not_expiring_soon" {
  data "tls_certificate" "site" {
    url = "https://${var.domain_name}"
  }

  assert {
    condition = alltrue([
      for c in data.tls_certificate.site.certificates :
      timecmp(plantimestamp(), timeadd(c.not_after, "-30d")) < 0
    ])
    error_message = "証明書の有効期限が 30 日以内に迫っています。"
  }
}

これらは terraform plan / apply 実行時に毎回評価され、失敗時は plan の最後に Warning: Check block assertion failed として出ます。

使い分け

シナリオ使うもの
変数の値範囲を縛るvariable.validation
このリソースを作る前提条件precondition
作った結果が期待通りかpostcondition
サービスの稼働状態を継続監視check
失敗で apply を止めたいvalidation / pre / postcondition
失敗を警告として伝えたいcheck
HCL セクション完了 お疲れ様でした。次は AWS セクション で具体的なリソースを書いていきます。