外部からawsのインスタンスの状態確認などを行うのに、インスタンスへ接続してコマンドをたたくのがめんどくさい場合に、簡単かつ安全にaws cliを操作したい場合のために、slackのslash commandを利用できるようにしました。
目次
lambda用資材の準備
pipのインストール
1 2 3 | sudo yum install epel-release sudo yum install python-pip --enablerepo=epel sudo pip install --upgrade pip |
アップロード用モジュールの作成
1 2 3 4 5 6 7 8 | mkdir aws_cli cd aws_cli pip install awscli -t ./ pip install colorama -t ./ pip install pyasn1 -t ./ pip install simplejson -t ./ pip install argparse -t ./ pip install pyyaml -t ./ |
awsコマンド実行ソース
ソースファイル名:aws
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/python import sys import os if os.environ.get('LC_CTYPE', '') == 'UTF-8': os.environ['LC_CTYPE'] = 'en_US.UTF-8' import awscli.clidriver def main(): return awscli.clidriver.main() if __name__ == '__main__': sys.exit(main()) |
lambda用関数のソース
ソースファイル名:lambda_function.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import commands import json import os from cStringIO import StringIO import re import logging from base64 import b64decode from urllib2 import Request, urlopen, URLError, HTTPError from time import sleep logger = logging.getLogger() logger.setLevel(logging.INFO) print('Loading function') def _(cmd): return commands.getoutput(cmd) def lambda_handler(event, context): logger.info("Event: " + str(event)) if event['token'] != 'slack slash commandで設定された値': return("error") etext = event['text'] ans = _("./aws " + etext) response_url = event['response_url'] slack_message = { 'channel': '@%s' % event['user_name'], 'response_type': 'ephemeral', 'isDelayedResponse': 'true', 'text': ans } logger.info("Send message to %s %s", response_url, slack_message) req = Request(response_url) req.add_header('Content-Type', 'application/json') response = urlopen(req, json.dumps(slack_message)) response.read() logger.info("Message posted to %s", slack_message['channel']) return("ok") |
slack slash commandで設定された値を設定するため、1回作った後に再度変更する必要があります。
資材をzipに固める
1 2 3 | chmod 755 -R * zip -r ../aws_cli.zip * |
lambdaの設定
先ほど作ったzipファイルをアップロードします。
aws cliの実行に時間がかかるため、タイムアウトを5分に設定します。
lambdaのロールに自分が制御したいサービスの権限を付加します。
この例では、EC2とS3のアクセス権を追加しています。
api gatewayの設定
GETメソッドを追加します
GETメソッドリクエストのURLクエリ文字列パラメータにslackから渡されるパラメータを追加します。
1 2 3 4 5 6 7 8 9 10 11 | channel_name user_id command text team_id token channel_id team_domain response_url user_name |
GET統合リクエストを編集します。
マッピングテンプレートにlambda関数へ引き渡すパラメータをセットします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | { "channel_name" : "$input.params('channel_name')", "user_id" : "$input.params('user_id')", "command" : "$input.params('command')", "text" : "$input.params('text')", "team_id" : "$input.params('team_id')", "token" : "$input.params('token')", "channel_id" : "$input.params('channel_id')", "team_domain" : "$input.params('team_domain')", "response_url" : "$input.params('response_url')", "user_name" : "$input.params('user_name')", "apiId" : "$context.apiId" } |
ステージングを行います。
URLの呼び出しを控えておきます。slackの設定で使用します。
slack slash commandの設定
slackにログインした後、下のURLへアクセスしてください。
https://my.slack.com/services/new/slash-commands
コマンドを入力して、追加してください。
API Gatewayで取得したURLを設定してください。
トークンを、lambda_function.pyに設定して、zipに固めなおし、lambdaへ再アップロードしてください。
使用例
ec2のインスタンスの状態を取得
1 | /aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Placement.AvailabilityZone, State.Name, InstanceId]' --output text |
結果
1 2 3 | ap-northeast-1a stopped i-04 ap-northeast-1a running i-0a |
S3バケットを表示
1 | /aws s3 ls |
結果
1 2 3 | 2019-03-27 05:39:00 aws-athe 2019-02-07 04:02:40 aws-logs |