Azure Arc を使って Logic App をオンプレミスで動かしてみる
Logic App の豊富なコネクタを活用しつつ、オンプレミスに閉じているサービスとの連携ができるととても良いのでは、という事で。
ドキュメント。
環境
- オンプレミスに閉じた k8s
- パブリックIP を持たない
-
https://zenn.dev/_ta/articles/dc1306ce1a7d4c で作ったやつ
- Azure Stack Hub 上に構築した k8s である必要は、全くない
前提条件
- Azure Arc enabled Kubernetes に接続されている事
- Azure Arc enabled App Service 拡張機能がインストールされている事
こんな感じ。
vscode で Logic App を作る
>mkdir arc-logicapp-test
>cd arc-logicapp-test
>code .
vscode のコマンドパレットから「Azure Logic Apps: Create New Project...」を選択。
プロジェクトのフォルダを選択。
「Statefull」を選択。
プロジェクト名を指定。
空のフローが出来る。
workflow.json を右クリックしてデザイナで開く。
「Use Connectors from Azure」を選択。
Logic Apps コネクタをデプロイする Azure のリソースグループを選択。ここでは新規作成する。
リージョンを選択。Azure Arc enabled k8s と同じリージョンを選択する。
vscode でデザイナーが開く。
この時点では、Azure には空のリソースグループが作られるだけ。
一旦、Azure コネクタを使わないフローをデプロイして動作を確認する。
Schedule トリガーで、オンプレミスにある適当なチャットに POST するフローを作成して保存。
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"HTTP": {
"type": "Http",
"inputs": {
"method": "POST",
"uri": "http://<your_host>",
"headers": {
"Content-Type": "aapplication/json"
},
"body": {
"text": "今は @{utcNow()} です。",
"username": "Azure Arc Logic App"
}
},
"runAfter": {}
}
},
"triggers": {
"Recurrence": {
"type": "Recurrence",
"recurrence": {
"frequency": "Minute",
"interval": 10
}
}
},
"contentVersion": "1.0.0.0",
"outputs": {}
},
"kind": "Stateful"
}
デプロイする。
コマンドパレットから「Azure Logic Apps: Deploy to Logic App...」を選択。
新規作成。Advanced を選択。
Logic App 名を入力。
ロケーションを選択。ここでカスタムロケーションを選択する。
リソースグループは、先ほど作成したリソースグループを選択する。
Logic App をデプロイするストレージアカウントを新規作成。
Application Insights を新規作成。Azure 上の Logic App と違って、フローのどこでエラーが発生したかが視覚的には分からないので、Application Insights は必須と言っていい。
App Service Plan が勝手に作られて(名称指定したかった)、デプロイが完了する。
13:36:03: Ensuring App Service plan "arc-logicapp-test2" exists...
13:36:03: Creating App Service plan "arc-logicapp-test2"...
13:36:09: Successfully created App Service plan "arc-logicapp-test2".
13:36:09: Creating storage account "arclogicapptest" in location "eastus" with sku "Standard_LRS"...
13:36:45: Successfully created storage account "arclogicapptest".
13:36:45: Verifying that Application Insights is available for this location...
13:36:46: Creating Application Insights resource "arc-logicapp-test"...
13:36:54: Successfully created Application Insights resource "arc-logicapp-test".
13:36:54: Creating new logic app "arc-logicapp-test"...
13:37:19 arc-logicapp-test: Starting deployment...
13:37:20 arc-logicapp-test: Creating zip package...
13:37:20 arc-logicapp-test: Zip package size: 1.02 kB
13:36:16 arc-logicapp-test: Updating submodules.
13:36:16 arc-logicapp-test: Preparing deployment for commit id '0796038f9d'.
13:36:16 arc-logicapp-test: Builder : K8SE Basic Builder
13:36:16 arc-logicapp-test: Writing the artifacts to Squashfs file at /home/apps/arc-logicapp-test/site/artifacts/0796038f9d6e4c48b1af891a55f248bf
13:36:16 arc-logicapp-test: Parallel mksquashfs: Using 2 processors
13:36:17 arc-logicapp-test: Creating 4.0 filesystem on /home/apps/arc-logicapp-test/site/artifacts/0796038f9d6e4c48b1af891a55f248bf/artifact.zip, block size 131072.
13:36:17 arc-logicapp-test: [===================================================================|] 3/3 100%
13:36:17 arc-logicapp-test: Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 131072
13:36:17 arc-logicapp-test: compressed data, compressed metadata, compressed fragments, compressed xattrs
13:36:17 arc-logicapp-test: duplicates are removed
13:36:17 arc-logicapp-test: Filesystem size 0.88 Kbytes (0.00 Mbytes)
13:36:17 arc-logicapp-test: 51.92% of uncompressed filesystem size (1.70 Kbytes)
13:36:17 arc-logicapp-test: Inode table size 82 bytes (0.08 Kbytes)
13:36:17 arc-logicapp-test: 50.62% of uncompressed inode table size (162 bytes)
13:36:17 arc-logicapp-test: Directory table size 91 bytes (0.09 Kbytes)
13:36:17 arc-logicapp-test: 85.85% of uncompressed directory table size (106 bytes)
13:36:17 arc-logicapp-test: Number of duplicate files found 0
13:36:17 arc-logicapp-test: Number of inodes 5
13:36:17 arc-logicapp-test: Number of files 3
13:36:17 arc-logicapp-test: Number of fragments 1
13:36:17 arc-logicapp-test: Number of symbolic links 0
13:36:17 arc-logicapp-test: Number of device nodes 0
13:36:17 arc-logicapp-test: Number of fifo nodes 0
13:36:17 arc-logicapp-test: Number of socket nodes 0
13:36:17 arc-logicapp-test: Number of directories 2
13:36:17 arc-logicapp-test: Number of ids (unique uids + gids) 1
13:36:17 arc-logicapp-test: Number of uids 1
13:36:17 arc-logicapp-test: root (0)
13:36:17 arc-logicapp-test: Number of gids 1
13:36:17 arc-logicapp-test: root (0)
13:36:17 arc-logicapp-test: Running post deployment command(s)...
13:36:17 arc-logicapp-test: Deployment successful.
13:36:17 arc-logicapp-test: Deployment Pod Rollout Started! Use 'kubectl -n k8se-apps get pods arc-logicapp-test --watch' to monitor the rollout status
13:36:17 arc-logicapp-test: Deployment Pod Rollout Started! Use kubectl watch deplotment arc-logicapp-test to monitor the rollout status
動く。
k8s では pod が動いている事が確認できる。
$ kubectl -n azs-tokyo get pods
NAME READY STATUS RESTARTS AGE
(略)
arc-logicapp-test-64f6c56cd-sgvnp 2/2 Running 0 16m
Azure コネクターを使う
Azure Blob トリガーを使って、作成された Blob 名を post する。
まず、トリガーとなる Storage Account を Azure に作成する。参照するコンテナーも。
vscode でワークフローデザイナーを起動して、Azure Blob トリガーを選択する。
上で作った Blob 名とアクセスキーを指定して「Create」。
Blob トリガーの設定画面に切り替わり、Blob とコンテナ―が選択できるようになる。
一度に取得する件数とポーリング間隔を指定して保存。
ちなみに Azure にはコネクタが作成されている。
作成された Blob 名を投げるように HTTP アクションを変更。
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"HTTP": {
"type": "Http",
"inputs": {
"method": "POST",
"uri": "http://<your_host>",
"headers": {
"Content-Type": "aapplication/json"
},
"body": {
"text": "@{utcNow()} @{triggerBody()?['Name']} が作成されました!",
"username": "Azure Arc Logic App"
}
},
"runAfter": {}
}
},
"triggers": {
"When_a_blob_is_added_or_modified_(properties_only)_(V2)": {
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"referenceName": "azureblob"
}
},
"method": "get",
"path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('arclogicapptestblob'))}/triggers/batch/onupdatedfile",
"queries": {
"folderId": "JTJmdHJpZ2dlcg==",
"checkBothCreatedAndModifiedDateTime": false,
"maxFileCount": 1
}
},
"recurrence": {
"frequency": "Minute",
"interval": 1
},
"metadata": {
"JTJmdHJpZ2dlcg==": "/trigger"
},
"splitOn": "@triggerBody()"
}
},
"contentVersion": "1.0.0.0",
"outputs": {}
},
"kind": "Stateful"
}
現在、Azure Arc 対応 Kubernetes クラスターでは、ロジック アプリのマネージド ID を使用したマネージド API 接続の認証はサポートされていません。 ワークフローでマネージド コネクタを使用する場合は、これらの Azure がホストするマネージド接続を作成します。
という事なので、サービスプリンシパルを作成する。
>az ad sp create-for-rbac --name arc-logicapp-test-sp
{
"appId": "********-****-****-****-************",
"displayName": "arc-logicapp-test-sp",
"name": "********-****-****-****-************",
"password": "**********************************",
"tenant": "********-****-****-****-************"
}
connectors.json の authentication を以下に置き換える。
"authentication": {
"type": "ActiveDirectoryOAuth",
"audience": "https://management.core.windows.net/",
"credentialType": "Secret",
"clientId": "@appsetting('WORKFLOWAPP_AAD_CLIENTID')",
"tenant": "@appsetting('WORKFLOWAPP_AAD_TENANTID')",
"secret": "@appsetting('WORKFLOWAPP_AAD_CLIENTSECRET')"
}
local.settings.json に以下を追加。
{
"IsEncrypted": false,
"Values": {
<...>
"WORKFLOWAPP_AAD_CLIENTID":"<my-client-ID>",
"WORKFLOWAPP_AAD_OBJECTID":"<my-object-ID>",
"WORKFLOWAPP_AAD_TENANTID":"<my-tenant-ID>",
"WORKFLOWAPP_AAD_CLIENTSECRET":"<my-client-secret>"
}
}
上書きデプロイする。
AAD 情報を要求されるので、object ID
, client ID
, tenant ID
, client secret
の4つのキーを指定する。
object ID
は az ad sp show --id <your_app_id>
で取得できる。
Azure ポータルのこれではないので注意(すげーハマった・・・)。
また、 client ID
にはサービスプリンシパル作成時の戻り値の appId
の値を、client secret
には password
の値を指定する。
上書きを認めてデプロイ完了。
Logic App のアプリケーション設定にサービスプリンシパルのキーと値が登録される。
サービスプリンシパルにコネクターのアクセスポリシーを付与する。
・・・と思ったら、もう付与されている。connectors.json から良い感じにやってくれているのか?
Azure Blob トリガーのテスト
Blob に適当なファイルをアップロードする。
来た!
動き始めるには数分待つ。初回のリクエストはキャンセルされた模様。
こういう事。
インターネットで発生したイベントをトリガーとしてオンプレのサービスを呼ぶには便利なパターンになるんじゃないか。
Application Insights
Application Insights でメトリックやアプリケーションマップなどが見れて、とても良い。
尚、k8s が proxy の内側にいる場合は、vscode の proxy 設定で .k4apps.io を除外する。.k4apps.io のアドレスはオンプレミスネットワークになるので、proxy 経由でオンプレにアクセスしようとして、proxy によっては弾かれる場合がある。
"http.proxy": "http://<your_proxy>",
"rest-client.excludeHostsForProxy": [
"*.k4apps.io"
]