Terraform
Features of Terraform
Infrastructure as Code: Terraform allows you to write, plan, and create infrastructure using configuration files. This makes infrastructure management automated, consistent, and easy to collaborate on.
Multi-Cloud Support: Terraform supports many cloud providers and on-premises environments, allowing you to manage resources across different platforms seamlessly.
State Management: Terraform keeps track of the current state of your infrastructure in a state file. This enables you to manage changes, plan updates, and maintain consistency in your infrastructure.
Resource Graph: Terraform builds a resource dependency graph that helps in efficiently creating or modifying resources in parallel, speeding up the provisioning process and ensuring dependencies are handled correctly.
Immutable Infrastructure: Terraform promotes the practice of immutable infrastructure, meaning that resources are replaced rather than updated directly. This ensures consistency and reduces configuration drift.
Execution Plan: Terraform provides an execution plan (terraform plan) that previews changes before they are applied, allowing you to understand and validate the impact of changes before implementing them.
Modules: Terraform supports reusability through modules, which are self-contained, reusable pieces of configuration that help you maintain best practices and reduce redundancy in your infrastructure code.
Community and Ecosystem: Terraform has a large open-source community and many providers and modules available through the Terraform Registry, which makes it easier to get started and integrate with various services.
Use Cases
- Multi-Cloud Provisioning
- Infrastructure Scaling
- Disaster Recovery
- Environment Management
- Compliance & Standardization
- CI/CD Pipelines
- Speed and Simplicity
- Team Collaboration
- Error Reduction
- Enhanced Security
Install Terraform CLI
Terraform Structure
Provider Block: Specifies the cloud provider or service (e.g., AWS, Azure, Google Cloud) that Terraform will interact with.
provider "aws" {
region = "us-east-1"
}
Resource Block: Defines the resources to be created or managed. A resource can be a server, network, or other infrastructure component.
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
Data Block: Fetches information about existing resources, often for referencing in resource blocks.
data "aws_ami" "latest" {
most_recent = true
owners = ["amazon"]
}
Variable Block: Declares input variables to make the script flexible and reusable.
variable "instance_type" {
description = "Type of instance to use"
type = string
default = "t2.micro"
}
Output Block: Specifies values to be output after the infrastructure is applied, like resource IDs or connection strings.
output "instance_ip" {
value = aws_instance.example.public_ip
}
Module Block: Used to encapsulate and reuse sets of Terraform resources.
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
}
Locals Block: Defines local values that can be reused in the configuration.
locals {
environment = "production"
instance_count = 3
}
SET these environment variables.
export AWS_ACCESS_KEY_ID="your-access-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
Simple S3 Bucket
simple_s3_bucket.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.70.0"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-east-1"
profile = "chandr34"
}
resource "aws_s3_bucket" "demo" {
bucket = "chandr34-my-new-tf-bucket"
tags = {
Createdusing = "tf"
Environment = "classdemo"
}
}
output "bucket_name" {
value = aws_s3_bucket.demo.bucket
}
Create a new folder
Copy the .tf into it
terraform init
terraform validate
terraform plan
terraform apply
terraform destroy
Variable S3 Bucket
variable_bucket.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.70.0"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-east-1"
profile = "chandr34"
}
variable "bucket_name" {
description = "The name of the S3 bucket to create"
type = string
}
resource "aws_s3_bucket" "demo" {
bucket = var.bucket_name
tags = {
Createdusing = "tf"
Environment = "classdemo"
}
}
output "bucket_name" {
value = aws_s3_bucket.demo.bucket
}
Create a new folder
Copy the .tf into it
terraform init
terraform validate
terraform plan
terraform apply -var="bucket_name=chandr34-variable-bucket"
terraform destroy -var="bucket_name=chandr34-variable-bucket"
Variable file
Any filename with extension .tfvars
terraform.tfvars
bucket_name = "chandr34-variable-bucket1"
terraform apply -auto-approve
Please make sure AWS Profile is created.
Create Public and Private Keys
Linux / Mac Users
// create private/public key
ssh-keygen -b 2048 -t rsa -f ec2_tf_demo
Windows Users
Open PuttyGen and create a Key
Terraform
- mkdir simple_ec2
- cd tf-aws-ec2-sample
- Create main.tf
// main.tf
#https://registry.terraform.io/providers/hashicorp/aws/latest
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.70.0"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-east-1"
profile = "chandr34"
}
resource "aws_key_pair" "generated_key" {
key_name = "generated-key-pair"
public_key = tls_private_key.generated_key.public_key_openssh
}
resource "tls_private_key" "generated_key" {
algorithm = "RSA"
rsa_bits = 2048
}
resource "local_file" "private_key_file" {
content = tls_private_key.generated_key.private_key_pem
filename = "${path.module}/generated-key.pem"
}
resource "aws_instance" "ubuntu_ec2" {
ami = "ami-00874d747dde814fa"
instance_type = "t2.micro"
key_name = aws_key_pair.generated_key.key_name
vpc_security_group_ids = [aws_security_group.ec2_security_group.id]
tags = {
Name = "UbuntuInstance"
Environment = "classdemo"
}
}
resource "aws_security_group" "ec2_security_group" {
name = "ec2_security_group"
description = "Allow SSH and HTTP access"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Allow SSH from anywhere (use cautiously)
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Allow HTTP from anywhere
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"] # Allow all outbound traffic
}
tags = {
Name = "EC2SecurityGroup"
}
}
output "ec2_instance_public_ip" {
value = aws_instance.ubuntu_ec2.public_ip
}
output "private_key_pem" {
value = tls_private_key.generated_key.private_key_pem
sensitive = true
}
goto terminal
- terraform init
- terraform fmt
- terraform validate
- terraform apply
- terraform show
Finally
- terraform destroy