ALBのヘルスチェック結果を確認するPowerShellスクリプトを書いてみた
CloudFormationからEC2インスタンスを起動する際、ALBのヘルスチェックをクリアするまで後続の処理を止めておきたいというときに作成したスクリプトです。
PowerShellの超初心者が書いた内容ですが、参考になれば幸いです。
スクリプト
# UTF8にエンコード
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 起動したEC2インスタンス自身のIDを取得
$data = Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing
$id = $data.Content
# ALBによるヘルスチェックの結果を取得
$state = Get-ELB2TargetHealth -TargetGroupArn <ターゲットグループのARN> -Target @{Id = $id} -Select TargetHealthDescriptions.TargetHealth.State
echo $state >> C:\cfn\state.log
# ヘルスチェックをクリアするまで10秒ごとに結果を取得
while ($state -ne "healthy") {
$state = Get-ELB2TargetHealth -TargetGroupArn <ターゲットグループのARN> -Target @{Id = $id } -Select TargetHealthDescriptions.TargetHealth.State
Start-Sleep -s 10
echo $state >> C:\cfn\state.log
}
echo "done" >> C:\cfn\state.log
エンコード
スクリプトの冒頭に
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
を記述することでUTF8にエンコードしています。
ユーザーデータ実行時にUTF8じゃないとエラーが発生したので以下の記事を参考にして記載しました。
cfn-initの実行時に「Unhandled exception during build: ‘utf8’ codec can’t decode byte…」のエラーが出る件について | DevelopersIO
自身のIDを取得
http://169.254.169.254/latest/meta-data/instance-id
上記でインスタンスのメタデータのうち、インスタンスIDを取得しています。
メタデータについて詳しくは以下のドキュメントをご覧下さい。
インスタンスメタデータの取得 - Amazon Elastic Compute Cloud
インスタンスメタデータのカテゴリ - Amazon Elastic Compute Cloud
PowerShellではcurlの代わりにInvoke-WebRequest
を使うようなので、これでメタデータのURLにリクエストしています。
また、-UseBasicParsing
のオプションは、EC2 Windows Server2019のデフォルトブラウザであるIEからのリクエスト時に付与しないとリクエストが通らなかったので付与しています。
EC2 user-data を使ってNAME Tagを設定する(Windows) | Oji-Cloud
Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing
にリクエストすると、以下のレスポンスが返ってきます。
StatusCode : 200
StatusDescription : OK
Content : i-07a427e54c9465742
RawContent : HTTP/1.0 200 OK
Connection: keep-alive
Accept-Ranges: bytes
Content-Length: 19
Content-Type: text/plain
Date: Thu, 15 Apr 2021 08:23:09 GMT
Last-Modified: Thu, 15 Apr 2021 08:13:06 GMT
Server: ...
Forms :
Headers : {[Connection, keep-alive], [Accept-Ranges, bytes], [Content-Length, 19], [Content-Type, text/plain]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml :
RawContentLength : 19
上記のうち、Content
にインスタンスIDが記載されているので、一度レスポンスを$data
に入れてから、$id = $data.Content
でインスタンスIDのみを取得しています。
ALBによるヘルスチェックの結果を取得
Get-ELB2TargetHealth
というAPIでヘルスチェックの結果を取得しています。
PowerShellではAWS CLIの代わりにAWS Tools for PowerShellを使用します。
詳しくはこちらをご覧ください。
各種APIについてはAWS Tools for PowerShell Referenceで確認できます。
Get-ELB2TargetHealth
についてはこちらで確認できます。
-
-TargetGroupArn
ALBのターゲットグループのARNです。
記述例:-TargetGroupArn <ターゲットグループのARN>
-
-Target
ヘルスチェックの結果を取得するインスタンスを指定できます。
記述例:@{Id = "i-0bcc62df9872bd0f7" }
実際のスクリプトでは$id = $data.Content
で取得したインスタンスIDを$id
という変数に入れ、@{Id = $id}
でインスタンスIDを指定しています。 -
-Select
レスポンスの値から任意の値を選択して取得します。
レスポンス内容はAPIにより異なるので、上記のドキュメントを参照してください。
実際のスクリプトでは-Select TargetHealthDescriptions.TargetHealth.State
でヘルスチェックの結果の値(healthy
やunhealthy
)のみ取得しています。
ループ処理
while ($state -ne "healthy") {
$state = Get-ELB2TargetHealth -TargetGroupArn <ターゲットグループのARN> -Target @{Id = $id } -Select TargetHealthDescriptions.TargetHealth.State
Start-Sleep -s 10
echo $state >> C:\cfn\state.log
}
-
($state -ne "healthy")
でヘルスチェックをクリアするまでループする。 -
Start-Sleep -s 10
で10秒処理を止める→10秒ごとにループする - リクエストは前述の内容と同様
echo $state >> C:\cfn\state.log
スクリプトが実行されたかどうかの確認のためにログファイルにヘルスチェックの結果を書き込んでいます。
使用方法
EC2インスタンスのユーザーデータにスクリプトを記述することで、インスタンス起動時にスクリプトが実行されます。
Windowsのユーザーデータについて詳しくはこちらをご覧ください。
また、カスタムAMIからの起動時や再起動時にもユーザーデータを実行する場合はこちらをご覧ください。
ユースケース
- CloudFormationでの更新時
CloudFormationからAuto Scalingグループを作成し、Auto Scalingグループ内で起動するEC2インスタンスがALBのヘルスチェックをクリアしたら、CloudFormationの更新を続行します。詳しくはこちらをご覧ください。
まとめ
今回はALBのヘルスチェック結果を確認するPowerShellスクリプトを作成したので紹介しました。
自分自身がPowerShellの超初心者なので、もっとよい記述方法があるかもしれませんが、ひとまず期待する動作は確認できたのでこちらを使用しています。
もっと書けるようになればインスタンス起動時の初期設定も自動でできるので、機会があれば別のスクリプトも作成してみたいと思います。
参考資料
cfn-initの実行時に「Unhandled exception during build: ‘utf8’ codec can’t decode byte…」のエラーが出る件について | DevelopersIO
インスタンスメタデータの取得 - Amazon Elastic Compute Cloud
インスタンスメタデータのカテゴリ - Amazon Elastic Compute Cloud
EC2 user-data を使ってNAME Tagを設定する(Windows) | Oji-Cloud
AWS Tools for PowerShell とは何ですか? - AWS Tools for PowerShell
AWS Tools for PowerShell Reference
ElasticLoadBalancingV2: Get-ELB2TargetHealth Cmdlet | AWS Tools for PowerShell
Windows インスタンスでの起動時のコマンドの実行 - Amazon Elastic Compute Cloud
Discussion