What is Terraform?
In this post, I want to speak about Terraform and how it's used nowadays.
This post will cover some core points of Terraform. So let's get started.
There are a lot of infrastructure as code tools to describe resources in a code:
- Terraform
- Pulumi
- CDK options
- AWS CloudFormation
- Ansible
On the Internet, you can find all the use cases and pros/cons for every option. But let's stick with Terraform in this post. Let's discuss some positive points of Terraform and why you need to use it:
- deploy infrastructure as a code quickly and confidently
- support all major cloud providers
- dry runs with terraform plan
- you can use modules for repeated parts of your infrastructure
- easy setup and learning curve
Let's create our first main.tf file and describe the main points. I will be using AWS provider here, also as Terraform recommends we will be using the remote state file in S3.
What is a state file?
A state file is a JSON file, that describes the existing infrastructure. Our first file will be looking this way:
Here we define our AWS provided, region, and S3/DynamoDB for our remote state.
We use DynamoDB for state locking if we want to collaborate with other developers and prevent concurrent operations at the same time.
Our S3 and DynamoDB resources are looking this way:
All the needed fields for Terraform resources are going from official Terraform documentation.
To check if we have a state stored in S3, let's double-check our bucket:
It's there, we can also open this file and check if all the created resources are there.
So now, let's create something interesting by using Terraform features.
There are core components of your infrastructure:
- Variables - here we can replace the hard-coded value with a required reference. Please see an example in our configuration. Let's add some variables:
- Outputs - we can see the information about our infrastructure as a CLI output, or we can reference the outputs between different components in our file.
Then we can use the command: terraform output to show all our outputs.
- Locals - we define a name with an expression, so we can reference it anywhere in our infra. Here is a tag example:
- Data - you can use reference external resources. Let's presume we have already created the KMS key in our AWS account. How to reference it in Terraform?
Data to the rescue. Here we define the data source:
Then we add encryption to our S3 bucket:
After terraform apply we can confirm that KMS is added to S3 bucket:
- Using Tfvars files - we can reference different input variables when using terraform plan and apply commands. It is useful when we have difference input variables/different environments.
So when we want to reference it in my configuration I would use this command:
terraform plan -var-file="./config/dev.tfvars"
For applying the plan I would paste: terraform apply -var-file="./config/dev.tfvars"
It's worth mentioning to use this good practice when using plan/apply commands. Sometimes when we use those commands, our infrastructure can be changed. For this case we would use:
terraform plan -out tf.plan and terraform apply tf.plan
Now we are sure we are applying the needed plan, which is in tf.plan file.
Also, I want to mention some useful snippets for validation. To check if our Terraform files are correct, we can use a run checking with terraform validate. Usage of this command you can find here: https://developer.hashicorp.com/terraform/cli/commands/validate
To rewrite the Terraform infrastructure to the correct format or style we can use: terraform fmt. Usage is described here: https://developer.hashicorp.com/terraform/cli/commands/fmt
OK, let's go to our main folder and s3.tf, we will add two S3 buckets. In our first example, I would use a random integer resource and generate a unique name for a bucket. The second example is showing how to use Terraform CLI workspaces (not Terraform Cloud workspaces) while generating unique names or tags.
To check the current workspace we can run terraform workspace list. From the beginning, we have only one workspace with a name default.
Using Terraform Console
Another great feature is Terraform console where we can evaluate our expressions. More you can find here: https://developer.hashicorp.com/terraform/cli/commands/console
So let's use it for our repo, here we can find out the name of a current workspace and our local tags:
Terraform Modules
The last thing I want to cover is Terraform Modules. It is a collection of configuration files in a specific directory. More here - https://spacelift.io/blog/what-are-terraform-modules-and-how-do-they-work
Let's add the official VPC module from Terraform registry:
https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest
Once we deploy it, we will have our running VPC. You can change the values of a module, to use your values. Apart from that, you can add additional input from a module page. After adding a module, we need to run terraform init.
Also, if we want to destroy just the added module, we can run terraform destroy -target module.vpc -var-file="./config/dev.tfvars".
That's all I wanted to cover.
Thank you for your time and happy Terraforming!