#
Exercise: Implementing Provisioners and Functions
#
Objective
In this exercise, participants will:
- Implement provisioners to install a web server (Nginx) on an Azure Virtual Machine.
- Use Terraform functions to dynamically adjust the configuration based on the environment.
- Create and use separate workspaces for development (dev) and production (prod) environments.
#
Steps
#
Step 1: Provision a Virtual Machine with Nginx Using a Provisioner
Define a Virtual Machine in
main.tf
:In your project directory, create or open a
main.tf
file.Add a resource block for an Azure Virtual Machine, configuring basic settings:
resource "azurerm_virtual_machine" "example" { name = "example-vm" location = var.location resource_group_name = var.resource_group_name network_interface_ids = [azurerm_network_interface.example.id] vm_size = var.vm_size storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } os_profile { computer_name = "examplevm" admin_username = "adminuser" admin_password = "P@ssw0rd123!" } os_profile_linux_config { disable_password_authentication = false } # Provisioner to install Nginx on the VM provisioner "remote-exec" { connection { type = "ssh" host = self.public_ip_address user = "adminuser" password = "P@ssw0rd123!" } inline = [ "sudo apt-get update", "sudo apt-get install -y nginx" ] } }
This configuration defines a Linux VM running Ubuntu Server 18.04 with an inline remote-exec provisioner to install Nginx after the VM is provisioned.
Define Network Interface and Public IP (if needed):
- Ensure the VM has a network interface and public IP so the provisioner can connect and install Nginx.
- Example:
resource "azurerm_network_interface" "example" { name = "example-nic" location = var.location resource_group_name = var.resource_group_name ip_configuration { name = "internal" subnet_id = azurerm_subnet.example.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.example.id } } resource "azurerm_public_ip" "example" { name = "example-pip" location = var.location resource_group_name = var.resource_group_name allocation_method = "Static" }
#
Step 2: Use Terraform Functions to Adjust Configuration Dynamically
Define the VM Size Based on Environment:
- Use the
terraform.workspace
variable and a conditional expression to set the VM size. - Add the following code to
variables.tf
or directly inmain.tf
:variable "vm_size" { description = "The size of the VM based on the environment" type = string default = terraform.workspace == "prod" ? "Standard_DS2_v2" : "Standard_DS1_v2" }
- Use the
Use the
length()
Function (Optional Example):To dynamically calculate values based on lists, you could use the
length()
function in expressions:output "number_of_nics" { description = "The number of network interfaces" value = length(azurerm_network_interface.example) }
This example calculates the number of network interfaces attached to the VM.
#
Step 3: Switch Workspaces for Dev and Prod Environments
Create and Switch to the Development Workspace:
- In the terminal, run:
terraform workspace new dev
- Terraform will create a new workspace called
dev
and switch to it.
- In the terminal, run:
Create the Production Workspace:
- Create another workspace for the production environment:
terraform workspace new prod
- Create another workspace for the production environment:
Verify Workspace:
- You can check your current workspace with:
terraform workspace show
- You can check your current workspace with:
Set Environment-Specific Values (Optional):
- Use separate variable files (e.g.,
dev.tfvars
andprod.tfvars
) to provide different values forlocation
orresource_group_name
based on the workspace.
- Use separate variable files (e.g.,
#
Step 4: Run terraform plan
and terraform apply
to Verify the Setup
Initialize the Project (if not already initialized):
- Run
terraform init
to download necessary provider plugins and prepare the environment:terraform init
- Run
Run
terraform plan
:- In the current workspace, run
terraform plan
to verify the configuration:terraform plan -var-file="dev.tfvars" # for dev terraform plan -var-file="prod.tfvars" # for prod
- Review the output to ensure Terraform will provision a VM with the correct configurations (e.g., VM size based on the workspace).
- In the current workspace, run
Run
terraform apply
to Deploy the VM:- Run
terraform apply
to create the VM and install Nginx via the provisioner:terraform apply -var-file="dev.tfvars" # for dev terraform apply -var-file="prod.tfvars" # for prod
- Type
yes
when prompted to confirm the apply operation.
- Run
Verify the Setup in the Azure Portal:
- Go to the Azure Portal and check that the VM has been created in the correct environment with Nginx installed.
#
Verification
Confirm VM Creation:
- Verify that a VM has been created in Azure for each workspace and is using the correct VM size based on the environment.
Verify Nginx Installation:
- Use SSH to connect to the VM and check if Nginx is running:
ssh adminuser@<VM_PUBLIC_IP> sudo systemctl status nginx
- Use SSH to connect to the VM and check if Nginx is running:
Verify Output Values (if configured):
- Check any outputs, such as
number_of_nics
, to ensure they reflect the actual setup.
- Check any outputs, such as