LoginSignup
0
0

More than 1 year has passed since last update.

Python で REST API を利用してリソースグループ内のリソースのデプロイ履歴・操作情報を取得してみました

Posted at

概要

REST API を利用して、リソースグループ内にあるデプロイ名毎にデプロイ情報・履歴を取得する Python プログラムです。
デプロイ履歴(情報)を取得するプログラムフローは以下となっています。

  1. Azureリソースに REST API アクセスするためのアクセストークンの取得
  2. REST API を利用したデプロイ履歴情報の取得
  3. 取得した履歴情報をデプロイ名単位でローカルファイルへ保存
  4. REST API を利用したデプロイ操作情報の取得
  5. 取得した操作情報をデプロイ名単位でローカルファイルへ保存

実行環境

  • macOS Monterey 12.1
  • python 3.8.3
  • Azure CLI 2.28.0

前提条件

  1. Azure環境がすでに用意されていること(テナント/サブスクリプション)
  2. ローカル環境に「azure cli」がインストールされていること
  3. リソースグループ(rg_ituru_deploy_test)配下にvNetリソース(vnet_ituru_deploy_test)のAzure環境が構築されていること

実行プログラム

GetDepeloymentHistory.py
import os
import time
import json
import argparse
import requests
import sys
from datetime import datetime
from azure.identity import AzureCliCredential, DefaultAzureCredential
from azure.mgmt.resource import ResourceManagementClient

# Azure Info
TENANT_ID = os.environ['AZURE_TENANT_ID']
CLIENT_ID = os.environ['AZURE_CLIENT_ID']
CLIENT_KEY = os.environ['AZURE_CLIENT_SECRET']

# Retrieve subscription ID from environment variable.
SUBSCRIPTION_ID = os.environ["ARM_SUBSCRIPTION_ID"]
API_VERSION = "2021-04-01"

# リソースの管理オブジェクトの取得
def GetResourceManagementClient():
    resource_client = ResourceManagementClient(
        # credential=DefaultAzureCredential()
        credential=AzureCliCredential(),
        subscription_id=SUBSCRIPTION_ID
    )
    return resource_client


# サブスクリプションのリソースグループ一覧の取得
def GetResourceGroup():
    # Obtain the management object for resources.
    resource_client = GetResourceManagementClient()

    # Retrieve the list of resource groups
    group_list = resource_client.resource_groups.list()

    # Show the groups in formatted output
    column_width = 50
    print("Resource Group".ljust(column_width) + "Location")
    print("-" * (column_width * 2))

    for group in list(group_list):
        print(f"{group.name:<{column_width}}{group.location}")


# デプロイ情報・履歴データをローカルファイルへ保存の取得
def DeploymentToLocalFile(item, filename):

    # 保存するファイル名の生成
    print(filename)

    # json.dump関数でファイルに書き込む
    fw = open(filename,'w')
    json.dump(item,fw,indent=2)
    fw.close()


# 指定したリソースグループ内のデプロイ名毎のデプロイ操作情報の取得
def GetDepeloymentOperation(access_token, rg_name, dp_name, now):

    # access_token を含めたヘッダ情報
    headers = {
        'Authorization': 'Bearer %s' % access_token
    }

    # 取得URL
    DeplumentOperation_URL = 'https://management.azure.com/subscriptions/' + \
                        SUBSCRIPTION_ID + '/resourcegroups/' + rg_name + \
                        '/deployments/' + dp_name + '/operations?api-version=' + API_VERSION
    # print(DeplumentOperation_URL)

    # 情報取得のGetリクエスト
    try :
        res2 = requests.get(
            DeplumentOperation_URL,
            headers=headers
        )
    except Exception as err:
        print("Something Fatal Happened")
        print (err)
        sys.exit()

    # requrest処理をクローズする
    res2.close

    # res2をjsonファイルに整形しユーザ情報の取得
    item = res2.json()['value']
    if len(item) > 0:
        # print(json.dumps(item, indent = 2))

        # 保存するファイル名の生成
        filename = './output/Deployment_Operation__' + rg_name + '_' + dp_name + '_' + now.strftime('%Y%m%d_%H%M%S') + '.json'

        # デプロイ履歴データをローカルファイルへ
        DeploymentToLocalFile(item, filename)


# 指定したリソースグループ内のデプロイ名毎のデプロイ履歴情報の取得
def GetDepeloymentInfo(access_token, rg_name):

    # access_token を含めたヘッダ情報
    headers = {
        'Authorization': 'Bearer %s' % access_token
    }

    # 取得URL
    DeplumentInfo_URL = 'https://management.azure.com/subscriptions/' + \
                        SUBSCRIPTION_ID + '/resourcegroups/' + rg_name + \
                        '/providers/Microsoft.Resources/deployments/?api-version=' + API_VERSION
    # print(DeplumentInfo_URL)

    # 情報取得のGetリクエスト
    try :
        res1 = requests.get(
            DeplumentInfo_URL,
            headers=headers
        )
    except Exception as err:
        print("Something Fatal Happened")
        print (err)
        sys.exit()

    # requrest処理をクローズする
    res1.close

    # デプロイ情報の取得有無判斷
    if len(res1.json()['value']) == 0:
        print("\n AzureCLI もしくは Terraform 等で構築されたリソースグループの場合、取得できません、、、、 \n")
        return 0 

    # res1をjsonファイルに整形しデプロイ履歴情報の取得
    for num, item in enumerate(res1.json()['value']):
        print("\n■ ■ ■ {}".format(item["name"]))
        # print(json.dumps(item, indent = 2))

        # 保存するファイル名の生成
        now = datetime.now()
        filename = './output/Deployment__' + rg_name + '_' + item["name"] + '_' + now.strftime('%Y%m%d_%H%M%S') + '.json'

        # デプロイ情報データをローカルファイルへ
        DeploymentToLocalFile(item, filename)

        # デプロイ操作データの取得
        GetDepeloymentOperation(access_token, rg_name, item["name"], now)

    return num+1


# Azureにアクセスするためのトークンの取得(Access_Token)
def get_azure_access_token() -> str:

    # access_token を取得するためのヘッダ情報
    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    payload = {
        'client_id': CLIENT_ID,
        'scope': 'https://management.azure.com/.default',
        'grant_type': 'client_credentials',
        'client_secret': CLIENT_KEY
    }

    # access_token を取得するためのURLを生成
    TokenGet_URL = "https://login.microsoftonline.com/" + \
        TENANT_ID + "/oauth2/v2.0/token"

    # アクセストークンの取得
    try :
        response = requests.get(
            TokenGet_URL,
            headers=headers,
            data=payload
        )
    except Exception as err:
        print("Something Fatal Happened")
        print (err)
        sys.exit()

    # requrest処理のクローズ
    response.close

    jsonObj = json.loads(response.text)
    return jsonObj["access_token"]


# メイン
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='引数なし:リソースグループ一覧の取得、  引数あり:指定したリソースグループ内のリソース毎のデプロイ情報・履歴の取得')
    parser.add_argument('-g', '--rg', type=str, help='リソースグループ名')
    args = parser.parse_args()

    start = time.time()

    if args.rg == None :
        GetResourceGroup()
    else :
        access_token = get_azure_access_token()
        print(f"取得アクセストークン :\n{access_token}\n")
        cnt = GetDepeloymentInfo(access_token, args.rg)
        print("\n  Deplyment_name 数 : " + str(cnt))

    generate_time = time.time() - start

    print("\n  取得時間:{0}".format(generate_time) + " [sec] \n")

プログラムのHELP表示

## HELPの表示
$ python GetDepeloymentHistory.py -h                                     

usage: GetDepeloymentHistory.py [-h] [-g RG]

引数なし:リソースグループ一覧の取得、  引数あり:指定したリソースグループ内のリソース毎のデプロイ履歴・操作情報の取得

optional arguments:
  -h, --help      show this help message and exit
  -g RG, --rg RG  リソースグループ名

プログラムの実行

まずは最初に、リソースグループ一覧の取得

$ python GetDepeloymentHistory.py

Resource Group                                    Location
----------------------------------------------------------------------------------------------------
rg_AzureStackHCI                                  eastus
rg_NetworkWatcher                                 japaneast
     :
    省略
     :
rg_ituru_vm02                                     japaneast
rg_ituru_deploy_test                              japaneast

  取得時間:0.4982631206512451 [sec] 

上記のリソースグループ一覧から、指定したリソースグループのデプロイ情報・履歴を取得し、ローカルファイルへ保存

$ python GetDepeloymentHistory.py -g rg_ituru_deploy_test

取得アクセストークン :
eyJ0eXAiOiJ・・・省略・・・VjCV6lrbWc8Dw

■ ■ ■ Microsoft.VirtualNetwork-20220201112413
./output/Deployment__rg_ituru_deploy_test_Microsoft.VirtualNetwork-20220201112413_20220201_160456.json
./output/Deployment_Operation__rg_ituru_deploy_test_Microsoft.VirtualNetwork-20220201112413_20220201_160456.json

  Deplyment_name 数 : 1

  取得時間:0.49964094161987305 [sec] 

Outputファイルの確認

$ ls -l ./output        
total 32
drwxr-xr-x   6 ituru  staff   192  2  1 16:08 ./
drwxr-xr-x  12 ituru  staff   384  2  1 16:05 ../
-rw-r--r--   1 ituru  staff  1483  2  1 16:04 Deployment_Operation__rg_ituru_deploy_test_Microsoft.VirtualNetwork-20220201112413_20220201_160456.json
-rw-r--r--   1 ituru  staff  2511  2  1 16:04 Deployment__rg_ituru_deploy_test_Microsoft.VirtualNetwork-20220201112413_20220201_160456.json

デプロイ履歴情報(Deployment__rg_xxxxxxxxxxx.json)

{
  "id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_deploy_test/providers/Microsoft.Resources/deployments/Microsoft.VirtualNetwork-20220201112413",
  "name": "Microsoft.VirtualNetwork-20220201112413",
  "type": "Microsoft.Resources/deployments",
  "tags": {
    "primaryResourceId": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_deploy_test/providers/Microsoft.Network/virtualNetworks/vnet_ituru_deploy_test",
    "marketplaceItemId": "Microsoft.VirtualNetwork-ARM"
  },
  "properties": {
    "templateHash": "15981414355539578904",
    "parameters": {
      "location": {
        "type": "String",
        "value": "japaneast"
      },
      "extendedLocation": {
        "type": "Object",
        "value": {}
      },
      "virtualNetworkName": {
        "type": "String",
        "value": "vnet_ituru_deploy_test"
      },
      "resourceGroup": {
        "type": "String",
        "value": "rg_ituru_deploy_test"
      },
      "addressSpaces": {
        "type": "Array",
        "value": [
          "10.6.0.0/16"
        ]
      },
      "ipv6Enabled": {
        "type": "Bool",
        "value": false
      },
      "subnetCount": {
        "type": "Int",
        "value": 1
      },
      "subnet0_name": {
        "type": "String",
        "value": "default"
      },
      "subnet0_addressRange": {
        "type": "String",
        "value": "10.6.0.0/24"
      },
      "ddosProtectionPlanEnabled": {
        "type": "Bool",
        "value": false
      },
      "firewallEnabled": {
        "type": "Bool",
        "value": false
      },
      "bastionEnabled": {
        "type": "Bool",
        "value": false
      }
    },
    "mode": "Incremental",
    "debugSetting": {
      "detailLevel": "None"
    },
    "provisioningState": "Succeeded",
    "timestamp": "2022-02-01T02:24:55.4064206Z",
    "duration": "PT4.7454974S",
    "correlationId": "a891f3f3-4477-4545-acac-d748ffdd2857",
    "providers": [
      {
        "namespace": "Microsoft.Network",
        "resourceTypes": [
          {
            "resourceType": "VirtualNetworks",
            "locations": [
              "japaneast"
            ]
          }
        ]
      }
    ],
    "dependencies": [],
    "outputResources": [
      {
        "id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_deploy_test/providers/Microsoft.Network/VirtualNetworks/vnet_ituru_deploy_test"
      }
    ],
    "validationLevel": "Template"
  }
}

デプロイ操作情報(Deployment_Operation__rg_xxxxxxxxxxx.json)

[
  {
    "id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_deploy_test/providers/Microsoft.Resources/deployments/Microsoft.VirtualNetwork-20220201112413/operations/557B59888B6CD293",
    "operationId": "557B59888B6CD293",
    "properties": {
      "provisioningOperation": "Create",
      "provisioningState": "Succeeded",
      "timestamp": "2022-02-01T02:24:55.2896236Z",
      "duration": "PT2.9130169S",
      "trackingId": "3838ccbb-f42d-4c26-92be-b46005570e40",
      "serviceRequestId": "f597efef-c06c-4ee4-8683-083f3a862760",
      "statusCode": "OK",
      "targetResource": {
        "id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_deploy_test/providers/Microsoft.Network/VirtualNetworks/vnet_ituru_deploy_test",
        "resourceType": "Microsoft.Network/VirtualNetworks",
        "resourceName": "vnet_ituru_deploy_test"
      }
    }
  },
  {
    "id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_deploy_test/providers/Microsoft.Resources/deployments/Microsoft.VirtualNetwork-20220201112413/operations/00585579225949072200",
    "operationId": "00585579225949072200",
    "properties": {
      "provisioningOperation": "EvaluateDeploymentOutput",
      "provisioningState": "Succeeded",
      "timestamp": "2022-02-01T02:24:55.3801548Z",
      "duration": "PT3.0035481S",
      "trackingId": "5252d103-4555-4c4c-821c-0c5ef88ccc34",
      "statusCode": "OK"
    }
  }
]

まとめ

このプログラムで、指定するリソースグループ内にあるリソースのデプロイ履歴・操作情報をサクッと取得し、その内容を json形式 でローカルファイルに保存できました。

この2つのデプロイ履歴情報とデプロイ操作情報の json ファイルは、Azure Portalから「リソースグループ」ー「設定:デプロイ」からデプロイ名を選択し、「展開の詳細」ー「ダウンロード」から入手できる「deployment.json(履歴情報)」「deployment_operations.json(操作情報)」の2つのファイルと同等となっています。

ただ、この2つのデプロイ情報は、AzurePortalからリソースを作成した場合のみ取得可能(?)であり、AzureCLI / Terraform 等でリソースを作成した場合には取得不可となります。なんでだろ、、、、、

AzureCLI / Terraform 等でリソースを作成した場合、デプロイ情報の取得は「テンプレートのエクスポート」しかないんでしょうか?、、、、、、、

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0