In my previous blog post, I demonstrated how to use Azure Storage to set up Remote Terraform State. In this post, I will illustrate the process of setting up an Azure Virtual Network (VNet).
This step is essential as it serves as a prerequisite for a future post, where I’ll explain how to deploy an Azure Kubernetes Service (AKS) cluster in a custom Azure VNet.
Azure Virtual Network
Azure Virtual Network offers several advantages for cloud networking. It allows you to isolate your resources, providing network security and access control through features like network security groups and virtual network service endpoints. VNet enables hybrid connectivity, connecting your Azure resources with on-premises infrastructure or other cloud environments. It also facilitates subnet and IP address management, allowing you to organize and control your resources effectively. VNet integrates with various Azure services, enabling seamless communication and integration, while regional connectivity and VNet peering support scalability and resource distribution.
Note: This article assumes you have Linux and Terraform experience.
Prerequisites
- Terraform Installed
- Azure Account
- Azure CLI
Code
You can find the GitHub Repo here.
Brief Overview of the Directory Structure
/terraform-aks/
├── modules
│ ├── 0-remotestate
│ └── 1-vnet
└── tf
└── dev
├── global
│ └── 0-remotestate
└── westus2
└── aksdemo
└── 1-vnet
- /terraform-aks: This is the top-level directory.
- /modules: Within this directory, we store the child modules that will be invoked by the root modules located in /tf/.
- /0-remotestate: This sub-directory, found within the /modules/ directory, contains the necessary resources for creating storage used to store our remote state.
- /1-vnet: This sub-directory, found within the /module/ directory, contains the necessary resources for creating our virtual network. These resources include a vnet, subnet, service endpoints, Nat Gateway.
- /tf: The configurations for all root modules are located in this directory.
- /dev: Representing the environment, this directory contains configurations specific to the dev environment.
- /global: This subdirectory houses configurations that are shared across different regions.
- /0-remotestate: Located within the /global/ directory, this subdirectory represents the root module responsible for calling the child module located in /modules/0-remotestate/ in order to create our storage.
- /tf/westus2/: This subdirectory represents anAzure region, in this case, westus2
- /tf/westus2/aksdemo/: This subdirectory is specific to the project within the westus2 region.
- /tf/westus2/aksdemo/1-vnet: This subdirectory represents the root module responsible for calling the child module located in /modules/1-vnet/ in order to create our virtual network resources.
Usage
To utilize the modules, make necessary modifications to the main.tf file located at the root level: /tf/westus2/aksdemo/1-vnet, according to your specific criteria.
Let’s take a look at the resources needed to create our Virtual Network within our child module located in terraform-aks/modules/1-vnet/main.tf
We are creating the following:
- Resource Group: The resource group serves as a logical container for all the resources related to the virtual network. It helps manage and organize your resources within Azure.
- Virtual Network (VNet): The AKS cluster requires a dedicated virtual network to operate. The VNet provides an isolated network environment where the AKS nodes and other related resources can communicate with each other. It helps ensure secure and controlled networking within the cluster.
- Subnet: Within the VNet, the AKS cluster requires a subnet to be provisioned specifically for the cluster. The subnet serves as a smaller segmented network within the VNet where AKS nodes are deployed. It helps control network traffic, security policies, and connectivity for the AKS cluster.
- Service Endpoints: Service endpoints allow the AKS cluster to securely access specific Azure services directly through the Azure backbone network. This helps improve network performance and security by bypassing the public internet.
- NAT Gateway: The NAT gateway can be used in scenarios where your AKS cluster needs outbound internet connectivity. It provides a way for the AKS nodes to communicate with external resources over the internet while appearing as if the traffic is originating from a single IP address (the NAT gateway’s IP).
Let’s go through main.tf and variables.tf files to understand the Terraform code.
Main.tf
- Resource Group for VNet: This block defines an Azure resource group that will be created to hold the virtual network resources. The name of the resource group is generated using variables like var.name , var.location , and var.environment.
- VNet: This block creates an Azure virtual network (VNet). It references the resource group created in the previous block and sets properties such as name, location, address space, and tags. The VNet’s name is generated similarly to the resource group name, using variables.
- AKS Subnet: This block creates a subnet within the VNet for an AKS (Azure Kubernetes Service) cluster. It specifies the subnet name, virtual network name, resource group name, address prefixes, service endpoints, and enables private endpoint network policies.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/TF-Azure-Vnet-blog-1024x872.jpg)
Nat Gateway Configuration: This section sets up a NAT (Network Address Translation) gateway and associates it with the VNet and subnet created earlier.
- azurerm_public_ip.natip: This block defines a public IP address for the NAT gateway, specifying its allocation method, name, location, resource group, and SKU (Stock Keeping Unit).
- azurerm_nat_gateway.natgw: This block creates a NAT gateway with a name, location, resource group, and SKU.
- azurerm_nat_gateway_public_ip_association.nat-ip: This block associates the public IP address with the NAT gateway.
- azurerm_subnet_nat_gateway_association.aks: This block associates the NAT gateway with the AKS subnet.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/TF-Azure-Vnet-blog2-1017x1024.jpg)
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/Terraform-azure-storage3-1024x186.jpg)
variables.tf
This file defines various input variables that can be customized when running the Terraform code. Here’s a breakdown of some of the variables:
- network_prefix: The prefix of the VNet’s IP address range.
- name: The name of the project.
- location: The Azure region where the VNet will be created.
- globalLocation: The Azure region where the resource group of the VNet exists.
- environment: The Azure environment, such as “dev,” “qa,” or “prod.”
- tags: Additional tags to add or overwrite the default tags for resources.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/TF-Azure-Vnet-blog3-1024x802.jpg)
- Locals: This block defines local values that can be used within the Terraform configuration. In this case, it sets the VNet’s network address space, service endpoints, and the AKS subnet’s address prefix. They have default values but can be overridden if desired.
- Additional Variables: These variables define the allocation method and SKU for the NAT gateway. They have default values but can be overridden if desired.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/TF-Azure-Vnet-blog5-1024x935.jpg)
The Terraform code sets up the Azure provider and defines local variables to extract information from the working directory path. It then calls the child module from terraform-aks/modules/1-vnet/to create an Azure VNet and associated resources. The state file for Terraform is stored in an Azure Storage Account using the specified backend configuration. The actual values for the <resource-group-name>, <storage_account_name>, <container_name>, and <key> will need to be replaced with actual values to work with your Azure environment.
/tf/dev/westus2/askdemo/1-vnet/main.tf
- Provider Block: This block configures the Azure provider, indicating that Terraform will be managing Azure resources in this configuration. The features {} block specifies that all provider features are enabled.
- Locals Block: This block defines local variables for the root module to make the configuration cleaner and more readable. It extracts information from the current working directory path to determine the environment, location, and name. It also defines a set of tags that will be applied to the resources.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/TF-Azure-Vnet-blog6-1024x646.jpg)
Module “network”: This block calls the child module 1-vnet located at terraform-aks/modules/1-vnet. The child module is used to create an Azure Virtual Network (VNet) and associated networking resources. The module is invoked with the following arguments:
- source: The relative path to the child module.
- name: The name of the project extracted from the local variables.
- environment: The environment extracted from the local variables.
- location: The Azure region extracted from the local variables.
- globalLocation: The Azure region where the resource group for the VNet exists. In this case, it’s set to “westus2”.
- network_prefix: The IP address prefix of the VNet. The value is an empty string, you will need to modify it. (e.g. 10.0)
- publicdns: The name of the public DNS, set to “public.dns”.
- tags: The tags defined in the local variables.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/TF-Azure-Vnet-blog7-1024x382.jpg)
Terraform Block: This block specifies some Terraform-specific configurations:
- required_version: It sets the minimum required version of Terraform to 0.14.11.
- backend “azurerm”: This indicates that Terraform will use the Azure Storage Account as the backend to store the state. The state file will be stored in the specified resource_group_name, storage_account_name, and container_name. The key is the name of the state file.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/07/TF-Azure-Vnet-blog9-1024x390.jpg)
Now that we have set up the root module in the terraform-aks/tf/dev/westus2/aksdemo/1-vnet/main.tf directory, it’s time to provision the necessary resources using the child module located at terraform-aks/modules/1-vnet.
terraform init:
- Open your terminal or command prompt.
- Navigate to the directory containing the root module code (terraform-aks/tf/dev/westus2/aksdemo/1-vnet/) .
- Run the following command:
terraform init
- This command initializes your working directory and downloads the necessary providers and modules specified in the configuration.
terraform plan:
- After successful initialization, you can now generate an execution plan to preview the changes that Terraform will make to your infrastructure.
- Run the following command:
terraform plan
- Terraform will analyze your configuration and display a summary of the changes it intends to apply, including any additions, modifications, or deletions of resources.
terraform apply:
- Once you have reviewed the plan and are ready to apply the changes to your Azure environment, run the following command:
terraform apply
- Terraform will prompt you to confirm that you want to apply the changes. Type “yes” and press Enter.
- The apply process will create or update the Azure resources based on the configuration provided in the terraform-aks/tf/dev/westus2/1-vnet directory.
- After the apply is completed, Terraform will display the details of the resources created or modified.
![](https://pvmdec.a2cdn1.secureserver.net/wp-content/uploads/2023/06/Matt.jpg)
Junior DevOps Engineer
Matt Mendez is a dedicated and passionate IT professional with a strong desire to help people as a consultant. With expertise in AWS, Linux, Terraform, and Google Cloud. He has acquired valuable certifications in these areas. Having hands-on experience in working with leading cloud platforms such as AWS, Azure, and Google Cloud, as well as proficient in managing infrastructure using Terraform and Kubernetes.
Follow Matt on LinkedIn