Azure Virtual Machines provide a flexible and scalable solution for running your applications in the cloud. By leveraging Terraform, we can automate the creation and configuration of VMs, ensuring consistency and reproducibility in our deployments. We will specifically focus on Linux VMs, as they are widely used for various purposes, such as web hosting, application deployment, and data analysis.
In this article, we will go through the steps of using Terraform to create an Azure Virtual machine with the following resources: Azure Resource Group, Azure Virtual Network, Network Subnet, Public IP address, Network Security Group, Network Interface, Linux Virtual Machine.
Prerequisites
Install and Configure Azure CLI
Install and Configure Terraform
Provision the Infrastructure on Azure
Destroy the infrastructure
Conclusion
Prerequisites
- An azure account and subscription: If you don't have an Azure subscription, create a free account before you begin.
- Infrastructure-as-Code Basics: Basic understanding of infrastructure as code is required to follow along.
Terraform is a declarative open-source “Infrastructure as Code" tool, created by HashiCorp, that enables the definition of on-premises and cloud resources in human-readable configuration files that can be versioned, reused, and shared as code.
Install and Configure Azure CLI
Open a command line from any device that has access to the Azure CLI. For steps on how to configure azure CLI locally, refer to this Microsoft Documentation
sudo apt update
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
Run the command az --version
to confirm this has been installed successfully.
Install and Authenticate Terraform to Azure
Install Terraform
Depending on your operating system, the command to install terraform may be slightly different. Refer to the terraform documentation for system-specific instruction: Terraform Installation Guide
sudo apt update
sudo snap install terraform --classic
Run terraform --version
command to view the version on terraform installed.
terraform --version
Make a Repository to hold our Terraform files and change the directory to this newly created repository.
mkdir Terraform
cd Terraform
Authenticate Terraform to Azure using a Microsoft Account
You can either authenticate to Azure using a Microsoft account or by using a service principal. In this blog, we will authenticate using a Microsoft account.
Run az login
without any parameters and follow the instructions to sign in to Azure. When you log in successful, az login
will display a list of the Azure subscriptions associated with the logged-in Microsoft account, including the default subscription.
az login
If you want to use a specific subscription, run the command below to show and set the required subscription.
az account show
az account set --subscription "<subscription_id_or_subscription_name>"
Provision the Infrastructure on Azure
Create a file to provision virtual machine on Microsoft Azure. This file will create following resources: Azure Resource Group, Azure Virtual Network, Network Subnet, Public IP address, Network Security Group, Network Interface, Linux Virtual Machine. We will call the file main.tf
.
nano main.tf
Copy and paste the code below into the file created above
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "main" {
name = "${var.prefix}-resources"
location = "eastus"
}
resource "azurerm_virtual_network" "main" {
name = "${var.prefix}-network"
address_space = ["10.0.0.0/22"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
}
resource "azurerm_subnet" "internal" {
name = "internal"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.2.0/24"]
}
resource "azurerm_public_ip" "public_ip" {
name = "acceptanceTestPublicIp1"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
allocation_method = "Dynamic"
}
resource "azurerm_network_interface" "main" {
name = "${var.prefix}-nic"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.internal.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.public_ip.id
}
}
resource "azurerm_network_security_group" "nsg" {
name = "ssh_nsg"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
security_rule {
name = "allow_ssh_sg"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "allow_publicIP"
priority = 103
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
resource "azurerm_network_interface_security_group_association" "association" {
network_interface_id = azurerm_network_interface.main.id
network_security_group_id = azurerm_network_security_group.nsg.id
}
resource "azurerm_linux_virtual_machine" "main" {
name = "${var.prefix}-vm"
resource_group_name = azurerm_resource_group.main.name
location = "eastus"
size = "Standard_D2s_v3"
admin_username = "adminuser"
admin_password = "The$admin#password"
disable_password_authentication = false
network_interface_ids = [
azurerm_network_interface.main.id,
]
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
os_disk {
storage_account_type = "Standard_LRS"
caching = "ReadWrite"
}
}
Remember to change the admin password to a string with your desired password (e.g. admin_password = "253P@assWord!@#"
.
Next, create a terraform variable file with name variable.tf
variable "prefix" {
description = "The prefix which should be used for all resources in this example"
}
variable "location" {
description = "eastus"
}
Run Terraform init
to initialize the repository.
To see changes that will take effect before any action run terraform plan
.
terraform plan
When prompted for location, enter your preferred location e.g. eastus
When prompted for prefix, enter the prefix that will be prepended to all resources created by terraform.
To apply the changes to our Azure environment, run the command below terraform apply
to apply the changes. This should go off and provision the resources in your azure cloud environment.
terraform apply
To see a list of resources provisioned, run the terraform state list
command.
terraform state list
Destroying the infrastructure
Run the below command and type yes
to destroy the infrastructure
terraform destroy
Conclusion:
In this article, we harnessed the power of Terraform for infrastructure as code to provision resources on Azure. Firstly, we installed and configured Azure CLI on local device, installed and authenticated Terraform to provision infrastructure and resources on Azure. At the end, we destroyed the infrastructure to avoid incurring much cost.
Thanks for reading. Let me know if you found this helpful. You are welcome to follow me on LinkedIn → Paschal Ogu and Twitter → Paschal_ik.
Coming Up Next:
- Configure Apache web server on Linux Virtual Machine using Ansible
- Enable SSL on a Custom Domain
- Install LAMP STACK on an Azure Virtual machine
References:
- Terraform on Azure documentation – Articles, samples, references, and resources – Terraform on Azure
- Terraform | HashiCorp Developer Terraform Documentation
Top comments (0)