
AWS Chatbotを使用して、SlackのチャットでEC2を起動・停止・IPアドレスを確認できる方法をご紹介
目次
やろうと思ったきっかけ
AWSでbotが自由に導入できるマイクラマルチサーバを作り、そのサーバを誰でも自由に起動停止でき、でもセキュリティはしっかりとして作りたいと思い、構築していたことがきっかけです。
マイクラマルチサーバは、参加するためにグローバルIPアドレスを入力してもらう必要があります。その際に、EC2を起動停止するとIPアドレスが変わってしまいます。
EIPを使用するのもいいのですが、起動停止するサーバだと余分にお金がかかってしまいます。そこで、スラックでIPを確認でき、さらに同じチャンネルにいる人なら誰でもサーバを起動停止できると便利だと思い、今回のChatbotを使用して、Slack上でEC2を操作できるようにしました。
マイクラサーバの構築は別で記事を書いていく予定です。
アーキテクチャ図
今回は赤枠の部分のやり方をご紹介します。

やり方
今回、EC2は別で作成してある前提で構築手順を紹介します。
①EC2を起動・停止・ステータス確認するためのLambdaを作成
「Lambda」→「関数」→「関数作成」を選択します。
関数名は好きなもので大丈夫です。今回は「hirakegoma」でいきます。
ランタイムはPythonを選択します。関数を作成しましょう。

コードに以下のコードを入力しましょう。
インスタンスがあるリージョン、インスタンスIDにはご自身のものを入力しましょう。
例)東京リージョンの場合:ap-northeast-1
import boto3
region = 'インスタンスがあるリージョン'
instances = ['インスタンスID']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.start_instances(InstanceIds=instances) # start instance
print('started your instances: ' + str(instances))
同様に、EC2停止用Lambda「tozirogoma」、EC2 IPアドレス確認用Lambda「IPmisete」を作成します。
EC2停止用Lambda関数
import boto3
region = 'インスタンスがあるリージョン'
instances = ['インスタンスID']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.stop_instances(InstanceIds=instances) # stop instance
print('stopped your instances: ' + str(instances))
EC2 IPアドレス確認用Lambda関数
EC2 IPアドレス確認用Lambda関数は、インスタンスIDの部分を変更するだけで大丈夫です。
メッセージ部分は好きに変えてもらって結構です。
import boto3
def get_ec2_instance_status(instance_id):
ec2_client = boto3.client('ec2')
try:
response = ec2_client.describe_instances(InstanceIds=[instance_id])
instance_state = response['Reservations'][0]['Instances'][0]['State']['Name']
return instance_state
except ec2_client.exceptions.ClientError as e:
if e.response['Error']['Code'] == 'InvalidInstanceID.NotFound':
return 'InstanceNotFound'
else:
raise
def lambda_handler(event, context):
instance_id = "インスタンスID" # EC2インスタンスのIDを指定
instance_state = get_ec2_instance_status(instance_id)
if instance_state == 'InstanceNotFound':
return {
'statusCode': 200,
'body': {
'message': 'EC2インスタンスが見つかりませんでした。'
}
}
if instance_state == 'stopped':
return {
'statusCode': 200,
'body': {
'message': 'マイクラサーバーは閉じてるよ。起動コマンドできどうしてね。'
}
}
ec2_client = boto3.client('ec2')
response = ec2_client.describe_instances(InstanceIds=[instance_id])
public_ip = response['Reservations'][0]['Instances'][0]['PublicIpAddress']
return {
'statusCode': 200,
'body': {
'IPアドレスだよ': public_ip,
'マイクラサーバーは開いてるよ。上のIPアドレスを入力して入ってね。': instance_state
}
}
EC2 IPアドレス確認用Lambda関数は処理時間が長く、デフォルトの3秒ではタイムアウトしてしまうので、5秒に変更しておきましょう。

②Lambda用のIAMロール作成
次に、作成されているIAMロールにEC2へのアクセスを許可します。
「IAM」→「ロール」を選択
先程作成したLambda関数に紐づいているIAMロールを選択します。
今回の場合は、「hirakegoma-role-文字列」
「許可の追加」→「ポリシーをアタッチ」を選択

ポリシーは「AmazonEC2FullAccess」を選択

同様に、Lambda関数で作成した分の「tozirogoma-role」、「IPmisete-role」にもポリシーを追加しましょう。
「IPmisete-role」のポリシーは、「AmazonEC2ReadOnlyAccess」にしましょう。
ポリシーをアタッチできたら、作成したLambda関数に戻り、「Test」を選択して動作テストをしましょう。
無事、EC2が起動・停止していたら成功です。
③ChatbotとSlackの紐づけ
「Chatbot」→「チャットクライアント設定」から「Slack」を選択します。
ワークスペースのURLを入力して、連携は完了です。
ワークスペースのURLは、PCの場合Slack上の左上のワークスペース名を選択したら見れます。
ワークスペース名を選択し、「Slackチャネルを設定」を選択します。
設定名はお好きな名前にしましょう。
Slackチャネルから、追加したいチャンネル名を選択します。

アクセス許可は「チャネルロール」を選択し、「テンプレートを使用してIAMロールを作成する」を選択します。
ロール名はお好きなもので大丈夫です。今回は「slack-chatbot-role」としています。
ポリシーテンプレートには「読み取り専用コマンドのアクセス許可」「Lambda 呼び出しコマンドのアクセス許可」を選択
チャネルガードレールポリシーには「AWS-Chatbot-LambdaInvoke-Policy」「AWS-Chatbot-ReadonlyCommands」「ReadOnlyAccess」を選択します。

チャネルガードレールポリシーと、チャネルロールはお互いの被った権限のみ許可されます。
チャネルがードレールでチャンネル全体の権限を管理し、チャネルロールとユーザレベルのロールでさらに許可レベルを掘り下げるイメージです。
サービスコントロールポリシーを思い浮かべると、想像しやすいです。
Slackのチャンネルで、「invite @aws 」とチャットして、AWSをチャンネルに入れます。

実際にLambda関数を、Slack上で起動させます。
「@aws lambda invoke hirakegoma –region ap-northeast-1」と入力し、botから返信があるので、[Run]commandを選択します。
region ap-northeast-1の部分は自分のリージョンを入力します。
2回目以降は「@aws lambda invoke hirakegoma」のように、リージョンを省いた形でチャットしても大丈夫です。

EC2が起動していたら成功です。他の関数も同じように起動できるので、試してみましょう。
まとめ
今回はChatbotを使用し、Slack上でEC2を起動・停止・IPアドレス確認をできるようにしました。
Slack→Chatbot→Lambdaと、それぞれロールも制限しているのセキュアになっています。
他にも色々なことが出来そうな気がするので、Chatbotを使用して試していきたいと思っています。
今後、Slack上で操作できるマイクラサーバをたてる方法を記事に書いていく予定なので、もしよろしければご覧ください。