この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS Chatbotを使ってLambdaを実行すれば、SlackからEC2の開始・停止を簡単にできます。 しかし、毎回コマンドを入力して実行するのはめんどくさいです。 そこでふと思いました。
「Slackのワークフローを使えば、ボタンぽちーで終わるんちゃう?」
基本的には、下記の記事を「AWS SAMで作ってみた」&「Slackワークフローで簡易化した」内容です。
おすすめの方
- AWS ChatbotでEC2を開始・停止したい方
- AWS ChatbotでLambdaを実行したい方
- AWS ChatbotでRead系のAWSコマンドを実行したい方
- AWS SAM(CloudFormation)でAWS ChatbotとLambdaを作りたい方
- SlackのワークフローでAWS Chatbotのコマンドを実行したい方
前提
- Amazon EC2インスタンスは作成済みとします
AWS Chatbotを準備する
Slackワークスペースの認証とワークスペースID取得
WebコンソールでAWS Chatbotにアクセスし、ワークスペースを追加します。下記のワークスペースIDはあとで必要なのでメモしておきます。
SlackチャンネルIDを取得
任意のチャンネルのリンクを取得します。
このリンクの最後の文字列を使います。下記例だとABCD1234
がチャンネルIDです。
https://classmethod.slack.com/archives/ABCD1234
Lambdaを作成する
SAM Init
sam init \
--runtime python3.8 \
--name Slack-EC2-Command \
--app-template hello-world \
--package-type Zip
SAMテンプレート
下記を作成しています。
- AWS Chatbotのチャンネル設定
- AWS Chatbot用のIAMロール
- Lambda(開始・停止)
- CloudWatch logs
AWS Chatbot用のIAMロールには、最低限の権限のみを付与しています。
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Slack-EC2-Command
Parameters:
Env:
Type: String
Default: Env
SlackWorkspaceId:
Type: String
SlackEc2ChannelId:
Type: String
Resources:
Ec2SlackChatbot:
Type: AWS::Chatbot::SlackChannelConfiguration
Properties:
ConfigurationName: !Sub xxx-ec2-slack-chatbot-${Env}
IamRoleArn: !GetAtt Ec2SlackChatbotIamRole.Arn
LoggingLevel: INFO
SlackWorkspaceId: !Ref SlackWorkspaceId
SlackChannelId: !Ref SlackEc2ChannelId
Ec2SlackChatbotIamRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub xxx-ec2-slack-chatbot-role-${Env}
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: chatbot.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: !Sub xxx-ec2-slack-chatbot-policy-${Env}
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- lambda:invokeAsync
- lambda:invokeFunction
Resource:
- !GetAtt StartEc2Function.Arn
- !GetAtt StopEc2Function.Arn
- Effect: Allow
Action:
- ec2:DescribeInstanceStatus
Resource:
- "*"
StartEc2Function:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub xxx-start-ec2-${Env}
CodeUri: start_ec2/
Handler: app.lambda_handler
Policies:
- arn:aws:iam::aws:policy/AmazonEC2FullAccess
Runtime: python3.8
Timeout: 10
StartEc2FunctionLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/lambda/${StartEc2Function}
StopEc2Function:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub xxx-stop-ec2-${Env}
CodeUri: stop_ec2/
Handler: app.lambda_handler
Policies:
- arn:aws:iam::aws:policy/AmazonEC2FullAccess
Runtime: python3.8
Timeout: 10
StopEc2FunctionLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/lambda/${StopEc2Function}
Labmdaコード
開始用のLambda
start_ec2/app.py
import boto3
ec2 = boto3.client('ec2')
instances_ids = ['i-xxxxx']
def lambda_handler(event, context):
ec2.start_instances(InstanceIds=instances_ids)
print(f'start instance: {instances_ids}')
停止用のLambda
stop_ec2/app.py
import boto3
ec2 = boto3.client('ec2')
instances_ids = ['i-xxxxx']
def lambda_handler(event, context):
ec2.stop_instances(InstanceIds=instances_ids)
print(f'stop instance: {instances_ids}')
デプロイ
--parameter-overrides
部分は、適宜変更してください。
aws cloudformation package \
--template-file template.yaml \
--output-template-file packaged.yaml \
--s3-bucket cm-fujii.genki-deploy
aws cloudformation deploy \
--template-file packaged.yaml \
--stack-name chatbot-ec2-command-stack \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides \
Env=dev \
SlackWorkspaceId=XYZXYZ \
SlackEc2ChannelId=ABCD1234 \
--no-fail-on-empty-changeset
SlackでAWSアプリを招待して、動作を確認する
AWSアプリを招待する
Slackの該当チャンネルで/invite @aws
を実行し、AWSアプリを招待します。
インスタンス状態を確認する(停止中?)
下記コマンドを実行します。初回のみ、リージョンを指定します。
@aws ec2 describe-instance-status --instance-ids i-xxxx --include-all-instances true --region ap-northeast-1
EC2インスタンスは、ストップ状態でした。なお、AWSアカウント等の一部情報は黒塗りしています。
EC2開始コマンドを実行する
下記で実行します。
@aws lambda invoke xxx-start-ec2-dev
実行すると、AWS Chatbotから「ええんか?」と聞かれるので、「Yes」を選択します。
無事に実行できました。
インスタンス状態を確認する(開始した?)
下記コマンドを実行します。
@aws ec2 describe-instance-status --instance-ids i-xxxx --include-all-instances true
EC2インスタンスが開始しました。
EC2停止コマンドを実行する
下記で実行します。
@aws lambda invoke xxx-stop-ec2-dev
実行すると、AWS Chatbotから「ええんか?」と聞かれるので、「Yes」を選択します。
インスタンス状態を確認する(停止した?)
下記コマンドを実行します。
@aws ec2 describe-instance-status --instance-ids i-xxxx --include-all-instances true
EC2インスタンスが停止しました。
SlackのワークフローでAWS Chatbotを実行する
ワークフローを作成する
EC2を開始するワークフロー
下記のワークフローを作成します。
@aws
部分が認識されない場合は、再入力など試してください。
また、コマンド部分に「by Name」みたいな文字を付与すると、Lambda実行に失敗するので、コマンドのみを記載しています。
EC2を停止するワークフロー
下記のワークフローを作成します。
EC2の状態を確認するワークフロー
下記のワークフローを作成します。
Slackショートカットの様子
作成したワークフローが表示されています。
Slackワークフローを実行する
EC2を開始する様子
EC2の状態を確認する様子
EC2を停止する様子
おまけ: 開始と停止を分かりやすくする
ワークフローを下記のようにすれば、メッセージ投稿も可能です。
ワークフローを実行した様子です。
さいごに
便利、かつ、楽になりました。エンジニア以外でも使いやすくなったと思います。