Terraform Explained in Detail

Terraform is Infra Building and Managing Tool on cloud platform
Terraform Installed on Machine.
Ansible, Chef, Pupper etc were designed for OS level configuration but Terraform is Infra level building.
Teraform was prepared by Mitchell HashiMoto and launched by Hashicorp in 28 July 2014.
Terraform is Open Source.
Terraform script is written in HCL language.

Terraform communicate with Cloud Provider through API

Terraform configuration file is written in .tf format

We create a .tf file and run it
First download Terraform on EC2 server using the link https://www.terraform.io/downloads
To check If Terraform has been installed..run command Terraform version.

Example:
create a file by command ….vim aws.tf
eg:
provider “aws” {
region = “us-west-2”
access_key = “AKIA5IIQ3TJPQBDYIS7Y”
secret_key = “9fHyLwgqQmvUQ4+4Eohn4YkiyVaED3b2wGSDMk7T”
}
resource “aws_instance” “test” {
ami = “ami-0cea098ed2ac54925”
instance_type = “t3.micro”
tags = {
Name = “HelloWorld”
}
}


Commonly used Terraform commands:

 init          Prepare your working directory for other commands
validate    Check whether the configuration is valid
plan          Show changes required by the current configuration.It is blueprint of the changes that would happen when apply is executed.
 apply         Create or update infrastructure
 destroy       Destroy previously-created infrastructure

All other commands:
  console       Try Terraform expressions at an interactive command prompt
  fmt           Reformat your configuration in the standard style
  force-unlock  Release a stuck lock on the current workspace
  get           Install or upgrade remote Terraform modules
  graph         Generate a Graphviz graph of the steps in an operation
  import        Associate existing infrastructure with a Terraform resource
  login         Obtain and save credentials for a remote host
  logout        Remove locally-stored credentials for a remote host
  output        Show output values from your root module
  providers     Show the providers required for this configuration
  refresh       Update the state to match remote systems
  show          Show the current state or a saved plan
  state         Advanced state management
  taint         Mark a resource instance as not fully functional
  test          Experimental support for module integration testing
  untaint       Remove the ‘tainted’ state from a resource instance
  version       Show the current Terraform version
  workspace     Workspace management

Terraform Resource configuration Example

Create instance, Default VPC, SSH key, Secuity groupprovider “aws” {
  region     = “us-west-2”
  access_key = “xxxxxxxxxxxxxx”
  secret_key = “xxxxxxxxxxxxxxx”
}

resource “aws_instance” “foo” {
  ami           = “ami-005e54dee72cc1d00” # us-west-2
  instance_type = “t2.micro”
  key_name      =”techcurious”
  vpc_security_group_ids =[aws_security_group.techcurious.id]
    }
resource “aws_key_pair” “deployer” {
  key_name   = “techcurious”
  public_key = “ssh-rsa xxxxxxxxxxxxroot@ip-172-31-32-25”
}
resource “aws_default_vpc” “default” {
  tags = {
    Name = “Default VPC”
  }
}

resource “aws_security_group” “techcurious” {
  name        = “techcurious”
  description = “Allow TLS inbound traffic”
  vpc_id      = aws_default_vpc.default.id

  ingress {
    description      = “TLS from VPC”
    from_port        = 443
    to_port          = 443
    protocol         = “tcp”
    cidr_blocks      = [“0.0.0.0/0”]
    ipv6_cidr_blocks = [“::/0”]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = “-1”
    cidr_blocks      = [“0.0.0.0/0”]
    ipv6_cidr_blocks = [“::/0”]
  }

  tags = {
    Name = “allow_tls”
  }
}
How to create AMI using Terraform from Snapshotresource “aws_ami” “example” {
  name                = “terraform-example”
  virtualization_type = “hvm”
  root_device_name    = “/dev/sda1”

  ebs_block_device {
    device_name = “/dev/sda1”
    snapshot_id = “snap-0fe45a80736ee3525”
    volume_size = 8
  }
}
Copy ami to anaother regionprovider “aws” {
  region     = “ap-south-1”
  access_key = “AKIA5IIQ3TJPQBDYIS7Y”
  secret_key = “9fHyLwgqQmvUQ4+4Eohn4YkiyVaED3b2wGSDMk7T”
}

resource “aws_ami_copy” “example” {
  name              = “terraform-example-copy”
  description       = “A copy of ami-xxxxxxxx”
  source_ami_id     = “ami-0f8b5c8a48d8424ca”
  source_ami_region = “us-west-2”

  tags = {
    Name = “HelloWorld”
  }
}
copy ami from instanceresource “aws_ami_from_instance” “example” {
  name               = “terraform-example”
  source_instance_id = “i-xxxxxxxx”
}
Modify ami permissionresource “aws_ami_from_instance” “example” {
  name               = “terraform-example”
  source_instance_id = “i-xxxxxxxx”
}

Terraform Variable

Variable–When the values assigned to resources frequently changes, we can use variables.
Steps in Creating Terraform Variable:
First we have to define variable
Then we have to call variable
Variable examplevaraible “Instancetype” {
Default=”t2.small”
}
How to map variable to resolurcceresource “aws instance” “new”
ami =var.image
instance=var.instancetype
How to create separate variable fileBoth resource file and variable file should be under same folder if a separate variable file is created. Terraform automatically picks up variable file
Creating a separate variable filevim variable.tf
variable “instancetype” {
default=t2.micro
}
variable “image” {
image=abbcvd
}
tarraform apply
To have variable value define in terminal remove default values variable “instancetype” {
}
variable “image” {
}
tarraform apply 
We can have variable and value in different files.Value file should always be terrafor.tfvars.
Variable file canbe named anyting.

If you don’t want to get desired value, you can keep the values as blank in .tfvars file, this will then take the default value from the variable file.
vim terraform.tfvars

instancetype=t2.nano
image=abcdef

Variable Example

List Variable Example

provider “aws” {
  region     = “ap-south-1”
  access_key = “xxxxxxxx”
  secret_key = “xxxxxxxxx”
}

variable “instancetype” {
 type= list
 default =[“t2.micro”,”t2.medium”,”t3.small”]
}
resource “aws_instance” “dev-team” {
  ami           = “ami-06489866022e12a14”
  instance_type = var.instancetype[0]

  tags = {
    Name = “dev-team”
  }
}
resource “aws_instance” “test-team” {
  ami           = “ami-06489866022e12a14”
  instance_type = var.instancetype[1]

  tags = {
    Name = “test-team”
  }
}
resource “aws_instance” “prod-team” {
  ami           = “ami-06489866022e12a14”
  instance_type = var.instancetype[2]

  tags = {
    Name = “prod-team”
  }
}

Map Variable Example

Count Parameter:

resource “aws_instance” “dev-team” {
ami=”ami-abcded”
instance_type=”t2.micro”
count=3
}
tags={
Name=”dev.$(count.index)
}

This will create instance as This will create tag as

1st tag–dev0
2nd tag–dev1
3rd tag-dev2

List with Count Variable

example-
provider “aws” {
region = “ap-south-1”
access_key = “xxxxxxxx”
secret_key = “xxxxxxxxx”
}

variable “instancetag” {
type =list
default =[“dev-dep”,”test-dep”,”prod-dep”]
}
variable “instancetype” {
type =list
default=[“t2.small”, “t2.nano”, “t2.medium”]
}
resource “aws_instance” “dev-team” {
ami = “ami-06489866022e12a14”
instance_type =var.instancetype[count.index]
count =3

tags= {
Name=var.instancetage[count.index]
}
}

This will assign the default values mentioned in list by sequence.

Terraform condition statement

Count parameter is used to set conditions.

Example

In the below example we define a variable named input and do not assign any values and then use the count parameter to set the condition statement to create the resources.

In the above example, in the statement count =var.input==”dev”?1:0 if the value of variable input is “dev”, then the condition is set to create 1 instance and if not dev, then no instance.

Example : Setting condition statement with greater than operator

In the above example the condition is like, if the variable input value is greater than 2, then create 4 instances else create no instances. Similarly we can set conditions using operators mentioned below
count =var.input>=”2″?1:0 (greater than and equal)
count =var.input<=”2″?1:0 (Less than and equal)
count =var.input<“2”?1:0 (Less than)
count =var.input!=”2″?1:0 (not equal)
count =var.input!=””?1:0 (what if variable value is not entered)

Local Value in Terraform

Using Local Value, we can define tag once and call it for number of resources.

provider “aws” {
region = “ap-south-1”
access_key = “xxxxxxxx”
secret_key = “xxxxxxxx”
}
locals {
comman_tag ={
Name =”UK-Project”
owner =”Rajeev Mishra”

}
}

Example: How to use Local Value.

Terraform Output Values

To see the information of resources without login to console, instead of running Terraform apply we can run Terraform output to see the outputs.

Syntax is

Output “instance_ami” {
value=aws_instance.web.arn
}
terraform output
tarraform output-json (to see the output in Json format)
We can create a separate file for output as well in same folder.
we can see the output value on terraform apply command or on terraform output command.
To see specific output only
example-
terraform output instance-cpu
terraform output instance-arn
terraform output instance-arn
Output Example-
terraform output -json (to see the information in json format}
If you do not want to show any particular information in output,mark it as sensitive.
eg:
output “instance-arn”
value=aws_instance.web.arn
sensitive=true
}

Terraform .tfstate file:

Whichever folder has .tf resource file, in same folder .tfstate fill will be created.
Once resources are updated in .tfstate file, it creates a backup of previous file terraform.tfstate backup.
Use case of .tfstate file
When we apply Terraform apply , it searces .tfstate file and if it did not get any resource details it considers the resources are fresh and it creates new resouces.
When terraform.tfstate file is there, it compares with that file and for any new resources creates a new terraform.tfstate file and creates backup.
Terraform.tfstate fill is in json format and contains all the proviosioned resource information and can be shared with any one who wants to know the resources
terraform.tfstate file will contain information regarding all the resources–it is in json format and can be sent to whomever want to know the resources.
terraform.tfstate file is stored on local folder, but if multiple people are working on the project,–then solution is to create a shared folder and upload .tfstate file there.or create a repository in Gitgub and push .tfstate file there.
Hasicorp provided the solution that .tfstate file can be stored in hasicorp storage.–Terraform enterprises cloud or AWS 
Best recommended option is s3 Storage on AWS cloud as it has versioning control, Locking with the help of dynamodb table and security.
How to keep .tfstate file to cloud storage
terraform {
  backend “s3” {
    bucket = “mybucket”
    key    = “path/to/my/key”
    region = “us-east-1”
   access key:
   secret key;
 Dynamodb_table:”table name”
  }
}

Terraform Provisionar: Application provisioning through terraform.

Provisoner always needs to be defined under resource parameter.

Syntax example:

Types of Provisioners:
Local-exec provisioner
When we want to execute the command on local system
remote-exec proviisionerCommand which we need to run same location where we are running resource file eg AWS Cloud
Command we want to execute on remote system. Need to define connection as well in remote-exec provisioiner.
File proviosionerTo copy file from local system to remote system.
In remote system, file will be copied only in destination/temp. Need to define connection as well in file provisioiner.

Vendor Provisioners–Chef, Puppet, Habitat, Salt states -supported by Terraform Provisioners which can define during setting up resource files

Example of Local-exec provisioner.

Please note when we are using Local-exec provisioner we still need to create remote-exec provisioner and establish a connection or else the local-exec provisioner will not execute.

Packers:

Packer is built by Hashicorp. Packer is built to use system AMI.

Advantages of Packer:

If AMI is saved, any new server with same configuration can be configured quickly.

Packer can be used to create image for the multiple platforms using single configuration file.

How does Packer Works:

Packer can be configured in Json and Hasicorp.

Main components of Packer Json file are builders and provisioners.

Builders– Contains the instance type details, Source image , Destination image etc.

Provisioner–Contains the configuration to be done inside the instance.

Once the image is created, instance is terminated.

In the same configuration file, we can define to create image for AWS, Azure, GCP etc.

To check for any error in the packer JSON file, use the command packer validate filename.json

To build the AMI, run the command packer build filename.json

syntax example

vim test.json

“builders”:[
{
“type”:”amazon-ebs”,
“access_key”:”AKIA5IIQ3TJPQBDYIS7Y”, “secret_key”:”9fHyLwgqQmvUQ4+4Eohn4YkiyVaED3b2wGSDMk7T”
“region”:”ap-south-1″,
“source_ami”:”ami-06489866022e12a14″,
“instance_type”:”t2.micro”,
“ssh_username”:”ec2-user”,
“ami_name”:”techcuriousami”
}
]

Be the first to comment

Leave a Reply

Your email address will not be published.


*