Terraform - Self Notes
Terraform - Self Notes
THAT TIME.
INVENTED BY MITCHEL HASHIMOTO, WRITTEN IN GO LANGUAGE
TERRAFORM IS USEFUL IN CASE OF MULTI-CLOUD AND HYBRID CLOUD
TERRAFORM USES HASHICORP CONFIGURE LANGUAGE (HCL), IT IS SIMILAR TO JSON BUT EASY AND
HUMAN READABLE.
IAC: INFRASTRUCTURE AS A CODE (IAC) IS THE MANAGING AND PROVISIONING OF INFRASTRUCTURE
THROUGH CODE INSTEAD OF THROUGH MANUAL PROCESS
1. IMPERATIVE 2. DECLARATIVE
IMPERATIVE: APPROACH DEFINES THE SPECIFIC COMMANDS NEEDED TO ACHEIVE THE DESIRED CONFIGURATION
AND THOSE COMMANDS THEN NEED TO BE EXECUTED IN THE CORRECT ORDER
IN MY LANGUAGE: IMPERATIVE KE ANDAR CHEEZE SEQUENCE ME PROPER CONFIGURE HONI CHAHIYE, JAISE
KHANA BANANA FIR KHANA NAKI PEHLE KHANA FIR BANANA WRONG
DECLARATIVE: APPROACH DEFINES THE DESIRED STATE OF THE SYSTEM, INCLUDING WHAT RESOURCES YOU
NEED AND ANY PROPERTIES THEY SHOULD HAVE AND AN IAC TOOL WILL CONFIGURE IT FOR YOU
IT IS IMPORTANT TO UNDERSTAND THE DIFFERENCE BETWEEN CONFIGURATION MANAGEMENT TOOL AND IAC
TOOL:
> ANSIBLE, CHEF, PUPPET ARE CONFIGURATION MANAGEMENT TOOL WHICH MEANS THEY ARE PRIMARILY
DESIRED TO INSTALL AND MANAGE SOFTWARE ON EXISTING SERIES
> TERRAFORM AND CLOUDFORMATION ARE IAC TOOLS WHICH ARE DESIGNED TO PROVISION SERVERS AND
INFRASTRUCTURE THEMSELVES
> YOU CAN USE IAC AND CMT ALLTOGETHER, FOR EG. YOU COULD USE TERRAFORM TO CREATE A NEW EC2
INSTANCE ON AWS, THEN TERRAFORM CAN CALL ANSIBLE TO INSTALL AND CONFIGURE SOFTWARE AND
APPLICATIONS ON THE EC2 INSTANCES
BENEFITS OF TERRAFORM
1. SUPPPORTS ALMOST ALL CLOUD PROVIDERS AND CAN MANAGE INFRASTRUCTURE ON ALL CLOUDS
5. IT IS FREE
INSTALLATION OF TERRAFORM
1. GO TO TERRAFORM OFFICIAL WEBSITE (TERRAFORM.IO) DOWNLOAD TERRAFORM SELECT WINDOWS AND
DOWNLOAD 386 AND A ZIP FILE WILL DOWNLOAD
3. IN THE PROGRAM FILES RIGHT CLICK OF YOUR MOUSE AND MAKE A NEW FOLDER NAME AS TERRAFORM
4. DOWNLOAD WINRAR
5. OPEN THE DOWNLOAD ZIP FILE IT WILL OPEN IN WINRAR THEN CLICK ON EXTRACT TO
6. CLICK ON PLUS SIGN OF C DRIVE AND THEN CLICK ON PROGRAM FILES THEN SELECT TERRAFORM FOLDER
AND CLICK ON OK
on windows_386
PROVIDERS:-
A PROVIDER IS RESPONISBLE FOR UNDERSTANDING API INTERACTIONS AND EXPOSING RESOURCES. IF AN API IS
AVAILABLE, YOU CAN CREATE A PROVIDER. A PROVIDER CREATE A PLUGINN, IN ORDER TO MAKE A PROVIDER
AVAILABLE ON TERRAFORM WE NEED TO MAKE A TERRAFORM INIT, THIS COMMAND DOWNLOAD ANY PLUGINNS
WE NEED FOR OUR PROVIDERS.
2. TERRAFORM PLAN: MAKING A PLAN, WHAT TO DO, WHAT IS THE PLAN, EVEN USEFUL FOR TEAMWORK
3. TERRAFORM VALIDATE: TO CHECK THE CODE IS CORRECT OR NOT, LIKE A DRY RUN COMMAND
1. TERRAFORM INIT:-
THE TERRAFORM INIT COMMAND IS USED TO INITIALIZE A WORKING DIRECTORY CONTAINING TERRAFORM
CONFIGURATION FILES, IT IS SAFE TO RUN THIS COMMAND MULTIPLE TIMES, THIS COMMAND WILL NEVER
DELETE YOUR EXISTING CONFIGURATION OR STATE DURING INIT, THE ROOT CONFIGURATION DIRECTORY IS
CONSULTANT FOR BACKEND CONFIGURATION AND THE CHOOSEN BACKEND IS INTIALIZED USING THE GIVEN
CONFIGURATION SETTING.
2. TERRAFORM PLAN:-
THE TERRAFORM PLAN COMMAND IS USED TO CREATE AN EXECUTION PLAN. TERRAFORM PERFORMS A
REFRESH, UNLESS EXPLICITLY DISABLED AND THEN DETRMINES WHAT ACTIONS ARE NECCESSARY TO ARCHIVE
THE DESIRED STATE SPECIFIED IN THE CONFIGURATION FILES.
3. TERRAFORM VALIDATE:-
THE TERRAFORM VALIDATE COMMAND VALIDATE THE CONFIGURATION FILES IN A DIRECRORY, REFERRING ONLY
TO THE CONFIGURATION AND NOT ACCESSING ANY REMOTE SERVER SUCH AS REMOTE STATE, PROVIDER API
ETC. VALIDATE RUNS CHECKS THAT VERIFY WHETHER A CONFIGURATION IS SYNTATICALLY VALID AND
INTERNALLY CONSISTENT, REGARDLESS OF ANY PROVIDER VARIABLES OR EXISTING STATE. IT IS THUS USEFUL IN
GENERAL VERIFIACTION OF REUSABLE MODULES INCLUDING CORRECTNESS OF ATTRIBUTES NAMES AND VALUE
TYPE.
4. TERRAFORM APPLY:-
THE TERRAFORM APPLY COMMAND IS USED TO APPLY THE CHANGES REQUIRED TO REACH THE DESIRED STATE
OF THE CONFIGURATION OR THE PRE-DETERMINED SET OF ACTIONS GENERATED BY A TERRAFORM PLAN
EXECUTION PLAN.
5. TERRAFORM DESTROY:-
THE TERRAFORM DESTROY COMMAND IS USED TO DESTROY THE TERRAFORM MANAGED INFRASTRUCTURE.
HCL SYNTAX IS BASIC AND SHOULD BE READABLE BY THOSE FAMILIAR WITH OTHER SCRIPTING
LANGUAGES
IT HAS 3 PARTS:
1. BLOCK: - BLOCKS GROUP EXPRESSION, ARGUEMENTS AND OTHER BLOCKS INTO A LABLE STRUCTURE, WHICH
EXTERNAL BLOCKS CAN THEN REFERNECE ITS CURLY BRACKET SYNTAX IS SHARED BY MOST OBJECT-ORIENTED
LANGUAGES
3. EXPRESSIONS: - EXPRESSIONS EITHER REPRESENT OR COMPUTE VALUES THEY CAN BE SIMPLE, SUCH AS A
STRING OR NUMERIC VALUE, OR MORE COMPLICATED, SUCH AS ARTHEMETIC OR LOGICAL EXPRESSIONS.
**********
PRACTICAL:
**********
OPEN GITBASH
$ terraform version
Terraform v1.7.3
$ cd documents/
$ mkdir terraform
$ cd dir1
SO LET’S CREATE HERE .tf FILES IN WHICH WE WILL WRITE OUR CODE (.tf) IS MANDATORY OR ELSE TERRAFORM
CAN’T READ IT
$ vi file1.tf
IN THIS FILE WE FIRST NEED A CODE TO CONNECT WITH US PROVIDER WHICH IS AWS, FOR THAT WE HAVE TO
GO TO TERRAFORM WEBSITE
GO TO GOOGLE TYPE: aws terraform provider : OPEN THE WEBSITE AND THERE RELATED TO AWS ALL
THE WORK CODE WILL BE THERE, LIKE THIS WE CAN SEE ALL PROVIDERS CODES
***************
terraform {
required_providers {
aws = {
source = "hashicorp/aws" #(This will pickup aws related provider from hashicorp website)
:wq
****************
$ ls - a
(we can see there is no file but after we will do init here it will initialize all plugins need for aws)
$ terraform init
output>
$ ls -a
output> .terraform/ .terraform.lock.hcl file1.tf (can see some plugins and files came and these are
hidden files)
$ cd .terraform/providers/registry.terraform.io/hashicorp/aws/5.36.0/windows_386/terraform-provider-
aws_v5.36.0_x5.exe
$ cd dir1
GO TO YOUR AWS ACCOUNT GO IN IAM ROLE CLICK ON USER AND ADD USER > Name it > terraform user
provider "aws" {
region = "ap-south-1" ( can give the region where you want to do work )
}
FOR EXAMPLE:
**************
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
region = "us-west-2"
access_key = "AKIA23YWPX7YRKN5XH4I"
secret_key = "/igxhC7T54ul82SHY0JD4M1ekeYNABS7uUqpJulu"
****************************************
$ terraform plan
$ terraform apply
# NOW WE WILL CREATE AN EC2 INSTANCE FROM THE TERRAFORM SO WE NEED AN AMI ID OF THE O/S ON
WHICH WE WANT TO CREATE
# COPY THE AMI ID OF THE O/S LIKE LINUX / UBUNTU AND THEN OPEN THE VIM FILE1.TF
*****************
ami = "ami-0449c34f967dbf18a"
instance_type = "t2.micro"
tags = {
Name = "server1" #(IF YOU WANT MORE THINGS GO IN THE TERRAFORM ARGUEMENTS
AND USE)
****************************
*********************
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
provider "aws" {
region = "ap-south-1"
access_key = "AKIA23YWPX7Y262MS6VW"
secret_key = "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"
}
resource "aws_instance" "s1" {
ami = "ami-0449c34f967dbf18a"
instance_type = "t2.micro"
tags = {
Name = "server1"
************************
$ terraform validate
$ terraform plan (IT WILL SHOW WHAT WILL HAPPEN WHAT THINGS WILL BE DONE IN + SIGN)
$ terraform apply
$ type yes
OUTPUT>
Apply complete! Resources: 1 added, 0 changed, 0 destroyed (ok the instance is created)
# NOW IF YOU WANT TO CREATE TWO/THREE INSTANCES SO WE JUST HAVE TO ADD IN THE SCRIPT LETS DO IT
$ terraform destroy ( we can even specifically delete the work we will do that later )
***************
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
provider "aws" {
region = "ap-south-1"
access_key = "AKIA23YWPX7Y262MS6VW"
secret_key = "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"
ami = "ami-0449c34f967dbf18a"
instance_type = "t2.micro"
tags = {
Name = "server1"
ami = "ami-0449c34f967dbf18a"
instance_type = "t2.micro"
tags = {
Name = "server2"
}
****************
# NOW WE WILL LAUNCH 3 INSTANCES WITH JUST COUNT SYNTAX IN VIM.TF FILE
***************
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
provider "aws" {
region = "ap-south-1"
access_key = "AKIA23YWPX7Y262MS6VW"
secret_key = "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"
ami = "ami-0449c34f967dbf18a"
instance_type = "t2.micro"
count =3
***************
$ terraform apply
OUTPUT> Apply complete! Resources: 3 added, 0 changed, 0 destroyed (ok 3 instances are created)
-----------------------------------------------------------------------------------------------
$ vim providers.tf
**************
provider "aws" {
region = "ap-south-1"
provider "github" {
token = "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"
*************
$ nano resources.tf
********************
name = "myrepo1"
description = "My repo for terraform"
visibility = "public" }
****************************
$ terraform plan
$ terraform apply
(NOW IF YOU WILL SEE THE GITHUB YOU CAN SEE THE NEW REPO IS CREATED)
---------****---------
VARIABLES IN TERRAFORM
---------****---------
TYPES:
1. INPUT VARIABLES:
input variables in terraform let users specify values when creating their infrastructure.
input variables are declared through "variables" block, but there are many other ways to define a
variable
variables can hold data of different datatypes.
2. OUTPUT VARIABLES
3. LOCAL VARIABLES
3. DESCRIPTION - a description of the variable, this description is also used to generate documentation for the
module.
5. SENSITIVE - a boolean value, if true, Terraform masks the variable's value anywhere it displays the variable.
$ vim variable.tf
**********************
ami = var.os
instance_type = var.size
tags = {
Name = var.name
variable "os" {
type = string
default = "ami-0449c34f967dbf18a"
variable "size" {
default = "t2.micro"
variable "name" {
default = "terraformEC2"
************************
$ terraform plan
$ terraform apply -auto-approve
(YOU CAN SEE A INSTANCE WILL BE CREATED AND THE VALUES ARE PICKED UP FROM OUR VARIABLE)
(THAT MESNS THESE ARE THE SOFT CORE VALUES WE GAVE AND CAN REUSE IT AGAIN AND AGAIN)
-----------------------------------------------------------------------------------------
$ vim resource.tf
****************
ami = var.os
instance_type = var.size
tags = {
Name = var.name
bucket = var.bucketname
**************************
NOW LET’S ADD THE VARIABLE THE VARIABLE FOR THIS IN THE FILE OF VARIABLE
*********************
variable "os" {
type = string
default = "ami-0449c34f967dbf18a"
variable "size" {
default = "t2.micro"
variable "name" {
default = "terraformEC2"
variable "bucketname" {
***********************
$ terraform plan (NOW THE TERRAFORM WILL ASK YOU THE BUCKET NAME AS YOU KEPT THE VARIABLES
ATTRIBUTES EMPTY)
O/P:>
var.bucketname
(YOU CAN SEE THE BUCKET WILL BE CREATE IF I RUN THE TERRRAFORM APPLY)
WHAT IF I RUN THIS COMMAND AGAIN SO IT WILL ASK ME THE SAME LIKE GIVE THE NAME SO IF I WANT TO
KEEP IT HARD-CORE VALUE:
(NOW YOU WILL SEE THE TERRAFORM WILL NOT ASK US THE BUCKET NAME AND WILL SHOW US THE PLAN)
NOW LET’S CREATE A AWS IAM USER WITH THE HELP OF TERRAFORM
$ vim iam.tf
*************
name = var.username
************
***************
variable "username" {
**************
$ terraform plan
$ terraform apply
---------------
OUTPUT VARIABLE:-
---------------
(IF I WANT AN OUTPUT OF ANYTHING LIKE IPADDRESS DNS ETC OF AN INSTANCE OR SOME OTHER SERVICES SO
I CAN USE THE OUTPUT I CAN SEE THOSE THINGS ON THE CLI)
LETS DO AN PRACTICAL ON IT:
**********************
output "IPaddress" {
value = aws_instance.s10.public_ip
**********************
$ terraform plan
o/p:> + IPaddress = 10.0.0.12 (this is the way you can get the ouput)
--
. NOW LETS TRY TO GET THE DNS FROM THE OUTPUT VARIABLE
$ vim out.tf
************
output "DNS" {
value = aws_instance.s10.public_dns
***********
$ terraform plan
+ DNS =
************************
STATE FILE TERRAFORM
************************
State file in Terraform is where Terraform records the information of the infrastructure it has created.
State file is important because it helps Terraform update and manage existing infrastructure instead of
creating new instances or resources.
Advantages of using the state file include updating existing infrastructure and destroying infrastructure
in a controlled manner.
One drawback of the state file is that it records sensitive information, such as passwords, by default.
---------------------
Terraform is an Infrastructure as Code (IaC) tool used to define and provision infrastructure resources. The
Terraform state file is a crucial component of Terraform that helps it keep track of the resources it manages and
their current state. This file, often named terraform.tfstate, is a JSON or HCL (HashiCorp Configuration Language)
formatted file that contains important information about the infrastructure's current state, such as resource
attributes, dependencies, and metadata.
-----------------------------------
-----------------------------------
Resource Tracking: The state file keeps track of all the resources managed by Terraform, including their attributes
and dependencies. This ensures that Terraform can accurately update or destroy resources when necessary.
Concurrency Control: Terraform uses the state file to lock resources, preventing multiple users or processes from
modifying the same resource simultaneously. This helps avoid conflicts and ensures data consistency.
Plan Calculation: Terraform uses the state file to calculate and display the difference between the desired
configuration (defined in your Terraform code) and the current infrastructure state. This helps you understand
what changes Terraform will make before applying them.
Resource Metadata: The state file stores metadata about each resource, such as unique identifiers, which is
crucial for managing resources and understanding their relationships.
-------------------------------------------------------------------------
-------------------------------------------------------------------------
Security Risks: Sensitive information, such as API keys or passwords, may be stored in the state file if it's committed
to a VCS. This poses a security risk because VCS repositories are often shared among team members.
Versioning Complexity: Managing state files in VCS can lead to complex versioning issues, especially when multiple
team members are working on the same infrastructure.
A remote backend stores the Terraform state file outside of your local file system and version control. Using S3
as a remote backend is a popular choice due to its reliability and scalability. Here's how to set it up:
----------------------------------------------------------
----------------------------------------------------------
SO AS WE CAN’T UPLOAD IT ON THE GITHUB BECAUSE THE STATE FILE CONTAINS SENSITIVE INFORMATION LIKE
OUR ACCESS KEYS AND INFRASTRUCTURE DETAILS SO WE DONT WANT TO SHARE THIS WITH ANYONE AND
LOCALLY IT’S NOT A GOOD PRACTICE TO KEEP IT SO THATS WE KEEP IT TO THE S3 BUCKET IN OUR AWS SO IT
WOULD BE VERY SAFE THERE ONLY WE CAN ACCESS OUR AWS AND THE TERRAFORM.TFSTATE FILE
----------
----------
$ terraform version
SO WHEN YOU DO ANY KIND OF APPLY IN THE AWS INFRASTRUCTURE A TERRAFORM STATE FILE CREATES SO
YOU CAN CHECK IT BY
# ls
OUTPUT> terrafrom.tfstate
# cat terrafrom.tfstate > IT WILL SHOW U ALL THE DETAILS ABOUT THE INFRASTRUCTURE YOU
CREATED SO WHEN YOU WILL CREATE THE .tf FILE FOR THE MAKING OF THE INSTANCE THEN YOU CAN DO THE
TERRAFORM APPLY YOU CAN SEE THAT THE .tfstate FILE IS GENERATED AND THEN IT CARRIES ALL THE
INFORMATION IN DETAILS OPEN IT AND SEE.
SO NOW I CANNOT PUSH IT TO THE GITHUB AS THEN I HAVE TO PUSH THE ENTIRE .tf FILE WHICH IS WRONG AS
BECAUSE IT CARRIES THE SENSITIVE INFORMATION
SO THE STATE FILE IS THE HEART OF TERRAFORM AS IF I WILL DELETE THE STATE FILE AND WILL DO THE terraform
apply COMMAND SO IT WILL AGAIN MAKE THE NEW EC2 INSTANCE BUT INSTEAD OF THIS IT COULD SAY THE
INSTANCE IS ALREADY THERE SO THATS WHY STATE FILE IS VERY IMPORTANT.
Storing Terraform state files in an S3 bucket is a recommended best practice because it provides a central location
for storing and managing your infrastructure’s state files.
PRACTICAL:
# WE WILL CREATE THE S3 BUCKET SO THAT WE CAN USE IT WITH THE CONFIGURATION DETAILS TO STORE THE
STATE FILE IN THE S3 BUCKET.
vi main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
terraform {
backend "s3" {
key = "terraform/terraform.tfstate" # terraform is the folder and inside that folder the
terraform.tfstate will be stored
region = "ap-south-1"
provider "aws" {
region = "ap-south-1"
ami = "ami-0449c34f967dbf18a"
instance_type = "t2.micro"
:wq
# NOW WE NEED TO PROVIDE THE AWS CONFIGURATION ACCESS ABD SECRET KEY OF THE IAM USER WHICH
WE MADE TO ACCESS THE AWS
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
# terraform init
# terraform apply
# IF YOU DONT HAVE THE BUCKET THEN YOU HAVE TO FIRST CREATE THE BUCKET THEN YOU CAN USE THAT
NAME OF THE BUCKET WHERE THE STATE FILE WILL BE UPLOADED.
and you backend file will run and the tf.state file will be store in the s3 bucket
SECURING THE STATE FILE ACCESS
*************************************************************************
----------------------------------------
SO IN THE SINGLE TERRAFORM PROJECT THERE CAN BE MULTIPLE DEVELOPERS WORK SO EVERY DEVELOPER CAN
DO THE CHANGES IN THE TERRAFORM INFRA OF OUR AWS SO TO KEEP THAT DATA OF THE TERRAFORM
INFRASTRUCTURE IS AUTOMATICALLY UPDATE IN THE TERRAFORM.STATE FILE SO IT ALWAYS STAYS
AUTOMCATICALLY IN THE LOCALLY MEANS ON OUR LAPTOP BUT TO KEEP THAT DATA SAFE AND SECURE WE KEEP
THAT FILE IN THE S3 BUCKET SO THAT THE DATA WOULD ALWAYS SAFELY STORED.
BUT ANY DEVELOPER CAN MAKE CHANGES IN OUR STATE FILE AND CHANGE OUR INFRA SO THAT IS NOT GOOD
FOR US SO WHAT WE DO FOR THAT # SO WE DO LOCK THAT STATE FILE WITH THE HELP OF THE DYNAMODB
TABLE.
--------------
# WE WILL CREATE A TABLE OF THE DYNAMO DB AN WE WILL LOCK OUR S3 BUCKET ACCESS AND ALSO WE
WILL LOCK THE CHANGES TO OUR INFRA
-------------
PRACTICAL :->
-------------
# GO TO AWS > SEARCH FOR THE DYNAMODB AND THERE U WILL SEE AND OPTION CREATE TABLESO CLICK ON
IT
vi main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
terraform {
backend "s3" {
bucket = "MYBUCKET"
key = "terraform/terraform.tfstate"
region = "ap-south-1"
provider "aws" {
region = "ap-south-1"
ami = "ami-0449c34f967dbf18a"
instance_type = "t2.micro"
count = "3"
:WQ
$ terraform apply
NOW YOUR STATE FILE ONLY YOU CAN ACCESS AND YOU ONLY CAN MAKE THE CHANGES IT IS LOCKED
# GO TO YOUR DYNAMODB TABLE AND IN ITEMS YOU CAN SEE YOUR STATE FILE
# SO OTHER DEVELOPER CANNOT MAKE CHANGES UNTILL YOU WILL REMOVE THIS LOCK