Serverless frameworkを使ってStripeのAPIを利用する関数を実装する(途中)

月の売上とかをStripeのAPIをリクエストしてくれるLambda関数(HTTPSエンドポイント)を用意して Redashで集計できるようにしたかったので試してみました。

StripeのAPIの概要

  • Authentication

    • API Keyをもとにベーシック認証方式で認証する
  • LIST ALL CHARGES

    • 支払いの一覧を取得するAPIを利用する
    • 月ごとの集計をする場合は、createdパラメータを利用する
    • 2019/8/1-2019/9/1の取得用パラメータ: created[gte]=1564585200&created[lte]=1567263600

Serverless frameworkで関数を実装

  • sls create -t aws-nodejs-typescript project-name で、いい感じにlambda用かつTypeScriptなプロジェクトの雛形が作成される
  • offlineで動作確認したかったので、すぐ serverless-offline パッケージを追加
  • Stripeのシークレットキーはセキュアに扱いたかったので調査した

コード全部を掲載しませんが、メモだけ残しておきます。

// StripeのCharge一覧取得用パラメータ作成
const params = {
  ['created[gte]']: Math.floor(DateTime.local().minus({ month: 1}).startOf('month').toSeconds()),
  ['created[lte]']: Math.floor(DateTime.local().minus({ month: 1}).endOf('month').toSeconds())
}
  • superagentしか使ったことなかったのでaxios使ってみた

    • basic認証はauthパラメータを利用する
// StripeのAPIをリクエスト
const res = await axios.get(url, { baseURL, auth, params })
  • KMSの復号化もサンプルコードがコンソールでも手に入るし、それをasync / await式にかきかえた

    • request.promise(); にちょっとつまずいた
// encryptedに、暗号化された文字が入ってる
const req = kms.decrypt({ CiphertextBlob: new Buffer(encrypted, 'base64') });
const data = await req.promise();
decrypted = data.Plaintext.toString('ascii');

Serverless Frameworkで機密情報を扱うとき

うえのほうで

lambdaのドキュメントではKMSを使うように書いてあった

と書いたがServerless FrameworkでもKMSのキーのARNを設定できましたが、 [Enable helpers for encryption in transit] をserverless.ymlでは(もっというと Cloud Formationでは)設定できなさそうでした。

結局 sls deploy したときに、平文で環境変数が登録されてそれを手動で暗号化することになりそうだったので、パラメータストアを使って関数内で復号化できないかためしたほうがよさそうでした。 (とはいえ正直 encryption in transitを有効にしないとどんなリスクがあるかあんまりピンと来てないです。。。。)

  • Serverless Variables

    • serverless.ymlでssmのリソースを指定できるし、 ~true とつけると復号化されるらしい
    • 逆に ~true を設定しないで、関数内で復号化できないかという作戦

Todo

  • パラメータストアを利用したLambda関数内での機密情報利用
  • StripeAPIのページング処理
  • Redash用の設定などなど(VPC内に配置するとか。。。