OPA/ConftestによるTerraformポリシー管理

1. 概要

  • OPA(Open Policy Agent)とConftestとは
  • Sentinelの無料版代替としての活用
  • Regoポリシー言語の基本
  • Conftestでterraform planをチェックする方法

OPA(Open Policy Agent)はCloud Native Computing Foundation(CNCF)のポリシーエンジンです。Conftestは、OPAのRegoポリシーでTerraform planの出力などをチェックするCLIツールです。Sentinel(Terraform Cloud Plus)の代替としてOSSで使えます。


2. ConftestとOPAのインストール

# macOSの場合(Homebrew)
brew install conftest

# 確認
conftest --version

# OPA単体のインストール(任意)
brew install opa

3. Regoポリシーの基本構文

# policy/terraform.rego

package main

# EBSが暗号化されていることを確認するルール
deny[msg] {
  # terraform planのJSON出力から対象リソースを取得
  resource := input.resource_changes[_]
  resource.type == "aws_instance"
  resource.change.actions[_] == "create"

  # root_block_deviceのencryptedがfalseまたは未設定
  not resource.change.after.root_block_device[0].encrypted

  msg := sprintf(
    "DENY: %s のEBSが暗号化されていません(encrypted = true が必要)",
    [resource.address]
  )
}

# 必須タグを確認するルール
required_tags := ["Name", "Environment", "ManagedBy"]

deny[msg] {
  resource := input.resource_changes[_]
  resource.mode == "managed"
  resource.change.actions[_] == "create"

  # 必須タグのうち1つでも欠けている場合
  tag := required_tags[_]
  not resource.change.after.tags[tag]

  msg := sprintf(
    "DENY: %s にタグ '%s' が設定されていません",
    [resource.address, tag]
  )
}

4. Conftestでのチェック手順

# Step 1: terraform planをJSON出力する
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json

# Step 2: Conftestでポリシーチェック
conftest test tfplan.json -p policy/

# 出力例(問題がある場合)
# FAIL - tfplan.json - main - DENY: aws_instance.web のEBSが暗号化されていません

# 出力例(全ポリシーPASS)
# 1 test, 0 failures

5. チェック対象のTerraformコード

terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

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

# ConftestのRegoポリシーがチェックするリソース
resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true  # ← Regoポリシーで確認
  }

  tags = {
    Name        = "${var.environment}-web"  # ← 必須タグ
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

6. GitHub ActionsへのCI統合

# .github/workflows/opa-policy.yml
name: OPA Policy Check

on:
  pull_request:
    branches: [main]

permissions:
  id-token: write
  contents: read

jobs:
  opa-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
          aws-region: ap-northeast-1

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: "~> 1.9"

      - name: Install Conftest
        run: |
          curl -sSL https://github.com/open-policy-agent/conftest/releases/download/v0.55.0/conftest_0.55.0_Linux_x86_64.tar.gz | tar xz
          sudo mv conftest /usr/local/bin/

      - name: Terraform Init & Plan (JSON)
        run: |
          terraform init
          terraform plan -out=tfplan
          terraform show -json tfplan > tfplan.json

      - name: Run OPA Policy Check
        run: conftest test tfplan.json -p policy/

7. Sentinelとの比較

比較軸Sentinel(TF Cloud)OPA/Conftest
コストTF Cloud Plus以上無料(OSS)
ポリシー言語Sentinel言語Rego
実行タイミングplan後(TF Cloud側)plan後(CI/CD側)
学習コスト中〜高(Regoの学習が必要)
GitHub Actions統合別途設定が必要容易

8. 関連記事


9. まとめ

  • OPA/Conftestを使うとSentinal相当のPolicy as CodeをOSSで実現できる
  • terraform show -jsonでterraform planをJSON出力し、Regoポリシーでチェックする
  • 必須タグ・EBS暗号化・インスタンスタイプ制限などのポリシーをRegoで自由に書ける
  • SentinelはTF Cloud Plusが必要だが、OPA/ConftestはGitHub ActionsなどどのCI/CDでも動く

対象バージョン: OPA v0.60+ / Conftest v0.55+ / Terraform >= 1.9 公式ドキュメント: https://www.openpolicyagent.org/ / https://www.conftest.dev/