Module 1: Terraform Basics - Understanding the Foundation
What is Terraform?
Explanation of Terraform as an Infrastructure-as-Code (IaC) tool that allows you to define and provision infrastructure using a declarative configuration language. 1. aws.plainenglish.io
1
Emphasis on its key benefits: version control for infrastructure, repeatability, automation, and infrastructure consistency.
HCL (HashiCorp Configuration Language) Syntax:
Introduction to HCL as the language used to write Terraform configurations.
Explanation of fundamental HCL concepts: blocks (e.g., resource, provider, module), arguments (key-value pairs within blocks), and expressions.
Basic HCL syntax examples: Terraform
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
tags = {
Name = "MyFirstTerraformInstance"
}
}
Providers:
Resources:
Setting up Terraform CLI:
terraform init, terraform plan, terraform apply, terraform destroy.Setting up AWS Provider Credentials:
Hands-on Lab:
main.tf file with the terraform block and the AWS provider configuration.terraform init to initialize the working directory and download the AWS provider plugin.Module 2: Writing Your First Configuration - Bringing Infrastructure to Life
Creating EC2, VPC, S3, and RDS Resources:
Step-by-step guide and code snippets for creating fundamental AWS resources using Terraform.
**EC2 Instance:**Terraform
resource "aws_instance" "web" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
subnet_id = aws_subnet.public_subnet_1.id
vpc_security_group_ids = [aws_security_group.web_sg.id]
key_name = "your-aws-key-pair-name"
tags = {
Name = "WebAppServer"
}
}
**VPC:**Terraform
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public_subnet_1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = {
Name = "public-subnet-1"
}
}
**S3 Bucket:**Terraform
resource "aws_s3_bucket" "website_bucket" {
bucket = "your-unique-website-bucket-name"
acl = "private"
versioning {
enabled = true
}
lifecycle_rule {
enabled = true
transition {
days = 30
storage_class = "STANDARD_IA"
}
}
}
**RDS Instance (MySQL example):**Terraform
resource "aws_db_instance" "mydb" {
allocated_storage = 20
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "admin"
password = "your-secure-password"
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.rds_sg.id]
db_subnet_group_name = aws_db_subnet_group.rds_subnet_group.name
}
resource "aws_db_subnet_group" "rds_subnet_group" {
name = "rds-subnet-group"
subnet_ids = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id]
}
Using Variables:
Introduction to variables for making your configurations more flexible and reusable.
Defining variables in variables.tf file with type and description.
Using variables in main.tf with the var. prefix.
Providing variable values through terraform.tfvars file or command-line arguments.
Example variables.tf:
Terraform
variable "aws_region" {
type = string
default = "us-east-1"
description = "The AWS region to deploy to."
}
variable "instance_type" {
type = string
default = "t2.micro"
description = "The EC2 instance type."
}
Example main.tf using variables:
Terraform
provider "aws" {
region = var.aws_region
}
resource "aws_instance" "example" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = var.instance_type
tags = {
Name = "MyVariableDrivenInstance"
}
}
Outputs:
Defining output values in outputs.tf to display information about your provisioned infrastructure after deployment (e.g., public IP address of an EC2 instance, DNS name of an RDS instance).
Example outputs.tf:
Terraform
output "instance_public_ip" {
value = aws_instance.example.public_ip
description = "The public IP address of the EC2 instance."
}
output "rds_endpoint" {
value = aws_db_instance.mydb.endpoint
description = "The endpoint of the RDS instance."
}
Locals:
Using locals block to define local variables within a configuration for simplifying complex expressions or reusing values.
Example main.tf using locals:
Terraform
locals {
common_tags = {
Environment = "Development"
Project = "MyWebApp"
ManagedBy = "Terraform"
}
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = merge(local.common_tags, { Name = "main-vpc" })
}
resource "aws_instance" "example" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
tags = merge(local.common_tags, { Name = "MyLocalVariableInstance" })
}
Hands-on Lab:
main.tf file to provision a VPC with a public subnet and an EC2 instance within it.variables.tf for the AWS region and instance type.terraform.tfvars file.outputs.tf to display the public IP address of the EC2 instance.terraform init, terraform plan, and terraform apply to provision the infrastructure.terraform output to see the output value.locals block to define common tags and apply them to your resources.terraform destroy to clean up the resources.Module 3: State Management - Tracking Your Infrastructure
Local vs Remote State:
terraform.tfstate file in your working directory. Explain the limitations of local state for collaboration and security.S3 + DynamoDB Backend:
Configuring an S3 bucket to store the state file remotely.
Configuring a DynamoDB table for state locking to prevent concurrent modifications to the state.
Example terraform block in main.tf to configure the S3 backend:
Terraform
terraform {
backend "s3" {
bucket = "your-terraform-state-bucket-name"
key = "my-project/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks" # Optional DynamoDB table for locking
}
}
Locking:
State File Structure:
terraform.tfstate file (JSON format) and the information it contains about your managed resources.Drift Detection:
terraform plan.terraform plan highlights any discrepancies or "drift."