はじめに
広島大学の谷です。8月中旬から9月はじめまでの4週間、ヤプリのSREチームでインターンをさせてもらっています!この記事では私がインターン期間中に取り組んだ、開発用EC2インスタンスの自動起動/自動停止と、Slackからコマンドで開発用EC2インスタンスを起動/停止できるようにした話をしたいと思います。
取り組んだ内容
目的
- 開発環境で使っているEC2インスタンスを夜間と休日に停止したい。
- 停止しているインスタンスをSlackから起動させたい
使った技術
- AWS
- Systems Manager Automation(SSM Automation)
- Lambda
- API gateway
- CloudWatch Events
- terraform
仕組み
仕組みとしては、2つ経路があります。
1.Slackからコマンドを打つ経路
- Slack botのSlash CommandsからAPI gatewayを叩く
- API gatewayからLambdaを起動
- Lambdaでslack botの引き数を見て行う処理を決める
- SSM Automationを起動、もしくは直接EC2に対して処理を行う
2.CloudWatch Eventsで定期的に実行する経路
- CloudWatch Eventsでcronで指定したruleから、定期的にSSM Automationを起動
- EC2を起動/停止
はじめはAWSに慣れるためにあまりコードを書かなくて済むSSM Automationを触ってみましょうということになり、CloudWatch Events + SSM Automationが先に出来上がりました。そのあとでSlackから起動できたらいいね、という話になり、すでにあったSSM Automationを利用してLambdaからキックする構成になりました。
便利だと思ったところ
SSM Automation
EC2をただ起動、停止するだけなら公式からdocumentが提供されていて、簡単な処理はコードを書く必要がなくて便利です。 ただ、今回はリソースグループを指定するなど少し複雑なことを行おうとしたので、そうなると参考になる物が少なくて、Lambdaの方が参考例が多くて楽なのではないかとも思いました。
terraform
今回初めてまともにterraformを触ったのですが、これすごいですね!destroyの安心感がすごいし、コンソールでGUIぽちぽちするのが苦手な自分にはとても合っていました。ただ、AWSはコンソールからやるとroleなどをいい感じにやってくれるのに対し、terraformからだと明示的に指定する必要があるので、少し注意が必要です。
詰まったところ
terraformのaws provider
今回の構成は全てterraformに落とし込んだのですが、かなり時間をかけてハマってしまったところとして、今回(terraform 0.12.29, aws provider 3.3)の環境だとSSM AutomationのdocumentのARNをCloudWatchEventから指定するときに、そのまま参照でとってくるとエラーになってしまうので、ARNの document/
を automation-definition/
に変更する必要があります。 こちらのissue を参考に以下のようにして乗り切りました。
resource "aws_cloudwatch_event_target" "target_name" { ... arn = replace(<SSM Automation DocumentのARN>, "document/", "automation-definition/") ... }
OpsWorksがEC2が落ちたときに自動起動を行ってしまう
EC2の定時停止ができるようになりチェックで動かしていると、なぜかEC2が停止して7-8分後にEC2が勝手に起動してしまうという現象が起こりました。しばらくメンターの方と考えて、OpsWorksのAuto HealingがONになっているのが原因だとわかりました。 AWSの公式ドキュメント によると、Auto HealingはデフォルトでONになっていて、インスタンスをOpsWorksを経由せずに停止させると、自動で起動するようです。 OpsWorksのAuto HealingをOFFにすることで解決しました。
cronの曜日指定
CloudWatch Eventsのruleでcronを用いてインスタンスの起動/停止時刻を設定する時はJSTではなくUTCです。このことは 公式ドキュメント を読んで分かっていたつもりでしたが、曜日を考慮せずにやっていたため、1日ずれてしまいました。 UTC(cronにかく実際の値)が15以上23以下の場合、JSTでは翌日の0-8時となるので曜日をJSTより一日分前を指定する必要があります。
まとめ
SSM Automation, Lambda, Slack botを利用してインスタンスの自動停止と自動起動、Slackからのインスタンス起動停止を行うことができました。 これで開発にかかる費用を削減!インターン生として少しは貢献できたでしょうか?