DEV Community

Ali KHYAR
Ali KHYAR

Posted on

Terraform 101 - Part 1/3: History, Workflow, and Resource Addressing | By Ali KHYAR

About Terraform:

Terraform is an open-source Infrastructure as Code (IaC) software tool, which simply means that it enables you to write resource deployment usually for the cloud in a human-readable way. IaC is one of the better DevOps practices that track infrastructure code and deploy it in a repeatable/predictable manner.

Back in 2011 when CloudFormation of AWS appeared, one of the creators of terraform saw the need for an open-source, cloud-agnostic tool that is not bound to one cloud provider, and that has the same functionalities as CloudFormation. The idea of terraform appeared in 2011, but the first lines of Golang code weren't written until July 2014, and version 0.1 only had support for AWS and DigitalOceans.

Terraform uses its own language known as Hashicorp configuration language (HCL), which was created to have both human and machine-friendly syntax, it has a native syntax intended to be pleasant to humans in writing/reading, and it has a JSON based variant that is easier for machines to generate and parse.

Terraform Workflow:

The core terraform workflow has three steps:

  1. write: writing your code.
  2. plan: reads the code and preview changes, basically, it makes Terraform mock what the code will apply. you can do any number of iterations between the write and plan phase.
  3. apply: tell Terraform to provision real infrastructure and update the state file

One other command that you will need to know is: terraform destroy, which looks at recorded, stored state file created during deployment and destroys all resources created, it is a non-reversible command so it should be used with caution.

Terraform Init:

Terraform expects to be invoked from a working directory that contains configuration files written in the Terraform language, and uses configuration content from this directory, and also uses the directory to store settings, caching plugins, and modules, and sometimes state data. Hence, if the working directory wasn't specified we should do so by using the terraform command: terraform init which is like git init for terraform, that downloads modules and plugins (I will cover modules in part 2/3), and sets up the backend for storing terraform state file; a mechanism which terraform tracks resources with. Note that if you run a command that relies on initialization without first initializing, the command will fail with an error and explain that you need to run init.

When initializing the working directory two files appear alongside Terraform configuration files :

  • .terraform: a hidden directory, used to manage cached provider plugins and modules, a record of active workspace, and a record of backend configuration.
  • State data file, if the configuration uses the default local backend. This is managed by Terraform in a terraform.tfstate file (if the directory only uses the default workspace) or a terraform.tfstate.d directory (if the directory uses multiple workspaces).

Terraform Configuration:

A Terraform configuration will always start with like below, which tells Terraform what provider we will interact with and define its config:

provider "aws"{
    region = "us-east-1"
}
Enter fullscreen mode Exit fullscreen mode

in the above configuration the word provider is a reserved keyword that fetches whatever provider is following the keyword which in this case is aws, and between braces, we have the config parameters which help to define the arguments of the AWS provider. The configuration parameters will vary depending on the used provider.

- - - - - - -

The most important thing you'll configure with Terraform is resources. Resources are a component of your infrastructure. It might be some low-level component such as a physical server, virtual machine, or container. Or it can be a higher-level component such as an email provider, DNS record, or database provider. Let's look at the example below which deploys an AWS ec2 instance:

resource "aws_instance" "web" {
    ami           = "ubuntu-focal-20.04-amd64-server"
    instance_type = "t3.micro"
}
Enter fullscreen mode Exit fullscreen mode

resource is a reserved keyword that tells Terraform to consider the block as a resource block, "aws_instance" is a resource provided by terraform provider, every provider is a plugin that implements resource types, for example, to look at AWS visit https://registry.terraform.io/providers/hashicorp/aws/latest, then "web" which can be given any arbitrary name by the user. The parameters between braces are resource config arguments, which in this case we only specified the AMI image and the instance type. If you want or need to go crazy with the configuration check https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance.
- - - - - - -
Another block you need to know about in Terraform is the data source block, The main difference between a data source block and a resource block is that a data source block is fetching and tracking details of an already existing resource, whereas a resource block creates a resource from scratch, look at the following example which stores id information about an already deployed VM:

data "aws_instance" "apache-server" {
   instance_id = "some-random-id"
}
Enter fullscreen mode Exit fullscreen mode

Resource Addressing:

Let's imagine a scenario where you need to call the deployed ec2 instance, you can do that by specifying the resource type which is aws_instance then separated by a dot with the user's arbitrary given name. So in the scenario above, we can reference the resource with aws_instance.web . The same process goes for data sources blocks.

It's recommended that if you want to reference a property of a resource inside of the same resource to use self attribute. take a look at the following example in which in line 18 we reference the IP address of the deployed ec2 instance using self keyword:

- - - - - -
In the next blog, we will talk more about state, variables, provisioners, and modules.

Top comments (0)