Terraform is a really useful tool when it comes to learning cloud engineering. In my opinion Terraform will become as ubiquitous for infrastructure provisioning as tools like git are for version control.
Today we’re going to talk about the 6 key fundamentals topics you need to know in order to get working with Terraform quickly. We won’t be covering the concepts in great depth (a good thing!) but we’ll just enough so that you’re aware of what the concept is and how it works before you go diving deep.
By the end of this article you’ll be aware of the 6 key concepts of Terraform, everything from the language to how to structure your files.
Prefer To “Watch” This Article?
What is Terraform?
Terraform is a client-based stand alone infrastructure as code (IaC) tool (not familiar with IaC? read this article first). What do I mean when I say client-based? Let me explain: Terraform is installed and ran from a machine that you own, rather than a hosted solution. This is an important distinction as tools like CloudFormation are ran on someone else’s infrastructure.
Terraform is also a declarative technology. But what do I mean by declarative vs imperative? A declarative tool means you specify (read: declare) what target end state you desire and then terraform works out how to do it. Other infrastructure as code tools often work in a non-declarative way, expecting you to specify both what you want and how to do it.
Why should you learn Terraform?
Before we get into what Terraform is, let’s understand why it’s important that you understand Terraform.
Terraform will help you learn other cloud tools — I seriously encourage experimenting with tooling in order to learn them best. I find working with Terraform an easy way to experiment with cloud tooling whilst being able to track of what I have done, and delete everything when I’m finished. Which ensures I’m not left with any nasty surprises, like unexpected large bills!
Learning infrastructure will make you a better engineer — If you’re an applications developer, I think learning infrastructure is a great opportunity. Many things can be done at an infrastructure level that can’t be done at an application level. So getting to know the infrastructure tools you have at your disposal can really help your ability to implement solid technical solutions.
Terraform is the best current provisioning tool — Terraform is the best tool in its category of infrastructure provisioning tools. I won’t cover why that is today, we’lll leave that subject for a whole article. Nonetheless if you’re going to invest in learning a tool it’s important to make sure that tool is going to be around for a long time, and with Terraform you get that assurance.
The Main Features To Know About Terraform
First up I want to explain why we’re talking about these 6 concepts. When it comes to learning a tool like Terraform, wouldn’t we be better off simply diving in and writing some code? And the short answer is: no.
If you take the time to be aware of these 6 main concepts then learning Terraform will be very easy for you. If you simply dive in to the deep, you’ll only end up wanting to understand these concepts when you’re already in the thick of learning.
So, what are the fundamentals we’ll be covering today?
- The Language — The basic structure of the language of Terraform, Hashicorp Configuration Language (HCL) and how we configure and create resources using the language.
- Planning & Applying — Plans are how Terraform knows what changes to make. Using the
terraform applycommands we can safely make infrastructure changes.
- State — How Terraform knows the infrastructure that we want to manage and change. We discuss how it’s created, updated, stored and more.
- Dependency Resolution — How Terraform uses dependency graphs to know the order to create our infrastructure.
- File Structure — How we should structure our Terraform code and our project layouts.
- Providers — How Terraform hooks into the third-party tooling that we want to create our infrastructure in/on.
These are the main feature’s we’ll cover, let’s get to it.
A Tiny Terraform Example
Before we get into the features, I wanted to show you a basic Terraform example. The above code in Terraform would setup Terraform, give it a configured version, setup an AWS provider and create an S3 bucket in AWS.
This is pretty much the smallest “hello world” type script you can write in Terraform. But anyway, with this example as a reference, let’s step through all the nuances that make this little example snippet work!
1. Terraform’s Language (HCL)
An example format of Terraform code.
The first thing to understand about Terraform is the syntax.
The above snippet shows how most resource code blocks within Terraform look, if you understand this basic structure reading Terraform becomes a breeze.
- Command — If you’re creating a resource, your command will be the keyword
resource, which tells Terraform you want to create a resource.
- Provider Resource Name — The first argument is the type of resource that you want to create, could be an EC2 instance, an S3 bucket, a database, etc. These resource names are given by the provider you have configured. If you have AWS configured, you’ll be able to pass AWS resources as this argument. If you have GCP configured you’ll be able to make GCP resources. Resources are usually namespaced based on their provider, i.e
aws_instanceis an instance resource from the AWS provider.
- Resource Name — The second argument is the name of the resource you’re creating. The name is important as it’s used later when referencing your resource. The name is pretty much up to you.
- Options — And lastly the options. Options in the code block again are defined by the provider. You only need to specify details related to the resource you’re creating.
And really, that’s it for the Terraform syntax. Pretty much all of Terraform is written in these code blocks, so you’ll get used to it pretty quick. But master the basic structure and you’re off to a flying start.
2. Planning & Applying
An example output when running Terraform plan.
The two most important commands you should know when working with Terraform are
terraform plan and
Working with Terraform pretty much consists of running
terraform plan and
terraform apply a whole bunch of times.
terraform plan will compare the code you’ve written with your state to check for changes. It’s a dry run, and it’s totally safe, nothing happens because of it. Terraform will output a delta, which shows you which resources will be destroyed (marked with a
-) which ones will be added (marked with a
+) and which ones will be updated in-place (marked with a
When you are happy with the changes that
terraform plan emits you can go ahead and run
terraform apply which will then execute those changes.
An example snippet of Terraform State (Source)
The second biggest concept to wrap your head around when it comes to Terraform is the idea of state. Terraform, since it’s a client-based application needs to keep a track of the resources it creates. And it does this through the concept of state, which you can think of like a database. Every time you update your infrastructure, Terraform updates your state file.
A state file is simply a JSON file listing the name, properties and dependencies of your resources. Terraform state by default stores locally, it literally creates a file called
terraform.tfstate. But you can also use what Terraform calls a backend and push the state file into a remote location. A remote back end is pretty much just that same JSON file, but on a server.
You don’t need to overthink state, it’s really that simple.
4. Dependency Resolution
Example output of
terraform graph command (dependency tree)
Whe we’re building infrastructure we’re often creating many resources at the same time, that all depend on each other. A unique and great feature of Terraform is how it manages to work out which of your resources depend on each other and therefore how to make an execution plan that will update resources in the correct order.
In order to ensure resources are created in turn, Terraform creates a graph, which can be seen if you run the
terraform graph command. The nuances of how Terraform makes and uses the graph aren’t relevant. What is relevant is that you can reference other pieces of infrastructure when you require a property of one resource feeding into another. Typically the referencing is done by a concept called interpolation. A typical interpolation looks like this:
Where the format is
Remember this from the syntax in section 1? Resource type comes from the provider, resource name is the name you gave it, and the property is what the provider allows you to reference about that resource.
5. File Structure
An example Terraform file structure.
When you run a Terraform command, such as
terraform plan Terraform will look by default into the current directory only. Terraform will import any file with the extension
tf and run the command you specified. Due to the dependency magic we talked about previously Terraform doesn’t need to include files in any order to just specify files with a
.tf extension in the current directory.
In order to provide an entry point to your Terraform, it’s common convention to have a
main.tf file that provides your base configurations, typically your terraform version and provider details. However, as Terraform imports all
tf files you don’t have to adhere to this standard.
But what if you want subdirectories? Subdirectories are introduced with the concept of Terraform modules. We won’t cover modules in any detail today, just know that you can bundle files into subdirectories when you use them.
An example configuration of AWS as a Terraform Provider.
The last concept we’ll talk about today is providers. Providers have a complicated sounding name for a simple concept. A provider is simply a third-party plugin that acts as a bridge between Terraform and any third-party, such as AWS, GCP, and more.
To configure a provider, as you can see above, the code block is similiar to what we’ve already seen. Just note that this time though we’re using the
provider command, not the
resource command. And instead of a resource type, we’re specifying our provider type.
For instance, in order to provision AWS resources, we’d need to configure the AWS provider. To provision GCP resources we’d need the GPC provider. Or, to have both we can even configure both providers at the same time! Another cool thing about providers is that they can apply to any third-party, which can be other infrastructure tools like stripe or Auth0.
The Terraform Fundamentals in 20 mins
And that’s it! I realise we didn’t cover each area in a lot of detail today, but I did just want to take you through the high level Terraform concepts so that you can now dive in to the technology and get learning, which is the best way.
If you’re keen to learn more about infrastructure as code, be sure to check out: Infrastructure As Code: An Ultimate Guide , and if you’re looking for things like books and courses, check out: Best Resources To Learn Terraform.
Speak soon, Cloud Native friend!