Slack Bolt for Python のクレデンシャル情報を AWS Systems Manager のパラメータストアに保管する

2022/06/21に公開

はじめに

こんにちは、クラスメソッド サービスグロースチームの筧です。
チーム内で、Bolt を使った Slack アプリ開発をやり始めたので学んだことをアウトプットします。

今回は、Slack アプリで払い出したクレデンシャルを、AWS Systems Manager のパラメータストアに保管する方法をご紹介します。

使うもの

前提

  • Bot User OAuth Token:
    • tokenに指定する値: "xxxxx"(仮)
  • Signing Secret:
    • signing_secretに指定する値: "yyyyy"(仮)

上記のクレデンシャル情報を、下記のコードのようにベタ書きせず、AWS Systems Managerのパラメータストアから呼び出せるようにすることをスコープとします。

app.py
from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler

app = App(
    process_before_response=True,
    token="xxxxx",
    signing_secret="yyyyy",
)

"""
リスナー関数はここに書く
"""

def handler(event, context):
    slack_handler = SlackRequestHandler(app=app)
    return slack_handler.handle(event, context)

やっていく

AWS Systems Manager のパラメータストアに保存

パラメータストアに以下の名前でクレデンシャル情報を保存します。

  • Bot User OAuth Token: token
    • /サービス名/ステージ名/SLACK_BOT_TOKEN
      • ex) /developersio2022-slack-bolt-app/dev/SLACK_BOT_TOKEN
  • Signing Secret: signing_secret
    • /サービス名/ステージ名/SLACK_BOT_SIGNING_SECRET
      • ex) /developersio2022-slack-bolt-app/dev/SLACK_BOT_SIGNING_SECRET

Lambda の環境変数を参照

一旦、Lambda のコード上で、tokensigning_secretが環境変数を参照するようにします。

app.py
from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler

app = App(
    process_before_response=True,
    token=os.environ["SLACK_BOT_TOKEN"],
    signing_secret=os.environ["SLACK_BOT_SIGNING_SECRET"],
)

"""
リスナー関数はここに書く
"""

def handler(event, context):
    slack_handler = SlackRequestHandler(app=app)
    return slack_handler.handle(event, context)

serverless.yml 上でパラメータストアを参照

You can reference SSM Parameters as the source of your variables with the ssm:/path/to/param syntax.

https://www.serverless.com/framework/docs/providers/aws/guide/variables#reference-variables-using-the-ssm-parameter-store

上記公式ドキュメントの通り、Serverless Framework で用意されている構文を使うことで、serverless.yml から簡単にパラメータストアに保管したクレデンシャル情報を参照できます。なお、IAM ロールssm:GetParameterの許可もあわせて必要です。

以下は上記を踏まえた、serverless.yml の例です。

serverless.yml
service: developersio2022-slack-bolt-app
frameworkVersion: '3'
provider:
  name: aws
  runtime: python3.9
  lambdaHashingVersion: 20201221
  stage: ${opt:stage, 'dev'}
  region: ${opt:region, "ap-northeast-1"}
# ・・snip・・
  iam:
    role:
      statements:
        - Effect: 'Allow'
          Action:
            - ssm:GetParameter
# ・・snip・・
  environment: ${self:custom.environment.${self:provider.stage}}
# ・・snip・・
custom:
  environment:
    dev:
      SLACK_BOT_TOKEN: ${ssm(${self:provider.region}):/${self:service}/${self:provider.stage}/SLACK_BOT_TOKEN}
      SLACK_BOT_SIGNING_SECRET: ${ssm(${self:provider.region}):/${self:service}/${self:provider.stage}/SLACK_BOT_SIGNING_SECRET}
    prod:
# ・・snip・・

おわりに

最後まで読んでいただきありがとうございます。

https://classmethod.jp/m/developers-io/

上記イベントで、Slack Bolt 関連のセッションでオンライン登壇しました。
よかったらこちらも御覧ください!

動画

https://www.youtube.com/watch?v=mz18T5uaHxQ

関連ブログ

https://classmethod.jp/m/developers-io/

それではまた!

Discussion