Hi everyone!
So in my last article , I hope you guys have got an understanding of DevOps and that it is THE future of IT Industry. Today I write this blog to tell you about one of the widely used tool, Terraform by Hashicorp , one of the Infrastructure As Code tool.
Terraform is an open source tool for provisioning infrastructure. Let me simplify it for you. Suppose you have your application ready to be deployed. There are two ways it could be done. One, you go to the Cloud Provider and create the infrastructure that you want to deploy the application. Though this seems better, imagine a scenario where you want to create a 100 resources. Obviously, its going to take so much of your time to create the resources. But what if ,we could create infrastructure by writing the code for it ? Cool right! Not to forget that we can create resource by just by changing the value of the variable. So, if I needed a 100 EC2 instances, I could just change the value in the code, as simple as that. Oh, and the code reusability makes it so much better.
Terraform gets better!!! It has a feature called “idempotency”. Imagine that you created a VPC, subnet and an EC2 instance. But for some reason the EC2 gets deleted ,maybe someone pushed the wrong button in the AWS Console. So I need to create an instance alone. That means that I would have to modify the code accordingly. But terraform makes it easier since it has got the idempotency feature. Since the VPC and subnet are already present , Terraform automatically creates only the EC2 instance for you and everything is back to normal as it was before. We shall talk about the “how” part later on :)
Terraform Files : These are the files that end with .tf extension. It is written using Hashicorp Configuration Language.
Terraform state files: These files have an extension of .tfstate . In the above example, how does Terraform know what are deployed and what needs to be deployed? It is done by comparing the state file. Terraform stores the desirable output ( infrastructure needed by the user) and the actual output (infrastructure that are actually present in cloud).So, if an infrastructure is not present, it automatically creates one so that current state matches the desired state, as if like magic!
Terraform variables files: These files store the variables that are used across the terraform files . It has an extension of .tfvars . These can be used to store the sensitive information like Access Key or Secret key , so that the variables can be referenced and this hides the confidential data.
Terraform File components
- Provider
This keyword helps you to specify the cloud provider of our choice. In case of AWS , the name is “aws”
provider "aws" {//Some code }// provider is the keyword
// aws is the keyword for creating infrastructures in AWS Cloud Platform
2. Variables
These keywords are used to specify variables in Terraform. Here is a sample piece of code. The main file has declared variables-aws_access_key, aws_secret_key in the Main.tf file . But the values of these variables are defined only in the Credentials.tfvars. Hence the sensitive data is not directly accessible.
Main.tf
-------------------------------------
variable "aws_access_key" {}
variable "aws_secret_key" {}provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "us-east-1"
}Credentials.tfvars
--------------------------------------aws_access_key = "AKIA***************"
aws_secret_key = "*******************************"
Note : This method of using “${some-value}” is called interpolation method.
access_key = “${var.aws_access_key}”
In the code snippet above, it means the a variable (used on Right Hand Side as var) called “aws_secret_key” needs to be passed to the access_key (Left Hand Side).
3. Resource
This keywords are used when we want to deploy a resource in AWS . It can be VPC, Subnet, EC2 instance etc.
Main.tf
----------------------------------------resource "aws_instance" "my_ec2" {
count = "${var.ec2_count}"
ami = "${var.ami_id}"
instance_type = "${var.instance_type}"
subnet_id = "${var.subnet_id}"tags = {
Name = "my_first_instance"
}}
The “aws_instance” is the resource to be deployed . The second parameter “my_ec2” is a logical name give to the resource. The arguments are passed as variables. For reference , you can visit terraform registry to know about the required and optional arguments for a resource.
The tags are used to so as to group the associated resources and infrastructures to the same tag. This can help for billing purposes.
4. Data
“data“ keyword is used to fetch the associated data from the cloud provider. Assume that you want to create an instance in a particular region. Hence you will definitely need the ami id of the instance to be deployed. Instead of manually hard coding the values , we use data keyword to fetch the ami id of the instance in that particular region ,so as to use the value in resource block code.
Main.tf
--------------------------------------
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["self"]
//List of AMI owners-self(current AWS account where we have configured the access key and secret key)
}
resource "aws_instance" "my_ec2" {ami = "${data.aws_ami.ubuntu.id}"
//It means the data called aws_ami(used above) has to take the id(AMI id) of the ubuntu instance. instance_type = "t2.micro"
tags = {
Name = "my_first_instance"
}
}
5. Output
The Output variable is used when we want to display a value in CLI or when we want to pass values from child module to parent module. We shall discuss more on it later.
Main.tf
---------------------------------------resource "aws_instance" "ubuntu" {
//some required arguments}output "aws_instance_public_dns" {
value = aws_instance.ubuntu.public_dns}Note: Since interpolation method is to be depreciated ,this is the way to follow.The public_dns is an export value which which we can view through AWS CLI.Since the public_dns is only generated after creation, you can see how it is useful, if ever we want to access the instance using SSH.
Terraform Commands
After we have written some code , we need to execute it . For that we require certain Terraform Commands:
terraform init
This command initializes the directory where the file is present. It downloads the necessary plugins and modules. This needs to be run just once after the code is written.terraform plan
This command is used to determine any kinds of syntax errors in the code. If successful, it shows the resources it is planning to create.terraform apply
This command execute the actions proposed in plan.terraform destroy
This command is used to destroy the resources that were created.This is the lifecycle of Terraform commands. Arguments can be added in these commands as well.
I know it is a lot too much to take in, but now you have a good understanding of Terraform. Next time, we shall take an example to deploy sample resources to the cloud.
Cheers!
Edit : Here’s an awesome article of Terraform that I came across! I had great fun reading it !