管理人Kのひとりごと

デジモノレビューやプログラミングや写真など

RDSでインスタンスが停止してからの経過時間を調べる(Powershell)

RDSは停止保持は最大7日までです。それ以上経過すると起動します。
マネコンを見ずとも、指定したRDSインスタンスが停止してからどれくらい経ったかを知りたかったので、Powershellスクリプトを書いてみました。
対象となるRDSの状態を、CloudTrailの結果から取得することで判定しています。
Powershellだと、JSONファイルのパースだとか、文字列日付のオブジェクト変換だとかを良しなにやってくれるのでサクっと書くことができました。

検証環境

PS C:\Users\hoge\> $PSVersionTable.PSVersion


Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      19041  610

ソース

単一のインスタンスのみを対象としています。
また、

  • AWS CLIがセットアップしてあること
  • CloudTrailの「lookup-events」可能な権限を有していること

が条件です。

param(
    [string]$rdsInstanceName    # RDSのインスタンス名
)

# エラーがあった時点で処理終了
$ErrorActionPreference = "stop"

function script:Main($filepath) {
    $filename = ".\temp_ctRDSStats.json"

    # 引数チェック(未指定なら終了)
    if($rdsInstanceName -eq ""){
        Write-Host "RDSのインスタンス名を指定してください"
        exit
    }

    # CloudTrailのAPIを叩いて結果をファイル出力する
    $ctRDSStats = (aws cloudtrail lookup-events `
    --lookup-attributes AttributeKey=EventSource,AttributeValue=rds.amazonaws.com `
    --lookup-attributes AttributeKey=ResourceType,AttributeValue=AWS::RDS::DBInstance `
    --lookup-attributes AttributeKey=ResourceName,AttributeValue=$rdsInstanceName `
    --query "Events[*].{EventName:EventName,EventTime:EventTime}" `
    --output json)

    try{
        $ctRDSStats | Out-File -FilePath $filename -Encoding utf8
    } catch {
        Write-Error "IOエラーが発生しました"
    }

    $ctRDSStatsJson = (Get-Content -Path $filename | ConvertFrom-Json)

    # オブジェクト化したJSONの先頭要素(一番最近発生したイベント)を取得
    # イベントに応じて処理を分岐
    # DeleteDBInstance-> 削除済みの旨表示
    # StopDBInstance-> 現在事項―イベント発生時刻を計算
    # StartDBInstance-> 起動中の旨表示
    # CreateDBInstance-> 起動中の旨表示

    # イベントが1つもなければ処理終了
    if($ctRDSStatsJson.Count -lt 1){
        Write-Host "イベントがありません"
        exit
    }

    $firstItem = $ctRDSStatsJson[0]

    if($firstItem.EventName -eq "StopDBInstance"){
        # 文字列からDateTime型に変換
        $eventTime = [DateTime]$firstItem.EventTime

        # 現在時刻 - イベント発生時刻を計算
        $now = Get-Date
        $dateDiff = $now - $eventTime

        Write-Host "インスタンス:" $rdsInstanceName "は停止から" $dateDiff.Hours "時間経過しています"
    }elseif ($firstItem.EventName -eq "DeleteDBInstance") {
        Write-Host "インスタンス:" $rdsInstanceName "は削除済みです"
    }elseif ($firstItem.EventName -eq "StartDBInstance" -Or $firstItem.EventName -eq "CreateDBInstance"){
        Write-Host "インスタンス:" $rdsInstanceName "は実行中です"
    }else{
        Write-Host "不明なイベントです:" $firstItem.EventName
    }
}

Main $rdsInstanceName

実行例

当該インスタンスが稼働中の場合

PS C:\Users\check_rds_wakeup_time> .\check_rds_wakeup_time.ps1 runningdb

インスタンス: runningdb は実行中です

当該インスタンスが削除済みの場合

PS C:\check_rds_wakeup_time> .\check_rds_wakeup_time.ps1 deleteddb

インスタンス: deleteddb は削除済みです

当該インスタンスが停止中の場合

PS C:\check_rds_wakeup_time> .\check_rds_wakeup_time.ps1 stoppeddb

インスタンス: stoppeddb は停止から 22 時間経過しています

当該インスタンスが存在しない場合

PS C:\Users\check_rds_wakeup_time> .\check_rds_wakeup_time.ps1 notexisteddb

イベントがありません

参考にしました

docs.aws.amazon.com