EC2インスタンスにRaspberry Piで電源スイッチを付けてみた【cloudpack 大阪 BLOG】
久しぶりにRaspberryPiを触ってみて思いついたので早速作ってみました。以前はLチカやったところで終わっていましたが、Pythonを少し覚えたので何かAPIと連携させてみようと考えていました。最近、EC2インスタンスを触ることが多くなりましたが、サーバの電源を入れるということを全てWeb上でやっているので物理スイッチでわざわざ起動、停止をやってみようと思い作ってみました。
今回やってみたのは以下のような内容です。
・RaspberryPiでスイッチを押すとEC2が起動もしくは停止
・起動中 or 停止中はLEDを点滅させる
・起動、停止が完了したらslackで自分に通知
準備
RaspberryPi B+ (OSはraspbian 今回使用したバージョンは「Linux raspberrypi 3.12.28+ 」)
ブレッドボード
LED
タクトスイッチ
抵抗 330Ω(LED用)、1kΩ(タクトスイッチ用)
ジャンパーワイヤ
モジュールのインストール
pipのインストール
apt-get install python-pip
boto3(AWS SDK FOR Python)のインストール
pip install boto3
配線の確認
実際に部品が正しく配置されているか確認するため、下記のプログラムを実行して動作確認を行います。
LEDの動作確認
#! /usr/bin/env python import RPi.GPIO as GPIO import time LEDPIN = 21 GPIO.setwarnings(False) # Suppress warnings GPIO.setmode( GPIO.BCM ) GPIO.setup( LEDPIN, GPIO.OUT ) while 1: GPIO.output( LEDPIN, True ) time.sleep( 1.0 ) GPIO.output( LEDPIN, False ) time.sleep( 1.0 )
実行すると一定間隔でLEDが点滅します。点滅しなければ部品の配置や配線が間違えてないか見直してください
タクトスイッチの動作確認
#! /usr/bin/env python import RPi.GPIO as GPIO import time # define INPUT_PIN = 4 # init GPIO.setwarnings(False) # Suppress warnings GPIO.cleanup() GPIO.setmode(GPIO.BCM) GPIO.setup(INPUT_PIN,GPIO.IN) if __name__ == "__main__": Btn_Flag = False while True: print (GPIO.input(INPUT_PIN)) time.sleep(0.2)
実行してボタンを押すとボタンが押されている間はコンソールに「1」が表示されます
EC2インスタンスの起動・停止プログラム
上記のテストプログラムが正常に実行されれば実際にボタンを押してEC2のストップ、スタートができるプログラムを作成していきましょう。
AWSのアクセスキー、シークレットキー及びSlackのAPIキーは取得したものに変更してください。また、Slackの送信先は自身のユーザー名(@ + ユーザー名)に変更してください。
#! /usr/bin/env python import RPi.GPIO as GPIO import time import boto3 from boto3.session import Session import sys import urllib import urllib2 # define INPUT_PIN = 4 LEDPIN = 21 # init GPIO.setwarnings(False) # Suppress warnings GPIO.cleanup() GPIO.setmode(GPIO.BCM) GPIO.setup(INPUT_PIN,GPIO.IN) GPIO.setup( LEDPIN, GPIO.OUT ) ################################################################# # Function ################################################################# def getResourceEC2 (): session = Session(aws_access_key_id='ACCESS_KEY', aws_secret_access_key='SECRET_KEY', region_name='ap-northeast-1') ec2 = session.resource('ec2') return ec2 def get_ec2_state(instanceId): ec2 = getResourceEC2() instance = ec2.Instance(instanceId) if(instance.state['Name']=='running'): return True else: return False def start_ec2(instanceId): ec2 = getResourceEC2() instance = ec2.Instance(instanceId) if(instance.state['Name']=='stopped'): instance.start() # Flashing LED led_flag = False while instance.state['Name'] != 'running': GPIO.output( LEDPIN, not led_flag) led_flag = not led_flag instance.reload() time.sleep( 1.0 ) GPIO.output( LEDPIN, True) print('EC2 Start!') post_slack('EC2 Start!') else: print('EC2 already Started!') post_slack('EC2 already Started!') def stop_ec2(instanceId): ec2 = getResourceEC2() instance = ec2.Instance(instanceId) if(instance.state['Name']=='running'): instance.stop() # Flashing LED led_flag = False while instance.state['Name'] != 'stopped': GPIO.output( LEDPIN, not led_flag) led_flag = not led_flag instance.reload() time.sleep( 1.0 ) GPIO.output( LEDPIN, False) print('EC2 Stop!') post_slack('EC2 Stop!') else: print('EC2 already Stopped!') post_slack('EC2 already Stopped!') def post_slack(message): url = "https://slack.com/api/chat.postMessage" params = {'token' :'SLACK_API_KEY', 'channel':'@USER', 'text' : message } req = urllib2.Request(url) req.add_header('Content-Type', 'application/x-www-form-urlencoded') req.add_data(urllib.urlencode(params)) res = urllib2.urlopen(req) ################################################################# # Main Function ################################################################# if __name__ == "__main__": print('Switch Start') argvs = sys.argv Id = argvs[1] Btn_Flag = get_ec2_state(Id) GPIO.output( LEDPIN, Btn_Flag) while True: if(GPIO.input(INPUT_PIN)): Btn_Flag = not Btn_Flag if(Btn_Flag): start_ec2(Id) else: stop_ec2(Id) time.sleep(0.2)
※簡略化するため、ステータスチェックなど細かい処理は省いています。