【Azure】VNet作成時に特定のタグを強制するAzure Policyを作ってみた

# はじめに
はじめてのAzureに関する投稿です。
今回はタイトルの通り、VNet作成時に特定のタグを強制するAzure Policyを作ってみました。
まだまだ知らないサービスだらけなので、検証を通して使い方や仕組みを理解していけたらなと思います。

# 目次

1. [Policyの作成](#policyの作成)
1. [Policyの解説](#policyの解説)
1. [Policyの稼働確認](#policyの稼働確認)
1. [さいごに](#さいごに)


<!-- 各チャプター -->




# Policyの作成
今回使用するポリシーは以下のようになります。
リソースグループに対してこのポリシーをアタッチして検証します。

```
{
  "mode": "Indexed",
  "policyRule": {
    "if": {
      "allof": [
        {
          "anyof": [
            {
              "field": "[concat('tags[', parameters('tagName'), ']')]",
              "exists": "false"
            },
            {
              "field": "[concat('tags[', parameters('tagName'), ']')]",
              "notEquals": "[parameters('tagValue')]"
            }
          ]
        },
        {
          "field": "type",
          "equals": "Microsoft.Network/virtualNetworks"
        }
      ]
    },
    "then": {
      "effect": "deny"
    }
  },
  "parameters": {
    "tagName": {
      "type": "String",
      "metadata": {
        "displayName": "タグ名",
        "description": "タグの名前 (例: environment)"
      }
    },
    "tagValue": {
      "type": "String",
      "metadata": {
        "displayName": "タグ値",
        "description": "タグの値 (例: pro)"
      }
    }
  }
}
```


# Policyの解説
ポリシーの仕組みを解説していきます。
「policyRule」セクション内の "if" で条件を判断しています。
このポリシーのif条件式の中では「allof」と「anyof」の２種類の論理演算子を使用しています。

それぞれの演算子について説明します。
* anyof演算子
anyofセクション内のどれか１つの条件がTrueだった場合はanyof演算子の結果をTrueとします。
このポリシーの場合、"tagName"が一致しない場合、もしくは"tagValue"が一致しない場合にTrueとなります。


* allof演算子
allofセクション内のすべての条件がTrueだった場合にTrueとなり、"then" の中のdenyがトリガーされます。
まず、タグの値に不備があった場合はanyof演算子でTrueが返ります。
さらに実行対象のサービスがVNetだった場合はallof演算子の中がすべてTrueということになるのでthenのdenyがトリガーされ、
VNetの作成が拒否される仕組みとなっています。


詳しく知りたい方はこちらのドキュメントをご参照ください
https://learn.microsoft.com/ja-jp/azure/governance/policy/samples/pattern-logical-operators


# Policyの稼働確認
作成したリソースグループにポリシーをアタッチします。
今回使用するポリシーは以下のtagName,tagValueをパラメータとして指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/40323cd4-7cd7-1cc0-c9a5-5b1b67025219.png)

* まずはタグの指定なしでVNetを作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/92a61a94-453f-c4fc-ad93-9f657d8d4f16.png)
VNetの作成に失敗しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/0deb41c6-8dd1-b578-53ca-f6942158f982.png)

* 次にtagNameに「test-tag-key」を指定した状態でtagValueに誤った値を指定してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/1b7ca813-ac8e-c0d3-8f5d-6480315dba31.png)
先ほどと同様にVNet作成に失敗しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/bfae2eda-b29f-df9c-d6f8-e367eb96345a.png)

* 最後にtagNameに「test-tag-key」,tagValueに「test-tag-value」を指定した値を指定してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/14230d3d-a08a-ce16-f59d-1fddb89ba22b.png)
成功しました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615865/0cf921da-9351-6ad0-689d-a9d502edfbd8.png)


# さいごに
AWSのIAMPolicyしか書いたことがなかったので同じJsonでも構文が全然違ってかなり戸惑いました。。。（笑）
リソースの作成時にタグを付与することはリソース管理の上で非常に重要な役割を持っていると個人的に思っており、タグを強制したい場面は結構多いんじゃないかなと思います。
そんな時に本記事で紹介したポリシーを流用してどこかの誰かの役に立てたらいいなと思ってます。

最後になりますが読んでいただきありがとうございました。
まだまだAzure初心者なのでAWSだけでなくこっちも勉強頑張ります！