Terraform Basics

Terraform Basics

Introduction to terraform and some of the resources Let's get our hands dirty.

ยท

11 min read

First Step with Terraform

What is Terraform?

Terraform is an infrastructure management tool developed by HashiCorp that lets you provision manage and maintain cloud resources like Servers, Networking, Storage etc. In one centralized set of code.

Terraform is a tool/command line program we run to define and make changes to our infrastructure. Terraform is also a language that defines those changes.

Terraform is not for Configuration Management.

Terraform is used for managing the base infrastructure itself for example creating a server instance and placing it behind LoadBalancer. we cannot change what is inside the server after it is deployed for this we need Configuration management tools like "Ansible"

  • deploy a server, but not what's on it
  • We can think terraform as Setting up blank canvas, but we still need other tools to paint the picture on it.

We just can't provision Cloud infrastructure with terraform but we can also work with Docker and Kubernetes. Isn't it cool? ๐Ÿ˜Ž๐Ÿ˜Ž

Download Terraform in Windows using Chocolatey

Chocolatey is a machine-level, command-line package manage and installer for windows software. It uses NuGet packaging infrastructure and Windows PowerShell to simplify the process of downloading and installing software.

Believe me It is best package management tool for windows I use it a lot and if you are Linux user you should try it once.

Now the command to install terraform software on Windows using chocolatey

choco install terraform

Steps :-

  1. Open PowerShell with administrative permission
  2. Run the above installation code
  3. paas yes in the command line if it asks for while installing.
    And you are Done...

image.png

Check if Terraform is installed or not by getting terraform version

terraform -v

If you don't use chocolatey you have to download the exe file from terraform website and add the path to your environment variable. then restart your system and use it.

Setting up AWS account for Terraform

Terraform need access to your cloud provider to make changes that's why we need to provide Access Key ID and Secret access key to terraform.

It is recommended to create a new IAM user and assign policies to the user and provide Access key and Secret key of this user to terraform. We can also provide credential of our root user but it is not recommended.

After getting Access keys and Secret key just Save them in your environment variable when the terraform needs it Terraform will automatically fetch them from environment variables.

Where to write Terraform Code?

Honestly speaking you can write your terraform code anywhere in your local machine. But it is recommended that you should write your terraform code on same location where your application code reside. Make a folder called terraform there and in that folder write terraform code.

Our first code of terraform

You can give any name to your terraform code file but that must be end with .tf extension.

provider "aws" {
  region = "ap-south-1"
}

resource "aws_s3_bucket" "tf_blog_s3" {
  bucket = "tf-blog-29072022"
}

In the above code we are going to create a resource called s3 bucket with name tf-blog-29072022 on AWS cloud in ap-south-1 region i.e. "Mumbai"

Isn't it simple? Simple code, Human readable?

Terraform in Action

Now we have a code we can now actually try out terraform

terraform init

  • This command must be run from the same directory where your code is written.
  • This command initialize terraform and it will look for any .tf files it can found in local directory.
  • this command pickup the fact that we mentioned in terraform code and automatically install the plugins that terraform is gong to use to talk with Cloud provider.

image.png

Now as we initialize the directory with terraform we can apply our code to make actual changes.

terraform apply

when we run above command it will give the detailed output of what it's going to do and asks for permission to really apply changes or not.

image.png

image.png

To apply changes pass "yes"

image.png

See your resource is created you can double check it by going to AWS console.

image.png

How Terraform works

1. Infrastructure as Code :- Terraform lets us define Infrastructure as code that gives us lots of flexibility on how we do that. We can freely use data from one resource to define another.

2. Execution Plan :- Terraform cannot just go and make huge changes at our infrastructure. when terraform compiles the plan we actually see what terraform is going to change in our infrastructure and we have a chance to decide whether we want that change or not.

Whiteboard (3).png

3. Resource Graph :- Terraform is able to do these things with the data structure known as graph. More specifically it uses a graph called "Directed acyclic graph" sound complicated?
Not its not lets understand this

  • A graph is made up of series of connected nodes like 3 circles connected by lines.
  • In terraform each node is a resource like S3 bucket, Domain Name, EC2 instance.
  • The graph is directed that means there is an order.
  • The graph is Acyclic means that there is no cycle, terraform is not going to create a resource then create another resource and gets back and create first resource again. (ooooh! so much cycling)
  • As compared to real world terraform graphs This graph is nothing. In real world terraform create much more complex graphs

Whiteboard (5).png

terraform plan

  • Terraform plan is a command used to know what will be the output or we can say what are the changes terraform is going to apply.
  • This command does not actually apply the changes but just show us what is going to be done.
  • This commands checks for the state that we desired and what is the actual state.

we can actually save our plan output in a file with extension .plan for this we need an option -out

terraform plan -out=example.plan
This plan file is just binary file we cannot directly see the content of file but we can use command terraform show example.plan to actually inspect the content of file.

terraform state

While working with terraform we must listen a word called state and we want to know what is exactly state is? so lets get into this.

  • As the name suggest state is nothing but the actual state of our infrastructure which is saved in ".tfstate" file in our local system.
  • This file is generated first time when we apply our code.
  • Every time when we change our resource via terraform the desired state is matched with the state file and if any thing is different is desired and actual file terraform changes that.

If we want to display the state file in our command ling we can run terraform show this command display our state file data.

Just a personal tip :- Just do not mess with state files, just not, if you are beginner ๐Ÿ˜ฃ

terraform graph

Terraform builds a graph as part of its plan we can actually get some insight what's going to happen by exporting that graph and rendering that visually

command to generate this is terraform graph

image.png

Take a look at the output this syntax id known as "dot" for "Dot file it is a common way for defining graphs. If you understand dot file you can easily understand the graph.

If you are not familiar with dot file syntax you need some visualizer to visualize the graph. For this we can use webgraphviz.com it is pretty simple to use.

image.png

Just paste the graph code in box and click Generate Graph! you will be presented with nice graph.

terraform apply

  • terraform apply is the important command which actually make changes in the infrastructure.
  • Before actually applying the change terraform display you what is going to change in your infrastructure and also ask for confirmation again.
  • If you are satisfied with the changes pass yes else pass no
  • if we want to just apply the changes without asking use we can use terraform apply with an option terraform apply -auto-approve

terraform destroy

  • this is very powerful command used to destroy the infrastructure created by terraform.
  • this command delete the infrastructure but before deleting it display what this command is going to do and again asks us to actually delete the infra or not.
  • if we do not want any prompt, just want to delete the infrastructure we can use this command with an option terraform destroy -auto-approve

Infrastructure as code

Resources

  • Resources are the building block of terraform code.
  • Resource defines the "what" of our infrastructure. It's the job of terraform to figures out "How"?
  • All resources shares the same syntax. But every provider has slightly different types and options.

Lets take example of our previous code

provider "aws" {
  region = "ap-south-1"
}

resource "aws_s3_bucket" "tf_blog_s3" {
  bucket = "tf-blog-29072022"
}

The first section of our code is not resource it is provider which is necessary to mention in the code so that terraform downloads and install API of mention cloud provider to talk to the provider.

The second section is our resource section. The resource syntax is self explanatory but lets walk through it.

First, we have the word "resource" that's the keyword to tell terraform that we are defining a resource and not a provider (for example).

Next we have resource type in our example it's "aws_s3_bucket" these words are defined by the providers and co-relate to actual infrastructure elements that can be created on AWS

Finally we have the resource name that terraform will going to use for this resource in our example it's "tf_blog_s3"

After the resource name we can give some details to terraform what we are going to create by passing some parameters between two curly braces. In terraform these are known as "Arguments"

Basic Resource Types

Now we have discussed about components and how to declare the resources in terraform now lets look up some of the basics resource types.

1. S3 :-

resource "aws_s3_bucket" "tf_blog_s3" {
  bucket = "tf-blog-29072022"
}

We already talked about S3 resource above

2. VPC:- VPC stands for virtual private cloud, think of it as the network infrastructure that wires our servers together. We do not need VPC for S3 because AWS handles it for us but for most of the resources we need one.

resource "aws_default_vpc" "default" {
  tags = {
    "Name" = "Default"
  }
}

The default VPC resource is it of a special case because it doesn't actually define a resource It just adopts the existing default VPC that AWS automatically created. It is possible to define VPC with terraform

3. Security Groups :- AWS security can function like firewalls. Let's see an example.

resource "aws_security_group" "allow_tls" {
  ingress {
    from_port = 443
    to_port = 443
    protocol = "tcp"
    cidr_blocks = ["1.2.3.4/32"]
  }
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
  }
}

In above example there is an ingress block which defines what ports and protocol to allow in, there is also a cidr_block which lets us define the IP address ranges to allow in.

There is also an egress block which defines what outbound traffic is allowed, In our example ports are set to 0 and protocol is set to -1 which signifies to allow any protocol on any port

4. ec2 instance :- For EC2 server instances the resource name is aws_instance

resource "aws_instance" "web_server" {
  ami = "ami-08df646e18b182346"
  instance_type = "t2.micro"
}

in our example we are deploying a ec2 server called web_server. The ami parameter defines the base image to use to create this server in our example an Amazon linux ami is used. (remember --- ami can be different in different regions). The last parameter in our example is instance_type so that AWS knows how big of server we like.

5. Elastic Ip :- In AWS a static public IP address is called an elastic IP since it can be easily reassigned. In terraform this resources is abbreviated as aws_eip

resource "aws_eip" "web-server-ip" {
  instance = aws_instance.web_server.id
  vpc = true
}

In the above example, we are naming the elastic Ip as "web-server-ip" just to remember it is associated with the server instance we created as web_server, we can also give same name to different resource type it means the name of resource eip can be same as resource web_server because there is no name collision for different resources.

Get ready to scale

Now we know how to create AWS EC2 instance but how do we scale it. I mean what if we need 5 EC2 instance we have to define 5 times the same resource?

The answer is no. We can add an argument called count and assign the number of instance we want.

Lets create 3 nginx ec2 instance

provider "aws" {
  region = "ap-south-1"
}

resource "aws_instance" "nginx_server" {
  ami = "ami-0103c056bcf088d0f"
  instance_type = "t2.medium"
  count = 3

  security_groups = [aws_security_group.nginx_sg.name]
}

resource "aws_security_group" "nginx_sg" {
    name = "nginxsg"
  ingress {
    from_port = 80
    to_port = 80
    protocol = "TCP"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port = 873
    to_port = 873
    protocol = "TCP"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port = 22
    to_port = 22
    protocol = "TCP"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port = 443
    to_port = 443
    protocol = "TCP"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
  }
}

Now here we se we just deployed 3 nginx webserver (ec2 instance) with the help of count attribute

Note:- for this AMI I subscribed AWS Marketplace and accept their terms and condition.

Now, For basics I think it more then enough and that's why I am going to end here. BUT another blog on Terraform advance concept like Terraform variables, modules and Terraform with CI/CD will be available soon.

Just Subscribe for my next blog update. ๐Ÿ˜Š๐Ÿ˜Š

Your comments are precious please put comments and let me know if I can do more with my content. ๐Ÿค—๐Ÿค—

Thank You for Reading ๐Ÿ˜Š๐Ÿ˜Š๐Ÿ˜Š

Have a Great Day :)

Did you find this article valuable?

Support Gautam Jha by becoming a sponsor. Any amount is appreciated!

ย