その1ではSlackアプリのベースを作った。その2ではそのtokenを使ってLambdaとそれを呼び出すSNSを作っていく。
2. SNSとpauseのLambdaを作る
今回のLambdaはpythonで書いた。
こんな感じ
import logging
import json
import os
import boto3
import traceback
from slack import WebClient
from slack.errors import SlackApiError
def lambda_handler(event, context):
token = os.environ["SLACK_API_TOKEN"]
channel_id = os.environ["channel_id"]
client = WebClient(token=token)
message = event["Records"][0]["Sns"]["Message"]
data = json.loads(message)
token = data["approval"]["token"]
codepipeline_name = data["approval"]["pipelineName"]
if codepipeline_name == "test-codepipeline-dev":
msg_text = "``` 承認してもよろしいでしょうか?```"
attachments_json = [
{
"fallback": "Upgrade your Slack client to use messages like these.",
"color": "#258ab5",
"attachment_type": "default",
"callback_id": "the_greatest_war",
"actions": [
{
"name": "ok",
"text": "承認",
"value": token + ',' + codepipeline_name,
"style": "primary",
"type": "button",
"confirm": {
"title": "承認しますか?",
"text": "本当によろしいですか?",
"ok_text": "OK",
"dismiss_text": "Cancel"
}
},
{
"name": "cancel",
"text": "キャンセル",
"style": "danger",
"value": token + ',' + codepipeline_name,
"type": "button"
}
]
}
]
try:
response = client.chat_postMessage(
channel=channel_id,
text=msg_text,
attachments=attachments_json
)
assert response["ok"]
except Exception:
print(traceback.format_exc())
SNSとLambdaのAWSへの作成はterraformにて実施
Lambdaを設置するところの例
Lambdaの環境変数にSlackアプリのtokenやチャンネルIDをセットする
# Function
resource "aws_lambda_function" "handler" {
function_name = "lambda-handler"
handler = "lambda_handler.lambda_handler"
filename = data.archive_file.function_zip.output_path
runtime = "python3.8"
role = aws_iam_role.lambda_iam_role.arn
source_code_hash = data.archive_file.function_zip.output_base64sha256
layers = ["${aws_lambda_layer_version.lambda_layer.arn}"]
timeout = 30
memory_size = 512
environment {
variables = {
ENVIRONMENT = "dev"
SLACK_API_TOKEN = [OAuth & Permissions の token]
VERIFICATION_TOKEN = [verification の token]
channel_id = [通知する slack の チャンネルID]
}
}
}
SNSトピックの作成とLambdaと繋ぐところの例
# SNS
resource "aws_sns_topic" "user_approval" {
name = "user_approval"
}
resource "aws_sns_topic_subscription" "user_approval_lambda_target" {
topic_arn = aws_sns_topic.user_approval.arn
protocol = "lambda"
endpoint = aws_lambda_function.handler.arn
}
resource "aws_lambda_permission" "default" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.handler.function_name
principal = "sns.amazonaws.com"
source_arn = aws_sns_topic.user_approval.arn
}
実行するとこのように設置できる
あとはこれをCodePipeline側で呼び出すだけ。
3. CodePipelineのApprovalの設定にSNSをセットする
これでslackへ通知が届くようになる。
(その3へ続く)