LoginSignup
9
2

More than 1 year has passed since last update.

こんにちは、GxPの平山です。
この記事はグロースエクスパートナーズ Advent Calendar 2022の18日目です。

現在携わっている案件にてAzureを扱っており、Azure Logic Appsを使用しております。
今回はLogic Appsのワークフローでパラメーターを扱う方法の紹介と、注意点、応用についてご紹介したいと思います。
Logic Appsを複数の環境で扱うような場合に、パラメーターを活用することで環境に合わせて動作を制御できて便利です。

※本記事内の検証内容は、Logic Appsの従量課金タイプ、ホスト環境がマルチテナントでの検証になります。

Logic Appsのパラメーター機能を使用する

Logic Appsが提供するパラメーター機能について紹介いたします。まずは基本から。
手順については以下に記載がありますが、細かい部分や、実際の画面内容も添えて説明いたします。

パラメーターの定義

Logic Apps のデザイナー上で「[@]パラメーター」を選択し、「パラメーターの追加」をクリック
image.png

以下のような画面が表示され、「パラメーターの名前」、「種類」、「既定値」を入力します。
「実際の値」についてはグレーアウトされており、入力ができません(後述の「パラメーターの実際の値を設定する」にて説明します)。
今回は外部のAPIを呼び出すようなケースを想定して、APIのURLをパラメーター化してみます。
image.png

パラメーターを使用する

ワークフロー上の設定したい項目を選択すると、前節で定義したパラメーターが表示されます。
以下のキャプチャでは、「URI」欄を選択している状態です。
image.png

パラメーターを選択することで、「URI」欄にパラメーターが設定されます。
image.png

この状態で保存の上、Logic Appsを実行すると、先ほど設定したパラメーターの値(既定値)が展開され、http://example.com にGETリクエストが実行されます。
image.png

パラメーターの実際の値を設定する

先ほど定義したパラメーターの値はあくまで既定値(デフォルト)です。
環境などに合わせてパラメーターを変更したい場合は、「実際の値」を設定します。
「実際の値」は、Logic Appsのコードエディタ上で指定できます。

先ほどのHogeApiURIパラメーターの「実施の値」を、 http://www.example.net にしてみます。

{
    "definition": {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "actions": {
            "HTTP": {
                "inputs": {
                    "method": "GET",
                    "uri": "@parameters('HogeApiUrl')"
                },
                "runAfter": {},
                "type": "Http"
            }
        },
        "contentVersion": "1.0.0.0",
        "outputs": {},
        "parameters": {
            "HogeApiUrl": {
                "defaultValue": "http://example.com",
                "type": "String"
            }
        },
        "triggers": {
            "manual": {
                "inputs": {
                    "schema": {}
                },
                "kind": "Http",
                "type": "Request"
            }
        }
    },
-   "parameters": {}
+   "parameters": {
+       "HogeApiUrl": {
+           "value": "http://www.example.net"
+       }
    }
}

変更内容について解説しておくと、json のトップレベルのparametersに対して、Logic Appsのデザイナーで定義したパラメーターと同じ名前のプロパティを追加し、valueプロパティの値を指定します
なお、デザイナーで定義したパラメーターは、definitionparametersプロパティに種類(type)と既定値(defaultValue)が記載されています
1つのjson内にparametersが2つ出てくるので、違いに注意してください。

再度、デザイナーでパラメーターを確認してみると、「実際の値」欄に http://www.example.net が設定されています。
image.png

実行してみると、「既定値」ではなく、「実際の値」に対してGETリクエストが実行されています。
image.png

パラメーターの種類と値サンプル

最後に、LogicAppsのパラメーターの種類と値のサンプルを照会しておきます。いずれも素直な構文なので、悩むことはないと思いますが、参考までに。

種類 値のサンプル
String "test value"
Array [1,2,3]
Bool true
Float 1.234
Int 123
Object {"column1":"value1", "column2":"value2"}
Secure String ※String型と同様
Secure Object ※Object型と同様

なお、Secure *型を使用する場合ですが、「既定値」には必ずダミー値を設定してください!
型の種類にかかわらず、「既定値」はプレーンテキストとして保存されるため、他人が閲覧できる状態となるためです。
既定値には何らかのダミー値を入れて置きましょう。
image.png
※「設定しないことをお勧めします」と出ていますが、値を入れないと保存できません…。

パラメーターの実際の値を設定する」で紹介した方法で「実際の値」を指定してください。
image.png
設定を保存したのち、画面のリロードを行うと見えないようになります。
これは、対応するパラメーターがSecure *型であることをLogic Appsが判別して、値を隠蔽してくれるようです 。
image.png
参考:ワークフロー定義内のパラメーターをセキュリティで保護する

Azure Key Vaultで定義したシークレットを取得する

Logic Appsの Secure *型パラメーターを使えば、秘匿情報を安全に扱うことができますが、管理が個々のLogic Appsに分散してしまいます。
Azureで秘匿情報を一元管理するサービスといえば、Azure Key Vaultですね。

Azureでは、Key Vault のシークレットをLogic Appsで扱うための、ビルトインコネクタが提供されています。
これを使えば、Key Vaultで管理されたシークレットを、簡単な手順で参照可能です。

Logic Apps の設定手順

Azure Key Vault のコネクタを選択し、「シークレットの取得」アクションを選択します
初期画面が表示されたら、まずはKey Vaultのリソース名を入力します。
image.png

Key Vaultへのアクセスは認証が必要です。推奨はマネージドIDでの認証です。
「マネージドIDを使用して接続する」を選択し、接続名と再度Key Vaultのリソース名を設定します。システム割り当てマネージドIDで作成を実行します(API 接続リソースが作成されます)。
image.png

シークレットの取得の設定画面に戻ったところで、取得したいシークレット名を入力します
入力しようとすると「値を取得できませんでした。(以下略)」と出てます。
あえてKey Vaultのシークレットに対する「一覧」の権限をつけていないためです。
「カスタム値の入力」か、コードエディタで直接入力できます。
image.png
image.png

Logic Appsでパラメーターを定義した場合と同様に、後続のステップで参照できるようになります。
image.png

:warning: シークレットを扱う上での注意事項

今回の個人的には一番伝えておきたいところです。案外見落としがちなところだと思います(私だけでしょうか…?)。

まずは以下を見てみてください。HTTPコネクタで外部のAPIを呼び出すシナリオを想定して、LogicAppsを実行した結果(ログ)です。
Key Vaultから取得したシークレット(APIキー)を、x-api-keyヘッダに指定して呼び出しています。
image.png
お か わ り い た だ け る だ ろ う か ? :rice:
そうです、ログにシークレット情報が表示されちゃってます。やばいですね!

このように、何も考えず後続のステップで取得したシークレットを参照すると、ログに記録されてしまう場合があります。
Logic Appsで定義したSecure *型のパラメーターを定義して使用する場合も同様です。

公式ドキュメントでも、このようなケースについて以下のように注意喚起されています。ちゃんと対策しましょう。

ロジック アプリの実行履歴を表示するときは、Azure Logic Apps によってアクセスの認証が行われた後、各実行の要求と応答に対する入力および出力へのリンクが提供されます。 ただし、パスワード、シークレット、キーなどの秘匿性の高い情報を処理するアクションについては、他のユーザーがそのデータを表示したり利用したりできないようにします。 たとえば、ロジック アプリが HTTP アクションの認証時に使用する Azure Key Vault のシークレットを取得する場合、そのシークレットが見えないようにする必要があります。

対策方法、設定手順についても上記の公式ドキュメントに書かれていますので、ご参照ください。
本記事では、実際に設定してみた結果をご紹介します。それぞれメリット/デメリットがありますので、ご利用の状況に合わせて選んでいただくとよいかと思います。

[対策1] IP アドレス範囲でアクセスを制限する

IPアドレスでの制限(ホワイトリスト形式)です。許可されていないIPアドレスからのアクセスだと、すべての実行ログが見えなくなります。これでもよいですが、関係ないところまで見えなくなってしまうのと、リモートワークが当たり前な昨今を考えると、IPアドレスでの制御は少々扱いづらいかもしれません。
image.png

[対策2] 難読化を使用して実行履歴のデータをセキュリティで保護する

「HTTP」の入力の保護設定を有効化することで、保護すべき部分だけ見えなくできます。個人的にはこちらのほうがオススメです。
この方法では見えてもよいユーザーも見えなくなりますが、ログに秘匿情報が残ってしまうのは予期せぬ漏洩のリスクを孕むので、表示させないほうが安全です。
image.png
※「シークレットの取得」の出力の保護設定は無効のままですが、シークレットのメタデータのみ出力される(値は出力されない)ので許容範囲と判断しました。必要であればこちらにも保護をかけておきましょう。

AppConfiguration上で定義したパラメーター(キー値)を取得する

App Configuration でアプリケーションの構成を一元管理しているような場合、LogicAppsで扱うパラメーターも管理したくなるかもしれません。
App Configuration ではキーと値のセットで構成管理を行うので、Key Vaultと同様の方法で取得ができそうですが…。
残念ながら、現時点でApp Configuration 用のコネクタは公式から提供されていません。
ということで、公式がサポートしてくれるのを待ちましょう…。

……だと面白くないので、『ないなら作ればいいじゃない』の精神で、自分で作ってみます。
このようなときに使える手段としては、カスタムコネクタという機能があります。

Azure Logic Apps、Microsoft Power Automate、Microsoft Power Apps には、Microsoft および検証済みサービスに接続するための 750 個のコネクタ 以上が用意されていますが、あらかじめ構築されているコネクタが利用できないサービスとの通信が必要になることもあります。 カスタム コネクタでは、独自のトリガーとアクションを備えたコネクタを作成 (さらには共有) できるようにすることで、このシナリオに対応しています。

ということで、今回の要件にはちょうど良さそうですね。

App Configuration のキー値作成

App Configurationで以下のようなキー値を用意しました。環境別にパラメータを分けているようなイメージです。

Key
LogicAppsTestParameter:Develop 開発用のパラメーター
LogicAppsTestParameter:Production 本番用のパラメーター

image.png

カスタムコネクタ用REST API作成

カスタムコネクタはREST APIのラッパー(Logic AppsはSOAP APIもサポート)なので、App Configurationからキー値を取得して返すREST APIを用意します
比較的シンプルな処理なので、今回はAzure Functions(HTTPトリガー)で実装してみます。

Azure Functionsのリソース作成、デプロイに関しては本稿内では割愛させていただきますが、以下を参考にしていただくとよいかと思います。

Azure Functionsで実行するコード

public class GetAppConfigurationKeyValue
{
    private readonly ILogger<GetAppConfigurationKeyValue> _logger;

    public GetAppConfigurationKeyValue(ILogger<GetAppConfigurationKeyValue> log)
    {
        _logger = log;
    }

    [FunctionName("GetAppConfigurationKeyValue")]
    [OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
    [OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
    [OpenApiParameter(name: "AppKey", In = ParameterLocation.Header, Required = true, Type = typeof(string), Description = "App Configuration Key")]
    [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Description = "The OK response")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
    {
        _logger.LogInformation("C# HTTP trigger function processed a request.");
        // Extract the Config Key from the Request header
        string appKey = req.Headers["AppKey"].FirstOrDefault();
        // Extract the Connection String from the Function App Settings
        string connectionString = System.Environment.GetEnvironmentVariable("AppConfigConnectionString");
        var builder = new ConfigurationBuilder();
        builder.AddAzureAppConfiguration(connectionString);
        var build = builder.Build();
        string message = build[appKey];
        return message == null
                ? new NotFoundObjectResult("Azure Configuration Key not found - " + appKey)
                : new OkObjectResult(message);
    }
}

Functionsにコードをデプロイしたら、関数アプリの構成設定で、App Configurationへの接続文字列を設定します。
image.png
設定ができたら、Functionsのポータル画面上でテストを実行してみます(LogicAppsTestParameter:Developを取得してみます)。
image.png
ちゃんと取れました。これでAPIの準備は完了です。
image.png

API Specの取得

以下のURLにアクセスすると、API Specが確認できます。こちらの内容をローカルにファイル保存しておきます(カスタムコネクタの設定にて使用します)。
https://{Azure Function Name}.azurewebsites.net/api/swagger.json
※カスタムコネクタはOpenAPI 3.0 スキーマ定義はサポートされていないため、Swagger 2.0 を取得してください(早くサポートしてほしいですね…)。

(参考)今回のサンプルで取得できたAPI Spec
{
  "swagger": "2.0",
  "info": {
    "title": "OpenAPI Document on Azure Functions",
    "version": "1.0.0"
  },
  "host": "*************************.azurewebsites.net",
  "basePath": "/api",
  "schemes": [
    "https"
  ],
  "paths": {
    "/GetAppConfigurationKeyValue": {
      "get": {
        "tags": [
          "name"
        ],
        "operationId": "Run",
        "produces": [
          "text/plain"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "AppKey",
            "description": "App Configuration Key",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "The OK response",
            "schema": {
              "type": "string"
            }
          }
        },
        "security": [
          {
            "function_key": [ ]
          }
        ]
      }
    }
  },
  "securityDefinitions": {
    "function_key": {
      "type": "apiKey",
      "name": "code",
      "in": "query"
    }
  }
}

カスタムコネクタを作成

下準備ができたところで、いよいよ本題です。カスタムコネクタを作成します。
リソースの作成については、特別触れておくようなところはないですね(名前を入力するぐらい)。
image.png

リソース作成が済んだら、編集を行います。
image.png

全般画面にて、「API Specの取得」で取得したファイルをインポートします。
image.png

独自のアイコンを設定できたりします。
image.png

セキュリティ画面ですが、インポートしたAPI Specによって設定が反映されています。
image.png

「概要」を入力して、「コネクタの更新」を実行すれば作成完了です(他の内容については割愛させていただきます)。
image.png

Logic Appsでカスタムコネクタを設定

準備が整ったところで、Logic Appsでカスタムコネクタを使用します。

Logic Appsのデザイナーで、カスタムタブを選択すると、作成したカスタムコネクタのアクションが出てきました!
image.png

API(今回はAzure Functions)リクエスト時のAPIキーを設定します。
image.png

ここまでで下準備は整いました!
早速「App Configuration のキー値作成」で設定した値を取得してみます。
LogicAppsTestParameter:Develop の値を取得する想定として、Environmentパラメーターに既定値として「Develop」を設定しています。
image.png

取得できました!
image.png

Environmentパラメーターの「実際の値」を「Production」に変更することで、本番のパラメーターも取得できました。
image.png
image.png

まとめ

Logic Appsでパラメーターを扱う方法について、いくつか紹介させていただきました。
今回はシークレットの扱いに関する注意点について書きたいと思ったのがきっかけでした。
それだけだと内容的に物足りないなと感じ、App Configurationからパラメータを取得する方法を検証してみましたが、思いのほか長くなってしまいました…。
カスタムコネクタは案件でも使用したことのない機能だったので、今回試せてよかったです。

ちなみにLogic AppsではAzure Functions用のビルトインコネクタが使用できるので、今回のケースだと実はカスタムコネクタを使用しなくても構成は可能です。
カスタムコネクタの魅力としては、対象となるAPIがAzure内外を問わずラップでき、デザイナー上でユーザーフレンドリーな操作感を提供できるところにあると感じました。
プログラミングができなくとも、ワークフローが構築できるLogic Apps の魅力を引き上げる要素の一つだなと理解しました。

参考文献

9
2
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
9
2