Deploying an Azure VM with Terraform

30 minutes
  • 2 Learning Objectives

About this Hands-on Lab

Deploying VMs is the primary target for almost all attempts at automation. Terraform provides a much more human-readable syntax than that of an ARM template, and allows for the creation of any prerequisites you may want, or need without having to jump around multiple portal screens. In this hands-on lab, we will take what we’ve done in the previous labs and add in the creation of a NIC and a marketplace Ubuntu VM. Additionally, we will create a Boot Diagnostics storage account to support the use of the serial console, providing a quick way to test the VM’s deployment.

Learning Objectives

Successfully complete this lab by achieving the following learning objectives:

Set Up the Command Line Interface (CLI)
  1. Open the CLI.
  2. Select Bash at the prompt.
  3. Click Show Advanced Settings. Both the Resource Group and Storage Account should be pre-selected with the lab generated values.
  4. In the File share section, choose the Create new radio button and enter console.
  5. Click the Attach Storage button.
  6. Once the command prompt is initialized, proceed to Task 2.
Deploy a Ubuntu VM
  1. Use the code block found in the Additional Information and Resources section to create a file and upload it to the CLI.
  2. In the (resource "azurerm_storage_account" "lab") declaration, you’ll need to edit the resource_group_name value with the name generated by the lab. The "provider" statement has been added to the code, so you won’t need to create a file to deploy the storage account.
  3. Once the file has been uploaded, run terraform init.
  4. Run terraform plan and review the output to confirm that Terraform will create the desired resource. Green plus signs will indicate the resources that need to be added.
  5. Run terraform apply, answering yes to the prompt to continue.
  6. Once Terraform completes the deployment, check the Azure Portal to confirm.

Additional Resources

We are editing the following code block to create an Ubuntu VM. Note that we must deploy a vNIC that will attach to the internal network and external IP addresses that are also created. As in other labs, you'll need to copy in the lab generated resource group name to the code block provided below. Note how each of the previous lab activities are building on each other for an easy, straightforward method of deploying a functional environment.

This code block sets up the:

  • VNet/Subnet
  • Public IP address
  • Network interface
  • Boot diagnostic account
  • Virtual Machine
terraform {

  required_version = ">=0.12"

  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "~>2.0"

provider "azurerm" {
  skip_provider_registration = "true"
  features {}

# Create virtual network
resource "azurerm_virtual_network" "TFNet" {
    name                = "TFVnet"
    address_space       = [""]
    location            = "East US"
    resource_group_name = "<RESOURCE_GROUP_NAME>"

    tags = {
        environment = "Terraform VNET"
# Create subnet
resource "azurerm_subnet" "tfsubnet" {
    name                 = "default"
    resource_group_name = "<RESOURCE_GROUP_NAME>"
    virtual_network_name =
    address_prefixes       = [""]

#Deploy Public IP
resource "azurerm_public_ip" "example" {
  name                = "pubip1"
  location            = "East US"
  resource_group_name = "<RESOURCE_GROUP_NAME>"
  allocation_method   = "Dynamic"
  sku                 = "Basic"

#Create NIC
resource "azurerm_network_interface" "example" {
  name                = "robot-nic"
  location            = "East US"
  resource_group_name = "<RESOURCE_GROUP_NAME>"

    ip_configuration {
    name                          = "ipconfig1"
    subnet_id                     =
    private_ip_address_allocation  = "Dynamic"
    public_ip_address_id          =

#Create Boot Diagnostic Account
resource "azurerm_storage_account" "sa" {
  name                     = "robodiags4tflab"
  resource_group_name      = "<RESOURCE_GROUP_NAME>"
  location                 = "East US"
   account_tier            = "Standard"
   account_replication_type = "LRS"

   tags = {
    environment = "Boot Diagnostic Storage"
    CreatedBy = "Admin"

#Create Virtual Machine
resource "azurerm_virtual_machine" "example" {
  name                  = "robot"
  location              = "East US"
  resource_group_name   = "<RESOURCE_GROUP_NAME>"
  network_interface_ids = []
  vm_size               = "Standard_B1s"
  delete_os_disk_on_termination = true
  delete_data_disks_on_termination = true

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"

  storage_os_disk {
    name              = "osdisk1"
    disk_size_gb      = "128"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"

  os_profile {
    computer_name  = "robot"
    admin_username = "vmadmin"
    admin_password = "Password12345!"

  os_profile_linux_config {
    disable_password_authentication = false

boot_diagnostics {
        enabled     = "true"
        storage_uri =

What are Hands-on Labs

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!

Get Started
Who’s going to be learning?