この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんばんは! 筧 です。
はじめに
最近、Serverless Framework を使って改善業務に取り組んでいます。 取り組んでいる中で、Serverless Framework でクレデンシャル情報を扱う Lambda ファンクションを作成する方法を確認しました。 今回はこちらの方法の一つをご紹介します。
目標
AWS Secrets Manager から Slack チャンネルの Webhook URL を取得して、 Slack チャンネルにメッセージを投稿する Lambda ファンクションを Serverless Framework で作成します。
やってみた
以下の流れで作業します。
- Slack 側の準備
- AWS Secrets Manager の設定
- Serverless Framework のサービス作成
- Serverless Framework のサービスデプロイ
- 動作確認
1. Slack 側の準備
Incoming Webhook の設定
次のページを参考に Incoming Webhook の設定をしてください。
https://hooks.slack.com/services/XXX/YYY/ZZZ
のような形式の Webhook URL を確認しておきます。
2. AWS Secrets Manager の設定
マネジメントコンソールから確認した Slack のクレデンシャル情報を登録します。
- SLACK_WEBHOOK_URL:確認した Webhook URL
シークレットの名前を付けます。ここでは、dev/slack とします。
今回は自動ローテーションは不要なので、自動ローテーションを無効にするにチェック入れます。
シークレットが正常に保存されれば OK です。
3. Serverless Framework のサービス作成
Serverless Framework 実行環境構築は省略します。 構築方法は以下を参照ください。
初めてのサーバーレスアプリケーション開発 ~Serverless Framework を使ってAWSリソースをデプロイする~ -> Serverless Framework実行環境構築
サービス作成
Serverless Framework のサービスを作成します。 今回は slack-post-serviceというサービス名で、Python 3.8の Lambda ファンクションを作成します。
$ serverless create --template aws-python3 --path slack-post-service
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "{省略}"
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v1.72.0
-------'
Serverless: Successfully generated boilerplate for template: "aws-python3"
プラグインインストール
この後登場する Lambda ファンクションで用いる外部モジュールの為に必要なプラグイン(serverless-python-requirements)をインストールします。
$ sls plugin install -n serverless-python-requirements
serverless.yml の編集
serverless.yml でサービスを定義します。
service: slack-post-service
provider:
name: aws
runtime: python3.8
region: ap-northeast-1
profile: ${opt:profile, "default"}
iamRoleStatements:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
- "*"
plugins:
- serverless-python-requirements
functions:
post_content:
handler: handler.post_content
environment:
SECRET_NAME: dev/slack
ハイライトの箇所がポイントです。
- iamRoleStatements で AWS Secrets Manager へのアクセスを許可しています(必要に応じて Resource を絞ってください)
- Lambda ファンクションの環境変数として、作成したシークレットの名前を記載
handler.py の編集
handler.py で Slack にメッセージを POST する Lambda ファンクションを作成します。
import os
import boto3
import json
import requests
# Get credentials
secret_name = os.environ['SECRET_NAME']
secretsmanager_client = boto3.client('secretsmanager', region_name='ap-northeast-1')
resp = secretsmanager_client.get_secret_value(SecretId=secret_name)
secret = json.loads(resp['SecretString'])
SLACK_WEBHOOK_URL = secret['SLACK_WEBHOOK_URL']
def post_content(event, context):
payload = {
"text": "テスト投稿"
}
content = json.dumps(payload)
response = requests.post(SLACK_WEBHOOK_URL, data=content)
return
ハイライトの箇所がポイントです。
- serverless.yml で設定した Lambda ファンクションの環境変数からシークレットの名前を取得
- シークレットの名前を元にクレデンシャル情報(Webhook URL)を取得
4. Serverless Framework のサービスデプロイ
デプロイ
サービスをデプロイします。
$ cd slack-post-service/
$ sls deploy -v
{省略}
5. 動作確認
Lambda ファンクションを実行する
デプロイされたLambdaファンクションを実行します。
sls invoke -f post_content
対象の Slack を確認すると、メッセージが投稿されていることが確認できました!
おわりに
誰かの参考になると幸いです。それでは良い夜を!
更新履歴
- プラグインのインストール方法を変更しました(2020/10/16)