GCP連載の6回目です。今回はTerraform Validatorを使って、組織のセキュリティポリシーの自動チェックを継続的に行う方法を紹介します。併せて、ポリシーをコードとして管理する方法も紹介します。Policy as code です。もちろんセキュリティポリシーのみだけではなく、命名規則やリージョン制限なども扱えます。
Infrastructure as code 理想と現実
Infrastructure as code (以下 IaC)、ここ最近大分一般的になってきました。弊社でも大半のプロジェクトは導入しています。3年前とかに導入するために一苦労していた時代が懐かしい..
IaCが当たり前になった今、インフラの構成管理はもう問題ないかというとそうではありません。特にプロジェクト数がスケールする場合、以下のような問題が発生してしまっているのではないでしょうか。
- 各チームに権限を委譲しインフラを管理してもらうが、組織のポリシーに反したリソースが作成されてしまう
- そもそも組織のポリシーが定義・明文化できていない
- できていても周知できない、周知できていても、守ってもらえない
例えば、”GCSのバケットを全世界に公開してしまっている” という誤った設定も本番環境にデプロイされてしまうかもしれません。
GCPだけではなく、多くのクラウド管理者が同じような悩みを抱えているかと思います。私もその一人です。各チームの開発者がクラウドインフラに熟知しているわけではありません。では、クラウド管理者がすべてソースコードをレビューすればよいか、いやいや、それも現実的ではない。
IaCがアプリケーション開発やっと同じ土俵に立った今、同じく CI(継続的インテグレーション) の仕組みが必要になってくるのは、自然の流れかと思います。terraform fmtがされているか、planが通るか、等の簡単なチェックをやっている人は多いと思いますが、それよりも高度なチェックを行う仕組みがなく私も方法を探しておりました。
Terraform Validator とは
これを実現するのが、今回紹介する Terraform Validator です。Terraform Validatorは、 terraformがapplyされる前に、インフラのリソース設定が定義したポリシーに従っているかをチェックできるツールです。GCPのオープンソースとして公開されています。 GoogleCloudPlatform/terraform-validator
以下が概要の図です。
仕組みはごく単純です
- Policy をソースコード(yaml)として定義
- Terraformのplanの結果(json)を生成
- Terraform Validatorに読み込みさせ、チェック結果を出力
ポリシーに反したリソースがterraformで定義された場合、以下のように Found Violations
と出力されます。 (以下のサンプルは、GCSのロケーションが許可されていないリージョンを利用している)
# Sample |
ハンズオン
ではさっそく、実際に試してみます。**”GCSのロケーションに制限をかける”** シンプルなパターンで試してみます。以下のようにフォルダ構成を用意し、2つのファイルを作成しました。
storage_location.yaml
: (ポリシーを定義するコード)main.tf
: (terraformのコード)
Terraform Validator インストール
バイナリファイルがGCSで公開されているので、最新版をダウンロードし適当なパスに配置
gsutil ls -r gs://terraform-validator/releases |
Policyを定義
PolicyをGit cloneし、POLICY_PATH
を定義
git clone https://github.com/forseti-security/policy-library.git |
Sampleからファイルをコピーし、ポリシーを定義します。policies/constraints 配下に配置したファイルが有効化されます。今回はGCSのLocationに制限をかけます (ap-northeast-1のみを許可する)
cd /<your_work_space>/policy-library/policies/constraints |
apiVersion: constraints.gatekeeper.sh/v1alpha1 |
Terraform planの実行
main.tfは以下のように定義されています。location="us-central1-a"
と設定しています
(その他 variable.tf, provider.tf等は省略)
resource "google_storage_bucket" "validator_trial" { |
planを実行 --out=
optionを利用
terraform plan --out=terraform.tfplan |
terraform.tfplanのバイナリをjsonへ変換
terraform show -json ./terraform.tfplan > ./terraform.tfplan.json |
Terraform Validatorの実行
これで準備は整いました。Terraform Validatorの実行を行います。
$ terraform-validator validate --policy-path=${POLICY_PATH} ./terraform.tfplan.json |
Validationによりポリシー違反を検知しました! 🚫
main.tf を修正して.。
resource "google_storage_bucket" "validator_trial" { |
再度実行してみると.。
$ terraform-validator validate --policy-path=${POLICY_PATH} ./terraform.tfplan.json |
今度はValidationが成功しました! ✅ 期待通りの動きをしてくれました。
ポリシー定義 (Policy as code)
サンプルポリシーは、先ほど利用した forseti-security/policy-library にあります。これらのyamlファイルを POLICY_PATH
で定義した /<your_work_space>/policy-library
の中の policies/constraints/
配下に配置すればOKです。Policy as codeが簡単に実現できます。
以下に、サンプルから一部をピックアップしてご紹介します。セキュリティポリシーを定義できるほかにも、リソースの命名規則の制限ができたりするのは地味に嬉しいですね。
ポリシー定義のサンプル
- 一般的な制限
- リソースの命名規則(正規表現で指定)
- Labelのアタッチの強制
- リソースタイプの制限
- GCE
- Public IPの無効化
- NWのWhitelist指定
- Cloud SQL
- Public IPの無効化
- Maintenance Windownの制限
- SSLの強制
- GKE
- Private Clusterの強制
- Dashboardの無効化
- Node poolのAuto upgradeの強制
- Node OSの指定
- BigQuery
- Datasetのパブリック公開制限
- IAM
- Service Accountへ付与するRoleの制限
- Audit loggingの強制
- Network
- Firewall ssh,rdp rule パブリック公開の禁止
- VPC Service Control
- 有効化プロジェクトの指定
どのような制限をかけることができるかイメージできたでしょうか。実はこちらに用意されていないものでも、Custom Policyとして自身でポリシールールを記述することもできます。詳細はこちら
実際の運用
実行方法とポリシーの定義方法が分かったところで、実際の運用方法についてです。
以下のように、TerraformのソースコードのPRに対して、Terraform Validatorを実行し、結果をPRにフィードバックさせるようにするのが良いと思います。Githubと連携が可能であれば、CloudBuildで以下のようにCIを回すのが簡単でよいです。
Cloud BuildのSteps イメージ
|
PR上でのフィードバックのイメージ
最後に
本記事ではあまり触れませんでしたが、実は、Forsetiというツールを用いてOngoingでの監視も可能です。こちらもGCPが公開しているオープンソースのツールです。これを用いれば、一元管理されたポリシーでTerraform経由ではない手作業によるポリシー違反の発生も検知できます。
GCPのプロジェクト数がスケールする際に必ずぶち当たるであろうこの課題、私たちもTerraform Validatorを用いて解決しようと現在、試行錯誤中です。導入自体はシンプルにできるため、まずは簡単なポリシーのチェックから始めてみてはいかがでしょうか。
GCP連載の6回目でした。次は加部さんのGCPのData Transfer Serviceを使って簡単にS3からBigQueryにデータ転送をしてみるです。