Testing of the Terraform code
Terraform is so good and popular, and community developed so many various providers for it, that it's suitable not only from Infrastructure as a Code (IaC), but also for configuration management. For example, with Zabbix provider, you can almost completely control that monitoring tool, and with Azure DevOps provider, it's possible to offload the control over CI/CD tool into Terraform code!
As a result, Terraform configurations increasing in size, using many different tricks, code practices, etc., that it's becoming necessary to look over TF files in automation mode, i.e. to test Terraform code against errors and styles.
What we have?
In general, I know two the most used methods of testing the Terraform code:
- terraform validate - native approach, which checks developed configuration, BUT WITHOUT ANY REQUESTS to any other systems.
- tflint - 3rd party utility, that's doing approximately the same, plus:
- validation against errors when working with cloud services (for example, if the virtual server size, that you're requesting, indeed exist)
- checks for unused variables and resources
- checks for following of best practices
Despite that, according to description, tflint
should include functionality of the terraform validate
, sometimes the latter is detecting errors, that were not detected by the former.
Below I'm describing, how to use these two approaches and their features in more detailed way.
Using 'terraform validate'
This is a command of the native terraform executable, which assumes that it's supporting all current features of the HCL language. Its convenience also in that you don't need to install\update any of other files - everything you need is already embedded in terraform binary!
Here's the description of functionality provided by terraform validate
:
-
Syntax check: command validates configuration files against syntax errors. If it finds some, it will return error messages with detailed description and location of the problem.
-
Check if all required arguments are exist: verifies if all mandatory arguments for resources and modules are set correctly, including data types and used expressions.
-
Providers existence checks: verifies that all used providers (AWS, Azure, etc.) specified and available.
-
Warning about providers compatibilities: in some cases command can warn about compatibility issues of used providers to prevent potential problems.
-
Modules validation: if you're using modules in you configuration,
terraform validate
will also check syntax and correct usage of all modules.
Before you run terraform validate
, it's needed to download modules and providers you're using in configuration. The most convenient way to do that - terraform init
. Then just run terraform validate
in the same folder - and - ready!
The main disadvantage of this method - is that command does not know, which values are suitable for arguments of various providers and thus does not check them. To overcome this, we will be using tflint
.
Using 'tflint'
Tflint
tool has similar features, but, except of just checking code, syntax, it also can do the following:
- Best practices validation: includes a set of rules, that can help identify potential problems and violation of best practices during development of development of infrastructure. For example, it cat detect the incorrect usage of resources, environment variables, as well as code styling, etc.
-
Custom rules support: you can define your own analysis rules to follow requirements of your specific project or company.
-
Provider support: validates code for various Terraform providers, that's allowing to validate configuration of different cloud services.
-
Reports and formats: can output analysis results in various formats, like plain text, JSON or Checkstyle XML, which simplifies integration with other utilities.
To run the command, do the following steps:
- First of all, of course, download binary and add path to it to the PATH environment variable.
- And then create configuration file
.tflint.hcl
in the same folder with the code. Here's the file that I'm using in my work:
config {
format = "default"
module = true
}
plugin "terraform" {
enabled = true
preset = "recommended"
}
# ====================================================
plugin "azurerm" {
enabled = true
version = "0.24.0"
source = "github.com/terraform-linters/tflint-ruleset-azurerm"
}
Notice the string 13 - you can attach various plugins when needed. Developers offer these native plugins:
- https://github.com/terraform-linters/tflint-ruleset-aws
- https://github.com/terraform-linters/tflint-ruleset-azurerm
- https://github.com/terraform-linters/tflint-ruleset-google
Then, as usual, terraform init
and, finally, two commands:
tflint --init
, to download plugins.tflint
, to execute tests.
You may face the situation (like me), when I'm not always using some variables in modules or configurations. For example - I'm declaring some variable, but not using it later.
terraform_unused_declarations
rule returns error and blocking automation scripts. For such cases tflint
has special exclusion syntax for some rules for a string:
# tflint-ignore: terraform_unused_declarations
variable "dev_be_storage_account_name" { type = string }
Conclusion
That's it, I hope my work will be useful for you.
Testing the Terraform code is important practice because of the following reasons:
-
Confidence in changes: In development, you make changes to the code to add new resources, change parameters, and so on. Testing allows you to make sure that each change does not break the existing infrastructure and the interaction between components.
-
Dependency tracking: Terraform resources can have many dependencies. Testing helps to make sure that changes in one part of the code do not break other parts of the infrastructure.
-
Automation and speed: automated tests can quickly and reliably check code for errors. This allows you to quickly identify and fix problems, saving time and ensuring the stability of the deployment process.
- Hits: 2204