AWS EC2上で自作のアプリケーションを回しているのですが、実行、停止を頻繁に繰り返すことがあり、EC2に入っていちいち操作させるのが結構めんどくさかったりします。
そこで、LineからEC2を操作して、プログラムの実行停止をできるようにしてみます。
全体像
以下のフローでLineからEC2を操作します。
- Line Messaging APIからAPI GatewayへPOSTリクエストを送信
- API Gatewayをトリガにして、Lambda関数が実行
- Lambda関数からEC2インスタンスが起動or停止される
- 起動時には設定したスクリプトが自動実行される
作成手順
- EC2インスタンスの作成
- IAMポリシーの作成
- Lambda関数の設定
- API Gatewayの設定
- Line Messaging APIの設定
- EC2起動時実行スクリプトの設定
1. EC2インスタンスの作成
プログラムを実行するためのEC2インスタンスを作成しておきます。(作成手順は省略)
後述のLambda関数で利用するため、作成したEC2のインスタンスIDをメモしておきます。
2. Lambda用IAMロールの作成
今回はLambdaの関数からEC2を操作するため、LambdaにEC2インスタンスの起動停止を行うための、IAMロールを付与してあげます。
こちらのAWS公式マニュアルに従います。
【IAMポリシーの作成】
IAM -> ポリシー -> ポリシーの作成 -> JSON
でエディタに下記のJSONを記載します。
ポリシー名はec2StartStopPolicyとします。
ポリシードキュメント
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:Start*",
"ec2:Stop*"
],
"Resource": "*"
}
]
}
【IAMロールの作成】
ロール -> ロールの作成 を選択し、エンティティの種類にAWSサービス、ユースケースにLambdaを選択します。
アクセス権限ポリシーで、上で作成したポリシーを選択し、ロール名をec2StartStopRoleとして、ロールを作成します。
3. Lambda関数の作成
EC2を起動、停止するためのLambda関数を作成します。
【関数の作成】
Lineから「起動」「停止」というメッセージを受け取って、対応するアクションを行う仕様とします。
Lambda -> 関数の作成 -> 一から作成 -> ランタイムにPython3.8を選択 -> 関数の作成
配置されたLambda関数の関数コード内、lambda_function.pyに下記のコードを記載します。
コード内のregionとinstancesには対象のEC2インスタンスの内容に置き換えてください。
Lambda関数
import json
import urllib.request, urllib.parse
import boto3
import os
region = '**リージョン**'
instances = ['**インスタンスID**']
ec2 = boto3.client('ec2', region_name=region)
def start_ec2():
ec2.start_instances(InstanceIds=instances)
def stop_ec2():
ec2.stop_instances(InstanceIds=instances)
def lambda_handler(event, context):
# TODO implement
text = event['events'][0]['message']['text']
if text == '起動':
start_ec2()
elif text == '停止':
stop_ec2()
else:
pass
print("Line Message is {}".format(text))
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
【IAMロールを付与】
作成したIAMロールをLambda関数に付与します。
Lambdaのアクセス権限タブで実行ロールの編集をクリックし、先ほど作成したIAMロールを選択して保存します。
4. API Gatewayの設定
作成したLambdaのデザイナー上から、トリガーを追加を選択し、API Gatewayをトリガーとして追加します。
作成したAPI GatewayのAPIエンドポイントをメモしておきます。
今回は、LineからのPOSTリクエストに応答して、Lambda関数をトリガするようにします。
API Gateway画面から、アクション -> メソッドを追加 -> POSTを選択 -> 作成したLambda関数を指定して、POSTリクエスト用のメソッドを作成します。
最後に、アクション->APIのデプロイ を選択し、デプロイします。
4. Line Messaging APIの設定
API GatewayにPOSTリクエストを送るためのLine Messaging APIを作成します。
Line Developers出ない方は新規登録をしましょう。
【チャネルの作成】
Line Developersにログインし、新規Providerを作成します。
Channelsに「Create a MEssaging API channel」を選択し、Channel nameなど適当に埋めて、Channelを作成します。
【Webhook URLの設定】
Messaging APIの設定で、Webhook URL選択し、作成したAPI GatewayのAPIエンドポイントを記載します。
【動作確認】
Messaging API設定画面で表示されるQRコードを読み取り、Lineで友達追加します。
このチャネルで、「起動」または「停止」を送って、実際にEC2インスタンスが起動、停止することを確かめます。
起動、停止を送ると、、、
5. 起動時設定
最後に、EC2が起動したときに特定のスクリプトを実行できるようにします。
今回は起動・停止時にメッセージを出力するだけの、mytestというスクリプトを登録します。
#!/bin/sh
# chkconfig: 2345 99 10
# description: test shell
case "$1" in
start)
echo "start!" > /tmp/start.txt
;;
stop)
echo "stop!" > /tmp/stop.txt
;;
*) break ;;
esac
下記のコマンドでchkconfigに登録すると、スクリプトが実行されるようになります。
$ chkconfig --add mytest
$ chkconfig mytest on
まとめ
以上で、好きなタイミングでLineからEC2を起動させプログラムを自動起動できるようになりました!外出中でも気軽にEC2を操作できるのが嬉しいですね。