S3バケットにファイルがアップロードされたらAlteryx Serverでワークフローを実行する

S3トリガーでAlteryx Serverのワークフローを実行します
2022.04.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データアナリティクス事業本部インテグレーション部コンサルティングチーム、新納(にいの)です。部署異動して所属部署名がとんでもなく長くなりました。

Alteryxでワークフローを実行する方法は手動実行かスケジュール実行の2パターンがあります。しかし誰しも一度はイベント駆動でのワークフロー実行をしたいと考えるのではないでしょうか。

そこで、今回はAlteryx ServerへのAPIアクセスの仕組みを利用して、S3バケットにファイルが置かれたらワークフローを実行する仕組みを作ってみました。

前提条件

今回の検証で使用した環境は以下の通り。

  • Alteryx Server 2021.3
  • Windows Subsystem for Linux 2(WSL2)

構成図は以下の通り。

  • 該当のS3バケットにファイルがアップロードされたトリガーでLambda関数を実行します。
  • Alteryx Serverのワークフローを実行するAPIをLambda関数経由で実行します。
  • Alteryx ServerのAPIキー、シークレットキー、URLはAWS Secrets Managerに保存したものを利用します。
  • Lambda関数作成時はWindows環境からWSL2を使用しています。

Alteryx Serverで必要情報を取得

APIキー、シークレットキーを取得

Alteryx ServerのAPIキー、シークレットキーはGalleryにログイン後、My Profile-->Key-->Private Studio APIから参照可能です。Showボタンを押すとシークレットキーが表示されます。

appIdを取得

実行したいワークフローのappIdは、API Documentationから確認可能です。

先ほど取得したAPIキー、シークレットを入力します。

Studio内のワークフローのリストを返す/v1/workflows/subscription/を選択し、Try it outボタンを押します。

Response Bodyでワークフローのリストが表示されます。idがappIdです。

AWS Secrets Managerにアクセス情報を保存

LambdaでAPIアクセスする際にAPIキーやシークレットを指定する必要がありますが、コードの中にそのまま書いてしまうとセキュリティ上の危険性があります。そこで機密情報を一元管理できるAWS Secrets Managerにアクセス情報を保存しておきます。

AWSマネジメントコンソールからAWS Secrets Managerにアクセスし、「新しいシークレットを保存する」を選択します。シークレットのタイプは「その他のシークレットのタイプ」を選択し、キー/値のペアで以下を指定します。

キー
Alteryx Server URL(キー名は任意) http://<Alteryx ServerのFQDN名>/gallery/api/
APIキー(キー名は任意) Private Studio API Key
シークレットキー(キー名は任意) Private Studio API Secret

シークレットの名前を指定します。

シークレットの自動ローテーションはオフにして次に進み、保存します。

Lambda関数内でシークレットを取得する際はサンプルコードを参考にできます。

Lambda関数を作成

関数の作成

ここからは実際にAlteryx ServerへAPIアクセスするLambda関数を実装します。

AWSマネジメントコンソールからAWS Lambdaへアクセスし、関数の作成を選択します。「設計図の使用」からS3トリガーでLambda関数を実行するs3-get-object-pythonを選択します。

関数名を指定し、今回はAWSポリシーテンプレートから新しいロールを作成します。デフォルトのままだとS3オブジェクトの読み取り専用アクセス権限がないので、後でSecrets Managerにアクセスするためのロールを付与します。

トリガーの設定でイベントソースとして使用するS3バケットを指定します。今回はファイルがアップロードされたらワークフローを実行させるため「すべてのオブジェクト作成イベント」を指定しています。特定のファイル名や拡張子に絞りたいときはプレフィックスやサフィックスを指定しましょう。

関数を作成後、IAMロールにアクセス許可の追加-->ポリシーをアタッチからSecretsManagerReadWriteをアタッチしておきましょう。

ファイルアップロード

今回はランタイムにPythonを使用しており、ライブラリのインストールが必要となるのですがLambdaではpip installができません。そこで、ローカル環境でライブラリをインストールした上でLambda関数を作成したものをファイルアップロード機能でAWS上で使用できるよう設定します。

以下のブログを参考に進めます。

ローカルで作業用ディレクトリを作成

ローカル環境に作業用ディレクトリ(今回はworkspace)を作成し、移動します。

$ mkdir workspace

$ cd workspace

ライブラリのインストール

今回使用するrequestsrequests_oauthlibをインストールします。

$ pip install requests -t .

$ pip install requests_oauthlib -t .

Lambda関数を実装

作業用ディレクトリの中でLambda関数を作成します。私はVSCodeが好きなのでcodeコマンドでVSCodeを起動し、lambda_function.pyを作成しました。

code

作成したコードは以下の通り。Secrets Managerで設定したキーやappIdは適宜書き換えてください。

import json
import urllib.parse
import boto3
import requests
from requests_oauthlib import OAuth1
import base64
from botocore.exceptions import ClientError


def lambda_handler(event, context):
    secret_name = "niino-test-alteryx"
    region_name = "ap-northeast-1"

    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )
    get_secret_value_response = client.get_secret_value(
        SecretId=secret_name
    )
    secret = json.loads(get_secret_value_response['SecretString'])
    client_key = secret['ALTERYX_KEY']
    client_secret = secret['ALTERYX_SECRET']
    gallery_url = secret['ALTERYX_URL']
    oauth = OAuth1(client_key, client_secret, signature_type='query')

    app_id = '該当ワークフローのappIdを指定'
    q = {
      "questions": [
        {
          "name": "",
          "value": ""
        }
      ]
    }
    response = requests.post(gallery_url + f'v1/workflows/{app_id}/jobs/', auth=oauth, json=q).json()    

    return response

余談ですが、私はWindows環境でWSL2を使用しており、上記のコードを保存するときに「WSL2のディレクトリってどうやって開くんだっけ…」と躓いてしまいました。エクスプローラに\\WSL$と入力することでアクセス可能です。

圧縮する

ここまで作成したファイルをすべてzipコマンドで圧縮します。zipコマンドが使えない場合は別途インストールしてください。

$ zip -r upload.zip *

ファイルをアップロード

AWSマネジメントコンソールから先ほど作成したLambda関数へ遷移し、アップロード元-->.zipファイルを選択して先ほど圧縮したファイルを選択します。これでライブラリをインストールした状態でLambda関数を作成できました。

テストする

作成したLambda関数が動くかテストしてみましょう。Testボタンから「Configure Test event」を選択します。 bucket nameをイベントソースのS3バケット名に、keyをS3に配置したオブジェクト名に書き換えて保存します。

Testボタンを押すとExecution resultタブに結果が表示されます。ここでエラーになっていなければAlteryx Server側のワークフローが実行されていることが確認できます。

最後に

Lambdaを使用し、S3バケットでのオブジェクト作成をトリガーにしてワークフローを実行してみました。Alteryx Server APIを使えばスケジュール実行以外にもイベント駆動での実行ができて便利ですね。Alteryx Server 2021.4からはAPIv3が使えるようになり、OAuth2.0にも対応しました。できることの幅が広がっているのでぜひお試しください。

参考資料