arm-templateにて構成を変更する

前回、AzureにてVPCとSubnetを作成した
しかし、Portal上から`privateLinkServiceNetworkPolicies`を無効にし、Subnetを作成できなかったため、ARMTemplateを使用し構成を変更する

https://qiita.com/nicnic69/items/9f0325ee1bd760ee4e6b

構成ディレクトリを作成する

```以下のように構成する
infrastructure-templates/
├── README.md                        # プロジェクトの概要や使用方法を記載
├── environments/                    # 環境ごとの設定を格納するディレクトリ
│   ├── dev/                         # 開発環境用の設定ディレクトリ
│   │   ├── dev.parameters.json      # 開発環境のパラメータファイル（VMサイズ、リージョン等）
│   │   └── main.json                # 開発環境用のARMテンプレート（リソース定義）
│   ├── prod/                        # 本番環境用の設定ディレクトリ
│   │   ├── main.json                # 本番環境用のARMテンプレート（リソース定義）
│   │   └── prod.parameters.json     # 本番環境のパラメータファイル（VMサイズ、リージョン等）
│   └── staging/                     # ステージング環境用の設定ディレクトリ
│       ├── main.json                # ステージング環境用のARMテンプレート（リソース定義）
│       └── staging.parameters.json  # ステージング環境のパラメータファイル（VMサイズ、リージョン等）
├── modules/                         # 共通のリソースモジュールを格納するディレクトリ
│   ├── app-service-template.json    # アプリサービス関連のリソース定義（App Service）
│   ├── network-template.json        # ネットワークリソース関連のリソース定義（VNet、サブネット等）
│   └── storage-template.json        # ストレージリソース関連のリソース定義（Storage Account等）
├── infra-common.json                # 共通リソースを定義（VNet、ストレージなど）
├── ci-cd-pipelines/                 # CI/CD パイプライン設定ディレクトリ（Azure DevOps や GitHub Actions の設定）
│   ├── azure-pipelines.yml          # Azure DevOps Pipelines 設定ファイル
│   └── github-actions.yml           # GitHub Actions 設定ファイル
└── .gitignore                       # Git で追跡しないファイルやディレクトリの設定

```
・以下を参考にディレクトリ構成を作成

https://zenn.dev/ukixyjp/articles/b56fbb003bf4de

以下コマンドでディレクトリ構成を作成
```bash
# 最上階のディレクトリを作成
mkdir -p infrastructure-templates/environments/dev
mkdir -p infrastructure-templates/environments/prod
mkdir -p infrastructure-templates/environments/staging
mkdir -p infrastructure-templates/modules
mkdir -p infrastructure-templates/ci-cd-pipelines

# environments ディレクトリ内のファイルを作成
touch infrastructure-templates/environments/dev/dev.parameters.json
touch infrastructure-templates/environments/dev/main.json
touch infrastructure-templates/environments/prod/main.json
touch infrastructure-templates/environments/prod/prod.parameters.json
touch infrastructure-templates/environments/staging/main.json
touch infrastructure-templates/environments/staging/staging.parameters.json

# modules ディレクトリ内のファイルを作成
touch infrastructure-templates/modules/app-service-template.json
touch infrastructure-templates/modules/network-template.json
touch infrastructure-templates/modules/storage-template.json

# 共通リソースのテンプレートを作成
touch infrastructure-templates/infra-common.json

# CI/CD パイプライン設定ディレクトリ内のファイルを作成
touch infrastructure-templates/ci-cd-pipelines/azure-pipelines.yml
touch infrastructure-templates/ci-cd-pipelines/github-actions.yml

# .gitignore を作成
touch infrastructure-templates/.gitignore

# README.md を作成
touch infrastructure-templates/README.md
```

ファイルに構成情報を記載する
--
・main.json
・parameters.json
これらのファイルに、ARM テンプレートとパラメータ情報を記載します。


ディレクトリでの作業手順
--
以下のディレクトリで作業を行います
```
pwd
~infrastructure-templates/environments/dev
```

Azure CLI を使用して Azure にサインイン
--
まず、Azure CLI を使用して Azure にサインインします
```
az login
```

サインイン後、使用しているアカウントとサブスクリプションを確認します
```
az account list --output table
```

次に、リソースグループを確認します
```
az group list -o table
```


ARM テンプレートを使用して現在の構成変更を確認
--
次に、what-if コマンドを実行して、現行の構成がどう変更されるかを確認します
```bash
az deployment group what-if \
  --resource-group rg-xxxxxx-xxxxxx-001 \
  --template-file main.json \
  --parameters dev.parameters.json
```

出力例
```bash
Note: The result may contain false positive predictions (noise).
You can help us improve the accuracy of the result by opening an issue here: https://aka.ms/WhatIfIssues

Resource and property changes are indicated with these symbols:
  ~ Modify
  x Noeffect

The deployment will update the following scope:

Scope: /subscriptions/xxxxxx/resourceGroups/xxxxxx

  ~ Microsoft.Network/virtualNetworks/xxxxxxxxxxxx [2024-01-01]
    ~ properties.subnets: [
      ~ 0:

        ~ properties.privateLinkServiceNetworkPolicies: "Enabled" => "Disabled"

      ]
    x properties.subnets[0].type: "Microsoft.Network/virtualNetworks/subnets"

  ~ Microsoft.Network/virtualNetworks/xxxxxxxxxxxx/subnets/xxxxxxxxxxxx [2024-01-01]
    ~ properties.privateLinkServiceNetworkPolicies: "Enabled" => "Disabled"

Resource changes: 2 to modify.
```

`az deployment group what-if`とは
実際にリソースをデプロイする前に、ARM テンプレートを適用した場合にどのような変更が行われるかをシミュレートする機能のこと

1.注意事項（Note）
--
```bash
Note: The result may contain false positive predictions (noise).
You can help us improve the accuracy of the result by opening an issue here: https://aka.ms/WhatIfIssues
```
False positive predictions (noise): 
>ARMやBicepによるAzureリソースのデプロイ時に使うwhat-ifには偽陽性が存在する．

https://blog.ottijp.com/2024/09/18/az-deployment-denoise/

もし、`偽陽性`があった場合、以下へ問い合わせてして欲しいとのこと

https://github.com/azure/arm-template-whatif/issues


2.変更のシンボル
--
```python
Resource and property changes are indicated with these symbols:
  ~ Modify
  x Noeffect
```


・`~ Modify:` リソースまたはプロパティが変更されることを示します
・`x Noeffect:` 変更が実際には影響しないことを示します。リソースやプロパティに対する変更が行われても、その結果としてリソースに影響を与えないケースのこと

3.更新対象のスコープ
--
・Scope: デプロイメントが変更を適用するリソースの範囲を示しす。
`/subscriptions/xxxxxx/resourceGroups/xxxxxx` というリソースグループ内のリソースが変更対象となってることを示す

4.変更されるリソース
--
```bash
  ~ Microsoft.Network/virtualNetworks/xxxxxxxxxxxx [2024-01-01]
    ~ properties.subnets: [
      ~ 0:

        ~ properties.privateLinkServiceNetworkPolicies: "Enabled" => "Disabled"

      ]
    x properties.subnets[0].type: "Microsoft.Network/virtualNetworks/subnets"
```
・`Microsoft.Network/virtualNetworks/xxxxxxxxxxxx:` 変更されるリソースは、virtualNetworks（仮想ネットワーク）が対象となる
・`properties.subnets[0].privateLinkServiceNetworkPolicies:` この仮想ネットワークのサブネットに設定された `privateLinkServiceNetworkPolicies` の値が、`"Enabled"` から `"Disabled"` に変更されることを示す
・`properties.subnets[0].type:` この行の変更は `x Noeffect` として示されており、実際には影響を与えないことを示す

5.追加のリソース変更
--
```bash
  ~ Microsoft.Network/virtualNetworks/xxxxxxxxxxxx/subnets/xxxxxxxxxxxx [2024-01-01]
    ~ properties.privateLinkServiceNetworkPolicies: "Enabled" => "Disabled"
```
・このデプロイメントで 2つのリソース が変更されることを示す。具体的には、仮想ネットワークとそのサブネットに関する設定が変更されるということ
・`properties.privateLinkServiceNetworkPolicies`: サブネットに関連する `privateLinkServiceNetworkPolicies` が `"Enabled"` から `"Disabled"` に変更されることを示す。


6.変更の概要
--
```bash
Resource changes: 2 to modify.
```
・このデプロイメントで `2つのリソース` が変更されることを示す。具体的には、仮想ネットワークとそのサブネットに関する設定が変更されるということ。


変更をデプロイ
--
変更内容が確認できたら、次に Incremental モードで変更をデプロイします
```bash
az deployment group create \
  --resource-group rg-xxxxxx-xxxxxx-001 \
  --template-file main.json \
  --parameters dev.parameters.json \
  --mode Incremental
```


デプロイ結果
--
デプロイ後、以下のような情報が表示されます
```bash
{
  "id": "/subscriptions/xxxxxxxxxxxx/resourceGroups/xxxxxxxxxxxx/providers/Microsoft.Resources/deployments/main",
  "location": null,
  "name": "main",
  "properties": {
    "correlationId": "fd3fb459-bd32-4aee-8aa2-bac9f983eca1",
    "debugSetting": null,
    "dependencies": [
      {
        "dependsOn": [
          {
            "id": "/subscriptions/xxxxxxxxxxxx/resourceGroups/xxxxxxxxxxxx/providers/Microsoft.Network/virtualNetworks/xxxxxxxxxxxx",      
            "resourceGroup": "rg-xxxxxx-xxxxxx-001",
            "resourceName": "vnet-xxxxxx-xxxxxx-001",
            "resourceType": "Microsoft.Network/virtualNetworks"
          }
        ],
        "id": "/subscriptions/xxxxxxxxxxxx/resourceGroups/rg-xxxxxx-xxxxxx-001/providers/Microsoft.Network/virtualNetworks/vnet-xxxxxx-jxxxxxx-001/subnets/snet-xxxxxx-xxxxxx-001",
        "resourceGroup": "rg-xxxxxx-xxxxxx-001",
        "resourceName": "vnet-xxxxxx-xxxxxx-001/snet-xxxxxx-xxxxxx-001",
        "resourceType": "Microsoft.Network/virtualNetworks/subnets"
      }
    ],
    "duration": "PT4.2100302S",
    "error": null,
    "mode": "Incremental",
    "onErrorDeployment": null,
    "outputResources": [
      {
        "id": "/subscriptions/xxxxxx/resourceGroups/rg-xxxxxx-xxxxxx-001/providers/Microsoft.Network/virtualNetworks/vnet-xxxxxx-xxxxxx-001",
        "resourceGroup": "rg-xxxxxx-xxxxxx-001"
      },
      {
        "id": "/subscriptions/xxxxxx/resourceGroups/rg-xxxxxx-xxxxxx-001/providers/Microsoft.Network/virtualNetworks/vnet-xxxxxx-xxxxxx-001/subnets/snet-xxxxxx-xxxxxx-001",
        "resourceGroup": "rg-xxxxxx-xxxxxx-001"
      }
    ],
    "outputs": null,
    "parameters": {
      "location": {
        "type": "String",
        "value": "japaneast"
      },
      "snetAddressPrefix": {
        "type": "String",
        "value": "10.0.0.0/24"
      },
      "snetName": {
        "type": "String",
        "value": "snet-xxxxxx-xxxxxx-001"
      },
      "vnetName": {
        "type": "String",
        "value": "vnet-xxxxxx-xxxxxx-001"
      }
    },
    "parametersLink": null,
    "providers": [
      {
        "id": null,
        "namespace": "Microsoft.Network",
        "providerAuthorizationConsentState": null,
        "registrationPolicy": null,
        "registrationState": null,
        "resourceTypes": [
          {
            "aliases": null,
            "apiProfiles": null,
            "apiVersions": null,
            "capabilities": null,
            "defaultApiVersion": null,
            "locationMappings": null,
            "locations": [
              "japaneast"
            ],
            "properties": null,
            "resourceType": "virtualNetworks",
            "zoneMappings": null
          },
          {
            "aliases": null,
            "apiProfiles": null,
            "apiVersions": null,
            "capabilities": null,
            "defaultApiVersion": null,
            "locationMappings": null,
            "locations": [
              null
            ],
            "properties": null,
            "resourceType": "virtualNetworks/subnets",
            "zoneMappings": null
          }
        ]
      }
    ],
    "provisioningState": "Succeeded",
    "templateHash": "15698401674872478446",
    "templateLink": null,
    "timestamp": "2024-12-21T08:08:19.273507+00:00",
    "validatedResources": null
  },
  "resourceGroup": "rg-xxxxxx-xxxxxx-001",
  "tags": null,
  "type": "Microsoft.Resources/deployments"
}
```

出力内容
以下のように見られます

`id`: このデプロイメントの一意の識別子（リソースグループやサブスクリプションIDを含むフルパス）。
`location`: デプロイメントが行われたリージョン（null の場合は未指定）。
`name`: デプロイメントの名前（ここでは "main"）。
`properties`: デプロイメントの詳細情報。ここには、デプロイメントの状態やリソースの依存関係、変更されたリソース、使用されたパラメータなどが含まれています。
`dependencies`: 依存するリソースの情報。仮想ネットワークやサブネットに依存関係があることが示されています。
`outputResources`: このデプロイメントによって作成または変更されたリソース。
`parameters`: デプロイメントで使用されたパラメータの値（リージョンやサブネットのアドレスプレフィックスなど）。
`provisioningState`: デプロイメントの状態（Succeeded は成功したことを示す）。
`timestamp`: デプロイメントが行われた日時。
`resourceGroup`: このデプロイメントが実行されたリソースグループの名前。
`type`: リソースのタイプ（ここでは Microsoft.Resources/deployments というデプロイメントリソースを示す）。


https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deploy-what-if?tabs=azure-powershell