Azure Hub-Spoke Deployment with Terraform
What will you learn from this code?
In the Terraform code, you will find a basic setup for an Azure Hub-Spoke model. It consists of Resource Groups, VNets, Subnets, Azure Firewall, Firewall rules, NGS’s, Azure Keyvault, Peerings, and Route tables.
To create this Hub-Spoke environment, I have used the following components within Terraform:
- Working with the ‘count Meta_argument‘
- Working with ‘cidrsubnet Function‘
- Calculates a subnet address within given IP network address prefix. Which are applied for calculating address_prefixes for the spoke subnets;
- Working with separate environments
- Creating a module
- Working with outputs (creating and using)
- Outputs from modules are used as input for other modules;
- Working with separate providers
- Sometimes you have specific needs (features within providers) for certain modules;
- Generate random integers and id’s
- For testing purposes it can be useful to create random integers;
- Working with ‘depends_on Meta-Argument‘
- Working with create_before_destroy ‘lifecycle Meta_argument‘
- Why? During destroy of the Azure Firewall public ip, an error occurred because the public ip was still in use by the Azure firewall. By applying the lifecycle Meta-Argument within the pip resource block with the argument ‘create_before_destroy = true’, first the Azure Firewall will be deleted;
IDEA
The idea for this setup is to function as a base for future blogs about workload deployments with best practices applied. Future deployments like AI cognitive services, K8s, App services, API management, data, or IaaS deployments. Ultimately, it will become a platform for providing services.
Source
Github
All the code that is use can be found in this repository.
Directory Structure
Directory | File | Used for | Creates |
---|---|---|---|
root | main.tf | Creates a random integer for testing Modules are specified with given variables from production.tfvars and output from other modules. | Further defined in modules |
providers.tf | They are responsible for understanding API interactions and exposing resources. | ||
backend.tf | Specifies which Terraform backend is used. | ||
variables.tf | Variables are specified which are needed for root module as well as other modules. | ||
./environments | production.tfvars | Defines the input values for the root module. | |
./modules/azfirewall | azfirewall.tf | Defines the resources for the child module. | Firewall subnet, Public IP, Azure Firewall, Application Rule, Network Collection rule and Route tables |
outputs.tf | Output values are reusable information about your infrastructure, which can be used on the command line, this information can be reused in other Terraform modules or configurations. | ||
variables.tf | Variables are specified which are needed for azfirewall module. | ||
./modules/keyvault | keyvault.tf | Defines the resources for the child module. | Resource group, Keyvault and permissions |
outputs.tf | Output values are reusable information about your infrastructure, which can be used on the command line, this information can be reused in other Terraform modules or configurations. | ||
providers.tf | Separate features are applied specific for Keyvault. | ||
variables.tf | Variables are specified which are needed for keyvault module. | ||
./modules/network_hub | outputs.tf | Output values are reusable information about your infrastructure, which can be used on the command line, this information can be reused in other Terraform modules or configurations. | |
variables.tf | Variables are specified which are needed for network_hub module. | ||
vnet_hub.tf | Defines the resources for the child module. | Resource group, VNets and peerings | |
./modules/network_spoke | outputs.tf | Output values are reusable information about your infrastructure, which can be used on the command line, this information can be reused in other Terraform modules or configurations. | |
variables.tf | Variables are specified which are needed for network_spoke module. | ||
vnet_spoke.tf | Defines the resources for the child module. | Resource group, VNets, subnets, NSGs and association |
Getting started
In previous posts about Infrastructure as Code, I have created step-by-step guides for Terraform and Azure DevOps. Check out the posts about TERRAFORM AND AZURE DEVOPS | PART 1, TERRAFORM AND AZURE DEVOPS | PART 2 and TERRAFORM AND AZURE DEVOPS | PART 3.
Adding a Spoke
Adding another spoke to this environment is as simple as just adding a name for the spoke and an address space to the ‘production.tfvars’. In the image, I highlighted ‘example3’ as an example input for adding another spoke.
Save the ‘production.tfvars’ file and run through the init, plan, and apply steps or run your pipeline.
Initiate
terraform init
This initiates the backend and modules.
Plan
terraform plan -var-file="./environments/production.tfvars" -out main.tfplan
In this step Terraform looks for what needs to be changed.
Apply
terraform apply main.tfplan
As the command suggests, it applies the changes.
After the changes are applied, the following resources are created:
Created | Info |
---|---|
Resource group for the spoke | rg-connectivity-spoke-example3-218 |
VNET for the spoke | vnet-spoke-example3 |
Subnets for the spoke | snet-privatelinkendpoints-example3 snet-endpoints-example3 |
NSGs for the spoke and apply these to the subnets | nsg-snet-privatelinkendpoints-example3 nsg-snet-endpoints-example3 |
Peerings for the spoke | peer-spoke-vnet-spoke-example3-2regionalhub peer-hub2spoke-vnet-spoke-example3 |
Route table for the spoke | route-table-example3 with next hop Azure firewall |
Firewall rules for the spoke | Network and application rules |
One Comment