Objective:
This lab documents the process of provisioning an Azure Resource Group and Virtual Network (with a subnet) using Terraform. It starts with a hardcoded configuration and progressively refactors it: extracting values into variables, loading defaults from a terraform.tfvars file, and using the hashicorp/random provider with string interpolation to generate a unique naming suffix for each resource. It closes with initializing, validating, planning, applying, verifying the resources in the Azure Portal, and tearing them down with terraform destroy.
Prerequisites:
- An active Azure subscription and an account with permission to create resource groups and virtual networks.
- Terraform CLI installed and available on the PATH.
- Azure CLI installed, for the az login step used to authenticate the azurerm provider.
- Visual Studio Code (or any editor) for writing the .tf configuration files.
Step 1: Declare the Providers
Create a main.tf with a terraform block declaring the required provider (azurerm, with its source and version constraint). The provider block below it sets the subscription_id. To keep the subscription ID from being exposed, it is read from a variable (var.subcription_id) that is defined in a separate credentialVariables.tf file rather than hardcoded.

Step 2: Create the Resource Group
In the main.tf, an azurerm_resource_group resource is declared with a name and location (both required) plus a tags block (environment and owner). At this stage every value is still hardcoded.

Step 3: Create the Virtual Network and Subnet
In the main.tf, declare the azurerm_virtual_network resource that refrences the resource group by name and location, and defines an address_space. A subnet block is nested inside it with its own name and address_prefixes. As with the resource group, every value here is still hardcoded.

Step 4: Extract Hardcoded Values into variable.tf file
Create a variable.tf file, all hardcoded values are pulled out into the variable.tf file: RG_name, RG_location, tag_environment, tag_owner, vnet_name, vnet_address_space, subnet_name, and subnet_address_prefixes. Default values could have been set directly on these declarations, but they are deliberately left unset here and supplied instead by a terraform.tfvars file.

Step 5: Set Default Values in terraform.tfvars
Create a terraform.tfvars file that supplies the concrete value for every variable declared in variable.tf. Terraform loads this file automatically, and its values take precedence over any defaults set in variable.tf.

Step 6: Reference the Variables in main.tf
In your main.tf file, replace every hardcoded value in the resource group and virtual network blocks with the variables declared, so main.tf now drives entirely off variable.tf and terraform.tfvars.

Step 7: Add the Random Provider
To generate a unique suffix for resource names, a second required provider (hashicorp/random) is added to the terraform block, alongside its version constraint.

Step 8: Create the random_string Resource
A random_string resource named random_suffix is declared with length = 3. special and upper are both set to false, so the generated suffix is a short, plain lowercase-and-number string safe to use in Azure resource names.

Step 9: Set the Random String Variables
length, special, and upper are extracted into their own variables: random_string_length, random_string_special, and random_string_upper, following the same pattern used for the resource group and virtual network.

Step 10: Set the Random String Defaults in terraform.tfvars
The new variables are given their default values in terraform.tfvars.

Step 11: Reference the Random String Variables in main.tf
The random_string resource in main.tf is updated to pull length, special, and upper from variables.

Step 12: Append the Random Suffix with String Interpolation
The resource group and virtual network name arguments are rewritten using string interpolation so that each generated name is prefixed (made a mistake, should have been suffixed) with the random string: “${random_string.random_suffix.result}-${var.RG_name}-RG” for the resource group, and “${random_string.random_suffix.result}-${var.vnet_name}” for the virtual network. This guarantees a unique name on every apply.

Step 13: Run “terraform init” to Initialize Terraform
terraform init downloads and installs the azurerm (~> 4.1.0) and random (~> 3.5.1) providers and writes the provider selections to .terraform.lock.hcl. The command completes with “Terraform has been successfully initialized!”, confirming the working directory is ready for plan and apply.

Step 14: Authenticate and Validate
Run “az login” which opens a browser window to authenticate the current session against Azure, which the azurerm provider needs in order to act on the target subscription to create the resources.
Run “terraform validate”, this checks the configuration files for internal consistency (correct syntax, valid argument names and types). If all are met It returns “Success! The configuration is valid.”

Step 15: Run “terraform plan” to Review the Execution Plan
terraform plan compares the configuration against the current state (there is none yet) and prints the actions it would take. All three resources: the resource group, the virtual network with its nested subnet, and the random string show a + (create) prefix, and the summary line confirms it: “Plan: 3 to add, 0 to change, 0 to destroy. Always run terraform plan to know the changes that will happen before applying it.


Step 16: Run “terraform apply” to Apply the Configuration
“terraform apply -auto-approve” carries out the plan without the “yes” confirmation prompt. Terraform creates the random string first (the resource group and virtual network names depend on its result), then the resource group, then the virtual network. It finishes with “Apply complete! Resources: 3 added, 0 changed, 0 destroyed.”

Step 17: Verify the Resources in the Azure Portal
With the apply complete, the Azure Portal confirms the resources exist as expected. The resource group s0r-Olalekan-RG contains a single virtual network, s0r-VNet, in the East US region and both names carrying the random three-character prefix.

In the s0r-VNet → Subnets confirms the nested subnet block was applied correctly. Subnet1 exists with the address range 10.0.1.0/24 and 251 available IP addresses, matching the address_prefixes value set in terraform.tfvars.

Step 18: Run “Terraform destroy” to Tear Down with terraform destroy
Once verification is complete, terraform destroy -auto-approve removes everything Terraform created. This avoids leaving billable resources running in Azure after the lab is finished. The command finishes with “Destroy complete! Resources: 3 destroyed.”


