First code
[root@localhost local]# cat local.tf
resource "local_file" "devops" {
filename = "/tmp/terraform/local/devops-auto.txt"
content = "i want to become devops engineer"
}
local_file
The local_file
resource in Terraform is used to manage the content of local files on your system. It’s useful for generating configuration files, scripts, or any other text files needed by your infrastructure.
terraform init
The terraform init command is used to initialize a working directory containing Terraform configuration files. It prepares the directory for use with Terraform by performing several setup tasks:
Install Plugins: Downloads and installs the providers and modules defined in the configuration.
Configure Backend: Sets up the backend configuration, which defines where and how state data is stored.
Validate Configuration: Checks the configuration files for syntax errors and compatibility issues.
terraform validate : it will validate the file
terraform plan :
The terraform plan
command is your crystal ball for predicting the future of your infrastructure. When you run it, Terraform will show you what changes it would make without actually applying those changes.
Terraform Apply : It will apply the code
terraform.tfstate :
State Management: Terraform maintains a state file that tracks the current state of your infrastructure. This state file helps Terraform understand the differences between the desired and actual states of your infrastructure, enabling it to make informed decisions when you apply changes.
Second code
resource "local_file" "devops" {
filename = "/tmp/terraform/local/devops-auto.txt"
content = "i want to become devops engineer"
}
resource "random_string" "rand_str" {
length = 18
special = true
override_special = "!#$%^&*():?"
}
output "rand_str" {
value = random_string.rand_str[*].result
}
Install nginx in docker container using terraform
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "2.13.0"
}
}
}
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.latest
name = "tutorial"
ports {
internal = 80
external = 80
}
}
Terraform State File
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.
Create terraform state file into s3 bucket
terraform {
backend "s3" {
bucket = "Ranjan-s3-demo-xyz" # change this
key = "ronny/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-lock"
}
}
What is `backend.tf`?
Terraform Backend is a configuration option in Terraform that allows you to store and manage the state of your infrastructure in a remote or local location. The backend is responsible for storing the state file and providing an interface for reading and writing state data. When you run Terraform, it checks the backend to see if there are any changes to the state file, and if there are, it applies those changes to your infrastructure.
What happens if you give the wrong configuration or code in Terraform and run it?
Validation Errors: If there are syntax errors or misconfigurations in your Terraform code, Terraform will display validation errors during the terraform plan
or terraform apply
commands, preventing execution.
Execution Errors: If the code is syntactically correct but semantically incorrect (e.g., referencing non-existent resources), Terraform may fail during the apply phase, resulting in an error message without making changes to the infrastructure.
Partial Changes: If the configuration leads to an error after some resources have already been created or modified, Terraform might leave the infrastructure in a partially applied state. This could result in inconsistent configurations.
Destructive Changes: In some cases, an incorrect configuration could lead to destructive changes, such as the deletion of resources. If a resource is mistakenly marked for deletion, it will be removed during the apply phase.
State File Issues: If the configuration doesn’t align with the actual infrastructure, it may cause inconsistencies in the Terraform state file, leading to confusion and potential issues in future operations.
What is the use of the terraform graph command?
It helps visualize how resources are interdependent. For example, it shows which resources depend on others, making it easier to understand the relationships between different parts of the infrastructure.
What is a null resource in Terraform?
A null resource in Terraform is a utility resource used to run scripts, trigger actions, or manage dependencies without creating or managing actual infrastructure. It is useful for automation, orchestration, and scenarios where you need to execute tasks outside of Terraform’s native infrastructure management.
What is the difference between a module and a template in Terraform?
Modules: Modules are used for organizing, reusing, and abstracting groups of related resources in Terraform.
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
}
Templates: Templates are used for dynamically generating content, such as configuration files or scripts, based on variables or conditions.
data "template_file" "init_script" {
template = "${file("init.sh")}"
vars = {
server_name = "my-server"
}
}
resource "aws_instance" "example" {
ami = "ami-123456"
instance_type = "t2.micro"
user_data = data.template_file.init_script.rendered
}
Aspect | Module | Template |
---|---|---|
Definition | A module is a reusable container for resources. | A template generates dynamic content (e.g., files or scripts). |
Purpose | Organizes, reuses, and abstracts resources. | Generates dynamic content based on variables or conditions. |
Usage | Used to manage groups of related resources. | Used to generate configuration files or scripts dynamically. |
Structure | Can contain multiple .tf files, variables, outputs, etc. | Typically a single file or function generating text. |
Example | Creating an AWS EC2 instance with a reusable module. | Generating a user_data script for EC2 using template_file . |
Jenkins pipeline for Terraform deployment
pipeline {
agent any
environment {
// Define your Terraform variables
TF_VAR_region = 'us-east-1'
TF_VAR_project = 'my-terraform-project'
AWS_ACCESS_KEY_ID = credentials('aws-access-key-id')
AWS_SECRET_ACCESS_KEY = credentials('aws-secret-access-key')
}
stages {
stage('Checkout') {
steps {
// Checkout the repository containing Terraform code
checkout scm
}
}
stage('Initialize Terraform') {
steps {
script {
// Initialize Terraform (downloads plugins, initializes backend, etc.)
sh 'terraform init'
}
}
}
stage('Terraform Plan') {
steps {
script {
// Run terraform plan to check for infrastructure changes
sh 'terraform plan -out=tfplan'
}
}
}
stage('Terraform Apply') {
steps {
script {
// Apply Terraform plan to deploy infrastructure
// Automatically approve the plan
sh 'terraform apply -auto-approve tfplan'
}
}
}
stage('Terraform Destroy') {
when {
branch 'main' // This will only run on 'main' branch
}
steps {
script {
// Optional: Destroy infrastructure after apply (for testing)
// Run this stage when required or on a separate branch to destroy resources
sh 'terraform destroy -auto-approve'
}
}
}
}
post {
always {
// Cleanup actions like removing temporary files
cleanWs()
}
success {
echo "Terraform deployment was successful."
}
failure {
echo "Terraform deployment failed."
}
}
How to create 10 EC2 machines with incremental values like 0,1,2, etc. ?
provider "aws" {
region = "us-east-1" # Specify your region
}
resource "aws_instance" "example" {
count = 10 # Number of EC2 instances to create
ami = "ami-0c55b159cbfafe1f0" # Replace with the appropriate AMI ID
Count v/s foreach
In Terraform, both count
and for_each
are used to create multiple instances of a resource, but they work differently. Here’s a breakdown of the differences between count
and for_each
:
Count
in Terraform
- Purpose: The
count
parameter allows you to specify how many instances of a resource to create. - Works with Numbers: It uses a numeric value to determine how many instances of a resource should be created. The value can either be a fixed number or a dynamic expression.
- Accessing Instances: You access the instances created by
count
using an index (count.index
), which starts from0
.
for_each
in Terraform
- Purpose:
for_each
allows you to create multiple instances of a resource based on a collection (map or set). - Works with Maps or Sets:
for_each
works by iterating over a map or set and creates one resource per element in that collection. - Accessing Instances: You can access instances created by
for_each
using the keys of the map or set (each.key
oreach.value
).
Feature | count | for_each |
---|---|---|
Works with | Numeric values or expressions | Maps, sets, or any collection of unique values |
Accessing Instances | count.index | each.key or each.value |
Flexibility | Less flexible, works with simple numbers | More flexible, works with complex collections |
Use Case | When you need a fixed number of resources | When you need resources based on a collection |
Unique Keys | Not ideal for handling unique keys | Works well with unique keys (e.g., string keys) |
Limitations | Works only with simple lists or ranges | Works better for dynamic or complex data type |
Data block in terraform ?
- A data block in Terraform is used to retrieve information about existing infrastructure.
- It does not create or manage the resource but allows you to reference that information in your Terraform configuration.
- Data blocks are essential for dynamic configurations, where resources need to be created based on existing resources or the latest available data.
data "aws_security_group" "example" {
name = "my-security-group"
}
resource "aws_instance" "example" {
ami = "ami-123456"
instance_type = "t2.micro"
security_groups = [data.aws_security_group.example.name] # Referencing the security group from data block
}
What are provisioners in terraform?
In Terraform, provisioners are used to execute scripts or commands on resources after they have been created or modified. Provisioners allow you to configure or manage a resource after it has been created by Terraform, typically for tasks like installing software, configuring system settings, or performing other setup activities.
resource "aws_instance" "example" {
ami = "ami-123456"
instance_type = "t2.micro"
provisioner "local-exec" {
command = "echo 'Instance created successfully!'"
}
}
Data vs resource in tf ?
Resource
- Purpose: Used to create, manage, and update infrastructure components (e.g., EC2 instances, S3 buckets).
- Action: Performs actual changes to the infrastructure, such as provisioning or modifying resources.
Data
- Purpose: Used to fetch and read existing information about infrastructure components managed outside Terraform or pre-existing resources.
- Action: Does not create or modify resources, only retrieves data.
How would you handle secrets management for AWS resources in your Terraform configuration?
To manage secrets for AWS resources in your Terraform configuration, the best practice is to store sensitive information like passwords, API keys, and database credentials in a dedicated secrets management service like AWS Secrets Manager, completely separate from your Terraform code, and access them using data sources within your Terraform configuration; this ensures secrets are never directly visible in your code and can be securely retrieved at runtime, with features like access control and rotation available through the secrets management service.
In Terraform, I’ve created a database with sensitive information like a password, and I don’t want it to appear in the output. How can I do that?
Prevent Sensitive Data from Appearing in Outputs: If you need to include sensitive data in your outputs but do not want it displayed in the terminal or logs, mark the output as sensitive.
output "db_password" {
value = var.db_password
sensitive = true
}
- Bridge Network: Creates an isolated network where containers can communicate with each other.
- Host Network: Shares the host’s network namespace, meaning the container uses the host’s network directly.
- None Network: Completely disables networking for the container.
- Overlay Network: Allows containers on different Docker hosts to communicate securely.
Terraform Workspace
In Terraform, a workspace is a way to manage multiple state files within a single Terraform configuration. Workspaces are useful when you want to reuse the same infrastructure code for different environments (e.g., dev
, stage
, prod
) without having to create separate directories or configurations.
Create new workspace: terraform workspace new <name>
List all workspace: terraform workspace list
Show Current Workspace: terraform workspace show
Switch Between Workspaces: terraform workspace select <workspace_name>
For managing different environment like dev, stage and prod, suppose i want to create ec2 for dev t2.micro and for stage t3.large, for this we can create separate terraform.tfvar(variable) file for each environment and and run it using that file while applying.
terraform apply -var-file="dev.tfvars"
terraform apply -var-file="stage.tfvars"
terraform apply -var-file="prod.tfvars"
What is the purpose of terraform fmt?
The command terraform fmt
is used to format Terraform configuration files (.tf
files) according to Terraform’s standard style conventions. It ensures that the code is consistently formatted, improving readability and maintaining a clean, standardized codebase.
- Pre-commit Hook: Run
terraform fmt
before committing changes to a version control system to ensure all code is properly formatted. - Collaboration: When multiple team members are working on the same Terraform configuration, use
terraform fmt
to ensure consistent formatting across the project. - CI/CD Pipeline: Include
terraform fmt
in your CI/CD pipeline to automatically format files before applying them.
Data vs resource in terraform
- resource: A
resource
block is used to create, update, or delete infrastructure components (e.g., virtual machines, databases, networks). - data: A
data
block is used to query or retrieve information about existing infrastructure that is not directly managed by Terraform or already exists.
Terraform lifecycle
The Terraform lifecycle allows you to define how Terraform manages the creation, updating, and deletion of resources. It is configured using the lifecycle
block within a resource. This is particularly useful for managing the behavior of resources in a controlled and predictable manner.
create_before_destroy
: Ensures that a new resource is created before the old one is destroyed.- prevent_destroy: Prevents Terraform from destroying a resource, even if explicitly instructed.
- ignore_changes: Instructs Terraform to ignore specific attributes of a resource when detecting changes.
Terraform taint
If we mark terraform resource as taint, then in next run terraform will destroy that resource and will create a new resource with same configuration. This forces Terraform to destroy and recreate the resource during the next terraform apply
terraform taint [options] <resource_name>
What is lock file in Terraform ?
The Terraform lock file (terraform.lock.hcl
) is used to ensure consistency in provider versions across different environments. It prevents unexpected provider upgrades that could break infrastructure deployments.