What is a terraform ?
1.terraform is an open-source software
tools created by HashiCorp in 2014.
2.Tool used to build, manage and version
infrastructure as code.
2.uses HCL to declare desired state.
2.It is developed by Mitchell Hashimoto
developer.
3.Terraform is written in GO language.
4.It supports declarative configuration
language know as HashiCorp configuration language (HCL).
With the help of terraform we can codify our infrastructure
Infrastructure means our component like EC2, RT, IGW, LB, Autoscaling etc.
Install terraform.
# mkdir /opt/terraform
# yum install wget zip
# wget https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_linux_amd64.zip
# unzip terraform_0.14.5_linux_amd64.zip
# mv terraform /usr/bin
# terraform -v
Terraform v0.14.5
Create user in IAM AWS.
1.User name :- terraform à select programmatic access
2.select à
attach existing policies directly à
AdministratorAccess.
Next à
create user.
Download key.
# aws configure
# AWS Access Key ID [None]:
AKIAWOZL57VN52ILHW22
# AWS Secret Access Key [None]: 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
# Default region name [None]: ap-south-1
# Default output format [None]:
# terraform help
Usage: terraform [global options]
<subcommand> [args]
Main commands:
init Prepare your working directory
for other commands.
validate
Check whether the configuration is valid.
plan Show changes required by the current
configuration.
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.
untaint Remove the 'tainted' state from a
resource instance.
version Show the current Terraform version.
workspace Workspace management.
Global options (use these before the subcommand,
if any):
-chdir=DIR Switch to a different working directory
before executing the
given subcommand.
-help Show this help output, or the help for
a specified subcommand.
-version An alias for the "version" subcommand.
terraform
apply
|
applies
state
|
terraform
destroy
|
destroys
all terraform managed state (use with caution)
|
terraform
fmt
|
Rewrite
terraform configuration files to a canonical format and style
|
terraform
get
|
Download
and update modules
|
terraform
graph
|
Create
a visual representation of a configuration or execution plan
|
terraform
[options] ADDRESS ID
|
Import
will try and find the infrastructure resource identified with ID and import
the state into terraform.tfstate with resource id ADDRESS
|
terraform
output [options] [NAME]
|
Output
any of your resources. Using NAME will output a specific resource
|
terraform
plan
|
terraform
plan, show the changes to be made to the infrastructure
|
terraform
push
|
Push
changes to Atlas, enterprise tool that can automatically run terraform from a
centralized server
|
terraform
refresh
|
Refresh
the remote state. Can identify differences between state file and remote
state
|
terraform
remote
|
Configure
remote state storage
|
terraform
show
|
Show
human readable output from a state or a plan
|
terraform
state
|
Use
this command for advanced state management e.g. Rename a resource
with terraform state mv aws_instance.example aws_instance.production
|
terraform
taint
|
Manually
mark a resource as tainted, meaning it will be destructed and recreated
at
the next apply.
|
terraform
validate
|
validate
your terraform syntax
|
terraform
untaint
|
Undo
a taint
|
Comments line in terraform :-
/*
Line1
Line2
*/
#mkdir terraform
# cat main.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region = "ap-south-1"
}
resource "aws_instance"
"base" {
ami = "ami-04b1ddd35fd71475a"
instance_type = "t2.micro"
}
1.Install plugin like aws.
# terraform init
# ls -la
2.Dry mode command use for check
changes and which resources will creating.
# terraform plan
# terraform plan -help
Plan: 1 to add, 0 to change, 0 to
destroy.
3. apply command use for create
resources then automatic create one more terraform.tfstate.
# terraform apply
# terraform apply -help
# terraform apply
-target=aws_instance.base (single resource target)
All instance details save in terraform.tfstate
file.
# cat terraform.tfstate
"monitoring": false,
"network_interface": [],
"outpost_arn":
"",
"password_data":
"",
"placement_group":
"",
"primary_network_interface_id":
"eni-0472b8f7436e30719",
"private_dns":
"ip-172-31-39-218.ap-south-1.compute.internal",
"private_ip":
"172.31.39.218",
"public_dns":
"ec2-15-206-172-204.ap-south-1.compute.amazonaws.com",
"public_ip":
"15.206.172.204",
4. destroy command for delete resources
and read state file like terraform.tfstate.
# terraform destroy
# terraform destroy -help
# terraform destroy
-target=aws_instance.base (Destroying
Specific Resource)
OR
/*
s3 resource name
*/
# terraform destroy (s3 bucket
delete)
i)terraform.tfstate
ii) terraform.tfstate.backup
5.validate command for check syntax in
template.
# terraform validate
6.fmt command use for arrange format.
# terraform fmt main.tf
# terraform fmt -help
# terraform fmt main.tf
7.providers command use for show
providers plugin used.
# terraform providers
Providers required by configuration:
.
└──
provider[registry.terraform.io/hashicorp/aws]
8.show command use for essay to read
files.
# terraform show
# terraform show
terraform.tfstate.backup
Set the environment
All template create in Defaut
Create a terraform.tfstate.d
1.list command.
# terraform workspace list
* default
2.create a env.
How to create environments DEV, UAT, PROD.
# terraform workspace
new dev
# terraform workspace
new uat
# terraform workspace
new prod
# terraform workspace list
3.show command for currently which
workspace are work.
# terraform workspace show
4.select command for change workspace.
# terraform workspace select dev
5.created one directory terraform.tfstate.d
and three directory dev,prod,uat in terraform.tfstate.d.
# tree terraform.tfstate.d
6. running main.tf and all state file
save in dev directory.
# terraform apply
Do you want to perform these actions in
workspace "dev"?
# ls -l terraform.tfstate.d/dev/
7.taint, untaint command use for
particular resource recreate/changes/any correction.
# terraform taint aws_instance.base
# terraform untaint aws_instance.base
Show to taint status
# terraform show
# terraform plan
Note :- instance rename then apply
command.
apply ke badh taint remove ho jata hai.
Delete hoga fir se create karega.
# terraform apply
1.Terraform State File
1.terraform stores the state of the
infrastructure that is being created from the TF files.
2.This state allow terraform to map real
world resource to your existing configuration.
if manual change a ec2 instance
through aws portal.
# terraform plan (one change show hoga.)
# terraform apply {fir se t2.micro set kar dega.}
2.What is Desired state and Current
state.
i)desired state à
Main.tf (what resource are launch)
ii)current state à terraform.tfstate (what resource are running in aws )
Plan command matching files
desired state == current state
refresh
command use for fetch current status from aws portal and update in
terraform.tfstate file.
Note :-
ec2-instance stop manual and how to terraform fetch status from aws.
To refresh the current state
# terraform refresh
# vim /terraform.tfstate.d/dev/terraform.tfstate
# terraform show
3.terrafrom provider versioning.
4.Types of terraform providers.
i) hashiCorp Distributed :- init command
use install plugin automatic.
ii) 3rd Party :- manual
download plugin and install.
5.Attributes and Output Values:-
i)Many attributes for ec2-instance and
other resources.
# terraform apply
ii) aws_instance.my_machine (show all
attributes)
# terraform apply
6.Referening Cross-account resource
attributes.
Example 1:- EIP and EC2 instance.
2.Example :-
Create a security group and add Elastic IP(other
security group)
7.Terraform Variables :-
Repeated static value can create more
work in the future.
Create one vpc and security group and
set IP variables in security group.
1.create variable file.
# vim variables.tf
2.create main.tf file
Approaches to variable Assignment.
1.Defaults variable.
# cat variables.tf
variable " instancetype" {
default = "t2.micro"
}
# terraform plan
2.command line Flags.
# terraform plan
-var="instancetype=t2.small"
# terraform plan
Note :- Not define default variable then ask to
variable name.
# cat variables.tf
variable "instancetype" {}
# terraform plan
3.From a File (first variable read to
terraform.tfvars file after that default variable read).
Example - 01
# cat variables.tf
variable " instancetype" {
default = "t2.micro"
}
# vim terraform.tfvars
instancetype="t2.large"
# terraform plan
Example – 02
# vim custom.tfvars
instancetype="t2.large"
# terraform plan -var-file=custom.tfvars
4. Environment variable.
# export TF_VAR_instancetype="t2.nano"
Data type of variables :-
# cat main.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
resource "aws_elb"
"test_lb" {
name = var.elb_name
availability_zones = var.az
listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
health_check {
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 3
target =
"HTTP:8000/"
interval = 30
}
cross_zone_load_balancing = true
idle_timeout = 400
connection_draining = true
connection_draining_timeout = 400
tags = {
Name = "test_terraform_elb"
}
}
#cat vaiables.tf
variable "elb_name" {
type = string
}
variable "az" {
type = list
}
variable "timeout" {
type = number
}
# cat terraform.tfvars
elb_name = "myelb"
timeout
= "400"
az
= ["us-west-1a", "us-west-1b"]
# terraform plan
Fetching data from Maps and List in
Variable.
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
resource "aws_instance"
"myec2" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = var.types["ap-south-1"]
tags = {
Name = "dev server1"
}
}
variable "types" {
type = map
default = {
us-east-1 = "t2.micro"
us-west-2 = "t2.nano"
ap-south-1 =
"t2.small"
}
}
# terraform validate
# terraform plan
List use
# cat main.tf
provider "aws" {
access_key
= "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
resource "aws_instance"
"myec2" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = var.list["0"]
tags = {
Name = "dev server1"
}
}
variable "list" {
type = list
default = ["m5.large",
"m5.xlarge", "t2.medium"]
}
}
Count Parameter.
With count parameter, we can simply
specify the count value and the resource can be scaled accordingly.
Example 01 :-
3 instance is create .
Count Index
In resource blocks where count is set,
an additional count object is available in expression, so you can modify the
configuration of each instance.
This object has one attribute:
count.index – The distinct index number
(starting with 0) corresponding to this instance.
Understanding Challenge with Count.
With the below code, terraform will
create 3 instances. But the problem is that all will have the same name.
count.index allows us to fetch the
index of each iteration in the loop.
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
resource "aws_instance"
"base" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = "t2.micro"
count = 3
tags = {
Name = "dev
server_${count.index}"
}
}
Output Instance name numbering like
:-
dev server_0
dev server_1
dev server_2
multiple name add in instances.
Output like :-
+ "Name" = "dev-server"
+ "Name" = "stage-server"
+ "Name" = "prod-server"
Conditional Expression.
1.Value is true then 3 dev instance is
create.
2.value is false then 1 prod instance is
create.
count = var.istest == true ? 3 : 0
##################
# vim main.tf
# vim terraform.tfvars
istest = false
3.value is true then 3 instance create
if not true then 1 instance create.
count = var.istest == true ? 3 : 1
Local Values :-
# vim main.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
locals {
common_tags = {
Name = "server1"
Owner = "DevOps team"
service = "backend"
}
}
resource "aws_instance"
"db-dev" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = "t2.micro"
tags = local.common_tags
}
resource "aws_ebs_volume"
"db-ebs" {
availability_zone = "ap-south-1a"
size = 8
tags = local.common_tags
}
# terraform apply
Terraform Functions :-
1.The terraform language include a
number of built-in functions that you can use to transform and combine values.
2.The general syntax for function calls
is a function name followed by
comma-separated arguments in parentheses.
# function (argument1, argument2)
Example:
max (5, 12, 9)
12
# ssh-keygen -t rsa
]# cat main.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"
region = var.region
}
locals {
time = formatdate("DD MMM YYYY hh:mm ZZZ", timestamp())
}
variable "region" {
default = "ap-south-1"
}
variable "tags" {
type = list
default = ["firstec2", "secondec2"]
}
variable "ami" {
type = map
default = {
"ap-south-1" = "ami-04b1ddd35fd71475a"
"us-east-1" =
"ami-01b3d4d785f71475n"
}
}
resource "aws_key_pair"
"loginkey" {
key_name = "login-key"
public_key = file("${path.module}/id_rsa.pub")
}
resource "aws_instance"
"app-dev" {
ami = lookup(var.ami,
var.region)
instance_type = "t2.micro"
key_name =
aws_key_pair.loginkey.key_name
count = 2
tags = {
Name = element(var.tags, count.index)
}
}
Data Sources: -
Region according fetch image.
Amazon image:-
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region = "ap-south-1"
}
data "aws_ami"
"app_ami" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
resource "aws_instance"
"instance-1" {
ami = data.aws_ami.app_ami.id
instance_type = "t2.micro"
key_name = "new-keypair-aws"
tags = {
Name = "dev server1"
}
}
Ubuntu image:-
data "aws_ami"
"app_ami" {
most_recent = true
owners =
["099720109477"]
filter {
name = "name"
values =
["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name =
"virtualization-type"
values = ["hvm"]
}
}
# image details
# aws ec2 describe-images --region
ap-south-1 --image-ids ami-042b34111b1289ccd
Debugging in Terraform :-
# export TF_LOG=TRACE
# export
TF_LOG_PATH=/tmp/terraform-crash.log
# terraform plan
Terraform Format check:-
Validating Terraform configuration
files.
Load Order & Semantics:
# ec2.tf, iam_user.tf,
provider.tf, variable.tf
# cat provider.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
# cat variable.tf
variable "iam_user" {
default = "demouser"
}
# cat ec2.tf
resource "aws_instance"
"base" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = "t2.micro"
tags = {
Name = "dev server1"
}
}
# cat iam_user.tf
resource "aws_iam_user"
"userdemo" {
name = var.iam_user
path = "/system/"
}
# terraform fmt
# terraform validate
# terraform plan
# terraform apply
Dynamic Block
# file dynamic-block.tf , provider.tf
# cat dynamic-block.tf
variable "sg_ports" {
type = list(number)
description = "list of ingress ports"
default = [8200, 8201, 8300,
9200, 9500]
}
resource "aws_security_group"
"dynamicsg" {
name =
"dynamic-sg"
description = "Ingress for vault"
dynamic "ingress" {
for_each = var.sg_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
ingress {
from_port = 9090
to_port = 9090
protocol = "tcp"
cidr_blocks = ["192.168.1.0/0"]
}
}
# terraform plan
Terraform taint
Eg :- terraform taint
<resource>.<name>
# terraform taint aws_instance.myec2
Splat expression
Example01
Output showing all user.
Example02:-
Showing one user.
Apply complete! Resources: 3 added, 0
changed, 0 destroyed.
Outputs:
arns = "arn:aws:iam::444084387163:user/system/iam_user.0"
Terraform Graph :-
# terraform graph > graph.dot
# cat graph.dot | dot -Tsvg >
graph.svg
# yum install nginx
# service nginx start
# cp -rvf graph.svg /usr/share/nginx/
Saving
terraform plan to file.
Change in terraform file
# terraform plan
-out=demopath
# terraform apply demopath
#
resource "aws_iam_user"
"userdemo" {
name =
"iam_user.${count.index}"
count = 3
path = "/system/"
}
output "arns" {
value = aws_iam_user.userdemo[*].arn
# terraform apply
How to fetch data.
# terraform output arns
[
"arn:aws:iam::444084387163:user/system/iam_user.0",
"arn:aws:iam::444084387163:user/system/iam_user.1",
"arn:aws:iam::444084387163:user/system/iam_user.2",
]
Terraform setting.
The special terraform configuration
block type is used to configure some behaviors of terraform itself, such as
requiring a minimum terraform version to apply your configuration.
# terraform -v
Terraform v0.14.5
+ provider registry.terraform.io/hashicorp/aws v3.26.0
# require for terraform version and
aws version then run int command.
terraform {
required_version =
"0.14.5"
required_providers {
aws = "3.26"
}
}
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
# terraform init
Dealing with larger Infrastructure:
Slow Down:
We can prevent terraform from querying
the current state during operations like terraform plan.
This can be achieved with the
-refresh=false flag
# terraform apply -auto-approve
Refresh to all resource like ec2, iam
, vpc.
# terraform plan
aws_iam_user.userdemo[1]: Refreshing
state... [id=iam_user.1]
aws_iam_user.userdemo[2]: Refreshing
state... [id=iam_user.2]
aws_iam_user.userdemo[0]: Refreshing
state... [id=iam_user.0]
How to disable refresh option :-
# terraform plan -refresh=false
Specify the Target:
If any specific resource changes in
terraform file.
Like :- port change , Ips , instance
name
The -target=resource flag can be used to
target a specific resource.
Generally used as a means to operate on
isolated portions of very large configurations.
# terraform plan -target=<resource>.<name>
# terraform plan -refresh=false -target=aws_security_group.allow_ssh_conn
Provisioners :
Create ec2 instance and install nginx
service.
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
resource "aws_instance"
"base" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = "t2.micro"
key_name =
"new-keypair-aws"
tags = {
Name = "dev server1"
}
provisioner "remote-exec" {
inline = [
"sudo amazon-linux-extras install -y
nginx1.12",
"sudo systemctl start nginx"
]
connection {
type = "ssh"
host = self.public_ip
user = "ec2-user"
private_key =
"${file("./terraform.pem")}"
}
}
}
Failure Behavior for Provisioners.
Dry Principle :-
Create directory like ec2, elb , ebs , cdn and put resource
and pick resource from directory.
# mkdir -p modules/ec2
# mkdir -p project
# vim modules/ec2/main.tf
resource "aws_instance"
"base" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = "t2.micro"
security_groups = ["default"]
key_name = "new-keypair-aws"
tags = {
Name = "dev server1"
}
}
# vim project/provider.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
# cat project/ec2_web_dry.tf
module "myec2" {
source =
"../modules/ec2"
}
# cd project
# terraform init
# terraform plan
Variable and terraform Modules
# mkdir -p modules/ec2
# mkdir -p project
# vim modules/ec2/main.tf
resource "aws_instance"
"base" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = var.instance_type
security_groups = ["default"]
key_name = "new-keypair-aws"
tags = {
Name = "dev server1"
}
}
# vim modules/ec2/variables.tf
variable
“instance_type” {
default = “t2.micro” (second variable)
}
# vim project/provider.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
# cat project/ec2_web_dry.tf
module "myec2" {
source =
"../modules/ec2"
instance_type = “t2.large”
(first variable)
}
# cd project
# terraform init
# terraform plan
Output showing :-
instance_type = t2.large
Terraform Registry
The Terraform Registry is a repository of
modules written by the Terraform community.
The registry can help you get started with
Terraform more quickly
3.1 Module Location
If we intend to use a module, we need to
define the path where the module files are present.
The module files can be stored in multiple locations,
some of these include:
●
Local Path
●
GitHub
●
Terraform Registry
●
S3 Bucket
●
HTTP URLs
3.2
Verified Modules in Terraform Registry
Within Terraform Registry, you can find
verified modules that are maintained by various third-party vendors.
These modules are available for various
resources like AWS VPC, RDS, ELB, and others
Using Registry Modules in Terraform
To use Terraform Registry module within the
code, we can make use of the source argument that contains the module path.
Below code references to the EC2 Instance
module within terraform registry.
module "ec2-instance" {
source =
"terraform-aws-modules/ec2-instance/aws"
version = "2.13.0" (code comment version)
#
insert the 10 required variables here
}
# ls main.tf provider.tf
# cat main.tf
module "ec2_cluster" {
source =
"terraform-aws-modules/ec2-instance/aws"
version = "~>2.0"
name =
"my-ec2"
instance_count = 1
ami =
"ami-04b1ddd35fd71475a"
instance_type = "t2.micro"
subnet_id =
"subnet-69d49425"
tags = {
Terraform = "true"
Environment = "dev"
}
}
# ls .terraform/modules/ec2_cluster/
CHANGELOG.md examples
LICENSE main.tf Makefile
outputs.tf README.md variables.tf
versions.tf
# terraform plan
# terraform apply
Terraform Workspace
Terraform allows us to have multiple
workspaces, with each of the workspaces we can have a different set of
environment variables associated.
1.Terraform starts with a single
workspace named "default".
2.Workspaces are managed with the terraform
workspace set of commands.
3.To create a new workspace and switch
to it, you can use terraform workspace new; to switch workspaces you can use
terraform workspace select; etc.
Environment according variable set.
# terraform workspace -h
# terraform workspace list
* default
# terraform workspace new prd
# terraform workspace new dev
# terraform workspace list
default
dev
* prd
# terraform workspace select default
# terraform plan
# cat main.tf
provider "aws" {
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
region =
"ap-south-1"
}
resource "aws_instance"
"base" {
ami =
"ami-04b1ddd35fd71475a"
instance_type = lookup(var.instance_type,terraform.workspace)
}
variable "instance_type" {
type = map(string)
default = {
default =
"t2.nano"
dev = "t2.micro"
prd = "t2.large"
}
}
Default workspace showing :-
+ instance_type = "t2.nano"
# ls terraform.tfstate
Dev workspace
showing :-
# terraform workspace select dev
+ instance_type = "t2.micro"
# ls
terraform.tfstate.d/dev/terraform.tfstate
Prd workspace
showing :-
# terraform workspace select prd
+ instance_type = "t2.large"
# ls terraform.tfstate.d/prd/terraform.tfstate
Integrating with GIT for team
management.
Module Source in terraform
1.Local path :-
module “local_dir” {
source = “../local_dir”
}
2.Git module source:-
module “vpc” {
source =
“git::https://example.com/vpc.git”
}
module “storage” {
source =
“git::ssh://username@example.com/storage.git”
}
module “branch_git” {
source = “git::ssh://username@example.com/storage.git?ref=<branch-name/revesion
no>”
}
3.Terraform Registry.
module
"consul" {
source = "hashicorp/consul/aws"
version = "0.1.0"
}
4.Bitbucket.
module
"consul" {
source =
"bitbucket.org/hashicorp/terraform-consul-aws"
}
5.Fetching archives over HTTP.
module
"vpc" {
source =
"https://example.com/vpc-module.zip"
}
6.S3 Bucket.
module
"consul" {
source =
"s3::https://s3-eu-west-1.amazonaws.com/examplecorp-terraform-modules/vpc.zip"
}
7.GCS Bucket
module
"consul" {
source =
"gcs::https://www.googleapis.com/storage/v1/modules/foomodule.zip"
}
# terraform init
# ls .terraform/modules/consul
Terraform and .gitignore
# vim
.gitignore
.terraform
*.tfvars
Terraform.tfstate
# git status
# git add .gitignore
# git commit -a “add gitignore file”
# git push origin master
Remote State management with
Terraform.
# ls
backend.tf main.tf
# cat backend.tf
terraform {
backend "s3" {
bucket =
"terraform-backend-s3-testing"
key = "remotedemo.tfstate"
region = "ap-south-1"
access_key = "AKIAWOZL57VN52ILHW22"
secret_key = "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"
}
}
# terraform init
# terraform plan
# terraform apply
State file locking
Create DynamoDB for terraform lock file
save.
# terraform init
# terraform plan
terraform.lock.hcl save in dynamodb
Terraform state Management
1.How many resources are running.
# terraform state list
2. This command is used in many case in
which you want to rename an existing resource without destroying and recreating
it.
Old resource name :- base
Rename resource name :- base01
# terraform state mv [option] SORUCE
DESTINATION
resource "aws_instance" "base01" { ß change
resource name
ami =
"ami-04b1ddd35fd71475a"
instance_type = lookup(var.instance_type, terraform.workspace)
tags = {
Name = "dev-test02"
}
# terraform plan
Plan: 1 to add, 0 to change, 1 to destroy.
# terraform state list
aws_instance.base
# terraform state mv
aws_instance.base aws_instance.base01
Move "aws_instance.base" to
"aws_instance.base01"
Successfully moved 1 object(s).
# terraform plan
No changes. Infrastructure is
up-to-date.
3.pull command use download terraform
state “remotedemo.tfstate”
from s3 bucket and show output.
# terraform state pull
4.The terraform state push command is
used to manually upload a local state file to remote state.
5.rm command is used to remove items
from the terraform state “remotedemo.tfstate”
file but resource running in aws.
# terraform state list
aws_instance.base
# terraform state rm aws_instance.base
# terraform state pull
6.show command use for show the
attributes of a single resource in the
Terraform state.
# terraform state show aws_instance.base
Importing Existing resources with
terraform Import.
# vim ec2.tf
# terraform import aws_instance.myec2 i-041732765374fbd98
# check terraform state file.
Terraform provider use case Resources
in multiple Regions
By default, resources use a default
provider configuration inferred from the first word of the resource type name.
For example, a resource of type
aws_instance uses the default (un-aliased) aws provider configuration unless
otherwise stated.
To select an aliased provider for a
resource or data source, set its provider meta-argument to a <PROVIDER
NAME>.<ALIAS> reference:
# vim providers.tf
# vim main.tf
Handling multiple aws account
# aws
s3 ls --profile
account02
# cat provider.tf
# cat eip.tf
Terraform & Assume role with AWS
STS
Sensitive parameter