組織のポリシーをタグで制御してみた

記事タイトルとURLをコピーする

G-gen の津守です。Google Cloud の組織ポリシー機能で、プロジェクトにタグを適用することで例外設定を行う方法を検証しました。

はじめに

当記事について

Google Cloud(旧称 GCP)では組織のポリシーを使って、組織内のプロジェクトに一律でセキュリティや統制強化のための設定を適用できます。このとき、特定のプロジェクトにのみ例外を設けたい場合もあります。

例えば、組織全体に「公開アクセスの防止を適用する(constraints/storage.publicAccessPrevention)」という組織のポリシーの制約を適用しているとします。しかし、あるプロジェクトでは Cloud Storage の公開バケットに静的コンテンツをホスティングしているとします。このときは、当該プロジェクトのみを制約の適用外にする必要があります。

当記事ではそのような場合を想定して、タグを使って特定のプロジェクトは制約の対象外としつつ、その他全ての組織内プロジェクトに制約を適用する検証を行いました。

前提知識

当記事では Resource Manager のタグ機能を利用します。タグの詳細や、類似機能であるラベルとの差異については、以下の記事を参照してください。

blog.g-gen.co.jp

組織のポリシー機能については、以下の記事を参照してください。特に、継承と呼ばれる性質については理解が必要です。

blog.g-gen.co.jp

検証

タグキーと値の作成

まず、組織のリソースとして、「IAM と管理」画面からタグキーを作成します。今回は apply-policy という名称で作成します。

タグキー作成

次に、タグキーの値として、truefalse を作成します。今回の検証ではこの値を使っていますが、必ずしもブール値である必要はなく、運用上都合の良い文字列を指定して構いません。

タグの値作成

フォルダとプロジェクトの作成

以下のようにフォルダとプロジェクトを作成します。

  • フォルダに属さないプロジェクト
    • test-20241028-true
    • test-20241028-false
    • test-20241028-none
  • フォルダ my_folder
  • 同フォルダ配下の、以下のプロジェクト
    • test-20241028-true-in-folder
    • test-20241028-false-in-folder
    • test-20241028-none-in-folder

タグ apply-policy: true を、プロジェクト test-20241028-truetest-20241028-true-in-folder に付与します。

タグ apply-policy: false を、プロジェクト test-20241028-falsetest-20241028-false-in-folder に付与します。

さらに、タグ apply-policy: false を、フォルダ my_folder に付与します。

プロジェクトの作成・タグの付与

フォルダにタグを付与した場合、そのフォルダに属するプロジェクトにはタグが継承されます。ただし、プロジェクトにタグが直接付与されている場合、そちらが優先されます。上記のスクリーンショットでは、プロジェクト test-20241028-none-in-folder の Tags 列に継承を表すアイコンが表示されており、フォルダから継承されたタグが適用されていることがわかります。

ポリシーの適用

この組織に対して、組織レベルで制約を適用します。今回適用する制約は「公開アクセスの防止を適用する(constraints/storage.publicAccessPrevention)」です。組織レベルにこの制約を適用しつつ、タグ apply-policy: false が付与されたプロジェクトではこの制約の効果が発揮されない状態を目指します。

組織のポリシーの Google Cloud コンソール画面で上記の制約を検索し、編集します。この時、設定値として、「親のポリシーをオーバーライドする」を選択します。編集画面では、2つのルールを追加します。

1つ目は、特定のタグキーと値を持っていることを条件に、「適用」を「オフ」とするものです。設定値「値のパス」は、[organization_name]/apply-policy/false とします。タグを作成済みの場合、プルダウンメニューから選択できます。

ポリシーの編集

値のパス

2つ目は、1つ目のルールの条件に合致しない場合に適用される、デフォルトのルールです。「ルールの追加」を押下し、「適用」のラジオボタンで「オン」を選択します。これを設定しない場合、A boolean policy must always include one unconditional rule. というメッセージが表示され、ポリシーの設定が完了しません。

組織レベルでポリシーが適用された場合、コンソール画面の表記は以下のようになります。

適用された組織ポリシー

ポリシーの適用後、各プロジェクトのポリシー適用状態は以下のようになります。

プロジェクト ○:適用済み、×:未適用
test-20241028-true
test-20241028-false ×
test-20241028-none
test-20241028-true-in-folder
test-20241028-false-in-folder ×
test-20241028-none-in-folder ×

以下は、各プロジェクトレベルでポリシーの適用状態を確認した際のキャプチャです。想定したとおりに、ポリシーが適用されていることがわかります。

test-20241028-true

test-20241028-false

test-20241028-none

test-20241028-true-in-folder

test-20241028-false-in-folder

test-20241028-none-in-folder

以上の検証結果から、以下のことが確かめられました。

  • 明示的にタグを付与したプロジェクトには、ポリシーが適用されない
  • 親フォルダのタグを継承しているプロジェクトには、ポリシーが適用されない
  • タグが付与されていないプロジェクトには、デフォルトルールに基づきポリシーが適用される

補足情報

条件の指定について

今回の検証では、ポリシーの除外対象とするプロジェクトをタグで指定しました。反対に、適用対象をタグで指定することも可能です。

また、今回の検証ではタグ名を使って指定する方法を紹介しましたが、他にタグの永続 ID(permanent ID。タグキーや値が持つリソース ID)で指定することもできます。

Terraform

当検証で使用した組織レベルのリソースは、以下のように Terraform で記述することができます。なお以下のサンプルコード内の変数 organization_number_id は10~13桁の数字で表される組織 ID です。

resource "google_tags_tag_key" "apply_policy" {
  short_name  = "apply-policy"
  parent      = "organizations/${var.organization_number_id}"
  description = "The flag indicating whether to apply the policy or not."
}
  
resource "google_tags_tag_value" "apply_policy_true" {
  parent      = "tagKeys/${google_tags_tag_key.apply_policy.name}"
  short_name  = "true"
  description = "Apply organization policy to the project."
}
  
resource "google_tags_tag_value" "apply_policy_false" {
  parent      = "tagKeys/${google_tags_tag_key.apply_policy.name}"
  short_name  = "false"
  description = "Do NOT apply organization policy to the project."
}
  
resource "google_org_policy_policy" "storage_public_access_prevention" {
  name   = "organizations/${var.organization_number_id}/storage.publicAccessPrevention"
  parent = "organizations/${var.organization_number_id}"
  
  spec {
    rules {
      enforce = "FALSE"
      condition {
        title       = "Do NOT apply with the tag"
        description = "Do NOT apply storage.publicAccessPrevention on the projects tagged with apply-policy: false"
        expression  = "resource.matchTag('${var.organization_number_id}/apply-policy', 'false')"
      }
    }
    rules {
      enforce = "TRUE"
    }
  }
}

津守 俊輔(記事一覧)

クラウドソリューション部

福岡在住のプログラマー。