How to make the block dynamic in terraform

In this blog, we will discuss about the dynamic block. Which is like more advanced version of looping available in terraform. It is better to have a knowledge of count, conditionals ,for_each and object data type before reading this blog.

First of all, understand the basic usage of dynamic blocks. The basic use case is to loop through blocks inside a resource block. For example, your security_rule in case of azure_network_security_group, when you want to create some 100 rules, you should do like the following

Security_rules in an nsg with out using dynamic blocks
Basic way of writing nsg rules without dynamic block.

From the above example, you can understand that managing and changing over time will be difficult when you have 100s or 1000s of lines of code. In this situation, you can have a variable called security rules and you can manage the exact rule values there in a separate variables file while you write a single security_rule block with dynamic block

Let explain the structure of dynamic block with an example.

Writing security_rules in nsg using dynamic blocks.
How to use dynamic block for the above nsg example

Let’s go, the line marked 1 in above image is the starting of dynamic block, need to use word dynamic to mention it, the next word in double quotes is the block name, it should be same name as the block name given by terraform. That’s why we have security_rule everywhere since it is defined by azurerm terraform. Then we open the block.

Line 2 is the looping mechanism, here you can use all variations with count, for etc; but for demo, we are taking simple variable which has all the rules.

Next line 3 is where we present the content, for that we have defined content block inside the dynamic block, which I have shown above.

Then line 4 is inside the content block, here we point the values for each rule. And so, the left hand side or arguments inside are defined by azurerm, not user defined. Coming to right side of it, the values, which are user defined in a variable that we passed to for_each at line 2. Usually we use each.value to use data inside a for_each loop but here instead of each, the name of block is given so it will become security_rule.value if the variable passed is an object then it will have attributes like name, priority which I have shown how to use in above example.

One advantage of this is that you can nest dynamic blocks, due to the each object conflicting about to which for_each loop object it points, we can’t create nested for_each but for dynamic we can do due to the name.

More examples of where we can use dynamic blocks are network rules, managed identity, frontdoor forntends and where ever there is block inside the resource group.

Conditionals with dynamic block

With if (?) you know how to give value to an argument conditionally, with count you know how to create the resource conditionally, now we will create blocks conditionally using dynamic.

It is very easy, we use if(?) and pass no data to iterate on false condition, while we pass the required data only to the true condition. which essentially makes it work only when the condition is true. Let’s understand through an example.

Using dynamic block to run the network_rules conditionally.
using dynamic blocks to conditionally run the block.

Here, In the final example, we are making our network_rules block provided by azurerm dynamic. The whole purpose is that the network rules comes into picture only when the user gives an input true to the variable is_network_required. When it is true, we are passing one value ‘true’ which will run the content block once, while it is false, the content block never runs and the network rules won’t be set.

To maximize the benefit, you can pass the data instead of just a value true, and you can make use of the network_rules.value to access and point the data for network_rules.

Hope you understand the dynamic blocks in terraform, If you have doubts/suggestions please comment below. Happy to help, Happy Infra.

Leave a comment

Your email address will not be published. Required fields are marked *