EC2
SNS
lambda
APIGateway

URLアクセスでEC2を起動/停止してその結果とIPアドレスをメール通知する

目的

主に Python の勉強用に、使いたい時にサッと使えるようにしたい

ローカル PC に入れたらえーやんとか言わない
ChromeBook ってコマンド使えるんかいな?

やり方

API Gateway + Lambda + EC2 + SNS を組み合わせる (AWS を利用する)

構成概要

Created using Draw.io

Created using Draw.io

作っていく

EC2 を作成

IP アドレス通知を自動化するのに起動スクリプトを利用するので、Linux (Amazon Linux) で作成

SNS Topic を作成

通知先メールアドレスをサブスクライブしておく

Lambda function を作成

コードを記述

EC2 起動用 Lambda function コード

ランタイムは Python 2.7 を使用
(print 構文を直せば Python 3.6 でも使えると思う)

import boto3

def lambda_handler(event, context):
    client = boto3.client('ec2')
    response = client.start_instances(
        InstanceIds=[
            'i-051e83f1cd4171403',
        ]
    )
    print "Response: ", response

    sns = boto3.client('sns')
    res = sns.publish(
        TopicArn='arn:aws:sns:ap-northeast-1:012345678912:mySnsTopic',
        Subject='Started EC2ID:i-051e83f1cd4171403',
        Message='Started EC2ID:i-051e83f1cd4171403'
    )

コード中のインスタンス ID やトピック名は、適宜自身のリソースのものに読み替える

EC2 停止用 Lambda function コード

ランタイムは Python 2.7 を使用
(print 構文を直せば Python 3.6 でも使えると思う)

import boto3

def lambda_handler(event, context):
    client = boto3.client('ec2')
    response = client.stop_instances(
        InstanceIds=[
            'i-051e83f1cd4171403',
        ]
    )
    print "Response: ", response

    sns = boto3.client('sns')
    res = sns.publish(
        TopicArn='arn:aws:sns:ap-northeast-1:012345678912:mySnsTopic',
        Subject='Stopped EC2ID:i-051e83f1cd4171403',
        Message='Stopped EC2ID:i-051e83f1cd4171403'
    )

コード中のインスタンス ID やトピック名は、適宜自身のリソースのものに読み替える

ロールを作成

Lambda 用のデフォルトロールに以下 Action を追加 (該当の Resource も追加しておく)

  • ec2:StartInstances
  • ec2:StopInstances
  • sns:Publish

API をデプロイ

※ロールの作成含め、API Gateway のチュートリアルが詳しい

AWS Lambda 関数の API GatewayAPI を作成する

  1. EC2 起動用と停止用のリソースを作成
  2. それぞれのリソースにGETメソッドを作成し、上記で作成した Lambda function と関連付ける
  3. ステージを作成
  4. すると、ステージ毎に下記のような URL が生成される
  5. URL を叩くと EC2 が起動/停止する。また、その通知がメールで届く (通知内容は Lambda function で定義しておく)

https://aaaabbbbcccc.execute-api.ap-northeast-1.amazonaws.com/test/startec2
https://aaaabbbbcccc.execute-api.ap-northeast-1.amazonaws.com/test/stoptec2

スマホのホーム画面にアイコンを置いておくと便利
でも開いたタブは閉じておかないと、次回ブラウザ起動時に開いてしまう恐れあり
2017/10/2 以降に起動する EC2 は秒課金 (最低 60 秒) なのであまり心配ない (メールも届く)

IP アドレスを通知

EC2 Public IPv4 アドレスは、Linux の起動スクリプトで通知

[ec2-user@ec2]$ sudo vi /etc/init.d/snspublish

#!/bin/bash
#
# chkconfig: 3 99 99
# description:

start() {
        su -l ec2-user -c "sh /home/ec2-user/snspublish.sh"
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  *)
        echo $"Usage: $0 {start}"
        exit 2
esac

[ec2-user@ec2]$ vi snspublish.sh

#!/bin/sh
publicipv4=`curl -s http://169.254.169.254/latest/meta-data/public-ipv4`
topic_arn="arn:aws:sns:ap-northeast-1:012345678912:mySnsTopic"
aws sns publish --topic-arn $topic_arn --message $publicipv4 --subject "Started EC2 IPv4 Address"

EC2 (Linux) が起動すると、本文に IP アドレスが書かれたメールが届く

[ec2-user@ec2]$ sudo chkconfig --add snspublish

※スクリプト中で aws コマンドで AWS リソースにアクセスするので、
「aws configure」をするか、EC2 をロール付きで再作成する必要あり

想定される課金内容

サービス 無料利用枠 コメント
API Gateway 100 万件/月の API 呼び出しの受信 ≒実質無料
Lambda 100 万件/月のリクエストおよび 320 万秒/月(128 MB)のコンピューティング ≒実質無料
SNS 100 万件/月のリクエストおよび 1000 件/月の E メール配信 ≒実質無料