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 Download

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

AWS Resource Types


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