【ツール活用|実務向け】TerraformのCIで守るべきセキュリティ:Open Policy Agent (OPA) とRegoによるIaCガードレール実装術

1. 導入:なぜIaCにPolicy as Codeが必要なのか

クラウドインフラがコード化(IaC)された現代において、手動でのセキュリティチェックはもはや限界です。特にTerraform等の構成ミスにより、「S3バケットが意図せず公開される」「必要なタグが付与されていない」といったインシデントは後を絶ちません。Policy as Code(PaC)を導入することで、これら「守るべきルール」を自動化し、CIパイプラインの段階で構成ミスを検知・ブロックすることが可能になります。本記事では、OPAとRegoを用いた実務的な実装方法を解説します。

2. 基礎知識:OPAとRegoとは

Open Policy Agent (OPA) は、あらゆるスタックでポリシーを適用するためのオープンソースの汎用エンジンです。そして、そのポリシーを記述するための言語が Rego です。Regoは宣言型の言語であり、JSONやTerraformの計画ファイル(plan)を入力として受け取り、ポリシーに合致しているかを判定します。イメージとしては、「インフラ構成ファイルに対するユニットテスト」を書く感覚に近いです。

3. 実装・解決策:Terraformのプランを検証する

OPAでTerraformを検証する一般的なフローは以下の通りです。
1. Terraformの構成を `terraform plan -out=tfplan.binary` でバイナリ化する。
2. `terraform show -json tfplan.binary` でJSON形式に変換する。
3. OPAエンジンにJSONとRegoポリシーを渡し、検証を実行する。
このプロセスをGitHub ActionsやGitLab CIに組み込むことで、ルール違反があればデプロイを強制停止させることができます。

4. サンプルプログラム:S3バケットのパブリックアクセスを禁止する

以下は、S3バケットがパブリックアクセスを許可していないか(`acl`が`public-read`等になっていないか)を判定するRegoコードの例です。

package terraform.security

入力データ(tfplanのJSON)からリソースを取得
import input as tfplan

デフォルトでは「許可」とする(必要に応じてポリシーによる)
default allow = false

S3バケットのリソースを抽出
s3_buckets = [res |
res := tfplan.resource_changes[_]
res.type == “aws_s3_bucket”
]

ポリシー違反の定義:aclがpublic-readやpublic-read-writeになっている場合
deny[msg] {
bucket := s3_buckets[_]
# 設定値の変更がある場合にチェック
acl := bucket.change.after.acl
bad_acls := {“public-read”, “public-read-write”}
bad_acls[acl]

msg := sprintf(“警告: バケット %s はパブリックアクセスが許可されています。”, [bucket.address])
}

違反がなければallowをtrueにする
allow {
count(deny) == 0
}

5. 応用・注意点:現場で陥りやすい罠

注意点1:TerraformのバージョンとJSON構造
`terraform show -json` の出力形式は、Terraformのバージョンによって微妙に異なる場合があります。CIで利用する際は、TerraformとOPAのバージョンを固定しておくことが重要です。

注意点2:ルールを厳しくしすぎない
最初から全てのルールを適用しようとすると、CIが落ち続けて開発体験が低下します。まずは「S3の暗号化」や「公開制限」といった、クリティカルな項目から導入し、徐々にルールを拡大する「段階的導入」を強く推奨します。

注意点3:テストコードを併用する
Rego自体もプログラムであるため、ロジックのバグが発生します。Regoにはテスト機能(`opa test`)が備わっているため、ポリシーを書く際は必ずユニットテストを併記し、ポリシー自体が正しく判定できることを確認してください。

コメント

タイトルとURLをコピーしました