はじめに
IaC(Infrastructure as Code)時代におけるインフラ統制では、「誰が何をどこまで作ってよいか」を定義するPolicy as Code(PaC)の導入が欠かせません。Terraformでのポリシー制御には以下の2つが主要手段となります:
- Sentinel:Terraform Enterprise / Cloud専用のポリシーエンジン
- OPA(Open Policy Agent) + Rego:汎用性の高いOSSポリシーエンジン
本記事では、両者のアーキテクチャ・適用範囲・メリット/デメリットを比較した上で、OPA + Regoによる複雑なTerraformポリシーの記述例も紹介します。
1. SentinelとOPA(Rego)の比較一覧
| 比較項目 | Sentinel | OPA(Rego) |
|---|---|---|
| 開発元 | HashiCorp(Terraform専用) | CNCF / OSS(汎用) |
| 言語 | Sentinel DSL(独自) | Rego(宣言的ポリシー言語) |
| Terraformとの統合 | Terraform Cloud / Enterprise にネイティブ統合 | 外部ツール(terraform plan -out tfplan.json → conftest で評価) |
| 実行環境 | TFC / TFE 専用 | ローカルCI/CD、GitHub Actions、OPAサーバーなど柔軟 |
| 導入の難易度 | 中(有料TFC環境が必要) | 低〜中(OSS。導入容易) |
| 拡張性 / 再利用性 | 中(TFC内で制限) | 高(KubernetesやCI/CDにも流用可) |
| エコシステム | Terraform専用 | Terraform / K8s / API Gateway / CI全般 |
2. SentinelとOPAはどちらを選ぶべきか?
Sentinelを選ぶケース
- Terraform Cloud / Enterprise をすでに使っている
- Terraformだけに特化したガバナンスを必要としている
- GUIでのルール適用やワークスペース連携を重視
OPA(Rego)を選ぶケース
- OSSで完結させたい
- CI/CDパイプラインでTerraformを使っている
- Kubernetesや他のポリシー制御にも拡張したい
結論としては、Terraform Cloud ユーザーなら Sentinel、CIやマルチプラットフォームで一貫管理したいならOPA + Regoが推奨されます。
3. OPA / RegoによるTerraformポリシーの実装
準備:tfplanファイルをJSON出力
# Terraform plan を JSON にエクスポート terraform plan -out=tfplan.binary terraform show -json tfplan.binary > tfplan.json
ポリシー適用:conftestを使ってRego評価
# conftestをインストール(Mac例) brew install conftest # Regoファイルを用意し、tfplanに適用 conftest test tfplan.json
4. Regoによる複雑ポリシー実装例
① コスト制御:t3.micro以外のEC2インスタンスは禁止
# policy/instance_type.rego package terraform.ec2 deny[msg] { resource := input.resource_changes[_] resource.type == "aws_instance" instance_type := resource.change.after.instance_type not instance_type == "t3.micro" msg := sprintf("許可されていないインスタンスタイプ: %v", [instance_type]) }
② タグチェック:Project, Owner, Environmentが必須
# policy/tags.rego package terraform.tags required_tags := ["Project", "Owner", "Environment"] deny[msg] { resource := input.resource_changes[_] resource.change.after.tags != null missing := [t | t := required_tags[_]; not resource.change.after.tags[t]] count(missing) > 0 msg := sprintf("タグが不足しています: %v", [missing]) }
③ 環境ごとにインスタンスタイプを制限(動的条件)
# policy/env_type.rego package terraform.env_restriction deny[msg] { resource := input.resource_changes[_] resource.type == "aws_instance" env := resource.change.after.tags["Environment"] instance := resource.change.after.instance_type env == "dev" not instance == "t3.micro" msg := "dev 環境では t3.micro のみ許可されています。" }
④ 日時ベース制御:業務時間外はapply禁止(例)
# policy/time_control.rego package terraform.time deny[msg] { t := time.now_ns() / 1000000000 weekday := time.weekday(t) hour := time.hour(t) weekday >= 1 # 月〜金 weekday <= 5 hour >= 20 # 20時以降 msg := "業務時間外の apply は許可されていません。" }
※ 実際のCI環境で time.now_ns() を使用するには、OPA/Conftestのオプションで明示的に許可設定が必要です。
5. CI/CDパイプラインでのOPA活用例(GitHub Actions)
# .github/workflows/terraform.yml jobs: terraform-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Terraform uses: hashicorp/setup-terraform@v1 - name: Terraform Init & Plan run: | terraform init terraform plan -out=tfplan.binary terraform show -json tfplan.binary > tfplan.json - name: Run OPA Policy Check run: | wget https://github.com/open-policy-agent/conftest/releases/download/v0.37.0/conftest_0.37.0_Linux_x86_64.tar.gz tar -xzf conftest_0.37.0_Linux_x86_64.tar.gz ./conftest test tfplan.json
このように、OPAはあらゆるCI環境に組み込むことができ、柔軟なポリシー適用が可能です。
まとめ
ポリシー制御は、クラウド時代のインフラ運用における「組織ルールの自動化」の中核です。TerraformにおけるPolicy as Codeの選択肢として、SentinelとOPAの両方を理解し、用途に応じた選定が求められます。
- Sentinel:Terraform Cloudに特化した一体型ガバナンス
- OPA / Rego:マルチCI環境や他クラウドサービスと統一管理
- Regoでは、日時・タグ・環境・コストなど複雑な条件も柔軟に対応可能
次章では、OPA Gatekeeperを使ったKubernetesリソースへの同様のポリシー制御について解説予定です。Terraformだけでなく、クラウドネイティブ全体のガバナンスを統一的に設計しましょう。