Newsletter zu Aktionen
Trage dich ein um keine Aktionen von uns zu verpassen.
Wir senden 1-2 E-Mails pro Quartal.
In this lab, we will create a Hub Spoke Network Topology using Terraform.
The hub network
storage and app via local peering. Each containing different services.onprem-vnet to simulate an onpremise network. It will be connect via global peering (different regions).In this exercise, we dive into type contraints when specifying variables. variables allows the caller to customize. To ensure, that the customization is valid, terraform offers type contraints and validations.
Though it provides flexibility, it is good practice to follow the principles „conventions over configuration“.
hub parameterIn this task, we will learn how to implement type contraints.
hub, the user can define various propertieshub = {
// mandatory if hub is specified.
name = "hub-vnet"
// optional. If not specified, "West Europe"
location = "West US"
// optional. If not specified, "rg-${hub.name}"
resource_group_name = "rg-hub-vnet"
// type constraint: list of address-spaces
}
hub, which contains the correct resource_group_name.hub is optional.local.hub to check if your logic does comply. You do not need to use any providers or modules for it to work.terraform init and terraform apply -auto-approve.hub = {
"address_space" = tolist([
"10.255.0.0/16",
])
"location" = "West Europe"
"name" = "hub-vnet"
"resource_group_name" = "rg-hub-vnet-hub"
}
tf plan -out .tfplan should output this# azurerm_resource_group.hub will be created
+ resource "azurerm_resource_group" "hub" {
+ id = (known after apply)
+ location = "westeurope"
+ name = "rg-hub-vnet"
}
# azurerm_virtual_network.hub will be created
+ resource "azurerm_virtual_network" "hub" {
+ address_space = [
+ "10.255.0.0/16",
]
+ dns_servers = (known after apply)
+ guid = (known after apply)
+ id = (known after apply)
+ location = "westeurope"
+ name = "hub-vnet"
+ private_endpoint_vnet_policies = "Disabled"
+ resource_group_name = "rg-hub-vnet"
+ subnet = (known after apply)
}
tf apply .tfplanspoke parameterIn this task, we will add a custom validation for spokes.
spoke, the user define the address range.spokes = {
// valid shorthand, will become 10.0.0.0/16
onprem = "10.0"
// valid
app = "10.2.0.0/24"
// valid
storage = "10.2.1.0/28"
}
10.0 will become 10.0.0.0/16) or a valid CIDR notation.
validation block in variable blockalltrue, cidrhost, can, regexall.for expression.regex raises an error. To test whether a given pattern matches a string, use regexall and test that the result has length greater than zero.spokes, which contains the extended (valid CIDR) address ranges for all the spokes.spokes toonprem = "10.0"
app = "10.2.0.0/24"
storage = "10.2.1.0/28"
local.hub to check if your logic does comply.
for expression..tfvars file and replace it content withspokes = {
invalid1 = "10."
invalid2 = "A.B"
invalid3 = "10.0.0.0/33"
invalid4 = "10.0.0.-1/33"
}
terraform plan -out .tfplan -var-file=.tfvars. You should seeInvalid value in var.spokes. Use a valid CIDR (e.g. 10.2.0.0/24) or a shorthand 'A.B' that can be expanded to 'A.B.0.0/16' (e.g. 10.1).
```bash
8. Remove the `.tfvars` and run `terraform apply -auto-approve`.
9. The result should look like this
# ...
hub = {
"address_space" = tolist([
"10.255.0.0/16",
])
"location" = "West Europe"
"name" = "hub-vnet"
"resource_group_name" = "rg-hub-vnet"
}
spokes = {
"app" = "10.2.0.0/24"
"onprem" = "10.0.0.0/16"
"storage" = "10.2.1.0/28"
}
hub with a new property fw_address_prefix, which is the address_prefix for the Azure Firewall. This property is optional. Terraform should validate:
hub based on the validation above by adding the new property fw_address_prefix.
AzureFirewallSubnet within the hub vnet is required.
azurerm_subnetaddress_prefixes to [local.hub.fw_address_prefix]azurerm_public_ipallocation_method to Staticsku to Standardazurerm_firewallsku_tier to Standardsku_name to AZFW_VNetterraform plan -out .tfplan.terraform apply .tfplan.This is just a lab configuration, please don’t. open use this for production. As this basically allows everything.
azurerm_firewall_network_rule_collection to add spokes’s address range.dynamic and for_each to dynamically create rule blocks for each item in local.spokes within azurerm_firewall_network_rule_collection:
protocols to ["Any"]destination_ports to ["*"]destination_addresses to ["*"]source_addresses to local.spokes’s address range.terraform plan -out .tfplan.terraform apply .tfplan.In this exercise, we will create a module, that will support the following block
module "spokes" {
source = "./modules/spoke"
for_each = local.spokes
name = each.key
address_space = each.value
location = local.hub.location
hub = azurerm_virtual_network.hub
nva = azurerm_firewall.hub.ip_configuration[0]
subnets = {
frontend = {
prefixes = [cidrsubnet(each.value,4,0)]
nsg = true
route = true
}
backend = {
prefixes = [cidrsubnet(each.value,4,1)]
nsg = true
}
data = {
prefixes = [cidrsubnet(each.value,4,2)]
nsg = true
}
}
}
rg-${var.name} will be createdvar.name with the given address_space will be created.subnets, which is defined subnet.name => subnet.prefixes. e.g. subnets = (frontend => [...])nsgs, array of all subnet names, that has nsg = true. e.g. nsgs = ["frontend", "backend", "data"]route, array of all subnet names, that has route = true. e.g. routes = ["frontend"]toset function and the filtering element of the for expression.route is true, route all the traffic from this subnet to the hub network.nsg is true, create a network security group and associate it with the respective subnet.hub and spoke vnet with each other. Keep in mind, that needs to be biliteral (created in hub and created in spoke).resource blocks: azurerm_resource_group, azurerm_virtual_network, azurerm_subnet, azurerm_network_security_group, azurerm_subnet_network_security_group_association, azurerm_virtual_network_peering, azurerm_route_table, azurerm_route, azurerm_subnet_route_table_associationterraform plan -out .tfplan.terraform apply .tfplan.In the previous exercise, we used a array to create 3 spokes, which is perfectly fine. But for the sake of this exercise. We will move the onprem spoke out of the array.
onprem item)app = "10.2.0.0/24"
storage = "10.2.1.0/24"
onprem.tf file in your project and paste module "onprem" {
source = "./modules/spoke"
name = "onprem"
address_space = "10.0.0.0/16"
location = "Germany West Central"
hub = azurerm_virtual_network.hub
nva = azurerm_firewall.hub.ip_configuration[0]
subnets = {
avd = {
prefixes = ["10.0.1.0/24"]
route = true
nsg = true
}
}
}
terraform state mv 'module.spokes["onprem"]' 'module.onprem'. This basically tells Terraform, what we just did.terraform plan -out .tfplan.Plan: 8 to add, 1 to change, 14 to destroy.. This looks like a lot of destruction. Check your code and find the value that needs to be changed, so that the output becomes Plan: 4 to add, 1 to change, 10 to destroy..
subnets should not be changed.terraform plan -out .tfplan.terraform apply .tfplan.In this exercise, we will migrate our infrastructure state to Azure. We use a different subscription to create a storage account and to push the state to this account.
tstate${your-initial} (and a resource group)
dt-sub-plm-001).Performance to Standard.tfstate.terraform block with a backend "azurerm" block
subscription_id to the Azure Subscription for Platform Management used to create the storage account.`resource_group_name, storage_account_name, and container_name accordingly.plc-hubspoke.tfstate (this is the file name).terraform init.Initializing the backend...
Acquiring state lock. This may take a few moments...
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "local" backend to the
newly configured "azurerm" backend. No existing state was found in the newly
configured "azurerm" backend. Do you want to copy this state to the new "azurerm"
backend? Enter "yes" to copy and "no" to start with an empty state.
Enter a value:
yes and press Enter.plc-hubspoke.tfstate.You can increase security by enabling
Enable versioning for blobsunderData protectionsetting from the storage account amongs other features, that the storage account has to offer (soft delete, feed, etc.)
Trage dich ein um keine Aktionen von uns zu verpassen.
Wir senden 1-2 E-Mails pro Quartal.