Lambda に Slack 連携の blueprint が追加されました。
Slack-echo-command と Cloudwatch-alarm-to-slack の二種類があるのですが、今回は前者の Slack から Lambda を叩ける機能を用いて Slack 上で EC2 の起動状態を確認できるようにしてみます。
やることは下記の通りです。
- Slack 側で Slash Command の初期設定を行う *
- Slash Command の token の暗号化を行う *
- Lambda ファンクションの作成
- IAM ロールの作成
- API Gateway の作成 *
- Slash Command に API Gateway のエンドポイントを設定する *
*が付いている部分については、クラスメソッドさんのブログ「【新機能】AWS LambdaにSlack連携のBluePrintが登場。ChatOpsがより手軽に」を参考にさせていただきましたので、今回は割愛したいと思います。
Lambda ファンクションの作成
今回は Python で書いていきたいと思います。
blueprint「slack-echo-command-python」を選択してください。
# -*- coding: utf-8 -*-
import boto3
from base64 import b64decode
from urlparse import parse_qs
import logging
ENCRYPTED_EXPECTED_TOKEN = "***" # Enter the base-64 encoded, encrypted Slack command token (CiphertextBlob)
kms = boto3.client('kms')
expected_token = kms.decrypt(CiphertextBlob = b64decode(ENCRYPTED_EXPECTED_TOKEN))['Plaintext']
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
req_body = event['body']
params = parse_qs(req_body)
token = params['token'][0]
if token != expected_token:
logger.error("Request token (%s) does not match exptected", token)
raise Exception("Invalid request token")
command_text = params['text'][0]
instances_info = ""
if command_text == "instances":
for reservation in boto3.client('ec2').describe_instances()["Reservations"]:
for instance in reservation["Instances"]:
instances_info = instances_info + instance["InstanceId"] + "->" + instance["State"]["Name"] + " "
return instances_info
IAM ロールの作成
- EC2 の操作権限(本当は参照だけでいいのですが全てつけてしまっています)
- CloudWatchLogs への Put 権限
- KMS の Decrypt 権限
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1448895482556",
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": [
"arn:aws:kms:ap-northeast-1:894357485438:key/xxxxxxxx"
]
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
テスト
/aws のあとに続く文字列が command_text に入ってくるので、その内容によって返す情報を変更してあげることで、AWS の様々な情報を Slack 上で確認することができるようになります!
課題
1) タイムアウト対応
たまに下記にようにタイムアウトが発生します。
調べてみると、3,000ms 以上経過するとタイムアウトになる模様。(stackoverflow)
対応しようと思えばできるみたいなので、いつかやろうと思います。
2) Slack に表示するインスタンス情報の改行
改行文字を返すだけではダメでした。
対応方法ご存知の方は教えていただきたいです。
まとめ
色々わかっていないところもあるのですが、Lambda を使うことで簡単に ChatOps 環境が作れる気がします。
次は、Cloudwatch-alarm-to-slack の方を使って何かやってみたいです。