Deconstructing JSON: Bring on the NICs

One of the final dependencies for deploying a server on a network is a network card.  For Azure, networking is crucial for VMs so you can remotely access and control your VM after deployment.

Now here’s the thing about JSON… The dependencies.  The resource dependencies allow you to basically pack all your resources, parameters and variables into one file and the deployment sorts out what needs to be created in what order.  This differs from writing a complete deployments in PowerShell, where you have to account for the dependencies yourself, by ensuring things are placed in the proper order and account for any necessary wait times.

So far in this blog series, I’ve done deployments that can stand alone: just the network, just storage, etc.  But now that I’m getting closer to my goal of being able to deploy VMs, the dependency requirements start to appear.

NICs are dependent on a public IP address and the virtual network.  While you can deploy NICs without having a VM to “plug” them into, the template that is used to deploy them does require those other two resources.  So even though I’ve already deployed the virtual network and would be deploying the NIC into that existing resource group and network, the template won’t be considered valid unless the networking resources are included.

So at this point, I’ve started adding the new resources to my existing template.  Upon deployment, ARM will verify the existence and configuration of all the resources an only add or change the ones that are missing or configured differently.

For the public IP address I’ve added:

 {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[variables('publicIPAddressName')]",
      "location": "[parameters('location')]",
      "properties": {
        "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[variables('dnsNameForPublicIP')]"
        }
      }
    },

For the network interface I’ve added:

 {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[variables('nicName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
        "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
             "privateIPAllocationMethod": "Dynamic",
             "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
              },
              "subnet": {
                "id": "[variables('subnetRef')]"
              }
              }
          }
        ]
      }
    },

We also needed to add a few variables, but you could make these parameters instead, depending on your needs.  Take note of vnetID and subnetRef variables, they are more complex expressions.

    "variables": {
       "virtualNetworkName": "SmallNet",
       "subnetName": "Subnet20",
       "addressPrefix": "192.168.0.0/16",
       "publicIPAddressName": "smallcloudpubip",
       "publicIPAddressType": "Dynamic",
       "dnsNameForPublicIP": "smallcloudlab",
       "nicName": "smallcloud_nic1",
       "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
       "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]"
        
     },

To see the full template up until this point, find it in my GitHub Repository.