DevOps Project: Azure Infrastructure and a static website deployment using Terraform
Lesson 25. Introduction
What is Terraform
Terraform is an infrastructure-as-code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.
This project demonstrates the practical use of Terraform as an Infrastructure-as-Code (IaC) tool to provision and manage Azure cloud resources. Through a series of guided steps captured in screenshots, the lab covers the creation of a Resource Group, a Virtual Network with a Subnet, and a static website hosted on Azure Storage. The workflow illustrates the complete Terraform lifecycle — initialization, planning, applying, validation in the Azure Portal, and eventual destruction of resources — providing hands-on experience with declarative cloud infrastructure management.
The core Terraform workflow consists of five stages:
1. Write (Define Infrastructure)
What you do: You author Infrastructure as Code (IaC) by writing declarative configuration files (.tf files) that describe your desired cloud or on-premises resources (such as virtual machines, networks, or databases).
2. Initialize (terraform init)
What it does: This command prepares your working directory. It downloads the required provider plugins (e.g., AWS, Azure, GCP), installs any declared modules, and sets up your state backend. You usually run this once when starting a project or adding new plugins.
3. Validate & Plan (terraform validate & terraform plan)
What it does:
Validate: Checks your configuration files for syntax errors and internal consistency.
Plan: Compares your desired configuration against your current infrastructure state and builds an execution preview (showing what will be created +, updated ~, or destroyed -) without making actual changes.
4. Apply (terraform apply)
What it does: Terraform executes the proposed execution plan. It provisions, updates, or deletes real-world infrastructure resources in the correct dependency order after you confirm the action. It then updates the state file.
5. Destroy (terraform destroy)
What it does: When you no longer need the resources, this command safely removes and tears down all the infrastructure managed by your Terraform configuration.
Terraform Configuration Files
1. main.tf: Core infrastructure resources and data sources
2. provider.tf: Cloud provider configurations (AWS, Azure, GCP, etc.)
3. variables.tf: Declarations for input variables
4. terraform.tfvars: Hardcoded input variable values (environment-specific)
5. outputs.tf: Data to print or share after a successful run
6. versions.tf: Minimum required Terraform and provider versions
Prerequisites
Install Terraform using: https://developer.hashicorp.com/terraform/install
Labs
- Provision an NGINX server in less than a minute using Docker on Windows.
- Deploy a static website on Azure Storage using Terraform
Resoruce: https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-static-website-terraform?tabs=azure-cli
Steps
> Create a Folder called Terraform
> Open VS Code.
> Click on File and select Open New Folder.
> Select the folder called Terraform
This screenshot shows the Windows File Explorer dialog used to open the project folder. The user navigates to the “Terraform” directory under the TechieHub Labs path and selects it as the working folder. This step establishes the local workspace where Terraform configuration files will reside and be executed.
> Open a new terminal.
> Run the command: terraform — version
> Run the command: az login
> Run the command: az account list -o table
Note: az account set — subscription “Your Subscription Name” — This is to switch between subs.
terraform --version
az login
az account list -o tableThe terminal output confirms that Terraform version 1.16.6 is installed and that the Azure CLI is authenticated. The “az account list” command displays the active Azure subscription, ensuring the environment is correctly configured before any infrastructure operations begin.
> Create a folder inside Terraform called terraform-lab
> Create a file inside Terraform-lab called main.tf — This is where you specify the main resource you are to create.
The VS Code interface displays the Terraform project structure, including the terraform-lab folder and the main.tf configuration file. The integrated terminal reconfirms the Terraform version and the authenticated Azure subscription, providing a single environment for editing code and running commands.
Configure the Azure provider
Copy and paste the code into the main.tf file
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
}
provider "azurerm" {
features {}
}Create a Resource Group
Copy and paste the code in the main.tf file
resource "azurerm_resource_group" "rg" {
name = "yth-terraform-rg"
location = "West us 3"
}> Save the code.
> Change directory to terraform-lab. Run the command: cd terraform-lab
> Run the command: terraform init
> Run the command: terraform validate — You should see Success! The configuration is valid.
cd terraform-lab
terraform init
terraform validateAfter changing into the terraform-lab directory, the “terraform init” command successfully downloads the AzureRM provider and creates the lock file. Subsequent “terraform validate” confirms that the configuration syntax is valid, indicating the workspace is ready for planning and deployment.
> Run the command: terraform plan
terraform planThe “terraform plan” output shows that a single Azure resource group named “cj-terraform-rg” will be created in the West US 3 region. The plan clearly indicates one resource to add, zero changes, and zero destructions, allowing the operator to review the intended action before applying it.
> Run the command: terraform apply. Type yes and click Enter.
terraform applyExecution of “terraform apply” confirms the creation of the resource group after the user types “yes.” The progress messages show the resource being provisioned, culminating in a successful completion message that one resource was added. This establishes the foundational container for subsequent Azure resources.
Verification in Azure Portal
The Azure Portal Resource Groups blade confirms that “cj-terraform-rg” has been successfully created. Navigation highlights the new resource group, and the overview pane displays its subscription, location (West US 3), and empty resource list, validating that Terraform’s changes are reflected in the live cloud environment.
Adding another resource (Virtual Network).
> Copy the code and add it to main.tf and save
resource "azurerm_virtual_network" "vnet" {
name = "yth-vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}Adding another resource (Subnet).
> Copy the code and add it to main.tf and save
resource "azurerm_subnet" "subnet" {
name = "yth-subnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.1.0/24"]
}> Run the command: terraform validate
> Run the command: terraform plan
terraform validate
terraform planAn updated “terraform plan” reveals the addition of a Virtual Network (cj-vnet) with address space 10.0.0.0/16 and a Subnet (cj-subnet) with 10.0.1.0/24. Both resources are associated with the previously created resource group, demonstrating how Terraform manages interdependent infrastructure components.
Get Emele Chijioke’s stories in your inbox
Join Medium for free to get updates from this writer.
> Run the command: terraform apply. Type yes and click Enter.
terraform applyThe “terraform apply” command provisions the Virtual Network and Subnet. Progress indicators show each resource being created, and the final summary reports two resources added successfully. This step extends the infrastructure beyond the resource group into networking components required for most Azure workloads.
Verification in Azure Portal
> Check the VNet and subnet created.
Within the Azure Portal, the cj-vnet Virtual Network is shown with its Subnets blade open. The cj-subnet appears with the expected IPv4 address range 10.0.1.0/24 and 251 available IPs, confirming that the Terraform-managed networking resources are correctly deployed and discoverable.
> Run the command: terraform destroy — This deletes and destroys everything, including the RG.
terraform destroyThe “terraform destroy” command generates a plan to remove the resource group, virtual network, and subnet. Each resource is marked for destruction, illustrating Terraform’s ability to tear down infrastructure cleanly and completely when it is no longer needed.
After the destroy operation, attempting to view the virtual network in the Azure Portal returns a “Resource not found” error (HTTP 404). This confirms that Terraform successfully deleted the resources, leaving no residual objects in the subscription.
Lab 2
Deploy a static website on Azure Storage using Terraform
https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-static-website-terraform?tabs=azure-cli
Steps
> In the Terraform folder, create a folder called static website
> In the static-website folder, create a file called providers.tf
> Copy the code from the above link and paste it into the file, and save.
> Create a main.tf file under the static-website
> Copy the code from the above link and paste it into the file, and save.
> Create a vairbles.tf file under the static-website
> Copy the code from the above link and paste it into the file, and save.
> Create an outputs.tf file under the static-website
> Copy the code from the above link and paste it into the file, and save.
> Create an index.html file under the static-website
> Copy the code from the above link and paste it into the file, and save.
> Change directory to the current project directory. Run the command: cd static-website
> Run the command: terraform init -upgrade — This helps to upgrade the necessary provider plugins
Switching to the static-website directory, the user runs “terraform init -upgrade.” After correcting a flag typo, the command initializes the AzureRM and random providers successfully. This prepares a new configuration focused on deploying a static website using Azure Storage.
> Run the command: terraform plan -out main.tfplan
terraform plan -out main.tfplanExecution of “terraform apply” creates a resource group, storage account, and related resources. The apply completes with five resources added and outputs the primary web host URL (gmanqydo.z13.web.core.windows.net), which will serve the static website content.
> Run the command: terraform apply main.tfplan
terraform apply main.tfplanA detailed “terraform plan -out” shows the planned creation of a random resource group name, a storage account name, and associated storage resources. The plan is saved to main.tfplan, providing a reviewable artifact before the actual apply step.
Verify the Results
Get the URL to the static website.
primary_web_host=$(terraform output -raw primary_web_host)
Open a browser and enter the URL in your browser’s address bar.
The browser displays the live static website at the Terraform-generated URL. The page simply states “This is a static website example,” confirming that the storage account’s static website feature is correctly configured and publicly accessible.
Verification in Azure Portal
The Azure Portal view of the storage account “gmanqydo” shows the $web and $logs containers. The $web container is the endpoint used by the static website feature, verifying that Terraform created the necessary storage structure for hosting web content. The $web container holds the index.html file.
Clean Up
> Run the command: terraform destroy — This deletes and destroys everything, including the RG.
terraform destroyChallenges and Resolution.
Conclusion
This Terraform lab successfully demonstrated end-to-end Infrastructure-as-Code practices on Microsoft Azure. From authenticating the environment and initializing providers, through planning and applying a resource group, virtual network, and subnet, to deploying a publicly accessible static website and finally destroying the resources, every stage of the Terraform lifecycle was exercised and validated both in the terminal and in the Azure Portal.
The project reinforced key IaC principles: declarative configuration, idempotent operations, state management, and the importance of reviewing plans before applying changes. Challenges such as CLI flag typos, provider versioning, and resource naming were identified and resolved, strengthening operational awareness. Overall, the lab provides a solid foundation for more complex Azure deployments using Terraform in real-world DevOps workflows.
Thank you
#LearnWithCeejay









