チュートリアル:デプロイ スクリプトを使用して自己署名証明書を作成する
Azure Resource Manager テンプレート (ARM テンプレート) でデプロイ スクリプトを使用する方法を説明します。 デプロイ スクリプトを使用すると、ARM テンプレートでは実行できないカスタム ステップを実行できます。 たとえば、自己署名証明書を作成できます。 このチュートリアルでは、Azure キー コンテナーをデプロイするためのテンプレートを作成した後、同じテンプレート内で Microsoft.Resources/deploymentScripts
リソースを使用して証明書を作成してからその証明書をそのキー コンテナーに追加します。 デプロイ スクリプトの詳細については、ARM テンプレートでのデプロイ スクリプトの使用に関する記事を参照してください。
重要
スクリプトの実行とトラブルシューティングのため、同じリソース グループ内に 2 つのデプロイ スクリプト リソース (ストレージ アカウントとコンテナー インスタンス) が作成されます。 これらのリソースは、通常、スクリプトの実行が最終状態になるとスクリプト サービスによって削除されます。 リソースが削除されるまでは、リソースに対して請求が行われます。 詳細については、「デプロイ スクリプト リソースのクリーンアップ」を参照してください。
このチュートリアルに含まれるタスクは次のとおりです。
- クイック スタート テンプレートを開く
- テンプレートの編集
- テンプレートのデプロイ
- 失敗したスクリプトをデバッグする
- リソースをクリーンアップする
デプロイ スクリプトについて取り上げた Learn モジュールについては、「デプロイ スクリプトを使用して ARM テンプレートを拡張する」を参照してください。
前提条件
この記事を完了するには、以下が必要です。
Resource Manager ツール拡張機能を持つ Visual Studio Code 。 「クイック スタート:Visual Studio Code を使用して ARM テンプレートを作成する」を参照してください。
ユーザー割り当てマネージド ID。 スクリプトからこの ID を使用して、Azure 固有のアクションを実行します。 作成するには、「ユーザー割り当てマネージド ID」を参照してください。 この識別 ID は、テンプレートをデプロイするときに必要です。 ID の形式は次のとおりです。
/subscriptions/<SubscriptionID>/resourcegroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<IdentityID>
次の CLI スクリプトを使用して、リソース グループ名と ID 名を指定することで ID を取得します。
echo "Enter the Resource Group name:" && read resourceGroupName && az identity list -g $resourceGroupName
クイック スタート テンプレートを開く
ゼロからテンプレートを作成するのではなく、Azure クイック スタート テンプレートからテンプレートを開きます。 Azure クイックスタート テンプレートは、ARM テンプレートのリポジトリです。
このクイックスタートで使用するテンプレートは、Create an Azure Key Vault and a secret と呼ばれます。 このテンプレートにより、キー コンテナーが作成され、そのキー コンテナーにシークレットが追加されます。
Visual Studio Code から、 [ファイル]>[ファイルを開く] を選択します。
[ファイル名] に以下の URL を貼り付けます。
https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.keyvault/key-vault-create/azuredeploy.json
[開く] を選択して、ファイルを開きます。
[ファイル]>[名前を付けて保存] を選択し、ファイルを azuredeploy.json としてご自身のローカル コンピューターに保存します。
テンプレートの編集
テンプレートに次の変更を加えます。
テンプレートをクリーンアップする (省略可能)
元のテンプレートでは、キー コンテナーにシークレットが追加されます。 チュートリアルを簡略化するために、次のリソースを削除します。
Microsoft.KeyVault/vaults/secrets
次の 2 つのパラメーター定義を削除します。
secretName
secretValue
これらの定義を削除しない場合は、デプロイ中にパラメーター値を指定する必要があります。
キー コンテナーのアクセス ポリシーを構成する
デプロイ スクリプトにより、キー コンテナーに証明書が追加されます。 キー コンテナーのアクセス ポリシーを構成して、マネージド ID にアクセス許可を付与します。
パラメーターを追加して、マネージド ID を取得します。
"identityId": { "type": "string", "metadata": { "description": "Specifies the ID of the user-assigned managed identity." } },
Note
Visual Studio Code の Resource Manager テンプレート拡張機能では、まだデプロイ スクリプトの形式を設定できません。 次のように、Shift + Alt + F キーを使用して
deploymentScripts
のリソースの形式を設定しないでください。マネージド ID がキー コンテナーに証明書を追加できるように、キー コンテナーのアクセス ポリシーを構成するためのパラメーターを追加します。
"certificatesPermissions": { "type": "array", "defaultValue": [ "get", "list", "update", "create" ], "metadata": { "description": "Specifies the permissions to certificates in the vault. Valid values are: all, get, list, update, create, import, delete, recover, backup, restore, manage contacts, manage certificate authorities, get certificate authorities, list certificate authorities, set certificate authorities, delete certificate authorities." } }
既存のキー コンテナーのアクセス ポリシーを次のように更新します。
"accessPolicies": [ { "objectId": "[parameters('objectId')]", "tenantId": "[parameters('tenantId')]", "permissions": { "keys": "[parameters('keysPermissions')]", "secrets": "[parameters('secretsPermissions')]", "certificates": "[parameters('certificatesPermissions')]" } }, { "objectId": "[reference(parameters('identityId'), '2018-11-30').principalId]", "tenantId": "[parameters('tenantId')]", "permissions": { "keys": "[parameters('keysPermissions')]", "secrets": "[parameters('secretsPermissions')]", "certificates": "[parameters('certificatesPermissions')]" } } ],
定義されているポリシーは 2 つあり、1 つはサインイン ユーザー用、もう 1 つはマネージド ID 用です。 サインイン ユーザーに必要なのは、デプロイを検証するための list 権限のみです。 チュートリアルを簡略化するために、マネージド ID とサインイン ユーザーの両方に同じ証明書が割り当てられています。
デプロイ スクリプトを追加する
デプロイ スクリプトで使用される 3 つのパラメーターを追加します。
"certificateName": { "type": "string", "defaultValue": "DeploymentScripts2019" }, "subjectName": { "type": "string", "defaultValue": "CN=contoso.com" }, "utcValue": { "type": "string", "defaultValue": "[utcNow()]" }
deploymentScripts
リソースを追加します。Note
インライン デプロイ スクリプトは二重引用符で囲まれているため、デプロイ スクリプト内の文字列は、代わりに単一引用符で囲む必要があります。 PowerShell のエスケープ文字は、バックティック (
`
) です。{ "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "2020-10-01", "name": "createAddCertificate", "location": "[resourceGroup().location]", "dependsOn": [ "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" ], "identity": { "type": "UserAssigned", "userAssignedIdentities": { "[parameters('identityId')]": { } } }, "kind": "AzurePowerShell", "properties": { "forceUpdateTag": "[parameters('utcValue')]", "azPowerShellVersion": "3.0", "timeout": "PT30M", "arguments": "[format(' -vaultName {0} -certificateName {1} -subjectName {2}', parameters('keyVaultName'), parameters('certificateName'), parameters('subjectName'))]", // can pass an argument string, double quotes must be escaped "scriptContent": " param( [string] [Parameter(Mandatory=$true)] $vaultName, [string] [Parameter(Mandatory=$true)] $certificateName, [string] [Parameter(Mandatory=$true)] $subjectName ) $ErrorActionPreference = 'Stop' $DeploymentScriptOutputs = @{} $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) { Write-Host 'Certificate $certificateName in vault $vaultName is already present.' $DeploymentScriptOutputs['certThumbprint'] = $existingCert.Thumbprint $existingCert | Out-String } else { $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose # private key is added as a secret that can be retrieved in the Resource Manager template Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose # it takes a few seconds for KeyVault to finish $tries = 0 do { Write-Host 'Waiting for certificate creation completion...' Start-Sleep -Seconds 10 $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName $tries++ if ($operation.Status -eq 'failed') { throw 'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)' } if ($tries -gt 120) { throw 'Timed out waiting for creation of certificate $certificateName in vault $vaultName' } } while ($operation.Status -ne 'completed') $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName $DeploymentScriptOutputs['certThumbprint'] = $newCert.Thumbprint $newCert | Out-String } ", "cleanupPreference": "OnSuccess", "retentionInterval": "P1D" } }
deploymentScripts
リソースは、キー コンテナー リソースとロールの割り当てリソースに依存します。 これには、次のプロパティがあります。identity
:デプロイ スクリプトでは、ユーザー割り当てのマネージド ID を使用してスクリプトの操作が実行されます。kind
: スクリプトの種類を指定します。 現時点では、PowerShell スクリプトだけがサポートされています。forceUpdateTag
:スクリプト ソースが変更されていない場合でもデプロイ スクリプトを実行するかどうかを決定します。 現在のタイム スタンプまたは GUID を指定できます。 詳細については、「スクリプトを複数回実行する」を参照してください。azPowerShellVersion
: 使用する Azure PowerShell モジュールのバージョンを指定します。 現在、デプロイ スクリプトでは、バージョン 2.7.0、2.8.0、3.0.0 がサポートされています。timeout
: ISO 8601 形式で指定される、スクリプトの許容最長実行時間を指定します。 既定値は P1D です。arguments
:パラメーター値を指定します。 値はスペースで区切ります。scriptContent
:スクリプトの内容を指定します。 外部スクリプトを実行するには、代わりにprimaryScriptURI
を使用します。 詳細については、「外部関数を使用する」を参照してください。$DeploymentScriptOutputs
の宣言は、ローカル コンピューターでスクリプトをテストする場合にのみ必要です。 変数を宣言すると、変更を加えなくても、ローカル コンピューターとdeploymentScript
リソースでスクリプトを実行できます。$DeploymentScriptOutputs
に割り当てられた値は、デプロイの出力として使用できます。 詳細については、PowerShell デプロイ スクリプトからの出力の操作に関する説明または CLI デプロイ スクリプトからの出力の操作に関する説明を参照してください。cleanupPreference
:デプロイ スクリプト リソースをいつ削除するかに関する設定を指定します。 既定値は Always です。これは、最終状態 (Succeeded、Failed、Canceled) にかかわらず、デプロイ スクリプト リソースが削除されることを意味します。 このチュートリアルでは、スクリプトの実行結果が表示されるように OnSuccess を使用します。retentionInterval
: 最終状態に達した後にサービスがスクリプト リソースを保持する期間を指定します。 この期間が経過すると、リソースは削除されます。 期間は ISO 8601 のパターンに基づきます。 このチュートリアルでは、1 日を意味する P1D を使用します。 このプロパティは、cleanupPreference
が OnExpiration に設定されている場合に使用されます。 このプロパティは現在有効ではありません。
デプロイ スクリプトは、
keyVaultName
、certificateName
、およびsubjectName
という 3 つのパラメーターを受け取ります。 それにより、証明書が作成された後、キー コンテナーにその証明書が追加されます。$DeploymentScriptOutputs
は、出力値を格納するために使用されます。 詳細については、PowerShell デプロイ スクリプトからの出力の操作に関する説明または CLI デプロイ スクリプトからの出力の操作に関する説明を参照してください。完成したテンプレートは、こちらで確認できます。
デバッグ プロセスを確認するには、デプロイ スクリプトに次の行を追加してしてコード内にエラーを配置します。
Write-Output1 $keyVaultName
正しいコマンドは
Write-Output1
ではなくWrite-Output
です。[ファイル]>[保存] を選択して、ファイルを保存します。
テンプレートのデプロイ
Azure Cloud Shell にサインインします。
左上の [PowerShell] または [Bash] (CLI の場合) を選択して、希望の環境を選択します。 切り替えた場合は、シェルを再起動する必要があります。
[ファイルのアップロード/ダウンロード] を選択し、 [アップロード] を選択します。 先のスクリーンショットをご覧ください。 前のセクションで保存したファイルを選択します。 ファイルをアップロードした後、
ls
コマンドとcat
コマンドを使用して、ファイルが正常にアップロードされたことを確認できます。次の Azure CLI または Azure PowerShell スクリプトを実行してテンプレートをデプロイします。
echo "Enter a project name that is used to generate resource names:" && read projectName && echo "Enter the location (i.e. centralus):" && read location && echo "Enter your email address used to sign in to Azure:" && read upn && echo "Enter the user-assigned managed identity ID:" && read identityId && adUserId=$((az ad user show --id ${upn}) | jq -r '.id') && resourceGroupName="${projectName}rg" && keyVaultName="${projectName}kv" && az group create --name $resourceGroupName --location $location && az deployment group create --resource-group $resourceGroupName --template-file "$HOME/azuredeploy.json" --parameters identityId=$identityId keyVaultName=$keyVaultName objectId=$adUserId
デプロイ スクリプト サービスでは、スクリプトの実行用に追加のデプロイ スクリプト リソースを作成する必要があります。 実際のスクリプトの実行時間に加えて、準備とクリーンアップ プロセスが完了するまでに最大で 1 分かかることがあります。
スクリプトで無効なコマンド
Write-Output1
が使用されているため、デプロイが失敗しました。 次のようなエラーが表示されます。The term 'Write-Output1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
デプロイ スクリプトの実行結果は、トラブルシューティングの目的でデプロイ スクリプト リソースに格納されます。
失敗したスクリプトをデバッグする
Azure portal にサインインします。
リソース グループを開きます。 これは、rg が付加されたプロジェクト名です。 リソース グループには 2 つの追加リソースが表示されます。 これらのリソースは、"デプロイ スクリプト リソース" と呼ばれます。
どちらのファイルにも azscripts というサフィックスが付いています。 1 つはストレージ アカウントで、もう 1 つはコンテナー インスタンスです。
[非表示の型の表示] を選択して、
deploymentScripts
リソースの一覧を表示します。azscripts サフィックスの付いたストレージ アカウントを選択します。
[ファイル共有] タイルを選択します。 デプロイ スクリプトの実行ファイルが格納される azscripts フォルダーが表示されます。
azscripts を選択します。 azscriptinput および azscriptoutput という 2 つのフォルダーが表示されます。 入力フォルダーには、システム用 PowerShell スクリプト ファイルとユーザー用デプロイ スクリプト ファイルが含まれています。 出力フォルダーには、executionresult.json とスクリプトの出力ファイルが含まれています。 エラー メッセージは、executionresult.json で確認できます。 実行が失敗したため、出力ファイルはありません。
Write-Output1
の行を削除して、テンプレートを再デプロイします。
2 回目のデプロイが正常に実行されると、cleanupPreference
プロパティが OnSuccess に設定されているため、デプロイ スクリプト リソースはスクリプト サービスによって削除されます。
リソースをクリーンアップする
Azure リソースが不要になったら、リソース グループを削除して、デプロイしたリソースをクリーンアップします。
- Azure portal で、左側のメニューから [リソース グループ] を選択します。
- [名前でフィルター] フィールドに、リソース グループ名を入力します。
- リソース グループ名を選択します。
- トップ メニューから [リソース グループの削除] を選択します。
次のステップ
このチュートリアルでは、ARM テンプレートでデプロイ スクリプトを使用する方法について学習しました。 条件に基づいて Azure リソースをデプロイする方法については、以下を参照してください。