After learning the basics of Terraform from the tutorial, I wanted to know more. What else can it do, and how can I utilize those features in my projects. Having experience with other programming languages, I suspected there are other features, and I went hungry for it.
The Cans and Cants in Terraform
After poking around the documentation and randomly searching for features in the documentation and also in Google, I found the following list of what I can or cannot do. There are more features, but these were the ones I was looking for:
You can
- Use Variables
- Use Loops with dynamic resources.
- Create Modules
- Use Built-in Functions
- Use the Ternary Operator
- Provisioners.
You cannot
- Create user-defined functions.
- Use if statements, although you have alternative tricks.
Note: Please, if you have a feature that you believe is important, let us know in the comment section.
Let’s discuss them a bit
Variables
The usage of variables is covered in the introduction tutorial of Terraform. Nothing is interesting about them. Here is a recap, using them with expressions: https://www.terraform.io/docs/configuration/expressions.html
Loops
On the other hand, using Loops in Terraform can be head-scratching first, but easy to understand, after reading the blog post on the HashiCorp website:
https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each/
I recommend this article better than the documentation itself. It has more examples, and it helps to understand the differences and similarities between looping mechanisms. It also explains the concept of dynamic resources that you need to understand to use loops.
Modules
As far as I know, modules are the only way to support code reusability (other than loops). A module would be an equivalent of creating a function that returns a configured set of resources. The only difference is, it is more complicated to develop since it needs an entire folder and file structure to make it work.
Learn how to do it here: https://www.terraform.io/docs/modules/index.html
Note: If you are aware of any more available tools that support code reusability, please, give some advice in the comment section. I am keen to learn more about it. Thank you in advance.
Functions
Yes, you can use built-in functions, but no, you cannot create a new one for yourself.
When I found out about modules, I was desperate to find a way around that limitation. Fortunately, you do not have to write advanced math in Terraform. Do you? But reusing code to create a complex infrastructure, or just simply to organize your projects into its folders and files, the modules the way to go.
Read more about the available built-in functions on HashiCorp’s website: https://www.terraform.io/docs/configuration/functions.html
Conditional Logic
I cannot imagine a situation in the programming world, where you wouldn’t need conditional logic implemented. You might want to achieve a testing environment where you want to be able to configure for different cost limits. Based on those scenarios, you might want to leave out resources entirely from your desired state.
The If Statement
Yes, the old if statement. The well-known and straightforward feature. That was the first thing I wanted to find. I could not. Unfortunately, if statements are not supported and I do not know if there is a plan to do it any time soon.
The Ternary Operator
We all know the if-else one-liner alternative: the ternary operator. To my surprise, it is supported.
It can be handy if a resource supports the “enabled” attribute. Unfortunately, there are only a few resources that support the “enabled” attribute.
Here is one example: https://www.terraform.io/docs/providers/azurerm/d/app_service.html#enabled
Another use case the terraform community found for it is using with dynamic resources (read more in the Loops section above). The idea is: depending on the input, you return a countable list or map (depending on the use case), or you can return an empty array or map if you do not want to create a resource at all. More simply, if you run a command zero times, it means you will not run it at all. So your resource will not be created. On the other side, you have the option to fine-tune how many times you want a resource to create if it is more than zero.
You can read more about the solution on Stack Overflow linked below, or you can find many blog articles discussing this feature in-depth:
Here is the link for the GitHub issue, requesting native support solving the problem above:
https://github.com/hashicorp/terraform/issues/12906
Provisioners, what are they?
Expressing it with my own words: Provisioners allows you to run code outside of Terraform, to prepare applications on virtual machines. That way, you can run Shell commands (for example, to initiate C++, Python, etc. scripts) depending on resource lifecycle events. At least that is how I interpreted it.
I know, Provisioners is a lot more than that, that is why you should read more about it on Terraform’s website: https://www.terraform.io/docs/provisioners/index.html
To be honest, I wasn’t looking for this feature specifically, but when I came across this, I found the idea of provisioners very useful.
As the documentation states: “Provisioner is a last resort” if you use it, be careful with it.