やったことまとめ
RDSの起動・停止するスクリプトを書いて、cronで営業時間の間だけ起動するように制御しています
なぜやろうと思ったか?
開発環境を業務時間外の時間で稼働させるとお金がもったいない
reactを勉強しててjavascript が思ったより面白かったから何か作りたくなった
やってみた感想
dash というスニペットツールで課金すると 公式ドキュメントが簡単に見れて文言で検索できたのがすごく便利でドキュメントを探す手間がかなり省けたので助かりました
javascript の書き方を理解し切れていないけれど、今後 react を触る過程で慣れたいな、、
実装した内容
事前準備
※ RDSを制御可能な権限を持った iam の認証情報を使います
~/.aws/credential
[プロファイル名]
aws_access_key_id = xxxxxx
aws_secret_access_key = xxxxxx
aws-sdk と @slack/web-api をインストールする
$yarn add @slack/web-api @slack/events-api
$yarn add aws-sdk
crontab サンプル
これを cron で起動時と終了時を指定して呼び出してます
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
#開発環境のDBを平日(月 ~ 金の 8時 ~ 19時)稼働制御
## dev01-03(jty)
00 8 * * 1,2,3,4,5 root node <配置したディレクトリパス>/dev-rds-controler.js start <RDS識別子>
00 19 * * 1,2,3,4,5 root node <配置したディレクトリパス>/dev_rds_controler.js stop <RDS識別子>
node での実装サンプル
constAWS=require('aws-sdk');const{WebClient}=require('@slack/web-api')//#### SlackconstslackNotifiCation=async(message)=>{consttoken='<SlackのトークンID>'constchannel='<通知するチャンネル名>'constclient=newWebClient(token)constparams={channel:channel,text:message}constresponse=awaitclient.chat.postMessage(params)//console.log(response)}constcredentials=newAWS.SharedIniFileCredentials({profile:'プロファイル名'});AWS.config.credentials=credentials;//利用する環境のリージョンを指定するAWS.config.update({region:'<利用するリージョンを指定する>'});// 東京とか→「ap-northeast-1」// Create RDS objectconstrds=newAWS.RDS({apiVersion:'2014-10-31'})// RDS AZを停止するconstfetch_rds_az={// RDSパラメータ定義params:{DBInstanceIdentifier:''},dbInstanceParams:"",// RDS の情報を取得getRdsStatus:asyncfunction(){awaitrds.describeDBInstances(this.params).promise().then(data=>{this.dbInstanceParams=data.DBInstances[0]}).catch(err=>{console.log(err)})},fetchRdsParams:asyncfunction(){awaitthis.getRdsStatus()awaitconsole.log(this.dbInstanceParams.DBInstanceStatus)},rdsController:asyncfunction(commandParam){awaitthis.fetchRdsParams()switch(commandParam){case'start':if(this.dbInstanceParams.DBInstanceStatus==='available'){slackNotifiCation(`${this.dbInstanceParams.DBInstanceIdentifier}は起動中だよ!`)break}rds.startDBInstance(this.params).promise().then(data=>{slackNotifiCation(`${this.dbInstanceParams.DBInstanceIdentifier}を起動するよ!`)}).catch(err=>{slackNotifiCation(`【test】起動処理中にエラー発生 message:${err}`)slackNotifiCation(`【test】起動処理中にエラー発生 message:${this.dbInstanceParams.DBInstanceStatus}`)})breakcase'stop':console.log('stop')if(this.dbInstanceParams.DBInstanceStatus==='stopped'){slackNotifiCation(`${this.dbInstanceParams.DBInstanceIdentifier}は停止中だよ!`)break}rds.stopDBInstance(this.params).promise().then(data=>{slackNotifiCation(`${this.dbInstanceParams.DBInstanceIdentifier}を停止するよ!`)}).catch(err=>{slackNotifiCation(`【test】停止処理中にエラー発生 message:${err}`)slackNotifiCation(`【test】停止処理中にエラー発生 message:${this.dbInstanceParams.DBInstanceStatus}`)})breakcase'watch':// RDS の AZ を監視するためのメソッドawaitthis.getRdsStatus()constcurrentAz=this.dbInstanceParams.AvailabilityZoneconstrdsInstance=this.dbInstanceParams.DBInstanceIdentifierawaitslackNotifiCation(`【test】${rdsInstance}は ${currentAz}で稼働しています`)breakdefault:console.log('arg params is Inappropriate ')slackNotifiCation(`残念でしたー、コマンド実行時の引数に誤りがあります${commandParam}`)break}}}//##>> コマンド引数を取得する( $node env-dev-rds-controller watch |start | stop)constcommandParam=process.argv[2].toString()//##>> 起動、停止するDBのインスタンス情報を指定するconsttargetRds=process.argv[3].toString()fetch_rds_az.params.DBInstanceIdentifier=targetRds//##>> 起動・停止するRDSの指定をオブジェクト内として実行fetch_rds_az.rdsController(commandParam)