てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Azure] 関連付けされていない NSG を Azure CLI で洗い出してまとめ削除する

はじめに

セキュリティグループ(NSG)の設定の自動化を試しているうちに、どのサブネット、どのネットワークインターフェースにも関連づいていない不要な NSG がちらほらできてしまいました。これらを洗い出したり、まとめ削除したいなと思うことがありました。

Azure CLI で割とさくっとできそうだったので試しました。

  • 環境
    • Azure CLI 2.43.0

前提環境

リソースグループ sakana に 6つある状態から始めます。

NSG 関連付け状態
nsg01 サブネットに関連付け
vm0201, vm9901 ネットワークインターフェースに関連付け
nsg02 サブネット、ネットワークインターフェースに関連付け
nsg_free01, nsg_free02 関連付けなし(洗い出し、削除対象)

一覧表示(az network nsg list コマンド

az network nsg list -g sakana 
[
  {
    // ...(略)...
    "name": "nsg01",
    // ...(略)...
    "subnets": [
      {
        "id": "/subscriptions/xxx/resourceGroups/sakana/providers/Microsoft.Network/virtualNetworks/vnet01/subnets/subnet01",
      }
    ],
    // ...(略)...
  },
  {
    // ...(略)...
    "name": "nsg02",
    "networkInterfaces": [
      {
        "id": "/subscriptions/xxx/resourceGroups/sakana/providers/Microsoft.Network/networkInterfaces/sakana-rhel82-test2995",
        "resourceGroup": "sakana"
      }
    ],
    // ...(略)...
    "subnets": [
      {
        "id": "/subscriptions/xxx/resourceGroups/sakana/providers/Microsoft.Network/virtualNetworks/vnet01/subnets/subnet-vm",
        "resourceGroup": "sakana"
      }
    ],
    // ...(略)...
  },
  {
    // ...(略)...
    "name": "nsg_free01",
    // ...(略)...
  },
  {
    // ...(略)...
    "name": "nsg_free02",
    // ...(略)...
  },
  {
    // ...(略)...
    "name": "vm0201",
    "networkInterfaces": [
      {
        "id": "/subscriptions/xxx/resourceGroups/sakana/providers/Microsoft.Network/networkInterfaces/vm0201",
        "resourceGroup": "sakana"
      }
    ],
    // ...(略)...
  },
  {
    // ...(略)...
    "name": "vm9901",
    "networkInterfaces": [
      {
        "id": "/subscriptions/xxx/resourceGroups/sakana/providers/Microsoft.Network/networkInterfaces/vm9901",
        "resourceGroup": "sakana"
      }
    ],
    // ...(略)...
  }
]

洗い出し

何かに関連付けしている NSGsubnetsnetworkInterfaces というキーがあることが分かりました。

なので、これらのキーがないものと言う条件を --query に指定します。見やすいように名前だけ表示するようにします。条件の書式は JMESPATH によるものです。

コマンド

az network nsg list -g sakana --query "[?!networkInterfaces && !subnets].name"

結果

[
  "nsg_free01",
  "nsg_free02"
]

狙い通りの対象の NSG が洗い出せました。

まとめて削除

今度は、洗い出した NSG をまとめて削除します。

削除のコマンドは az network nsg delete です。複数の NSG を指定するには -n ではなく、--ids を利用するといいようです。

なので、洗い出しコマンド(az network nsg list) の --query では、name ではなく id を指定します。

また、az network nsg delete--ids ではスペース区切りの ID を指定する必要あるので、洗い出しの az network nsg list 側のフォーマットは -o tsv にします。Azure CLI では、-@ を使うとパイプで渡された値を取得できるようです。今回はこれを使ってみます。

まとめると以下のコマンドです。

az network nsg list -g sakana \
  --query "[?!networkInterfaces && !subnets].id" \
  -o tsv | az network nsg delete --ids @-

これらのやり方は、「Azure CLI を正しく使用するためのヒント)」の「別のコマンドへ値を渡す」でヒントを得ました。

結果

[
  null,
  null
]

使い方がいまいちなようで、結果もちょっとイマイチですね・・

消えたことを確認します。

コマンド

az network nsg list -g sakana --query "[].name" 

結果

[
  "nsg01",
  "nsg02",
  "vm0201",
  "vm9901"
]

無事に対象の nsg_free01nsg_free02 が消えました。

おわりに

条件にマッチした一覧を洗い出してまとめて操作、というのはいろいろ応用がききそうな気がします。

ただし、まとめて削除するのはリスクがあることがあるため、いったん洗い出すなど動作確認をしながら実施したほうがよさそうです。

参考

Ansible 版

tekunabe.hatenablog.jp