Exercise - Extend the Quickstart template to deploy a basic web site

Now that you've defined the template resource for the Custom Script Extension that configures Nginx on your VM, let's add it to the existing VM template and run it.

Here's what the Nginx configuration will look like.

A web browser showing the resulting Nginx configuration

Build the template

Here you'll download the template and modify it.

  1. From Cloud Shell, run curl to download the template you used previously from GitHub.

    curl https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-vm-simple-linux/azuredeploy.json > azuredeploy.json
    
  2. Open azuredeploy.json through the Cloud Shell editor.

    code azuredeploy.json
    
  3. In the file, locate the resources section. Add the Custom Script Extension resource you built in the previous part to the top of this section, then save the file.

    Here's the code as a refresher.

    {
      "name": "[concat(parameters('vmName'),'/', 'ConfigureNginx')]",
      "type": "Microsoft.Compute/virtualMachines/extensions",
      "apiVersion": "2018-06-01",
      "location": "[parameters('location')]",
      "properties": {
        "publisher": "Microsoft.Azure.Extensions",
        "type": "customScript",
        "typeHandlerVersion": "2.0",
        "autoUpgradeMinorVersion": true,
        "settings": {
          "fileUris": [
            "https://raw.githubusercontent.com/MicrosoftDocs/mslearn-welcome-to-azure/master/configure-nginx.sh"
          ]
        },
        "protectedSettings": {
           "commandToExecute": "./configure-nginx.sh"
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
      ]
    },
    

    Note the comma , character at the end, which is needed to separate resources. The order you define resources doesn't matter, but here you add it to the top for simplicity.

  4. In the file, under resources locate the "Microsoft.Network/networkSecurityGroups" section. Under "securityRules, add a new rule to open port 80. Use the following rule:

     {
       "name":"allow_80",
       "properties": {
       "priority": 101,
       "protocol": "TCP",
       "access": "Allow",
       "direction": "Inbound",
       "sourceAddressPrefix": "Internet",
       "sourcePortRange": "*",
       "destinationAddressPrefix": "*",
       "destinationPortRange": "80"
       }
     },
    
  5. If you get stuck or want to compare your work, you can download the resulting file from GitHub.

    curl https://raw.githubusercontent.com/MicrosoftDocs/mslearn-build-azure-vm-templates/master/linux/azuredeploy.json > azuredeploy.json
    
  6. You're all done editing files. Select the ellipses in the corner and Save.

  7. To close the editor, click the ellipses in the corner and then select Close Editor.

Verify the template

Here you'll validate the template from the CLI.

In practice, you might run lint tests or run your template through the Azure Resource Manager Visualizer before you run a test deployment.

Similar to what you did previously, run az deployment group validate to validate your template.

az deployment group validate \
  --resource-group $RESOURCEGROUP \
  --template-file azuredeploy.json \
  --parameters adminUsername=$USERNAME \
  --parameters authenticationType=password \
  --parameters adminPasswordOrKey=$PASSWORD \
  --parameters dnsLabelPrefix=$DNS_LABEL_PREFIX

Notice that this time you use the --template-file argument, and not --template-uri, because you are referencing a local file.

If you see errors, refer back to the previous part or compare your code to the reference implementation.

Deploy the template

Here you'll run a command that's similar to the one you ran earlier to deploy the template. Because you haven't modified any existing resources – the VM, its network settings, or the storage account – Resource Manager won't take any action on those resources. It will only apply the resource you just added that runs the Custom Script Extension that installs Nginx on your VM.

Run az deployment group create to update your deployment.

az deployment group create \
  --name MyDeployment \
  --resource-group $RESOURCEGROUP \
  --template-file azuredeploy.json \
  --parameters adminUsername=$USERNAME \
  --parameters authenticationType=password \
  --parameters adminPasswordOrKey=$PASSWORD \
  --parameters dnsLabelPrefix=$DNS_LABEL_PREFIX

Again, notice that this time you use the --template-file argument because you are referencing a local file.

The command takes a couple minutes to complete. You see a large block of JSON as output, which describes the deployment.

Verify the deployment

The deployment succeeded, so let's see the resulting configuration in action.

  1. Run az vm show to get the VM's IP address and store the result in a Bash variable.

    IPADDRESS=$(az vm show \
      --name simpleLinuxVM \
      --resource-group $RESOURCEGROUP \
      --show-details \
      --query [publicIps] \
      --output tsv)
    
  2. Run curl to access your web server.

    curl $IPADDRESS
    

    You see this.

    <html><body><h2>Welcome to Azure! My name is simpleLinuxVM.</h2></body></html>
    
  3. From a separate browser tab, navigate to your web site.

    First, print the IP address.

    echo $IPADDRESS
    
  4. Navigate to the IP address you see from a separate browser tab. You see something like the following message:

    A web browser showing the resulting Nginx configuration

Great work! With the Custom Script Extension resource in place, you're able to extend your deployment to do more.

Now that you've defined the template resource for the Custom Script Extension that configures IIS on your VM, let's add it to the existing VM template and run it.

Build the template

Here you'll download the template and modify it.

  1. From Cloud Shell, run curl to download the template you used previously from GitHub.

    curl https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-vm-simple-windows/azuredeploy.json > azuredeploy.json
    
  2. Open azuredeploy.json through the Cloud Shell editor.

    code azuredeploy.json
    
  3. In the file, locate the resources section. Add the Custom Script Extension resource you built in the previous part to the top of this section.

    Here's the code as a refresher.

    {
      "name": "[concat(parameters('vmName'),'/', 'ConfigureIIS')]",
      "type": "Microsoft.Compute/virtualMachines/extensions",
      "apiVersion": "2018-06-01",
      "location": "[parameters('location')]",
      "properties": {
        "publisher": "Microsoft.Compute",
        "type": "CustomScriptExtension",
        "typeHandlerVersion": "1.9",
        "autoUpgradeMinorVersion": true,
        "settings": {
          "fileUris": [
            "https://raw.githubusercontent.com/MicrosoftDocs/mslearn-welcome-to-azure/master/configure-iis.ps1"
          ]
        },
        "protectedSettings": {
           "commandToExecute": "powershell -ExecutionPolicy Unrestricted -File configure-iis.ps1"
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
      ]
    },
    

    Note the comma , character at the end, which is needed to separate resources. The order you define resources doesn't matter, but here you add it to the top for simplicity.

  4. In the file, locate the securityRules under theresources section. Add in a section to open port 80.

          {
            "name": "allow_80",
            "properties": {
              "priority": 101,
              "access": "Allow",
              "direction": "Inbound",
              "destinationPortRange": "80",
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "sourceAddressPrefix": "Internet",
              "destinationAddressPrefix": "*"
            }
          }    
    
  5. If you get stuck or want to compare your work, you can download the resulting file from GitHub.

    curl https://raw.githubusercontent.com/MicrosoftDocs/mslearn-build-azure-vm-templates/master/windows/azuredeploy.json > azuredeploy.json
    
  6. You're all done editing files. Select the ellipses in the corner and Save.

  7. To close the editor, click the ellipses in the corner and then select Close Editor.

Verify the template

Here you'll validate the template from the CLI.

In practice, you might run lint tests or run your template through the Azure Resource Manager Visualizer before you run a test deployment.

Similar to what you did previously, run az deployment group validate to validate your template.

az deployment group validate \
  --resource-group $RESOURCEGROUP \
  --template-file azuredeploy.json \
  --parameters adminUsername=$USERNAME \
  --parameters adminPassword=$PASSWORD \
  --parameters dnsLabelPrefix=$DNS_LABEL_PREFIX

Notice that this time you use the --template-file argument, and not --template-uri, because you are referencing a local file.

If you see errors, refer back to the previous part or compare your code to the reference implementation.

Deploy the template

Here you'll run a command that's similar to the one you ran earlier to deploy the template. Because you haven't modified any existing resources – the VM, its network settings, or the storage account – Resource Manager won't take any action on those resources. It will only apply the resource you just added that runs the Custom Script Extension that installs IIS on your VM.

Run az deployment group create to update your deployment.

az deployment group create \
  --name MyDeployment \
  --resource-group $RESOURCEGROUP \
  --template-file azuredeploy.json \
  --parameters adminUsername=$USERNAME \
  --parameters adminPassword=$PASSWORD \
  --parameters dnsLabelPrefix=$DNS_LABEL_PREFIX

Again, notice that this time you use the --template-file argument because you are referencing a local file.

The command takes a couple minutes to complete. You see a large block of JSON as output, which describes the deployment.

Verify the deployment

The deployment succeeded, so let's see the resulting configuration in action.

  1. Run az vm show to get the VM's IP address and store the result in a Bash variable.

    IPADDRESS=$(az vm show \
      --name simple-vm \
      --resource-group $RESOURCEGROUP \
      --show-details \
      --query [publicIps] \
      --output tsv)
    
  2. Run curl to access your web server.

    curl $IPADDRESS
    

    You see this.

    <html><body><h2>Welcome to Azure! My name is simple-vm.</h2></body></html>
    
  3. From a separate browser tab, navigate to your web site.

    First, print the IP address.

    echo $IPADDRESS
    

    Navigate to the IP address you see from a separate browser tab. You see this.

    Screenshot of a web browser that shows the message welcome to Azure.

Great work! With the Custom Script Extension resource in place, you're able to extend your deployment to do more.