DEV Community

ckmonish2000
ckmonish2000

Posted on • Edited on

Terraform 101

Infrastructure as code makes our lives easy by allowing us to deploy our servers by describing the configurations for our infrastructure as code.

When you're setting up your servers you go through a 3-step process i.e

  1. Provision your servers: You create your EC2 instances, S3 buckets etc...

  2. Configure your servers: You install docker or some other software that will help you during the application setup.

  3. Application setup: You setup your app in production or test mode.

All the above steps are time consuming processes hence we can automate each of the above step by:

Types-of-iac-tools

  • Provisioning our infrastructure using tools like terraform or cloud formation.
  • Managing Configurations using ansible or puppet
  • Finally containerizing your application to make sure it runs the same everywhere with docker or vagrant

In this post we'll learn about basics of provisioning tool called terraform.

Terraform is an infrastructure provisioning tool similar to AWS's cloud formation or the serverless framework which allow you to manage resources via code.

Install Terraform

You can setup terraform by downloading a binary file and adding it to your system PATH from here.

Basic Concepts

Terraform has its own language called HCL (Hashicorp configuration language) through which you have describe your infrastructure.

you define all your configs in files that have a .tf extension.

Terraform supports various cloud providers like AWS, GCP and much more in order to manage infrastructure on these platforms terraform has plugins.

plugins are of 3-types:

  • Official - These are plugins created and maintained by Hashicorp eg: AWS, Azure, GCP and etc....
  • Verified - These are plugins created and maintained by Hashicorp's partners like Linode, Digital Ocean and etc....
  • Community - These are plugins built and maintained by the community.

you can learn more about plugins from here

Basic commands

Once you define your config you can create your resources using 3 basic commands in a sequence:

  1. terraform init: This command looks at your config and downloads all the plugins that's required to create and manage your resources.

  2. terraform plan: Before actually creating your resources, you can review the changes that will be made to your infrastructure using this command.

  3. terraform apply: finally running the apply command will create your resources

Creating your first resource with terraform

The first resource we'll be creating will be a file.

So, first create a file with a .tf extension and add the code down below.

terraform local file

In terraform everything is defined as a block and the above image we are using something called a resource block the resource block takes 2 arguments first is the resource type and second is a logical name for your resource.

In the resource type argument the keyword before the _ indicates the provider we are using in this case it's an official provider from hashicorp called local and the keyword after the _ indicates the resource provided by the provider.

another example can be aws_s3_bucket where aws is the provider and s3_bucket symbolizes the S3 feature provided by aws.

Each block expects you to enter a few key value pairs to function,
Here the resource block's key value pair will change depending on the provider and resources being used.

In the above image the local_file provider expects us to pass the filename key which will create a file in the provided path and the content key specifies what content will be added to the newly created file.

No if you run terraform init, plan, apply you'll see a new file created with the name pet.txt with the content hello pets

Using variables

Terraform allows us to define variables and use them in our config file.

you can learn about the variable types supported by terraform here

you can create a variable by starting the block with the variable keyword,

Each keyword block expects you to enter a default value and if required you can enter a variable type.

if you do not enter a default value terraform will require you to enter a default value when you run the apply command.

you can also set a default value by passing the value while running the apply command using the -var flag or you can initialize your variables using a .tfvar file.

You can also export the value for variables as an environment variable.

simple terraform variable

you can use the variable in your config like this var.test

here's a more complex variable for your reference

complex terraform variable

let's access the name of the dog and print it in the console.

You can print values from terraform using the output block and the output block expects you to provide it a value to print.

output terraform

now when you run the terraform apply command you will see the output in your console.

terraform console

Resource Dependency

There are times where we might want to supply the output of one resource as an input to another resource or we might want a resource B to be created after the creation of resource A we can achieve this with resource dependency.

There are 2 types implicit and explicit

Implicit Resource Dependency

We can use the output of one resource to be the input of another by referencing the resource using the resource type followed by the resource's logical name and one of the property that's being returned by the resource.

here in our case, we are using the random provider and resource pet that returns and id.

Implicit Resource Dependency

Now run apply the changes and see what happens.

Explicit Resource Dependency

using references will make your resource implicitly dependent but if you want to explicitly make a resource dependent, we can use the depends_on key in the resource block like in the image below

Explicit Resource Dependency

Now if you have a look at the console the resource time is created first following the petz resource.

res

Terraform Lifecycle

Generally, in terraform most of the time when you make a change the resource block the resource is completely destroyed and recreated.

For example, say that you change the name of the file the file will first be deleted then a new copy will be created but there are times where you might want the old file to be deleted only when the new one is up and running you can achieve that using the lifecycle block.

there are 3 types create_before_destroy, prevent_destroy and ignore_changes

create_before_destroy: when set to true will first create the new resource and then delete the old one.

resource "azurerm_resource_group" "example" {
  # ...

  lifecycle {
    create_before_destroy = true
  }
}
Enter fullscreen mode Exit fullscreen mode

prevent_destroy: when set to true will cause Terraform to reject with an error any plan that would destroy the infrastructure.

ignore_changes: Accepts a list of attributes it should ignore when changed.

resource "aws_instance" "example" {
  lifecycle {
    ignore_changes = [
      tags,
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

These are the basic concepts of terraform which will help you provision and manage your resources.

If you are looking for resources on how to use terraform with cloud providers stay tuned will soon publish how to setup your linode and digital ocean instances using terraform.

Also checkout Getting Started With Terraform on AWS.

Thanks for the read.

Top comments (0)