やったことまとめ
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 での実装サンプル
const AWS = require('aws-sdk');
const { WebClient } = require('@slack/web-api')
//#### Slack
const slackNotifiCation = async (message) => {
const token = '<SlackのトークンID>'
const channel = '<通知するチャンネル名>'
const client = new WebClient(token)
const params = {
channel: channel,
text: message
}
const response = await client.chat.postMessage(params)
//console.log(response)
}
const credentials = new AWS.SharedIniFileCredentials({profile: 'プロファイル名'});
AWS.config.credentials = credentials;
//利用する環境のリージョンを指定する
AWS.config.update({region: '<利用するリージョンを指定する>'}); // 東京とか→「ap-northeast-1」
// Create RDS object
const rds = new AWS.RDS({apiVersion: '2014-10-31'})
// RDS AZを停止する
const fetch_rds_az = {
// RDSパラメータ定義
params:{
DBInstanceIdentifier: ''
},
dbInstanceParams:"",
// RDS の情報を取得
getRdsStatus: async function(){
await rds.describeDBInstances(this.params).promise()
.then(data => {
this.dbInstanceParams = data.DBInstances[0]
}
).catch(err => {
console.log(err)
})
},
fetchRdsParams: async function(){
await this.getRdsStatus()
await console.log(this.dbInstanceParams.DBInstanceStatus)
},
rdsController: async function(commandParam){
await this.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}`)
}
)
break
case '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}`)
}
)
break
case 'watch': // RDS の AZ を監視するためのメソッド
await this.getRdsStatus()
const currentAz = this.dbInstanceParams.AvailabilityZone
const rdsInstance = this.dbInstanceParams.DBInstanceIdentifier
await slackNotifiCation(`【test】${rdsInstance} は ${currentAz}で稼働しています`)
break
default:
console.log('arg params is Inappropriate ')
slackNotifiCation(`残念でしたー、コマンド実行時の引数に誤りがあります${commandParam}`)
break
}
}
}
//##>> コマンド引数を取得する( $node env-dev-rds-controller watch |start | stop)
const commandParam = process.argv[2].toString()
//##>> 起動、停止するDBのインスタンス情報を指定する
const targetRds = process.argv[3].toString()
fetch_rds_az.params.DBInstanceIdentifier = targetRds
//##>> 起動・停止するRDSの指定をオブジェクト内として実行
fetch_rds_az.rdsController(commandParam)