In the previous post of the Microsoft Azure with Terraform series we have described how to setup Terraform Azure backend for managing remote states. In this post, we explore how to spin up an Azure Virtual Machine (VM) with Terraform and how to bootstrap the first simple Web Application.
Before digging into the Terraform HCL (Hashicorp Configuration Languages) for the Azure VM configuration, we create the Azure cloud architecture that we will deploy. Microsoft provides a package of Azure Cloud symbols that can be used for designing our solution. The minimum Azure cloud infrastructure for creating an Azure VM consists of:
The following picture depicts the Azure cloud infrastructure with all the above listed components. We will implement it with Terraform HCL.
We look now on how to implement this architecture using Terraform HCL.
The “name” and the “location” keys have variables assigned to them. The variables are declared and defined in separate Terraform .tf files. The resource group resource is configured with a lifecycle for preventing Terraform to destroy it in case we perform the “terraform destroy” command.
The Azure VM shall be created inside an Azure Virtual Network. For the Azure Virtual Network Terraform provides the azurerm_virtual_network resource. For the Azure Subnet Terraform provides the azurerm_subnet resource. We use them for our implementation
For the Vnet the address range is specified by the CIDR 10.0.0.0/16 that is giving 65536 addresses available for this Network. The subnet CIDR is 10.0.2.0/24 giving 256 addresses for the subnet. To this example we leave this setup even if we don´t need all these network addresses.
To be able to communicate with the Azure VM we need to have a Public IP address to associate to the Azure Network Interface . For the Azure Public IP address Terraform provides the azurerm_public_ip resource. We use it for creating the Public IP address we need
Azure gives the possibility to have max 5 static public IP address per region. In our case we must define the IP address as static since Terraform has an issue when using the remote_exec provisioner with dynamic IP address.
To be able to setup the rules for accessing the Azure VM we need to use the Azure Network Security Group. For the Azure Network Security Group Terraform provides the azurerm_security_group resource. We can use it for setting up the inbound rules for SSH (port 22) and HTTP (port 80).
Using the Azure Network Security Group and the Azure Public IP we can now setup the Azure Network Interface. For the Azure Network Interface Terraform provides the azurerm_network_interface resource. We can now use it for our implementation.
Now we have all the Azure architecture resources to be able to spin up an Azure VM and its OS Disk. For the Azure VM Terraform provides the azurerm_virtual_machine resource. We create a Linux VM with Ubuntu 16.04 LTS version. The OS disk is created at the Azure VM creation as unmanaged disk.
The Linux VM is created and SSH login is used. For creating the SSH keys pair we use ssh-keygen command and we pass to the Linux VM the public key as parameter for the “ssh_keys” list.
Now we have the following Terraform files based on the described HCL
We can execute the “terraform plan” command
and “terraform apply” and see if we can create the Azure Linux VM with Terraform.
If we look to the Azure Portal we can see that all the resources have been created
We can try now to test the Azure Security Group SSH into the virtual machine using the generated ssh key
We access the Azure VM and we validate the Azure Security Group
At this point we have created the Azure VM with all the infrastructure needed. Usually we create such Azure VM with the purpose of running a Web Application on it. Terraform is not the best tool for bootstrapping a Web Application but it can be done using the Terraform provisioners. To be able to do that we need to add the following HCL to the azure_virtual_machine resource.
Terraform uses the provisioner Connection for connecting to the Azure VM using the SSH key. The Terraform provisioner File for copying the bash script.sh file to be executed after the Azure VM is created.
The script is installing Apache server for the Web Application. The index.html is also copied into the Azure VM and used after the Apache server is installed
The Terraform provisioner remote_exec invokes the scripts and performs the copy of the index.html file in the /var/www/html/ directory.
If we run “terraform apply” with the Terraform provisioners we create the Azure VM and install and run the Apache server with our index.html file
We can access the web application using the static IP address and validate at the same time the Azure Security Group HTTP inbound rule
In this post, we deployed an Azure VM using Terraform. We used the architecture first approach designing the Azure infrastructure and then implementing it with Terraform HCL. Terraform is also capable to bootstrap applications into Azure infrastructure and we demonstrated it bootstrapping a simple Web application into the new Azure VM using Terraform.