概要
さくらのクラウド上に検証等の用途でサーバを作ることがありますが、毎日起動・停止を手作業で実行するのは面倒です。
毎朝始業時に自動で起動して、終業後に停止してくれるといいですよね。
何かそういったサービス(ニフクラでいうとタイマー)はあるかな・・・と探しましたが、見つかりませんでした。
さくらのサービスは安いので、定期処理実行用に VPS を 1個持っておく、といったことでも十分とは思いますが、そこはやはりサーバーレスにしたいところ。
ということで、AWS を使って Lambda + CloudWatch Events で実装してみよう! と思い立ちました。
(GCP で Cloud Functions + Cloud Scheduler や、Azure で Azure Functions + TimerTrigger でもできるかとは思いますが、試したことはありません)
スクリプト
スクリプトは Python で作りたいと思います。
調べてみると、こちらに saklient というライブラリが紹介されていました。
確認してみたところ動作したので、こちらを利用させていただくことにします。
Beta という記載があって、かつ数年前から更新が無さそうなので、そこは悩ましいところでしょうか。
実行結果は Slack に Incoming Webhook で通知するようにしたいと思います。
全体のコード
Terraform でまとめてデプロイできるようにしました。
以下で公開しています。
https://github.com/shztki/lambda-sakuracloud-startstop
使い方は README に記載しています。
今回 Lambda の環境変数にアクセスキー等の情報が入るため、ここはなんとしても暗号化したいところです。
ただ aws_lambda_function
に kms_key_arn
を渡したとしても、environment
内の variables
の値は暗号化されません。
通常ですとデプロイ後、こちらにある「クライアント側で環境変数を暗号化するには」のとおり、AWSコンソールにアクセスして、手動で「転送中の暗号化のためにヘルパーを有効にする」を選択して「暗号化」しないといけません。
これは、忘れると非常に危険ですし、手動で暗号化するまでの間に、誰かに見られる可能性もあります。
なんとしても、デプロイが完了した時点で、環境変数には暗号化済みの値に入っていてもらいたい・・・。
苦肉の策ではありますが、今回は kms.sh
というシェルスクリプトを用意し、AWS CLI で暗号化したものを variables
に渡すことで、実現してみました。
※あとから気づいたら、Secret Manager を使ったり、Systems Manager パラメータストアを使う方法がありました。。。Systems Manager パラメータストアなら費用かけずにできそうですね。
data "external" "slack_webhook_url" {
program = ["bash", "kms.sh"]
query = {
key_id = module.kms_key.key_arn
plaintext = var.slack_webhook_url
}
}
#!/bin/bash
set -e
eval "$(jq -r '@sh "KEY_ID=\(.key_id) PLAINTEXT=\(.plaintext)"')"
result=$(aws kms encrypt --key-id $KEY_ID --plaintext $PLAINTEXT --query CiphertextBlob --output text)
jq -n --arg result "$result" '{"result":$result}'
イメージ
Slack に毎日以下のように投稿されます。
今後
祝日は除外するような処理を追加しようかな・・・どうしようかなと考えています。
最後に
さくらのクラウドの操作を AWS でやるのかよ、というツッコミもあろうかと思いますが、そこはマルチクラウドな時代ということでご容赦ください。
VPS 1個分よりかは、月のコストは安くなるとは思います(正確なところは不明ですが)。
どうぞよいさくらのクラウドライフを!