見出し画像

BicepテンプレートでリソースグループからAzure VMまで、環境を一気にデプロイしてみよう 【output】

こちらの記事でリソースグループと併せて仮想ネットワークも一緒にデプロイできるファイルを作成しましたが、今回はさらに Azure VM も一気に作成してデプロイできるようにしたいと思います。

ズバリ今回のテーマは、『 モジュール間で出力値を受け渡してデプロイ 』です。
具体的には、作成しする仮想ネットワークに所属する Windows Server も一緒にデプロイします。

前提知識

出力 【 output 】

デプロイされたリソースから値を返す必要がある場合に出力を使用します。

Bicep の出力

出力値を介してモジュールファイル同士を連携させます。
もう少し具体的にいうと、モジュールファイルからデプロイされた一部のリソースの値をメインテンプレートファイルに渡し、さらにそれを別のモジュールファイルに渡すのです。

今回は仮想ネットワークを作成するモジュールファイルから出力した値を、仮想マシンを作成するモジュールファイルに受け渡します。

必要なファイルを完成させる

必要となるファイル

こちらの記事で作成したフォルダ( nested )にVM作成用の新たなモジュールファイルを格納し、VNet作成用のモジュールファイルとデプロイ時に指定するテンプレートファイル( main.bicep )に手を加えました。

Sample-Templatemain.bicep 
│ 
└─nested 
        vm-winsv.bicep 👈新たなモジュールファイル
        vnet-subnets.bicep

VNet作成モジュールファイルの修正

こちらの記事で作成したVNet作成モジュールファイルの最終行に以下を追記しました。

output subnet1Idinfo string = vnet.properties.subnets[0].id

output <name> <data-type> = <value>

出力値の定義

「 subnet1Idinfo 」 と出力の名前を定義し、文字列で値を返すようにしています。

「 シンボリック名.properties.subnets[0].id 」 と書くと、そのシンボリック名のVNetリソースにおけるプロパティの一つである 「 subnets 」 から値を引っ張ってくることができます。

今回の場合、サブネットは配列で二つ定義しておいたので、その一番目[0]を指定し 「 subnet1 」 からとしました。
そして、最後の 「 .id 」 により subnet1 のリソースID をお願いね、としたわけです。

VM作成モジュールファイルの作成

最終的な記述内容

今回の内容から外れるので細かな点は解説しませんが、パブリックIPを持ちRDPで接続できる Windows Server を1台作成します。

param subnetId string // 1️⃣
param location string 
param adminUsername string 
param adminPassword string 
param vmName string = 'winsv-vm' 
param virtualMachineSize string = 'Standard_B2s' 
param storageProfileImageReferenceVersion string = '17763.3127.220119' 

var nicName = 'winsv-nic' 
var publicIPAddressName = 'winsv-publicIp' 
var networkSecurityGroupName = 'winsv-NSG' 

resource vm 'Microsoft.Compute/virtualMachines@2021-11-01' = { 
  name: vmName 
  location: location 
  properties: { 
    osProfile: { 
      computerName: vmName 
      adminUsername: adminUsername 
      adminPassword: adminPassword 
      windowsConfiguration: { 
        provisionVMAgent: true 
      } 
    } 
    hardwareProfile: { 
      vmSize: virtualMachineSize 
    } 
    storageProfile: { 
      imageReference: { 
        publisher: 'MicrosoftWindowsServer' 
        offer: 'WindowsServer' 
        sku: '2019-Datacenter' 
        version: storageProfileImageReferenceVersion 
      } 
      osDisk: { 
        createOption: 'FromImage' 
      } 
    } 
    networkProfile: { 
      networkInterfaces: [ 
        { 
          properties: { 
            primary: true 
          } 
          id: winsvNic.id 
        } 
      ] 
    } 
  } 
} 
resource winsvNic 'Microsoft.Network/networkInterfaces@2021-05-01' = { 
  name: nicName 
  location: location 
  properties: { 
    ipConfigurations: [ 
      { 
        name: 'ipconfig-winsv-1' 
        properties: { 
          subnet: { 
            id: subnetId // 2️⃣
          } 
          privateIPAllocationMethod: 'Dynamic' 
          publicIPAddress: { 
            id: pip.id 
          } 
        } 
      } 
    ] 
    networkSecurityGroup: { 
      id: nsg.id 
    } 
  } 
} 
resource pip 'Microsoft.Network/publicIPAddresses@2021-05-01' = { 
  name: publicIPAddressName 
  location: location 
  properties: { 
    publicIPAllocationMethod: 'Dynamic' 
  } 
} 
resource nsg 'Microsoft.Network/networkSecurityGroups@2021-05-01' = { 
  name: networkSecurityGroupName 
  location: location 
  properties: { 
    securityRules: [ 
      { 
        name: 'default-allow-rdp' 
        properties: { 
          priority: 1000 
          sourceAddressPrefix: '*' 
          protocol: 'Tcp' 
          destinationPortRange: '3389' 
          access: 'Allow' 
          direction: 'Inbound' 
          sourcePortRange: '*' 
          destinationAddressPrefix: '*' 
        } 
      } 
    ] 
  } 
}

重要

1⃣ 今回の肝となるのは、ズバリ、パラメーターとして定義した 「 subnetId 」 です。

param subnetId string

2⃣ Windows Server に取り付ける NIC が参加するサブネットのリソースID(の値)をこのパラメーターで渡します。

properties: {
          subnet: {
            id: subnetId
          }

しかし、ここで疑問が湧きませんか?

サブネットについては別のモジュールファイルに書かれているし、このモジュールファイルにもデフォルト値は書かれていません。
どーやって、このパラメーターに値を入れるの?

このファイル内にVNet(サブネット)リソースが記述されていれば

publicIPAddress: {
            id: pip.id
          }

のようにパラメーターなしで、シンボリック名と .id で簡単に呼び出せるのに。
でもまとめちゃうとテンプレートファイルの行数が増えてイヤだ。

というか、さきほど定義した出力値を呼び出すことが一切書かれていないんだが。

その答えは、読み進めてもらえればすぐにわかりますが、先に言ってしますと

テンプレートファイル 「 main.bicep 」から受けとる

です。

テンプレートファイルの修正

こちらの記事で作成したテンプレートファイルに以下の内容を追記しました。
二つのパラメーター(管理者ユーザー名とパスワード)とVM作成のモジュールの宣言です。

@description('Default Admin password')
@secure()
param adminPassword string


@description('Default Admin username')
param adminUsername string


module winsvModule 'nested/vm-winsv.bicep' = {
  scope: newRG
  name: 'WinSV-deploy'
  params: {
    adminPassword: adminPassword
    adminUsername: adminUsername
    location: resourceGroupLocation
    subnetId: vnetModule.outputs.subnet1Idinfo // 3⃣
  }
}

重要

3⃣ ここですべてがつながります。

VM作成モジュールファイルで定義した 1⃣ パラメーター 「 subnetId 」 に、VNet作成モジュールファイルで定義した 「 subnet1Idinfo 」 という出力の値を渡すのです。

vnetModule.outputs.subnet1Idinfo

ということなので、
<module-name> はモジュールとして宣言した 「 vnetModule 」 というシンボリック名を書きます。
また、<property-name> は VNet作成モジュールファイルで定義した 「 subnet1Idinfo 」 と書きます。

<module-name>.outputs.<property-name>

モジュールからの出力

🟠 さいごに 🔚

いかがだったでしょうか?
これらのファイルをサブスクリプションのレベルでデプロイしてください。
RDP でサインインできる Windows Server がデプロイされますよ。
これでついにちょっとは実用的なテンプレートファイルになってきましたね。

こんな感じで出力値の受け渡し方法を知っておき色々なモジュールを作っておいておけば、「こんな環境が欲しい」となった時に必要なモジュールを組み合わせて簡単にデプロイできます。

今後も Azure に関する技術情報やその他の資格試験に関する記事を書いていこうと思いますので、よろしければフォローをお願いします🔆

また、この記事が少しでもタメになった、面白かったという方がいらっしゃいましたら、ぜひ 「 スキ 」 ボタンのクリックをお願いします😋

最後までお読みいただきありがとうございました 😊

▶ 続けて読むのにおススメな記事


この記事が参加している募集

スキしてみて

つくってみた

もしこの記事が何かの参考になったもしくは面白かったという方は、応援していただけると大変嬉しいです😊 これからもよろしくお願いします。