Azure Resource Group & Policy
Resource Group & Policy
Resource Group と Policy の関係性について理解するためには、MSラーニングパスの「Azure Resource Manager」を見て頂くと分かりやすいと思います。
Azure Policy(管理ポリシー)
Azure の管理ポリシーは面白い機能を提供してくれます。
例えば、社内検証用のサブスクリプションに対して、使用できるリソースの種類、場所、マシン性能などを制限すると、そこで作成される Azure Resource Manager 内のリソースはその制限を継承します。
Azure には、管理グループ、サブスクリプション、リソース グループ、およびリソースという4つのレベルのスコープが用意されています。
それぞれのレベルで、管理ポリシー(Azure Policy)を定義することができ、下位レイヤーの全ての要素に継承されます。
Resource Group
MSラーニングパスの「Azure Resource Manager」の内容としては、Resource Group の利用方法やベストプラクティスについての解説が中心でした。
概要を箇条書きします。
- Resource Group は入れ子にできない。
- Resource Group にタグを付与できるが、Resource Group 内のリソースに継承されない。
- Azure Policy を利用することで、Resource Group 内のリソースに制限を与えられる。
- リソースの種類のインスタンスを最大 800 個までデプロイできる。
Azure Resource Manager とは何なのか
Azure Policy や Resource Group を調べているとよく出てくるワードが「Azure Resource Manager(ARM)」です。これは、AWS で言うところの CloudFormation です。
まさに、リソースの作成・変更・削除を行う司令塔のような役割を果たしているものです。
Resource Manager は Azure ポータル、Azure ツール、API、SDK から要求を受信し、その要求に対して認証と承認を行います。
その後、Resource Manager は各 Azure サービスに要求を送信します。
すべての要求は同じ API を介して処理されるため、異なるツールであっても一貫した結果と機能が得られます。
すごいですね~。
試してみる
Resource Group に Azure Policy をアタッチしてみて動作を確認してみましょう。
前提
Azure を操作するツールは色々ありますが、今回は Terraform を使っていきます。
- azcli はインストール済み
- ADアカウント、サブスクリプションは作成済み
terraform の認証方法(Service Principal with a Client Secret)
いくつかやり方はありますが、簡単なのは App registrations を作成する方法です。
言い換えれば、terraform 用の実行ユーザーを作成してしまうということです。併せて、リソース作成権限(ロール "Contributor")も付与します。
詳細はこちらを確認ください。
Terraform のファイル構成
今回は Resource Group を作成するだけのシンプルな構成です。
tf ファイルの中身
provider.tf
# tfstate on storage account
terraform {
required_version = "= 0.13.5"
backend "azurerm" {
resource_group_name = "atsushi.koizumi.data"
storage_account_name = "terraform0tfstate"
container_name = "tfstate"
key = "test01.tfstate"
}
}
# provider azurerm
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret
# az ad sp create-for-rbac
provider "azurerm" {
version = "=2.38.0"
subscription_id = var.subscription_id
client_id = var.client_id
client_secret = var.client_secret
tenant_id = var.tenant_id
features {}
}
main.tf
# Create a resource group
resource "azurerm_resource_group" "test01" {
name = "atsushi.koizumi.test01"
location = "East US"
tags = {
"Owner" = "koizumi",
"Env" = "test01"
}
}
# Policy assignment
resource "azurerm_policy_assignment" "Allowed_locations" {
name = "Allowed-locations"
scope = azurerm_resource_group.test01.id
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c"
description = "This policy enables you to restrict the locations your organization can specify when deploying resources. Use to enforce your geo-compliance requirements. Excludes resource groups, Microsoft.AzureActiveDirectory/b2cDirectories, and resources that use the 'global' region."
display_name = "Allowed locations"
identity {
type = "SystemAssigned"
}
location = "eastus"
parameters = <<PARAMETERS
{
"listOfAllowedLocations": {
"value": [ "East US","East US 2" ]
}
}
PARAMETERS
}
resource "azurerm_policy_assignment" "inherit_tag_from_rg" {
name = "Inherit-tag-from-resourcegroup"
scope = azurerm_resource_group.test01.id
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/cd3aa116-8754-49c9-a813-ad46512ece54"
description = "Adds or replaces the specified tag and value from the parent resource group when any resource is created or updated. Existing resources can be remediated by triggering a remediation task."
display_name = "Inherit a tag from the resource group"
identity {
type = "SystemAssigned"
}
location = "eastus"
parameters = <<PARAMETERS
{
"tagName": {
"value": "Owner"
}
}
PARAMETERS
}
# Create a virtual network within the resource group
resource "azurerm_virtual_network" "test01" {
name = "test01"
resource_group_name = azurerm_resource_group.test01.name
location = azurerm_resource_group.test01.location
address_space = ["10.0.0.0/16"]
}
# Create a virtual network within the resource group
resource "azurerm_virtual_network" "test02" {
name = "test02"
resource_group_name = azurerm_resource_group.test01.name
location = "East US 2"
address_space = ["10.0.0.0/16"]
}
# Create a virtual network within the resource group
resource "azurerm_virtual_network" "test03" {
name = "test03"
resource_group_name = azurerm_resource_group.test01.name
location = "West US 2"
address_space = ["10.0.0.0/16"]
}
variable.tf
variable subscription_id {}
variable client_id {}
variable client_secret {}
variable tenant_id {}
terraform.tfvars
# azure AD
tenant_id = "00000000-0000-0000-0000-000000000000"
# Subncriotsion
subscription_id = "00000000-0000-0000-0000-000000000000"
# server principals
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = "00000000000000000000000000000000"
ポイント
大事なところは以下の3点です。
- policy_definition_id において buil-in Policy は MS で用意してくれている固定値を指定
- buil-in Policy の JSON ソースコードを読み解いてパラメータを指定
- azurerm_policy_assignment で identity とlocation を指定
Terraform apply
リソース作成
上記のファイルを使ってリソースを作成してみます。
Error: creating/updating Policy Assignment
権限不足の Error で失敗しました。
Policy をアタッチするためには、Owner または、User Access Administrator の権限が必要です。
MS の公式サイトにトラブルシューティングが載っていました。Service principal にロールを追加します。
リソース作成(リトライ)①
上記のファイルを使ってリソースを作成してみます。
そのまま Tearrform apply してしまうと、Azure policy のアタッチに1分程度の時間が掛かってしまい、先に Virtual Network が作成されてしまいます。
それでは、Resource group に設定した Azure Policy がリソースに適用されません。
以下の順で明示的にリソースを指定して作成します。
実行すると、Resource group に Policy がアタッチされていることが画面で確認できます。
リソース作成(リトライ)②
残りの Virtual Network を作成していきます。
ちなみに、Resource group に適用した Policy の内容は以下です。
- Resource group の所有するタグ Owner を継承する。
- リソースが作成可能なリージョン指定 East US ,East US 2
ということなので、terraform apply の実行結果は、3つの Virtual Network に対してタグ Owner が継承され、test03(West US 2)の作成に失敗、と想定しています。
やってみましょう。
結果は想定通り
エラーコード「Code="RequestDisallowedByPolicy"」と表示されています。
また、タグの継承についても画面で確認することができました。
おまけ
実は、Terraform でタグ継承の Policy 運用は難しいということが分かりました。
試しに
上記の実行結果のあと、再度、terraform apply してみますと、
このように、タグの有無が差分として出てきてしまい、terraform としては継承したタグを消しにいく動きを見せます。
main.tf の中身と実体の差分を埋めるように動いているので当然の動きとなります。
terraform で Policy を使用する場合は、何かを継承するようなものではなく、リソースの作成を制限するような機能を利用すると良いと思われます。
今回は以上です。
Icons made by Flat Icons from www.flaticon.com