配置スクリプトとは何ですか?

完了

このユニットでは、deploymentScripts リソースを使って Azure Resource Manager (ARM) テンプレートを拡張する方法について学習します。

ARM テンプレートはすばらしいものです。 これを使って、クラウド インフラストラクチャの望ましい状態を宣言し、API とサービスからそこに到達する方法を見つけられるようにすることができます。 ただし、場合によっては、Azure Resource Manager に用意されている以外のアクションを実行する必要があります。

配置スクリプトとは何ですか?

deploymentScripts リソースは PowerShell または Bash スクリプトであり、テンプレート配置の一部として Docker コンテナーで実行されます。 既定のコンテナー イメージでは、Azure CLI または Azure PowerShell のいずれかを使用できます。 これらのスクリプトは、ARM テンプレートの処理中に実行されるので、配置プロセスにカスタム動作を追加することができます。

配置スクリプトでは、Azure への認証にマネージド ID を使います。 マネージド ID とは、Azure プラットフォームによって資格情報とライフサイクルが管理されるサービス プリンシパルです。 この ID は、Azure PowerShell または Azure CLI コマンドが環境上で動作するために使うものです。 ID を割り当てるので、deploymentScripts リソースが影響を与える可能性があるスコープを制御できます。

deploymentScripts リソースによって、配置内の他のリソースが使用できる出力が生成されます。 これで、外部システムから情報を検索することや、環境の現在の状態に基づいてデータを用意し、配置の残りの部分に影響を与えることができます。

配置スクリプトのしくみ

deploymentScripts リソースは、ユーザーが (テンプレートまたは URI で) 用意したスクリプトと、場合によっては何らかのサポート スクリプトを受け取り、Azure コンテナー インスタンスでそれらを実行します。 そのコンテナー インスタンスには、ユーザーが指定したマネージド ID が割り当てられます。 スクリプトとその出力は、Azure Storage アカウントのファイル共有に格納されます。

テンプレート配置が実行されると、対象となるリソース グループに既存の deploymentScripts リソースがあるかどうかが確認されます。 そうである場合は、プロパティが比較されます。 すべてが一致する場合、新しいことは何も起こりません。 リソースが存在しないか、変更されている場合、Azure Resource Manager によって新しいコンテナー インスタンスが作成され、そのコンテナー インスタンス内で配置スクリプトが実行されます。 定義された出力は、後の配置で使うために Azure Resource Manager に返されます。

配置スクリプトの構造

ARM テンプレートにカスタム動作を追加するには、deploymentScripts リソースから始めます。 少なくとも、次のような一般的な詳細情報を指定する必要があります。

  • deploymentScripts リソースに対する name
  • typeapiVersion の値。
  • サポートするリソースを作成する場所 (location 値)。
  • 空の properties オブジェクトです。 後ほど説明します。

2 つの deploymentScripts 固有の値が必要です。

  • kind: 実行するスクリプトの種類 (AzurePowerShell または AzureCLI)。

    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "myFirstDeploymentScript",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid": {}
        }
      }
    }
    
    resource myFirstDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
      name: 'myFirstDeploymentScript'
      location: resourceGroup().location
      kind: 'AzurePowerShell'
      identity: {
        type: 'UserAssigned'
        userAssignedIdentities: {
          '/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
        }
      }
    }
    
  • identity: コンテナー インスタンスに使われるマネージド ID。 次の例のように、事前にマネージド ID を作成して指定することができます。または、テンプレート内に作成し、それを参照することもできます (これについては、次の演習で行います)。

    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "myFirstDeploymentScript",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid": {}
        }
      }
    }
    
    resource myFirstDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
      name: 'myFirstDeploymentScript'
      location: resourceGroup().location
      kind: 'AzurePowerShell'
      identity: {
        type: 'UserAssigned'
        userAssignedIdentities: {
          '/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
        }
      }
    }
    

これらの要素を設定した後、deploymentScripts リソースの properties セクションに移動することができます。 この中で主な部分は scriptContent です。実際に実行するスクリプトを指定します。

"properties": {
  "scriptContent": "
      $output = 'Hello Learner!'
      Write-Output $output
      $DeploymentScriptOutputs = @{}
      $DeploymentScriptOutputs['text'] = $output
  ",
}
properties: {
  scriptContent: '''
    $output = 'Hello Learner!'
    Write-Output $output
    $DeploymentScriptOutputs = @{}
    $DeploymentScriptOutputs['text'] = $output
  '''
}

scriptContent に複数行の文字列を使っていることに注目してください。 Bicep では、文字列の前後に 3 つの引用符 (''') を一緒に使うことで、複数行の文字列を指定できます。

配置スクリプトを使って、配置に出力を返すのが一般的です。 たとえば、スクリプトを使って API から情報を検索する場合、その情報を出力として配置に返すことができます。 これで、配置内の他のリソースから、独自の定義でその情報を使用できるようになります。

PowerShell スクリプトの場合、$DeploymentScriptOutputs という変数を作成することで出力を返しますが、これはハッシュ テーブルにする必要があります。 この例のスクリプトでは、ハッシュ テーブルを初期化して、text という出力を作成し、その値を $output ローカル変数から取得します。

$output = 'Hello Learner!'
Write-Output $output
$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['text'] = $output
$output = 'Hello Learner!'
Write-Output $output
$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['text'] = $output

ヒント

Bash で配置スクリプトを記述することもできます。 Bash スクリプトから出力を作成するには、AZ_SCRIPTS_OUTPUT_PATH 環境変数で指定された場所に JSON ファイルを作成する必要があります。

properties セクション内に、deploymentScripts で受け取ることができるさまざまなオプションも定義します。 このモジュールでは、シンプルな状態を保ち、スクリプトを実行するために必要なものだけを追加します。 少なくとも、使う Azure PowerShell または Azure CLI のバージョン、実行するスクリプト、保持間隔を指定する必要があります。

保持間隔は、リソースを保持する場合に、結果を保持する期間です。 既定では、スクリプトを実行した後の結果は削除されます。

"properties": {
  "azPowerShellVersion": "3.0",
  "scriptContent": "
      $output = 'Hello Learner!'
      Write-Output $output
      $DeploymentScriptOutputs = @{}
      $DeploymentScriptOutputs['text'] = $output
  ",
  "retentionInterval": "P1D"
}
properties: {
  azPowerShellVersion: '3.0'
  scriptContent: '''
    $output = 'Hello Learner!'
    Write-Output $output
    $DeploymentScriptOutputs = @{}
    $DeploymentScriptOutputs['text'] = $output
  '''
  retentionInterval: 'P1D'
}

完成したテンプレートは次のようになります。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.1",
  "apiProfile": "",
  "parameters": {},
  "variables": {},
  "functions": [],
  "resources": [
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "myFirstDeploymentScript",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid": {}
        }
      },
      "properties": {
        "azPowerShellVersion": "3.0",
        "scriptContent": "
            $output = 'Hello Learner!'
            Write-Output $output
            $DeploymentScriptOutputs = @{}
            $DeploymentScriptOutputs['text'] = $output
        ",
        "retentionInterval": "P1D"
      }
    }
  ],
  "outputs": {
    "scriptResult": {
      "type": "string",
      "value": "[reference('myFirstDeploymentScript').outputs.text]"
    }
  }
}
resource myFirstDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
  name: 'myFirstDeploymentScript'
  location: resourceGroup().location
  kind: 'AzurePowerShell'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
    }
  }
  properties: {
    azPowerShellVersion: '3.0'
    scriptContent: '''
      $output = 'Hello Learner!'
      Write-Output $output
      $DeploymentScriptOutputs = @{}
      $DeploymentScriptOutputs['text'] = $output
    '''
    retentionInterval: 'P1D'
  }
}

output scriptResult string = myFirstDeploymentScript.properties.outputs.text

スクリプト ファイルを含める

テンプレートにインラインでスクリプトを埋め込むのは、面倒で、読みにくく、理解しにくく、変更も難しい場合があります。 Bicep では、loadTextContent() 関数を使って、外部のテキスト ファイルを配置に埋め込みます。 Bicep によってテンプレートが JSON にトランスパイルされるときに、出力されるテンプレートに外部ファイルが埋め込まれます。

たとえば、Bicep テンプレートと同じフォルダーに myscript.ps1 という PowerShell ファイルがあるとします。 次のようにファイルを埋め込むように Bicep に指示できます。

properties: {
  azPowerShellVersion: '3.0'
  scriptContent: loadTextContent('myscript.ps1')
  retentionInterval: 'P1D'
}

deploymentScripts リソースのすべてのプロパティについては、ARM テンプレートのリファレンス ドキュメントを参照してください。