カスタム スクリプト拡張 (Custom Script Extension) を使用した SQL Server VM の構成の自動化


このポストは、7 月 15 日に投稿した Automating SQL Server VM Configuration using Custom Script Extension の翻訳です。

Azure VM のカスタム スクリプト拡張 (Custom Script Extension) を使用すると、PowerShell スクリプト (および関連ファイル) を Storage アカウントからダウンロードして実行できます。一見シンプルな機能のようですが、PowerShell のパワーを利用して VM の構成を柔軟に自動化できるため、さまざまな VM のカスタマイズに利用できます。この記事では、カスタム スクリプト拡張を使用して Azure VM イメージ ギャラリーから作成した SQL Server 2014 VM をカスタマイズする方法を手順を追って説明します。SQL PowerShell スクリプトを使用して Azure への SQL Server マネージ バックアップを行います。これにより、SQL Server 2014 データベースを Azure Blob ストレージ サービス (英語) にバックアップすることが可能になります。

SQL Server 構成スクリプト

下に示すように、構成スクリプトの内容は単純です。[your Azure storage account][your Azure storage account key] は自分の Azure Storage 資格情報で置き換えてください。このスクリプトを CustomScriptSQLPS.ps1 という名前で保存します。

#SQL Server PowerShell モジュールをインポートします。

import-module  sqlps -DisableNameChecking

 

#グローバル変数 - 使用する Storage アカウント名とキーに置き換えてください。

$credentialName = "AzureStorageCredential_"+(RANDOM)

$storageAccountName = "[your Azure storage account]"

$storageAccountKey = "[your Azure storage account key]"

 

# SQL エージェント サービスを開始します。                                                               

write-host "Starting SQL Server Agent service ..."

Start-Service  sqlserveragent -verbose

 

CD SQLSERVER:SQL\$env:COMPUTERNAME\DEFAULT

 

write-host "Creating SQL credential ..."

$secureString = convertto-securestring $storageAccountKey  -asplaintext -force

 

# 資格情報を作成します。

New-SqlCredential –name $credentialName –Identity $storageAccountName –secret $secureString

 

$encryptionOption = New-SqlBackupEncryptionOption -NoEncryption

 

write-host "Enabling Managed SQL Server Backup..."

 

get-sqlsmartadmin | set-sqlsmartadmin -BackupEnabled $True -BackupRetentionPeriodInDays 7 -SqlCredential $credentialName -EncryptionOption $encryptionOption

 

write-host "Managed SQL Server backup current configuration:"

get-sqlsmartadmin | fl

このスクリプトはそのままではカスタム スクリプト拡張に渡すことはできません。カスタム スクリプト拡張は NTAUTHORITY\SYSTEM アカウントを使ってスクリプトを実行しますが、このアカウントには SQL 構成コマンドを実行するのに十分な権限がありません。これを解決するために、別途ブートストラップ スクリプトを作成し、管理者アカウントの権限を借用してからスクリプトを呼び出します。

別の資格情報でスクリプトを呼び出す

start.ps1 という名前の次のようなスクリプトを作成します。説明しやすいように、ここでは行番号を振っています。

1: $password =  ConvertTo-SecureString "[your admin account user password]" -AsPlainText -Force

2: $credential = New-Object System.Management.Automation.PSCredential("$env:COMPUTERNAME\[your admin account]", $password)

3: $command = $file = $PSScriptRoot + "\CustomScriptSQLPS.ps1"

4: Enable-PSRemoting –force

5: Invoke-Command -FilePath $command -Credential $credential -ComputerName $env:COMPUTERNAME

6: Disable-PSRemoting -Force

1 行目では、権限を借用する管理者のパスワードをプレーン テキストから安全な文字列に変換しています。パスワードをプレーン テキストのままスクリプトで使用することは推奨されません。これについては後ほど説明します。2 行目ではメイン スクリプトの実行に使用する資格情報を作成しています。VM のプロビジョニングの際に選択したアカウントを使用できます。3 行目では、メイン スクリプトの絶対パスを取得しています。借用した資格情報でメイン スクリプトを実行するには、Windows Remote Management (WinRM) (英語) を使用します。4 行目では WinRM を有効にし、6 行目では使用が終了したので WinRM を無効にしています。最後に 5 行目では、Invoke-Command コマンドレットを使用してメイン スクリプトを呼び出し、Credential パラメーターで資格情報を指定しています。

カスタム スクリプト拡張を使用する

これで、2 つのスクリプトをカスタム スクリプト拡張に渡す準備が整いました。Storage アカウントで両方のスクリプトを scripts コンテナーにアップロードします。カスタム スクリプト拡張のしくみの詳細や、既定の Storage アカウントではなく別のアカウントや scripts 以外のコンテナーを使用したい場合の情報については、最初に紹介したこちらのブログ記事を参照してください。次に、自分のワークステーションから下のようなスクリプトを実行します (行番号を振っています)。

1: $servicename = "[cloud service that hosts the VM]"

2: $vmname = "[name of the VM]"

3: $vm = Get-AzureVM -ServiceName $servicename -Name $vmname

4: Set-AzureVMCustomScriptExtension -ContainerName scripts -StorageAccountName '[your storage account name]' -VM $vm -FileName 'start.ps1', 'CustomScriptSQLPS.ps1' -Run 'start.ps1' | Update-AzureVM -Verbose

5: $status = Get-AzureVM -ServiceName $servicename -Name $vmname

6: $result = $status.ResourceExtensionStatusList.ExtensionSettingStatus.SubStatusList | Select Name, @{"Label"="Message";Expression = {$_.FormattedMessage.Message }}

7: $result |fl

このスクリプトで重要なのは 4 行目です。カスタム スクリプト拡張が VM にインストールされていることを確認した後、start.ps1CustomScriptSQLPS.ps1 の両方をダウンロードして start.ps1 を実行するよう指示しています。

外部ファイルからパスワードを読み込む

スクリプトを作成する際は、プレーン テキストのパスワードをそのまま埋め込まないように注意してください。ここでは、パスワードの暗号化/復号化の証明書を使用します。IT 管理者が既に証明書と秘密キーを対象の Virtual Machines にデプロイし、この証明書の公開キーを使用してパスワードを Base64 形式の password.txt ファイルに暗号化していると仮定します。

$cert = Get-ChildItem Cert:\LocalMachine\My\[certificate thumbprint]

$bytes = [Text.Encoding]::UTF8.GetBytes("abcdefg")

$encrypted = $cert.PublicKey.Key.Encrypt($bytes, $true)

$base64 = [Convert]::ToBase64String($encrypted)

Set-Content .\password.txt $base64

makecert を使用した管理証明書の新規作成方法については、こちらの記事を参考にしてください。証明書を Azure VM でデプロイする方法については、こちらのブログ記事 (英語) を参照してください。

start.ps1 の最初の行を次の行に置き換えます。

$cert = Get-ChildItem Cert:\LocalMachine\My\[certificate thumbprint]

$base64 = Get-Content .\password.txt

$encrypted = [Convert]::FromBase64String($base64)

$bytes = $cert.PrivateKey.Decrypt($encrypted,$true)

$password = [Text.Encoding]::UTF8.GetString($bytes)

最後に、カスタム スクリプト拡張に渡すファイルのリストに password.txt を追加します。

Set-AzureVMCustomScriptExtension -ContainerName scripts -StorageAccountName '[your storage account name]' -VM $vm -FileName 'start.ps1', 'CustomScriptSQLPS.ps1', 'password.txt' -Run 'start.ps1' | Update-AzureVM -Verbose

まとめ

この記事では、カスタム スクリプト拡張を使用して SQL Server 2014 VM をカスタマイズする手順を説明しました。また、カスタム スクリプト拡張の実践的な使用方法を紹介し、権限の借用やパスワードの暗号化といったスクリプトでよく使用する処理について取り上げました。

謝辞

このブログ記事の執筆にご協力いただいた Madhan Arumugam と Sethu Srinivasan に心から感謝します。

Comments (0)

Skip to main content