At my day job, I have been working with HashiCorp’s Terraform. Terraform is a way to achieve “Config-as-code” or “Infrastructure-as-code,” and I Love it!
Setup
As a company grows, it acquires more people, more infrastructure, and new third-party tools, and moves more things to the cloud. Managing changes from many developers to infrastructure or third-party tools can be very difficult. Because of this, it is more important to track changes as well as have the ability to reapply or undo a configuration.
For a simple example, a user wants to change the default font and size for the whole machine, so they go to settings and make the adjustments, and then they realize that they really want to use the accessibility settings. If they go in and enable accessibility along with the zoom, now things are unusable. Now, extrapolating this scenario to many engineers and departments, it can quickly be chaos.
Enter Terraform
Terraform can apply settings to different systems (called transformations), each one using a “Provider” which is coded in Golang by HashCorp themselves, by the developer of the service (PagerDuty, AWS, Microsoft Azure), or by the developer community. The configuration uses HCL, HashiCorp Configuration Language.
Since we now have configurations stored in a file, we can add them to source control. From here we can do a lot of things:
- History of changes and by whom
- Undo changes
- Have review process
- Automatically apply a transformation
What is in a transformation
Since each provider has different commands, the usual way a developer works with Terraform is by having the provider’s registry as they code the configuration.
The key commands are provider, resource, data, and variable.
“Provider” specifies the connection properties: API Token or User/Password.
“Resource” is a new resource we are adding and want to manage with Terraform. Removing the managed resource from the .tf file will delete it from the provider.
“Data” is used for resources that already exist in the provider, but we want to get some data from them.
“Variable” is used exactly like one, with a description and a default value.
A key feature of Terraform is that it is idempotent, meaning, that if a transformation is applied but has no changes, nothing happens.
For example, the PagerDuty has commands to add users, teams, services, and many more items, each of these takes different parameters. So by going to PagerDuty’s Registry, and based on this, the developer knows what they need to create it. See the below example of a simple “main.tf” for PagerDuty:
Simple PagerDuty transformation
How to run Terraform
Terraform is just one executable that runs on PowerShell or “command prompt,” there’s no installation process per se, but having an environment variable with the path to the executable is highly recommended.
There are a few file types with Terraform, but the main ones to work on are .tf and .tfvars. There is another, very important file called “statefile” which I will mention below.
.tf files are where the actual configurations go. Something neat thing is that Terraform loads all .tf files regardless of the name, so the organization is up to the developer. Anything goes!
.tfvars files have dictionary-style values: key-value. for values that change per environment or secrets that should not be shared, so, these files should not be source-controlled.
Similar to .tf files, .tfvar files are loaded automatically as long as the file name starts with “terraform” or has “auto” in the file name. There is a hierarchy in which Terraform loads the values from .tfvars that also takes into account any command-line parameters.
What to watch out for
Within Terraform, there is something called “statefile.” This file is what it uses to know what changes are applied and what the current state is. The caveat here is if a change happens without using Terraform, the statefile would remain unchanged, and on the next run, Terraform will change that setting back to what the statefile says, overwriting the intended setting.
Everything Terraform does is based on the statefile, so it is very important to protect this file by preventing unauthorized changes, locking the file, and storing the file in an AWS S3 bucket, Artifactory, or some other mechanism.
Conclusion
Config-as-code ideology has been growing a lot because of cloud services. The more things we have as code, the better. It’s easy to track changes, reapply if needed, know who made the changes, etc.
Starting early with Terraform to configure things can help keep control of changes. Besides, it’s easy to set up and run. Terraform all the things!
Leave a Reply