ご登録ください: Configuration as Data を使用したポリシー契約の作成
Google Cloud Japan Team
※この投稿は米国時間 2021 年 4 月 27 日に、Google Cloud blog に投稿されたものの抄訳です。
Configuration as Data は、新たなクラウド インフラストラクチャ管理パラダイムです。アプリケーションやインフラストラクチャで目的とする状態の宣言を、その実現のための正確なアクションや手順を指定することなく実施できます。しかし、構成の宣言だけでは不十分です。構成をどのように使用するかを定義するポリシーも必要です。
Configuration as Data を使用すると、すべてのクラウド リソースにわたって標準化したポリシー契約を実現できます。デプロイがどのように動作するかを認識したうえで、CI / CD パイプライン全体でこの契約を検査し、適用できます。このパイプラインは、開発環境のアップストリームから、デプロイ段階、ライブのランタイム環境で進行中の稼働段階に至ります。この整合性は、開発とオペレーションのライフサイクル全体を通じ、構成をデータとして表現することで実現できます。
Config Connector は、Google Cloud で構成をデータとして表現できるようにするツールです。このモデルでいう構成とは、デプロイする対象です。たとえば、「標準のストレージ クラスと統一したアクセス制御を設定したストレージ バケット my-bucket」が考えられます。
一方でポリシーは、多くの場合、何をデプロイできるかを指定します。その指定は、組織のコンプライアンスのニーズに対応することが普通です。たとえば、「すべてのリソースは、Google Cloud のロンドン リージョンにデプロイするものとする」というポリシーが考えられます。
パイプラインの各段階で構成をデータとして扱っていれば、任意のツールまたは言語を使用して、構成をデータとして操作できます。これらの構成が相互運用され、パイプラインの任意の段階またはすべての段階にポリシーを適用できることがわかっているからです。また、ポリシー エンジンでは、各ツールを認識できなくでも、各ツールで生成されたデータを検証することは可能です。このデータは、データベースに保存されたデータのようなものです。データベースにどのツールでデータが書き込まれたかに関係なく、スキーマを理解していれば誰でもデータを検査できます。
現代のパイプラインでは、ポリシーを手動で検査するか、パイプラインのロジック自体にスクリプトでポリシーをハード コーディングするか、構成のテンプレートを特定のインスタンスにレンダリングした後で未加工のデプロイ アーティファクトに対してポリシーを後処理します。この点がデータベースと異なります。どの場合もポリシーがサイロ化しているので、同じポリシーを採用してパイプラインの任意の場所に適用することができません。ツールごとに形式が異なるからです。
たとえば、Helm には、次のようにその形式固有のコードが使用されています。1
Terraform HCLでは、これによって次のように Helm チャートをデプロイできます。2
HCL は JSON プランとなり、デプロイできる状態の構成を、ライブ環境に適用する前に検証できます。3
これらの例では、2 種類のツールにわたって 3 つの異種データ形式が見られ、目的とする完了状態の異なる部分が示されています。Python スクリプト、gcloud CLI、kubectl のコマンドを追加し、同じデプロイに対して 10 種類の形式すべての使用を開始します。ポリシー契約を確実に適用するには、状況に応じてツール固有および形式固有の検証ロジックを追加する必要があります。構成手順を Python から Terraform、または Terraform から kubectl に移動する場合は、現在の契約を再評価する必要があります。また、多くの場合、そのポリシー検証の部分的な再実装が必要です。
これらのツールが互いに整然と機能しない理由は何でしょうか。使用するデプロイツールに応じてポリシー検証が異なるのはなぜでしょうか。それぞれのツール自体は、ポリシーの適用で良好に動作できます。あらゆる条件下で同じツールを使用している限りは問題にはなりません。しかし、開発作業の実情がそうもいかないことは誰でも知っています。誰でも自分に都合の良いツールを使用する傾向があり、統合に対する配慮は後回しになります。
ポリシー契約の重大な要点
全員がそれぞれに都合の良いツールと形式を使用しながら、構成をデータとして定義しているとします。オーケストレーションには Terraform または Python を使用します。アプリケーションのパッケージ化には Helm を使用します。データの変換と検証には Java または Go を使用します。データ形式がオープンソースであり、拡張可能であることから、そのデータ形式がパイプラインで認識されると、そのパイプラインはバスとなります。そのバスには誰でも構成を push でき、そこから構成を pull できます。
YAML 上で動作するカスタム関数または既製の関数を使用して、ポリシーを commit 時または構築時に自動的に検証できます。commit 権限と結合権限を構成とポリシーとで別々に管理することで、これらの明確な問題を切り分けることができます。組織規模のポリシー、チーム規模のポリシー、アプリ固有のポリシー向けにフォルダと一意の権限を設定できます。この方法には大きな可能性があります。
構成を生成する最も一般的な方法は、Kubernetes でリソースをどのように作成するかを記述した YAML ファイルを作成することです。作成した YAML ファイルを git リポジトリに置いておけば、そのファイルはそこでバージョン管理され、他のツールで選択されて Kubernetes クラスタに適用されます。git リポジトリ側でポリシーを適用すると、誰がリポジトリに変更を push できるか、最終的に誰がデプロイの際にその変更を参照できるかを制限できます。
大半のユーザーにとっては、ここでポリシーの適用が終了するわけではありません。コードレビューで多くの問題が見つかることもありますが、スタックのどのレイヤでも「信頼するが検証はする」ことがベスト プラクティスと考えられます。ここではアドミッション コントローラを使用します。ここはポリシー適用の最終段階と見なすことができます。Gatekeeper が、Kubernetes クラスタ内部のアドミッション コントローラとして機能します。定義された制約を満足する構成のみが、ライブのクラウド環境での使用を認められます。
これらのコンセプトを 1 つにまとめた例を見てみます。Cloud Storage バケットをユーザーが作成できるようにする場合に、その作成手段として Google Cloud Console と gcloud コマンドライン ツールは使用できないようにするとします。ユーザーが必要とする処理を各ユーザーが宣言し、基盤となる Cloud Storage バケットが Config Connector によって作成される前に、目的の変更を git リポジトリに push してレビューできるようにすることを、すべてのユーザーに求める必要があります。実質的には、次のような YAML ファイルをユーザーが送信できるようにします。
このファイルの処理によって、デフォルトのロケーションにストレージ バケットが作成されます。この方法には、企業のポリシーによって別途規制されていても、ユーザーがどのロケーションにもバケットを作成できるという問題があります。バケットの配置先として禁止されているロケーションを使用するユーザーをコードレビューで把握することは確かにできますが、それは間違いを誘発しやすい方法です。
このような場合には Gatekeeper を使用します。Cloud Storage バケットの配置先とすることができるロケーションを制限する機能が必要です。次のようなポリシーを記述できれば理想的です。
この StorageBucketAllowedLocation ポリシーでは、Cloud Storage のマルチリージョン ロケーションである ASIA、EU、US のいずれでもない値が spec.location フィールドに設定されている StorageBucket オブジェクトが拒否されます。選択したツールによる制限を受けず、パイプラインのどの段階でも制限も受けずに、ポリシーを検証する場所を決定します。
いよいよ、構成パイプラインの最後の段階に達しました。
契約のテスト
作成した構成が実際にどのように機能するかを確認します。次の構成を使用して StorageBucket リソースにチェックインしていたユーザーがいるとします。
ここで取り上げているポリシーでは、ロケーションの指定を空白にすることが認められないので、このバケットは拒否されます。Cloud Storage のロケーションとしてこのポリシーで認められていないロケーションをこの構成で設定していると、どのような結果になるか考えてみます。たとえば、次のように US-WEST1 をロケーションとして指定します。
この構成が git リポジトリにコミットされる前に、コードレビューのプロセスでこのエラーを把握することが理想的ですが、すでに指摘したように、これは誤りを誘発しやすい方法です。
幸いなことに、allowmultiregions ポリシーの制約により、マルチリージョンのバケット ロケーションとして ASIA、EU、US のみが許可されているので、この構成は拒否され、失敗します。ロケーションとして「US」を設定すれば、この Cloud Storage バケットをデプロイできます。このようなタイプのロケーション ポリシーや同様のポリシーを、すべてのリソースタイプに適用することもできます。このようなリソースとして、Redis インスタンス、Compute Engine 仮想マシン、Google Kubernetes Engine(GKE)クラスタなどがあります。アドミッション コントロール以外でも、任意の段階で「シフトレフト」によるポリシー検証を実施することで、パイプラインのあらゆる段階で同様の制約を適用できます。
1 件の契約ですべてを管理
多数のツール、パイプライン、グラフィカル インターフェース、コマンドラインで構成がサイロ化して管理されている場合は、それぞれのインターフェース専用としたツールを構築しないと構成にロジックを追加できません。フロントエンド向けに作成したポリシーを定義し、バックエンドでは変更が発生しないことを期待することも考えられます。また、デプロイ段階まで待ち、なんらかの逸脱がないか検査したうえで、正念場では問題が発生しないことを期待するという手もあります。
このような方法を、Configuration as Data の契約と比較してみます。Configuration as Data は、さまざまなリソースタイプにわたる透明性と標準化を提供します。また、多彩な構文(YAML、JSON)による Kubernetes とさまざまな言語(Ruby、Typescript、Go、Jinja、Mustache、Jsonnet、Starlark など)で構築したツールの充実したエコシステム実現が進んでいます。このような特長はデータモデルがないと実現できません。
Config Connector や Gatekeeper のように、Configuration as Data に触発されたツールを使用することで、git を基本とする既存のワークフローにポリシーとガバナンスを無理のない方法で適用できます。手動のプロセスと承認を作成する必要はありません。Configuration as Data は、さまざまなリソースタイプ、さらには多数のクラウド プロバイダにわたって契約を標準化します。契約が履行されているかどうかは、データを見るだけで判断できます。スクリプトとコードパスをリバース エンジニアリングする必要はありません。
1. https://github.com/helm/charts/blob/master/stable/jenkins/templates/jenkins-master-deployment.yaml
2. https://medium.com/swlh/deploying-helm-charts-w-terraform-58bd3a690e55
-デベロッパー アドボケイト Kelsey Hightower
-Google Cloud シニア プロダクト マネージャー Mark Balch