LogicAppsでTableStorageからサーバーリストを取得してみる

### 初めに
皆さんこんにちは、こちらの記事は[LogicAppsとHybridRunbookWorkerで複数台の仮想マシンを操作する](https://qiita.com/pienhalifax/items/72c97967b3ec809b96fe)の2本目の記事となっております。
もちろん、この記事だけでも十分意味のあるものですので好きなように利用していって下さい。

本記事では、LogicAppsでTableStorageからサーバーリストを取得して配列に格納するまでの流れを解説しております。以下要素が学べることです。
+ TableStorageをAzurePortalから構築する
+ LogicAppsをBicepで構築する
+ Bicepでリソースにロール付与をしてみる
+ LogicAppsでTableStoage内のデータを取得してみる
+ LogicAppsでJSON形式のデータを加工して配列に格納する

関連記事は以下よりジャンプしてください。
ROOT：[LogicAppsとHybridRunbookWorkerで複数台の仮想マシンを操作する](https://qiita.com/pienhalifax/items/72c97967b3ec809b96fe)
NEXT：準備中

## 目次

+ [TableStorageから仮想マシンのリストを取得する](#tablestorageから仮想マシンのリストを取得する)
    + [TableStorageを用意する](#tablestorageを用意する)
    + [LogicAppsを用意する（Bicep）](#logicappsを用意する)
    + [TableStorageから仮想マシンのリストを取得する](#tablestorageから仮想マシンのリストを取得する)
    + [仮想マシンのLinuxサーバーだけにフィルタしてみる](#仮想マシンのlinuxサーバーだけにフィルタしてみる)

## TableStorageから仮想マシンのリストを取得する
このセクションでは以下のような処理フローを実現していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/cc3cbaf1-12a0-6ddf-29e5-9bb8318b679f.png)



### TableStorageを用意する
まずは、前提として必要なTableStorageの構成をしていきます。
今回は以下のようなテーブルを作成していきます。
ちなみに、テーブル操作は「StorageExplorer」があるとCSVインポートもできるので便利です。

|Partition Key|Row Key|
|---|---|
|DemoServer01|001|
|DemoServer02|002|

Partition Keyにはサーバー名を記載し、RowKeyは一意であれば何でもよいです。
テーブルの作成方法は以下、MSの公式ドキュメントを参考にしてください。
+ [MS公式ドキュメント|クイック スタート: Azure portal でテーブルを作成する](https://learn.microsoft.com/ja-jp/azure/storage/tables/table-storage-quickstart-portal)

こんな感じで作成出来たら次へ進みましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/fcd16cc7-c529-fa59-40fc-c8259170d498.png)


## LogicAppsを用意する
今回は従量課金モデルで作成していきます。
以下を参考にBicepで作っていきましょう。
+ [MS公式ドキュメント|クイック スタート: クイック スタート: Bicep を使用してマルチテナント Azure Logic Apps で従量課金ロジック アプリ ワークフローを作成してデプロイする](https://learn.microsoft.com/ja-jp/azure/logic-apps/quickstart-create-deploy-bicep?tabs=CLI)
+ [MS公式ドキュメント|クイックスタート: Bicep を使用して Azure でのロールを割り当てる](https://learn.microsoft.com/ja-jp/azure/role-based-access-control/quickstart-role-assignments-bicep?tabs=CLI)

私が使用したコードはこんな感じです。
サンプルから、ワークフローの作成部分を抜いています。
```LogicApps.bicep
param logicAppName string
param testUri string = 'https://azure.status.microsoft/status/'

param location string = resourceGroup().location
var frequency = 'Hour'
var interval = '1'
var type = 'recurrence'
var actionType = 'http'
var method = 'GET'
var workflowSchema = 'https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#'

resource stg 'Microsoft.Logic/workflows@2019-05-01' = {
  name: logicAppName
  location: location
  tags: {
    displayName: logicAppName
  }
  //追加：ここでシステム割当てユーザーをオンにする
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    definition: {
      '$schema': workflowSchema
      contentVersion: '1.0.0.0'
      parameters: {
        testUri: {
          type: 'string'
          defaultValue: testUri
        }
      }
      triggers: {
        recurrence: {
          type: type
          recurrence: {
            frequency: frequency
            interval: interval
          }
        }
      }
      actions: {
        actionType: {
          type: actionType
          inputs: {
            method: method
            uri: testUri
          }
        }
      }
    }
 }
}

output name string = stg.name
output resourceId string = stg.id
output resourceGroupName string = resourceGroup().name
output location string = location
```

以下、ロール割り当てのBicepFileになります。
```RoleAssignment.Bicep
param roleDefinitionID string
param logicAppName string
param storageAccountName string

resource LogicApps 'Microsoft.Logic/workflows@2019-05-01' existing = {
  name: logicAppName
}

resource StorageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = {
  name: storageAccountName
}

var roleAssignmentName= guid(LogicApps.id, StorageAccount.id, roleDefinitionID)
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  scope: StorageAccount
  name: roleAssignmentName
  properties: {
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionID)
    principalId: LogicApps.identity.principalId
  }
}
output role_name string = roleAssignment.name
output role_resourceGroupName string = resourceGroup().name
output role_resourceId string = roleAssignment.id
```

あとは以下コードでデプロイしていきます。
リソースグループがまだ作成していない方は、先に作成して下さい。
```PowerShell
##テントにログインします。
az login --tenant <テナントのドメイン名>

##以下コマンドでデプロイしていきます。
##logicAppName：LogicAppsの名前
az deployment group create --resource-group kensho-rg --template-file LogicApps.bicep --parameters logicAppName='demo-LogicApp'

##以下コマンドでロール割り当てをしていきます。
##logicAppName：LogicApps名(上記と同じ値)
##storageAccountName：ストレージアカウント名
###ストレージ テーブル データ共同作成者
az deployment group create --resource-group kensho-rg --template-file RoleAssignment.bicep --parameters logicAppName='demo-LogicApp' storageAccountName=<StorageAccount名> roleDefinitionID='0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'
###ストレージ アカウント共同作成者
az deployment group create --resource-group kensho-rg --template-file RoleAssignment.bicep --parameters logicAppName='demo-LogicApp' storageAccountName=<StorageAccount名> roleDefinitionID='17d1049b-9a84-46fb-8f53-869881c3d3ab'
```

AzurePortalで作成したLogicAppsを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/74eba6ac-a603-6b7a-2796-8356a1a2b94d.png)


ロール割り当ても念のため確認しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/eab90595-35a3-72cb-6281-5101f165eeaa.png)



## TableStorageから仮想マシンのリストを取得する
ここからはAzurePortalを使用して、LogicAppsのワークフローを作成していきます。
ここからはGUIで操作していきます。
### トリガーを作成する
まずは、トリガーを作成しましょう。今回はスケジュールを使用します。
（上のBicepコードで作成した方は最初からトリガーが設置されているかと思います。）
※不用意にワークフローが起動しないように、少し未来の日付で設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/3d00d0ce-03f8-2e68-8c3f-4ec1e875490c.png)

### TableStorageからサーバーリストを取得する
こちらのコンポーネントを使用していきます。
+ [MS公式ドキュメント|Azure テーブル ストレージ](https://learn.microsoft.com/ja-jp/connectors/azuretables/#get-entities-(v2))

まずは接続を設定します。ManagedIDを選択しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/73405e17-1116-c57d-e986-7ba11b5a9663.png)

次に、各パラメーターを記載していきます。
PartitionKeyにサーバー名を記載しておりますので、PartitionKeyを取得していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/4d309abc-839f-3c5f-b4ce-682ec81271b6.png)


### 取得したエンティティからサーバー名を取得
取得したデータはこんな感じのJSOON形式になっています。
```Json:加工前
[
  {
    "odata.etag": "W/\"datetime'2025-01-24T03%3A39%3A20.812372Z'\"",
    "PartitionKey": "DemoServer01"
  },
  {
    "odata.etag": "W/\"datetime'2025-01-24T03%3A41%3A58.5135315Z'\"",
    "PartitionKey": "DemoServer02"
  }
]
```
これをこんな感じに加工します。
```Json:加工後
[
  "DemoServer01",
  "DemoServer02"
]
```

ここでは以下コンポーネントを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/1af32f53-7534-6a21-545e-5ae6bb748c89.png)

以下操作のヒントを載せておりますので、完成系みつつ作って設定してみて下さい。
①前のコネクタで取得したエンティティを使用するには以下のように雷マークを押すことで選択できます。
②切り替えボタンをクリックすることで、「Mapモード」に切り替えられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/b1b419cc-49cc-f4c0-6321-495816418dfc.png)

こちらも、前のコネクタの「Output」を使用して作成してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/546ed443-2e96-59be-c46d-316d5c7cbb7a.png)

### サーバー名をTargetServerListに代入
続いて先ほどのコネクタで作成したサーバーリストを配列に格納していきます。
次はこちらのコネクタを用意していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/bdb1d726-4f2b-0152-fb5b-335a4125ff1e.png)

設定したらこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/cd3548f3-5aec-5cf0-dcfc-ae35b06f3405.png)

ここまでできたので、実行してみましょう。
画面左上の「保存」⇒「実行」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/bf15f163-385f-7773-e9ae-448f49a9746a.png)

実行結果は「実行履歴」から確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/a308780b-d7ca-5100-0b7e-ba5842f50bd7.png)

いい感じですね。では、次へ進んでいきましょう。

## 仮想マシンのLinuxサーバーだけにフィルタしてみる
### TableStorageにOS列を追加する
このセクションでは、TableStorageにOS列を追加してそのOS列でフィルタリングした結果を取得していきます。まずは、TableStorageにOS列を追加していきましょう。
以下のような感じでできたらOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/109d0fed-2657-0997-a592-aff4d313e625.png)

### フィルタークエリを追加する。
前段で作成した「TableStorageへ接続するコネクタ」にフィルターを追加していきます。

```KQL:クエリフィルタ
OS eq 'Linux'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/85ea4c9e-6a94-e95b-b43b-8d7b2bd20e31.png)


### 実行結果
こんな感じで、Linuxサーバーだけ取得できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/260b45cb-a01b-e08e-8675-e2127e9fc664.png)


### 続き
次の記事で説明します。
NEXT<準備中>