CloudWatch dashboard custom widgetsのcwdb-actionで実行するLambda関数にパラメーターを渡したいときはどうするの?

2021.08.29

CloudWatch dashboardに任意のLambda関数の結果を表示できるという新機能、custom widgetsがリリースされました。

そしてこのcustom widget内から、更にLambda関数を呼ぶこともできます。

以下のようなHTMLを返すLambda関数を作って、これを使ってcustom widgetを作ると、

<a class="btn">execute lambda</a>
<cwdb-action 
    display="widget"
    action="call" 
    endpoint="arn:aws:lambda:us-east-1:123456789012:function:cwdb-action-test"
> 
</cwdb-action>

custom widget内にボタンが作成されます。 20210829-cwdb ボタンをクリックすると、上記HTML内のcwdb-actionタグのendpoint属性に書かれているLambda関数が実行されて、その返り値でwidgetが更新されます。 20210829-cwdb-result Lambda関数の中でAWSサービスのAPIをキックしてリソースを停止するなどのアクションを取れるようにしておくと、例えば障害対応を迅速にできるようになったりといったことが期待できます。

今回はこの「cwdb-actionタグのendpoint属性に書かれているLambda関数の実行」について書きます。この関数にパラメーターを渡したくなったら、どのように渡せば良いのでしょうか?

方法1: cwdb-actionタグ内にJSONで定義する

以下のように、cwdb-actionタグで囲った中にJSONオブジェクトを書いておきます。

<a class="btn">execute lambda</a>
<cwdb-action 
    display="widget"
    action="call" 
    endpoint="arn:aws:lambda:us-east-1:123456789012:function:cwdb-action-test"
> 
{ "test": "wataseru" }
</cwdb-action>

上記cwdb-actionから呼ばれるLambda関数のコードは、testパラメーターを返すものにします。

exports.handler = async (event) => {
    const response = event.test
    return response;
};

このcustom widgetを表示して、 20210829-cwdb ボタンをクリックすると、 wataseru testパラメーター値が関数から返ってきて、その内容でwidgetが更新されました!

方法2: custom widgetに設定されたパラメーターを使い回す

cwdb-actionから呼ばれるLambda関数には、widgetContextという要素が渡されてきます。

これは、custom widgetからLambda関数を呼ぶときにも渡される要素です。中身はcustom widgetに関する情報です。

{
    "widgetContext": {
        "dashboardName": "Name-of-current-dashboard",
        "widgetId": "widget-16",
        "accountId": "012345678901",
        "locale": "en",
        "timezone": {
            "label": "UTC",
            "offsetISO": "+00:00",
            "offsetInMinutes": 0
        },
        "period": 300,
        "isAutoPeriod": true,
        "timeRange": {
            "mode": "relative",
            "start": 1627236199729,
            "end": 1627322599729,
            "relativeStart": 86400012,
            "zoom": {
                "start": 1627276030434,
                "end": 1627282956521
             }
        },
        "theme": "light",
        "linkCharts": true,
        "title": "Tweets for Amazon website problem",
        "forms": {
            "all": {}
        },
        "params": {
            "original": "param-to-widget"
        },
        "width": 588,
        "height": 369
    }
}

これがcwdb-actionから呼ばれるLambda関数でも使えるので、
関数コードを以下のように書きます。widgetContextは関数第一引数の子要素です。

exports.handler = async (event) => {
    const response = event.widgetContext.params.test2
    return response;
};

そしてcustom widgetの設定を以下のようにして、 20210829-custom-widget-param ボタンをクリックすると、 kore-mo-wataseru パラメーターを渡せることがわかりました。

方法3: widgetの中のフォームの入力値を渡したい

以下のように、widgetの中に入力フォームを作って、送信ボタンを押した時点の入力内容をLambda関数に渡したい場合はどうすればよいでしょうか。 20210829-form

前述のwidgetContext要素の例を見てください。formsという子要素がありますね。これを使います。

widgetのHTMLが以下になるように、custom widgetに設定するLambda関数コードを修正します。

<form>
    <p>お名前:<input type="text" name="NAME"></p>
    <p>メールアドレス:<input type="text" name="email"></p>
    <p>
        <input type="submit" value="送信する">
        <cwdb-action 
            display="widget"
            action="call" 
            endpoint="arn:aws:lambda:us-east-1:123456789012:function:cwdb-action-test"
        > 
        </cwdb-action> 
    </p>
</form>

cwdb-actionから呼ばれるLambda関数ではevent.widgetContext.forms.allを返すようにしておきます。

exports.handler = async (event) => {
    const response = event.widgetContext.forms.all
    return response;
};

フォームに入力して、送信してみます。 widget-input 入力内容でwidgetを更新することができました! 20210829-ret

まとめ

cwdb-actionから呼ばれるLambda関数にパラメーターを渡す方法をご紹介しました。

  • custom widgetを作る段階で決まっているパラメーターは、custom widgetのパラメーターとして渡して、cwdb-actionから呼ばれる関数内でwidgetContext.params.xxxを参照する(方法2)
  • custom widgetから呼ばれるLambda関数内で値が決まるパラメーターは、返り値のHTMLのcwdb-actionタグ子要素にJSON形式で渡し、cwdb-actionから呼ばれる関数内で第一引数(eventと名付けられることが多い).xxxを参照する(方法1)
  • widget内のformの入力値を渡したい場合は、widgetContext.forms.all.xxxを参照する(方法3)

参考情報