Picking up the same theme as my last blog, and enticing you dear reader with a another provocative title, in this blog post I’ll further expand on using CSV files, but target my displeasure of writing the equivalent of War in Peace but in Terraform, at another great Azure service- Azure Firewall.
Specifically with this example, Azure Firewall Network Rule Collections, there’s another opportunity to reduce the amount of writing of Terraform code required to achieve the target state.
How this came about was because of the outcomes of my previous blogs in needing to route lots of CIDR ranges though Azure Firewall - via Route Tables / UDRs. To allow that traffic through Azure Firewall now requires the relevant allow rules to complete the puzzle.
["Example1", "Example2", "Example3"]
I took my learnings from using CSVDECODE outlined in a previous blog I did (Terraform + CSVs = Netflix) and tweaked the recipe slightly so that the same functionality could be leveraged. Network Rules are like Routes in Route Tables. Similar in that once you have the Network Rule Collection akin to have a Route Table setup, the Rules in the Network Rule Collection can be pretty much rince and repeat. So using a CSV and Excel’s power, smashing out dozens (or in my requirement 100’s) of rules saves a lot of time. Again, see above caveats for.. err caveats?
One last point I wanted to mention is around the rule itself in terraform. There are certain constraints around formatting that need to be met. I assume this is because of the way the provider is built and interacts with the Azure API.
So more caveats? Just two quick points, more pro-tips really around the module, specificly the Rule itself.
Firstly, the syntax does not allow us to use each.value.<reference>
since the specific block is 'dynamic "rule"'
, so my understanding is we need to reference that name. That’s why we have rule.value.name
.
The second and last point is that “v0.12, the Terraform language has built-in syntax for creating lists using the [ and ] delimiters.” Thank you official Terraform doco. So, where we have lists required, that being the values
Apart from that, the rest is quite similar in the module flow. Below is an example of what that looks like, including an example CSV file:
locals {
collection_rules = csvdecode(file("${path.module}/network_collection_rules.csv"))
}
resource "azurerm_firewall_network_rule_collection" "Example-Collection" {
name = "Example-Allow-Collection"
azure_firewall_name = azure_firewall.name
resource_group_name = resource_group.name
priority = "1000"
action = "Allow"
dynamic "rule" {
for_each = { for netrule in local.collection_rules : netrule.name => netrule }
content {
name = rule.value.name
source_addresses = [rule.value.source_addresses]
destination_ports = [rule.value.destination_ports]
destination_addresses = [rule.value.destination_addresses]
protocols = [rule.value.protocols]
}
}
}
Finally, here’s an example of the CSV file that contains the details that’s used to create the Network Rule Collection.
name,source_addresses,destination_ports,destination_addresses,protocols
CloudFlareDNSPrimary,10.0.0.0/8,53,1.1.1.1/32,Any
CloudFlareDNSSecondary,10.0.0.0/8,53,1.0.0.1/32,Any
Within weeks of figuring my first usage of CSVDECODE and using CSV files to streamline my Terraforming of Azure resources, I found another. As I said before “there’s more resources this can be applied to than just Route Tables”.
Cheers!