Terraform variables
Class 15th Terraform Variables Apr 30th(Devops)
Terraform Target and ".tfvars" files
Terraform output block
Terraform import
Terraform Taint and replace
Terraform workspace
Terraform comments
Creating AWS Resources (VPC,S3 Buket,EC2,EBS and RDS)
Variables
In the .tf file access key and secrete key assign the variable not good practice
[ec2-user@ip-172-31-35-32 ccit]$ cat cloudinfra.tfprovider "aws"{
region="eu-west-1"
access_key="AKIATFBMO7H4MQLOWPFY"
secret_key="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"
}
resource "aws_s3_bucket" "ccitbucket"{
bucket="ccitapril"
}
Step1:
[ec2-user@ip-172-31-35-32 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
access_key = "AKIATFBMO7H4MQLOWPFY"
secret_key = "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"
}
resource "aws_s3_bucket" "ccitbucket" {
bucket = "ccitapril"
}
resource "aws_instance" "ccitinst" {
ami = var.inst_ami
instance_type = var.inst_type
count = var.inst_cnt
tags = {
Name = var.inst_tag
}
}
variable "inst_ami" {
default = "ami-04e7764922e1e3a57"
}
variable "inst_type" {
default = "t2.micro"
}
variable "inst_cnt" {
default = 2
}
variable "inst_tag" {
default = "ccit"
}
Step2: Two instances created successfully
Bucket created
Step3: you can you the command state list ,we get know what resources are created
and observed below resource showing [0],[1],because we have labeled resource "aws_instance" "ccitinst" same for two instance same identity with array number,if give uniquely labeled it will sperate identity
[ec2-user@ip-172-31-35-32 ccit]$ terraform state list
aws_instance.ccitinst[0]
aws_instance.ccitinst[1]
aws_s3_bucket.ccitbucket
Step4: you can destroy the resource ,with inputs also before modify .tf file all variables empty
variable "inst_ami" {
}
variable "inst_type" {
}
variable "inst_cnt" {
}
variable "inst_tag" {
}
just simple give enter
[ec2-user@ip-172-31-35-32 ccit]$ terraform destroy -auto-approve
Plan: 0 to add, 0 to change, 3 to destroy.
aws_s3_bucket.ccitbucket: Destroying... [id=ccitapril]
aws_instance.ccitinst[1]: Destroying... [id=i-04bd0311752379056]
aws_instance.ccitinst[0]: Destroying... [id=i-0e19a1b1e8d912d57]
aws_s3_bucket.ccitbucket: Destruction complete after 0s
aws_instance.ccitinst[1]: Still destroying... [id=i-04bd0311752379056, 10s elapsed]
aws_instance.ccitinst[0]: Still destroying... [id=i-0e19a1b1e8d912d57, 10s elapsed]
aws_instance.ccitinst[0]: Still destroying... [id=i-0e19a1b1e8d912d57, 20s elapsed]
aws_instance.ccitinst[1]: Still destroying... [id=i-04bd0311752379056, 20s elapsed]
aws_instance.ccitinst[1]: Still destroying... [id=i-04bd0311752379056, 30s elapsed]
aws_instance.ccitinst[0]: Still destroying... [id=i-0e19a1b1e8d912d57, 30s elapsed]
aws_instance.ccitinst[0]: Still destroying... [id=i-0e19a1b1e8d912d57, 40s elapsed]
aws_instance.ccitinst[1]: Still destroying... [id=i-04bd0311752379056, 40s elapsed]
aws_instance.ccitinst[0]: Destruction complete after 40s
aws_instance.ccitinst[1]: Destruction complete after 40s
Destroy complete! Resources: 3 destroyed.
Step5: We have remove accesskey and secrete key in the couldinfra.tf file ,we plan to attached admin access role to Ec2,if you give admin role to Ec2 machine not required keys, you see below error role not attached to Ec2 machine.
[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve
var.inst_ami
Enter a value: "ami-04e7764922e1e3a57"
var.inst_cnt
Enter a value: 1
var.inst_tag
Enter a value: "ccit"
var.inst_type
Enter a value: "t2.micro"
│ Error: No valid credential sources found
│
│ with provider["registry.terraform.io/hashicorp/aws"],
│ on cloudinfra.tf line 1, in provider "aws":
│ 1: provider "aws" {
│
│ Please see https://registry.terraform.io/providers/hashicorp/aws
│ for more information about providing credentials.
│
│ Error: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, http response error
│ StatusCode: 404, request to EC2 IMDS failed
Step6:Before as you see Iam role is null ,not having access required to pass keys
Step7: role create EC2-amin ,that role assigned to ec2 machine and click update Iam roleStep8:you see below now Iam role attached
Step9:[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve -var="inst_ami=ami-04e7764922e1e3a57" -var="inst_type=t2.micro" -var="inst_cnt=1" -var="inst_tag=ccit"
aws_s3_bucket.ccitbucket: Refreshing state... [id=terraform-20250502130858021500000001]
Plan: 1 to add, 0 to change, 0 to destroy.
aws_instance.ccitinst[0]: Creating...
aws_instance.ccitinst[0]: Still creating... [10s elapsed]
aws_instance.ccitinst[0]: Creation complete after 12s [id=i-07cb874dc434c0560]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Step10:ccit instance create successfully
[ec2-user@ip-172-31-35-32 ccit]$ terraform destroy -auto-approve -var="inst_ami=ami-04e7764922e1e3a57" -var="inst_type=t2.micro" -var="inst_cnt=1" -var="inst_tag=ccit"
Step12: we can put our variable to different file also variable.tf , we can mentioned our inputs
[ec2-user@ip-172-31-35-32 ccit]$ ls -lrt
total 20
-rw-r--r--. 1 ec2-user ec2-user 7462 May 2 13:31 terraform.tfstate.backup
-rw-r--r--. 1 ec2-user ec2-user 182 May 2 13:31 terraform.tfstate
-rw-r--r--. 1 ec2-user ec2-user 267 May 2 13:35 cloudinfra.tf
-rw-r--r--. 1 ec2-user ec2-user 182 May 2 13:39 variable.tf
Step13:terraform very smart it will take inputs from cloudinfra.tf file variable automatically
[ec2-user@ip-172-31-35-32 ccit]$ cat variable.tf
variable "inst_ami" {
default="ami-04e7764922e1e3a57"
}
variable "inst_type" {
default="t2.micro"
}
variable "inst_cnt" {
default=1
}
variable "inst_tag" {
default="CCIT-INST"
}
Step14: see Instance created successfully
[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve
Plan: 2 to add, 0 to change, 0 to destroy.
aws_instance.ccitinst[0]: Creating...
aws_s3_bucket.ccitbucket: Creating...
aws_s3_bucket.ccitbucket: Creation complete after 1s [id=terraform-20250502134319274600000001]
aws_instance.ccitinst[0]: Still creating... [10s elapsed]
aws_instance.ccitinst[0]: Creation complete after 12s [id=i-07ff13eb10f4969fc]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Step15: you see above created two resouce , given aws bucket is give empty ,it create bucket name default some name:[ec2-user@ip-172-31-35-32 ccit]$ cat cloudinfra.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "ccitbucket" {
}
resource "aws_instance" "ccitinst" {
ami = var.inst_ami
instance_type = var.inst_type
count = var.inst_cnt
tags = {
Name = var.inst_tag
}
}
Terraform varfilesStep1: create these below file and make variable.tf null all variables
.tfvars
vi dev.tfvars
inst_ami="ami-04e7764922e1e3a57"
inst_cnt="t2.micro"
inst_type=1
inst_tag="CCIT-DEV"
vi test.tfvars
inst_ami="ami-04e7764922e1e3a57"
inst_type="t2.micro"
inst_cnt=1
inst_tag="CCIT-test"
vi prod.tfvars
inst_ami="ami-04e7764922e1e3a57"
inst_type="t2.micro"
inst_cnt=1
inst_tag="CCIT-prod"
Step2: passing the inputs to var file to the command,see dev instance created successfully
[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve -var-file="dev.tfvars"
Step3:[ec2-user@ip-172-31-35-32 ccit]$ terraform destroy -auto-approve -var-file="test.tfvars"Destroy complete! Resources: 1 destroyed.
Note: Better maintenance, we have split the variable declaration separate files ,instead of maintained in cloudinfra.tf single file .tf file terraform it will take consideration
Output block
[ec2-user@ip-172-31-35-32 ccit]$vi coudinfra.tf
esc :set number (display numbers for file)
:d 10 (where your cursor ,botton all 10 lines deleted)
Step1: Output block use for want to know what creation done ,log information
Step2: bucket created successfully you see the output of the bucket
[ec2-user@ip-172-31-35-32 ccit]$vi coudinfra.tf
provider "aws" {
region = "eu-west-1"
}
provider "aws" {
alias = "west2"
region = "eu-west-2"
}
resource "aws_s3_bucket" "ccitwest1bucket" {
provider = aws
bucket = "ccit-apr2025west1"
}
resource "aws_s3_bucket" "ccitwest2bucket" {
provider = aws.west2
bucket = "ccit-apr2025west2"
}
output "ccitoutblock" {
value = {
bucket=aws_s3_bucket.ccitwest1bucket.bucket
}
}
[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve
Plan: 2 to add, 0 to change, 0 to destroy.
aws_s3_bucket.ccitwest2bucket: Creating...
aws_s3_bucket.ccitwest1bucket: Creating...
aws_s3_bucket.ccitwest1bucket: Creation complete after 1s [id=ccit-apr2025west1]
aws_s3_bucket.ccitwest2bucket: Creation complete after 1s [id=ccit-apr2025west2]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
ccitoutblock = {
"bucket" = "ccit-apr2025west1"
}
Step3: arn display for the bucket
output "ccitoutblock" {
value = {
bucket = aws_s3_bucket.ccitwest1bucket.bucket
arn = aws_s3_bucket.ccitwest1bucket.arn
region = aws_s3_bucket.ccitwest1bucket.region
}
}
Outputs:
ccitoutblock = {
"arn" = "arn:aws:s3:::ccit-apr2025west1"
"bucket" = "ccit-apr2025west1"
"region" = "eu-west-1"
}
Step4: For two output block buckets
output "ccitoutblock" {
value = {
bucket = aws_s3_bucket.ccitwest1bucket.bucket
arn = aws_s3_bucket.ccitwest1bucket.arn
region = aws_s3_bucket.ccitwest1bucket.region
}
}
output "ccitoutblock1" {
value = {
bucket = aws_s3_bucket.ccitwest2bucket.bucket
arn = aws_s3_bucket.ccitwest2bucket.arn
region = aws_s3_bucket.ccitwest2bucket.region
}
}
Import
Step1: import option which you have created bucket manually inform to terraform take control for the bucket using import
Step2:see here i have enter destory only two buckets destory there is no control to which is we have created manually
[ec2-user@ip-172-31-35-32 ccit]$ terraform destroy -auto-approve
aws_s3_bucket.ccitwest1bucket: Refreshing state... [id=ccit-apr2025west1]
aws_s3_bucket.ccitwest2bucket: Refreshing state... [id=ccit-apr2025west2]
Plan: 0 to add, 0 to change, 2 to destroy.
aws_s3_bucket.ccitwest1bucket: Destroying... [id=ccit-apr2025west1]
aws_s3_bucket.ccitwest2bucket: Destroying... [id=ccit-apr2025west2]
aws_s3_bucket.ccitwest1bucket: Destruction complete after 1s
aws_s3_bucket.ccitwest2bucket: Destruction complete after 1s
Destroy complete! Resources: 2 destroyed.
Step3: after apply two Buckets are created again
Step4: need to check state of the terraform file using command ,you see below terraform control has only two buckets
[ec2-user@ip-172-31-35-32 ccit]$ terraform state list
aws_s3_bucket.ccitwest1bucket
aws_s3_bucket.ccitwest2bucket
Step5: Added details of the manually bucket which is created
[ec2-user@ip-172-31-35-32 ccit]$ vi cloudinfra.tf
provider "aws" {
alias="west1"
region = "eu-west-1"
}
provider "aws" {
alias = "west2"
region = "eu-west-2"
}
resource "aws_s3_bucket" "ccitwest1bucket" {
provider = aws
bucket = "ccit-apr2025west1"
}
resource "aws_s3_bucket" "ccitwest2bucket" {
provider = aws.west2
bucket = "ccit-apr2025west2"
}
resource "aws_s3_bucket" "ccitwest1manually" {
provider = aws.west1
bucket = "ccit-apr2025west-manually"
}
Step6: See here imported successfully
[ec2-user@ip-172-31-35-32 ccit]$ terraform import aws_s3_bucket.ccitwest1manually ccit-apr2025west-manually
aws_s3_bucket.ccitwest1manually: Importing from ID "ccit-apr2025west-manually"...
aws_s3_bucket.ccitwest1manually: Import prepared!
Prepared aws_s3_bucket for import
aws_s3_bucket.ccitwest1manually: Refreshing state... [id=ccit-apr2025west-manually]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
Step7: After import state of the terraform
[ec2-user@ip-172-31-35-32 ccit]$ terraform state list
aws_s3_bucket.ccitwest1bucket
aws_s3_bucket.ccitwest1manually
aws_s3_bucket.ccitwest2bucket
Step8: three buckets destroyed
[ec2-user@ip-172-31-35-32 ccit]$ terraform destroy -auto-approve
aws_s3_bucket.ccitwest2bucket: Destroying... [id=ccit-apr2025west2]
aws_s3_bucket.ccitwest1bucket: Destroying... [id=ccit-apr2025west1]
aws_s3_bucket.ccitwest1manually: Destroying... [id=ccit-apr2025west-manually]
aws_s3_bucket.ccitwest2bucket: Destruction complete after 1s
aws_s3_bucket.ccitwest1bucket: Destruction complete after 1s
aws_s3_bucket.ccitwest1manually: Destruction complete after 0s
Destroy complete! Resources: 3 destroyed.
Step9:After apply
[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve
[ec2-user@ip-172-31-35-32 ccit]$ terraform state list
aws_s3_bucket.ccitwest1bucket
aws_s3_bucket.ccitwest1manually
aws_s3_bucket.ccitwest2bucket
Step10: Remove particular bucket
[ec2-user@ip-172-31-35-32 ccit]$ terraform state rm aws_s3_bucket.ccitwest1manually
Removed aws_s3_bucket.ccitwest1manually
Successfully removed 1 resource instance(s).
Step11: removed from terraform state but bucket there physically
[ec2-user@ip-172-31-35-32 ccit]$ terraform state list
aws_s3_bucket.ccitwest1bucket
aws_s3_bucket.ccitwest2bucket
Tait and replace
Step1: Created one VM
[ec2-user@ip-172-31-35-32 ccit]$ cat cloudinfra.tf
provider "aws" {
alias = "west1"
region = "eu-west-1"
}
resource "aws_instance" "ccitinst" {
ami="ami-04e7764922e1e3a57"
instance_type="t2.micro"
count=1
tags ={
Name ="CCITINST"
}
}
Step2: taint command for if any case destroyed or corrupted our instance CCINST, immediately
you need instance use the command with same confirgure to create VM use tait, but whatevery inside files of the VM not come, only instance will create
taint is old replace new one
Step3: you see below state list has one instance which was corrupted you want taint for the instance use the command ,it will destory the existing one create new one data will not come
[ec2-user@ip-172-31-35-32 ccit]$ terraform state list
aws_instance.ccitinst[0]
Step4: See here taint mark added for the server
[ec2-user@ip-172-31-35-32 ccit]$ terraform taint aws_instance.ccitinst[0]
Resource instance aws_instance.ccitinst[0] has been marked as tainted.
Step5: you see below one terminated with same name created one more instance
[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve
Step6:Replace will directly, replace instance on top the instance not required taint mark
[ec2-user@ip-172-31-35-32 ccit]$ terraform apply -auto-approve -replace="aws_instance.ccitinst[0]"
Comments
Note:-Need to do carefully ,if you put resouce block comment any unnessary after apply resoue will destroy
Single line comment # count=0 or // count=0
Multiple line comments /*count=0
Name ="ccit" */