Powershellを用いて、aws ec2-instance-connect open tunnelをバックグラウンドで実行
はじめに
先日、EC2 Instance Connect Endpointを用いて、パブリックIPがないWindows Serverへ接続!という記事を書きました。
その中で、AWS CLIコマンドを用いてプライベートトンネルを確立するところがあります。
具体的には、タイトルにあるコマンド「aws ec2-instance-connect open tunnel」を実行します。
Powershellで実行すると、下記のように実行中状態になるため複数同時実行に困ります。 (新しくPowershellプロセスを開けばいい、、、)
そのため、複数実行するためにバックグラウンド実行しようと思いました。
さらに、手動で毎回実行するのは手間がかかるためスクリプト化しました!
コード
インスタンスが起動していない場合、強制終了するようにしています。
インスタンスが起動していて、やっとジョブによってバックグラウンド実行されます!
Start-Jobのコマンドの際にAWS CLIコマンドを指定していますが、インスタンスIDパラメータで変数を指定するとジョブが完了します。
そのため、インスタンスIDを直書きしています。(何故だろう、、、)
# awsのプロファイル定義
$env:AWS_PROFILE="kano-test"
# server1のインスタンスID
$server1 = "i-0a52120b80a762b5c"
# server2のインスタンスID
$server2 = "i-0f6b1765365ca59dc"
# インスタンスの起動有無確認
$instanceStatus1 = aws ec2 describe-instances --instance-ids $server1 --query "Reservations[].Instances[].State.Name" --output text
$instanceStatus2 = aws ec2 describe-instances --instance-ids $server2 --query "Reservations[].Instances[].State.Name" --output text
if ($instanceStatus1 -eq "stopped" -or $instanceStatus2 -eq "stopped") {
# エラー文言
$errorString = "強制終了ため、「Enter」押してください"
# 両方のインスタンスが停止している場合
if ($instanceStatus1 -eq "stopped" -and $instanceStatus2 -eq "stopped") {
Write-Host "両方のインスタンスが停止しています:$server1 , $server2"
Read-Host $errorString
exit
}
# server1のみ停止している場合
elseif ($instanceStatus1 -eq "stopped" -and $instanceStatus2 -ne "stopped") {
Write-Host "片方のインスタンスが停止しています:$server1"
Read-Host $errorString
exit
}
# server2のみ停止している場合
else {
Write-Host "片方のインスタンスが停止しています:$server2"
Read-Host $errorString
exit
}
}
# (インスタンスIDを変数で入れた場合、ジョブ状態がRunningにならないため直打ち)
# WIN2022-DC01のプライベートトンネルジョブ
$job1 = Start-Job { aws ec2-instance-connect open-tunnel --instance-id i-0a52120b80a762b5c --remote-port 3389 --local-port 65000 }
# WIN2022-FS01のプライベートトンネルジョブ
$job2 = Start-Job { aws ec2-instance-connect open-tunnel --instance-id i-0f6b1765365ca59dc --remote-port 3389 --local-port 65001 }
# ジョブ情報取得 or ジョブの削除
$isValidJob = $false
while (-not $isValidJob) {
$chooseAction = Read-Host "ジョブ情報取得[G] or ジョブ削除[D]を選択してください"
# Gの場合、ジョブ情報取得
if ($chooseAction -eq "G" -or $chooseAction -eq "g") {
Get-Job
Write-Host "ジョブ一覧を取得しました。"
}
# Dの場合、プライベートトンネルのジョブ削除
elseif ($chooseAction -eq "D" -or $chooseAction -eq "d") {
$isValidJob = $true
Remove-Job -Id $job1.Id,$job2.Id -Force
Write-Host "ジョブを削除しました。"
}
else {
Write-Host "無効な入力です。[G] か [D] で再入力してください。"
}
}
使用イメージ
両方のインスタンスが停止している場合
片方のインスタンスが停止している場合
両方のインスタンスが起動している場合 (ジョブ一覧取得かジョブ削除)
もちろん接続できます!
課題
現状のコードが2インスタンスを想定して書いてるが、
3インスタンス以上の複数インスタンスを想定していないこと。
(いつかコードより良くしたいです!)
まとめ
コードをテンプレート化していません。基本変更が必要なところは下記のとおりです。
・awsのプロファイル定義
・server1, 2変数のインスタンスID
・job1, 2変数のインスタンスIDとローカルポート (空きポート)
目的のバックグラウンド実行を果たすことができました!少しはWindows Serverの勉強が捗りそうです。
本記事が誰かの一助になれば嬉しいかぎりです!