[PowerShell] EC2Launchを最新バージョンにするスクリプトを作ってみた
しばたです。
Windows Server 2016以降のEC2インスタンスに導入されているEC2Launchですが、これまでのEC2Configではバージョンアップを自動化するAWS-UpdateEC2Config
ドキュメントが提供されているのですが、EC2Launchでは同様のドキュメントは提供されておらずAMI全体のアップデートを行うAWS-UpdateWindowsAmi
ドキュメントに統合されており単体でバージョンアップすることができません。
そこで今回EC2Launchのバージョンアップを自動化する簡単なスクリプトを作ってみました。
EC2Launchのバージョンアップ手順
EC2LaunchはPowerShellモジュールとして提供されているのですが、標準のモジュールパスに登録されていないためUpdate-Module
では更新できず手動で最新パッケージをダウンロードしてインストールする必要があります。
詳細は以下のドキュメントに記載されています。
手順としてはコンテンツのEC2-Windows-Launch.zip
とinstall.ps1
を一緒にダウンロードして実行するだけなのですが、これくらいなら公式な更新ドキュメントを提供してほしいという気持ちもひとしおです...
ちなみEC2Launchの更新履歴は以下にあります。
バージョンアップスクリプト
作ったスクリプトを以下に記載します。
#
# 最新バージョンの EC2Launch をインストールするスクリプト
# Ref : https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch-download.html
#
# ※ EC2Launch 設定ファイルのバックアップには対応していません。
#
<#
.SYNOPSIS
EC2Launchの最新バージョンを取得します
#>
function Get-LatestEC2LaunchVersion() {
# https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch-version-details.html
# より最新バージョンを取得
#
# ※いつHTMLの構造が変わるかわからないので最悪
# return [Version]"1.3.2003150"
# の様に固定値を設定しても良いと思われる
try {
$res = Invoke-WebRequest -Uri 'https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch-version-details.html' -UseBasicParsing
$versions = ([Xml]$res.Content).html.body.GetElementsByTagName("table") |
Where-Object { $_.id -like 'w???????????????????' } |
ForEach-Object { $_.tr } |
ForEach-Object {
if ($_.td[0].p) {
[Version]($_.td[0].p)
}
else {
[Version]($_.td[0])
}
}
$latestVersion = $versions |
Sort-Object -Descending |
Select-Object -First 1
return $latestVersion
}
catch {
Write-Host $_
return $null
}
}
<#
.SYNOPSIS
現在インストールされているEC2Launchのバージョンを取得します。
EC2Launchがインストールされていない場合は $null を返します。
#>
function Get-EC2LaunchVersion() {
$psdPath = 'C:\ProgramData\Amazon\EC2-Windows\Launch\Module\Ec2Launch.psd1'
if (-not (Test-Path -Path $psdPath -PathType Leaf)) {
Write-Warning "Ec2Launch isn't installed."
return $null
}
return [Version](Import-PowerShellDataFile $psdPath).ModuleVersion
}
<#
.SYNOPSIS
EC2Launchの最新パッケージをダウンロードします。
#>
function Save-LatestEC2LaunchPackage([string]$SavePath = $env:TEMP) {
$packages = @(
@{FileName = 'EC2-Windows-Launch.zip'; Uri = 'https://s3.amazonaws.com/ec2-downloads-windows/EC2Launch/latest/EC2-Windows-Launch.zip' },
@{FileName = 'install.ps1'; Uri = 'https://s3.amazonaws.com/ec2-downloads-windows/EC2Launch/latest/install.ps1' }
)
foreach ($package in $packages) {
Write-Host "Download $($package.FileName) ..."
$outFile = Join-Path $SavePath ($package.FileName)
Invoke-WebRequest -Uri $package.Uri -OutFile $outFile
}
}
<#
.SYNOPSIS
ダウンロードしたEC2Launchの最新パッケージを削除します。
#>
function Clear-LatestEC2LaunchPackage([string]$InstallerPath = $env:TEMP) {
$items = @(
(Join-Path $InstallerPath 'EC2-Windows-Launch.zip'),
(Join-Path $InstallerPath 'install.ps1')
)
foreach ($item in $items) {
if (Test-Path -LiteralPath $item) {
Write-Host "Remove $item ..."
Remove-Item -LiteralPath $item -Force
}
}
}
<#
.SYNOPSIS
EC2Launchのインストーラーを実行します。
#>
function Invoke-EC2LaunchInstaller([string]$InstallerPath = $env:TEMP) {
$installer = Join-Path $InstallerPath 'install.ps1'
try {
Push-Location $InstallerPath
Write-Host "Execute $installer ..."
& $installer
}
finally {
Pop-Location
}
}
<#
.SYNOPSIS
EC2LaunchがサポートされているOS(2016 Server以降)か判定します。
#>
function Test-SupportedVersion() {
$ProductType_WorkStation = 1
try {
$versionInfo = Get-CimInstance -ClassName Win32_OperatingSystem -Property Version, ProductType, Caption
Write-Host "OS : $($versionInfo.Caption)"
if (([Version]$versionInfo.Version).Major -lt 10) {
return $false
}
if ($versionInfo.ProductType -eq $ProductType_WorkStation ) {
return $false
}
return $true
}
catch {
return $false
}
}
<#
.SYNOPSIS
Main関数です。
#>
function Main() {
if (-not (Test-SupportedVersion)) {
Write-Host "This is unsupported OS."
return -1
}
# Check EC2Launch version
$latestVersion = Get-LatestEC2LaunchVersion
if ($null -eq $latestVersion) {
Write-Host 'Failed to get the latest version.'
return -1
}
Write-Host "Latest EC2Launch version is $latestVersion ..."
$currentVersion = Get-EC2LaunchVersion
Write-Host "Current EC2Launch version is $currentVersion ..."
if ($currentVersion -gt $latestVersion) {
Write-Host "Failed to get the latest version information."
return -1
}
if ($currentVersion -eq $latestVersion) {
Write-Host "EC2Launch is the latest version."
return 0
}
# Update EC2Launch
try {
Save-LatestEC2LaunchPackage
Invoke-EC2LaunchInstaller
}
finally {
Clear-LatestEC2LaunchPackage
}
$currentVersion = Get-EC2LaunchVersion
Write-Host "Current EC2Launch version is $currentVersion ."
}
exit Main
- Gistはこちら : Update-EC2Launch.ps1
このスクリプトを適当な名前で保存して実行すれば前項で説明した手順を自動化できます。
スクリプトの中身について細かく説明はしませんが、機能ごとに関数を分けてるのでやっていることの雰囲気は掴んで頂けるのではないかと思います。
バージョンアップスクリプトを実行してみる
本記事ではこのスクリプトをSSM Run Commandで実行してみるところまで紹介します。
開発環境にあるWindows Server 2016インスタンスに対して実行する想定でRun Commandを実行できるところまでは設定済みとします。
1. コマンド指定
本記事ではAWS-RunPowerShellScript
コマンドでスクリプトを実行します。
2. スクリプト貼り付け
選んだコマンドのCommands
欄に上記スクリプトをそのまま貼り付けます。
Working Directoryは指定しなくても大丈夫です。
3. ターゲット指定、コマンド実行
ターゲットとなるEC2インスタンスを指定します。
ログの出力オプションなどは自由に設定してください。
設定後、「実行」を押してコマンドを実行します。
4. 結果確認
実行が完了したら出力を確認してみます。
このスクリプトでは下図の様なログを出す様にしており、今回はVer.1.3.2000930からVer.1.3.2001040に更新できていることがわかります。
最後に
ざっとこんな感じです。
利用機会はそれほど多くないかもしれませんがこのスクリプトが誰かの役に立てば幸いです。
追記 : EC2Launch v2の更新手順
2020年7月にリリースされたEC2Launch v2ではSSM Run Commandでバージョンアップすることが可能になっています。
以下の記事を参考にAWS-ConfigureAWSPackageを使ってパッケージ名にAWSEC2Launch-Agent
を指定して最新バージョンをインストールしてやればOKです。