Learn Terraform and deploy Azure resource via Azure DevOps pipeline (Part 4)

In my last blog (Part 3), we have provisioned a Windows Virtual Machine (VM) using terraform modules. In this part we will learn how we can install an application or software on that VM.

At first, I will try to install IIS Web Server on the VM, as IIS is a built-in feature of Windows server, I do not need any executable to install it. I only need to run a PowerShell command to install IIS on the VM. I just have to figure out how I can run the command via terraform.

I was doing some research on this and found Azure Custom Script Extension is a great way to install something on a VM via terraform as to do this you do not need to login to the VM and hence, a private Azure DevOps agent is not necessary.

To, achieve this I am gonna create another module called install-iis, then call the module from main to install IIS on my VM. So below is my latest folder structure.

rohan@K42N:~/Documents/tfdemo$ tree --dirsfirst
.
└── azuredeploy
├── modules
│ ├── install-iis
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── README.md
│ │ └── variables.tf

│ ├── network-interface
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── README.md
│ │ └── variables.tf
│ ├── virtual-machine
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── README.md
│ │ └── variables.tf
│ └── virtual-network
│ ├── main.tf
│ ├── outputs.tf
│ ├── README.md
│ └── variables.tf
├── main.tf
├── terraform.tfvars
└── variables.tf

Lets take a look at the main.tf file of the install-iis module

resource "azurerm_virtual_machine_extension" "install-iis" {
name = "iis-webserver"
virtual_machine_id = var.virtual_machine_id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"

settings = <<SETTINGS
{
"commandToExecute": "powershell Install-WindowsFeature -Name Web-Server -IncludeAllSubFeature"
}
SETTINGS
}

Here, I am gonna need the output of the virtual-machine module, which is the VM id. Under settings section, I am running a simple powershell command to install IIS Web Server feature including all sub-features. Technically I can run any powershell command within the VM this way.

Now that our new module is ready, we have to update main to call it. Let’s take a look.

terraform {
backend "azurerm" {}
}
provider "azurerm" {
version = "=2.0.0"
features {}
}
resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.location
}
module "virtual-network" {
source = "./modules/virtual-network"
virtual_network_name = var.virtual_network_name
resource_group_name = var.resource_group_name
location = var.location
virtual_network_address_space = var.virtual_network_address_space
subnet_name = var.subnet_name
subnet_address_prefix = var.subnet_address_prefix
}
module "network-interface" {
source = "./modules/network-interface"
vmname = var.vmname
location = var.location
resource_group_name = var.resource_group_name
subnet_id = module.virtual-network.subnet_id
}
module "virtual-machine" {
source = "./modules/virtual-machine"
vmname = var.vmname
location = var.location
resource_group_name = var.resource_group_name
network_interface_ids = [module.network-interface.nic_id]
vm_size = var.vm_size
os_disk_type = var.os_disk_type
admin_usename = var.admin_usename
admin_password = var.admin_password
image_publisher = var.image_publisher
image_offer = var.image_offer
image_sku = var.image_sku
}
module "install-iis" {
source = "./modules/install-iis"
virtual_machine_id = module.virtual-machine.vm_id
}

So, I just added the last module block where I am calling the install-iis module and passing out vm id output of virtual-machine module to it.

Now we have to perform the same steps again to deploy this on Azure.

  • Commit code on local git repo
  • Push code to Azure DevOps repo
  • Run build pipeline
  • Create a release

On successful release, we will be verify from portal that our custom extension has been provision successfully. We can login to the VM and check IIS as well.

Custom Script Extension

Now, I was thinking what if I have to install something that has an executable. I have to copy the executable to the VM and install it, right? I think this can be achieved by using custom script extension as well. I will try this some time soon.

Thanks for reading, give it a 👏 if you like it. Please leave a comment and let me know if you have any feedback.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store