How Do You Create a Server in Azure with Terraform?

Problem scenario
You want to use Terraform to create a virtual machine in Azure. What do you do?

Solution
Prerequisites

i. Terraform must be installed on a Linux server. If you need assistance with this, see this posting.
ii. The Azure CLI must be installed and configured on the Linux server. If you need assistance with this, see this posting. (Normally you would need a client_id and client_secret in the provider block of the .tf file; you do not need these if your Azure CLI has been configured properly.)
iii. You have run ssh-keygen on the Linux server with Terraform, and you have the id_rsa.pub file. You'll need the content of the file for the directions below.

Procedures

  1. Create a file called instance.tf with the following content (this was mostly taken from https://docs.microsoft.com/en-us/azure/virtual-machines/linux/terraform-create-complete-vm) :
# Configure the Microsoft Azure Provider
provider "azurerm" {
    subscription_id = "abcdefghijklmnopqrstuvwxyz1234567891"
    tenant_id       = "777777777777777777777777777777777777"
    version = "=1.22.0"
}

# Create a resource group if it doesn’t exist
resource "azurerm_resource_group" "myterraformgroup" {
    name     = "Coolthing"
    location = "eastus"

    tags {
        environment = "Terraform Demo"
    }
}

# Create virtual network
resource "azurerm_virtual_network" "myterraformnetwork" {
    name                = "myVnet"
    address_space       = ["10.0.0.0/16"]
    location            = "eastus"
    resource_group_name = "${azurerm_resource_group.myterraformgroup.name}"

    tags {
        environment = "Terraform Demo"
    }
}

# Create subnet
resource "azurerm_subnet" "myterraformsubnet" {
    name                 = "mySubnet"
    resource_group_name  = "${azurerm_resource_group.myterraformgroup.name}"
    virtual_network_name = "${azurerm_virtual_network.myterraformnetwork.name}"
    address_prefix       = "10.0.1.0/24"
}

# Create public IPs
resource "azurerm_public_ip" "myterraformpublicip" {
    name                         = "myPublicIP"
    location                     = "eastus"
    resource_group_name          = "${azurerm_resource_group.myterraformgroup.name}"
    allocation_method            = "Dynamic"

    tags {
        environment = "Terraform Demo"
    }
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "myterraformnsg" {
    name                = "myNetworkSecurityGroup"
    location            = "eastus"
    resource_group_name = "${azurerm_resource_group.myterraformgroup.name}"

    security_rule {
        name                       = "SSH"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "22"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
    }

    tags {
        environment = "Terraform Demo"
    }
}

# Create network interface
resource "azurerm_network_interface" "myterraformnic" {
    name                      = "myNIC"
    location                  = "eastus"
    resource_group_name       = "${azurerm_resource_group.myterraformgroup.name}"
    network_security_group_id = "${azurerm_network_security_group.myterraformnsg.id}"

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = "${azurerm_subnet.myterraformsubnet.id}"
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = "${azurerm_public_ip.myterraformpublicip.id}"
    }

    tags {
        environment = "Terraform Demo"
    }
}

# Generate random text for a unique storage account name
resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = "${azurerm_resource_group.myterraformgroup.name}"
    }

    byte_length = 8
}

# Create storage account for boot diagnostics
resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = "${azurerm_resource_group.myterraformgroup.name}"
    location                    = "eastus"
    account_tier                = "Standard"
    account_replication_type    = "LRS"

    tags {
        environment = "Terraform Demo"
    }
}

# Create virtual machine
resource "azurerm_virtual_machine" "myterraformvm" {
    name                  = "myVM"
    location              = "eastus"
    resource_group_name   = "Coolthing"
    network_interface_ids = ["${azurerm_network_interface.myterraformnic.id}"]
    vm_size               = "Standard_DS1_v2"

    storage_os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

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

    os_profile {
        computer_name  = "myvm"
        admin_username = "azureuser"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/azureuser/.ssh/authorized_keys"
            key_data = "ssh-rsa AAAAB...ec2-instance5.azure.gcp.com"
        }
    }

    boot_diagnostics {
        enabled = "true"
        storage_uri = "${azurerm_storage_account.mystorageaccount.primary_blob_endpoint}"
    }

    tags {
        environment = "Terraform Demo"
    }
}

2.a. Replace "ssh-rsa AAAAB…ec2-instance5.azure.gcp.com" in the above file with the content of the id_rsa.pub file. To find this file run sudo find / -name id_rsa.pub. To create this file if you do not have it, run ssh-keygen -t rsa -P ""
2.b. Change "abcdefghijklmnopqrstuvwxyz1234567891" to your subscription ID. If you need assistance finding your subscription ID, see this posting.
2.c. Change "777777777777777777777777777777777777" in the file above to your tenant ID.
2.d. (Optional.) Change "eastus" to the region of your choice (e.g., "westus").

3. Run these commands:

terraform init
terraform apply

(Respond with "yes" to the prompt.)

4. You have now created a VM in Azure. You will be able to log in with SSH to the new VM using the "azureuser" account from the server you ran the Terraform commands from.

Leave a comment

Your email address will not be published. Required fields are marked *