Terraform Zero to Hero: Part 0

Arko Chakraborti
Technogise
Published in
6 min readMay 31, 2021

You have an application that needs to be publicly accessible. What do you do? Install ngrok, start your application, route it to your local server. Easy right?!

But then you decide to shutdown your system, or maybe there’s a power cut, or maybe the load simply exceeds the abilities of your system. What do you do?
Well, you go to one of the Cloud platforms (...AWS / Azure / GCP / any others, which are all the rage…) and create a lucrative free account. You experiment with basic VM and quickly realise that this can potentially solve your issues. Great!
You spin it up, set up your code and expose it to the internet via the public IP.

But soon you realise that a dedicated database would be a better idea, and you find out that the cloud provider has a solution for that too.
You create a managed database instance, secure it with a user id and password and connect it to your VM.

But wait a second! Your database is publicly exposed. Do you really want that?
Wouldn’t it be amazing if you could keep your VM and DB instances in a local network and expose only your VM? That reduces your contact point with the internet. And we all know how dangerous the internet is.
Cool! Off to creating a virtual private cloud (VPC) then.

Now, what if I told you that in the time you spent reading the above scenario, you can spin up the entire set up defined with simply one command from your terminal?
What if I told you that all the infrastructure you can think of on the cloud can be created, destroyed, modified with a single command? Sounds like a dream right? Well, what if I told you that it’s a solved problem… 🙂

Introducing Terraform

Terraform is an open-source infrastructure as code (IaC) tool that provides a consistent CLI workflow to manage hundreds of cloud services.

Terraform follows a declarative approach to IaC. One simply defines what they want; not how they want it. Terraform processes it and smartly generates a plan of what all needs to be done.

In this “n” part series we will explore what Terraform is, and understand how to work with it. Each part will be accompanied by code. Each part has a corresponding tag on Github.

Terminologies

Before we dive into code, let’s understand a few terminologies around Terraform.

  1. Providers
  2. Resources
  3. Data Sources
  4. Variables (input, output, local)
  5. State file
  6. Meta Arguments
  7. Functions

There are a lot more keywords around Terraform, but these should cover about 90% of our use cases. Let’s briefly go through them

Providers

AWS Provider

Terraform simply provides us with a platform to create infrastructure. It does not automatically enable us to do that.
In order to create infrastructure on a specific cloud platform, we need a tool that can hook on to Terraform. These tools are called providers. They act like plugins to Terraform and enable it to communicate with the cloud platform. The example in the image instructs Terraform 3 things:

  1. The cloud provider to target (AWS)
  2. The default region, and
  3. The local AWS CLI profile to use to communicate with the cloud infrastructure.

This CLI profile needs to have enough permissions for Terraform to work as expected. Terraform will use this profile to spin up the resources.

Thus, if you do not have permission to modify EC2 instances on your profile, you will not be able to do the same via Terraform either. The provider dictates the types of resources and data sources you have access to. More on this later…

Resources

Resources for S3 and DynamoDB table on AWS

Resources are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.

A resource block declares a resource of a given type aws_s3_bucket with a given local name sample_bucket. The name is used to refer to this resource from elsewhere in the same Terraform module, but has no significance outside that module’s scope.
Imagine an analogy to programming, where aws_s3_bucket would be the data type and sample_bucket would be the name of the variable. A lot like int sample_bucket.
To have a more concrete analogy, each resource is like a class. We use the Terraform syntax to set specific arguments of the class, and once done, we get a few attributes in return.

Data Sources

Data sources allow data to be fetched or computed for use elsewhere in Terraform configuration.
Use of data sources allows a Terraform configuration to make use of information defined outside of Terraform, or defined by another separate Terraform configuration.
We can use a similar analogy to programming languages here as we did for resources. aws_iam_policy is the data type; devops is the name of the variable.
Data sources differ from resources in one key way. They DO NOT create any infrastructure. They are strictly used to fetch information. In the image attached, this block in itself will NOT create an IAM Policy, but will simply generate the skeleton. We will need to create a dedicated resource where we pass this data source as input.

Variables

We have 3 types of variables:

  1. Input variables: Sends values to Terraform.
  2. Output variables: Retrieves values from Terraform.
  3. Local variables: Assigns names to an expression.

State File

State files are what Terraform uses to understand the cloud infrastructure.
State files are central to Terraform’s working. This state is used by Terraform to map real world resources to your configuration, keep track of metadata, and to improve performance for large infrastructures. Whenever we make any changes to our Terraform code, it will be compared against the state file and create a diff of what needs to be done.

Meta Arguments

Each resource has its own set of arguments, as defined by the provider. Terraform plugs in some of its own arguments too. It lets us control the behaviour of the resource creation to some extent. Conditions like dependency management, multiple resource instances of the same type etc., can be controlled using the meta arguments. The Terraform language defines several meta-arguments, which can be used with any resource type to change the behaviour of resources. E.g. depends_on, count, for_each, provider, lifecycle, provisioner, connection

Functions

Most programming languages have some functions that are associated with each object, or are available in the standard library itself. Terraform has them too. Functions are further broken down into several types. Numeric, string, collection, encoding, type conversion etc. In the example above, we can see 2 functions being used, lookup and templatefile.
The lookup function searches a map by its key. The templatefile function reads the file at the given path and renders its content as a template using a supplied set of template variables.

We will dive into depth in each one of these parts in the upcoming parts of the series. Watch this space for updates.
Follow me on LinkedIn and Github. Follow Technogise on LinkedIn, Twitter, YouTube, Meetup for more such insights.

--

--