Writing Your First Terraform Script for AWS
Prerequisites
Before we begin, ensure you have:
1. AWS account with IAM credentials
2. Terraform installed on your local machine
3. AWS CLI configured with proper credentials
4. Basic understanding of AWS services
Terraform Basics Recap
Key Concepts:
1. HCL Syntax: HashiCorp Configuration Language used by Terraform
2. Providers: Plugins that interact with APIs (AWS, Azure, GCP, etc.)
3. Resources: Infrastructure components you want to create
4. Variables: Parameters to make your configurations reusable
5. State: Terraform's record of your infrastructure
Setting Up Your First Terraform Script
1. Create a Project Directory
mkdir terraform-aws-demo
cd terraform-aws-demo
2. Create Your Main Configuration File
Create a file named main.tf:
# Configure the AWS Provider
provider "aws" {
region = "us-east-1" # Change to your preferred region
}
# Create a VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "MyFirstVPC"
}
}
# Create a Subnet
resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "MyFirstSubnet"
}
}
# Create an Internet Gateway
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "MyFirstIGW"
}
}
# Create a Route Table
resource "aws_route_table" "example" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "MyFirstRouteTable"
}
}
# Associate Route Table with Subnet
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.main.id
route_table_id = aws_route_table.example.id
}
# Create a Security Group
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.main.id
ingress {
description = "SSH from anywhere"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port =0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_ssh"
}
}
# Create an EC2 Instance
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI (us-
east-1)
instance_type = "t2.micro"
subnet_id = aws_subnet.main.id
vpc_security_group_ids = [aws_security_group.allow_ssh.id]
tags = {
Name = "MyFirstEC2Instance"
}
}
Understanding the Configuration
1. Provider Block
provider "aws" {
region = "us-east-1"
}
• Specifies the cloud provider (AWS) and the region
• Terraform will use your AWS credentials from the default AWS CLI
configuration
2. Resource Blocks
Each resource block defines an infrastructure component:
• aws_vpc: Creates a Virtual Private Cloud
• aws_subnet: Creates a subnet within the VPC
• aws_internet_gateway: Enables internet access for the VPC
• aws_route_table: Defines routing rules
• aws_security_group: Acts as a virtual firewall
• aws_instance: Creates an EC2 instance
3. Resource Dependencies
Notice how resources reference each other using syntax like aws_vpc.main.id.
Terraform automatically understands and creates these dependencies.
Initializing and Applying Your Configuration
1. Initialize Terraform
terraform init
This command:
• Downloads the AWS provider plugin
• Sets up the backend for storing state files
2. Validate Your Configuration
terraform validate
Checks for syntax errors and validates the configuration.
3. Plan the Execution
terraform plan
• Shows what Terraform will do before making any changes
• Review the output carefully
4. Apply the Configuration
terraform apply
• Terraform will prompt for confirmation
• Type "yes" to proceed
• Terraform will create all the defined resources
Best Practices for Terraform Scripts
1. Use Variables
Create a variables.tf file:
variable "region" {
description = "AWS region"
default = "us-east-1"
}
variable "instance_type" {
description = "EC2 instance type"
default = "t2.micro"
}
Then update main.tf to use these variables:
provider "aws" {
region = var.region
}
resource "aws_instance" "web" {
instance_type = var.instance_type
# ... rest of the configuration
}
2. Use Outputs
Create an outputs.tf file:
output "instance_public_ip" {
description = "Public IP address of the EC2 instance"
value = aws_instance.web.public_ip
}
3. Organize Your Code
For larger projects, organize resources into modules:
project/
├── main.tf
├── variables.tf
├── outputs.tf
└── modules/
└── networking/
├── main.tf
├── variables.tf
└── outputs.tf
4. State Management
• Never commit .terraform directory or terraform.tfstate files to version
control
• Consider using remote backends like S3 for team collaboration
Cleaning Up
To destroy all created resources:
terraform destroy
Advanced Concepts to Explore Next
1. Remote State Management: Using S3 or Terraform Cloud
2. Workspaces: Managing multiple environments
3. Dynamic Blocks: For complex configurations
4. Provisioners: For configuration management
5. Modules: Reusable components
Common Errors and Troubleshooting
1. Authentication Errors: Verify AWS credentials
2. Region Availability: Some instance types aren't available in all regions
3. Resource Limits: AWS accounts have default limits
4. State Locking: If a command fails, you might need to manually unlock
the state