Setting Up Terraform for AWS - My CRC Walkthrough
This guide walks through setting up Terraform for AWS infrastructure management, from installing tools to understanding state management. This is part of my Cloud Resume Challenge journey where I'm deploying a multi-cloud resume website.
Prerequisites
Before starting, you need:
- An AWS account
- Windows computer (commands shown for Windows, but concepts apply to all OS)
- Basic command line knowledge
Step 1: AWS Authentication Setup
Understanding AWS SSO vs IAM Users
AWS SSO (Single Sign-On) - What I used:
- Temporary credentials that auto-rotate
- More secure than static access keys
- Recommended for organizations and personal use
IAM User with Access Keys - Alternative:
- Static credentials (Access Key ID + Secret)
- Need manual rotation every 90 days
- Simpler for beginners
My Setup: AWS SSO
I configured AWS SSO through my organization's identity provider. After setup, I verified it works:
Output:
{
"UserId": "AROA4J3XQK62E6GYZQBET:ramsi_admin_access",
"Account": "845822318516",
"Arn": "arn:aws:sts::845822318516:assumed-role/AWSReservedSSO_AdministratorAccess_f600b682105275a8/ramsi_admin_access"
}
The --profile ramsi_admin_access flag tells AWS CLI which credentials to use. This profile is configured in ~/.aws/config.
Step 2: Install Terraform
Using Windows Package Manager (winget)
Output:
Found HashiCorp Terraform [Hashicorp.Terraform] Version 1.14.0
Downloading https://releases.hashicorp.com/terraform/1.14.0/terraform_1.14.0_windows_amd64.zip
Successfully verified installer hash
Extracting archive...
Path environment variable modified; restart your shell to use the new value.
Successfully installed
After installation, restart your terminal for the PATH changes to take effect.
Verify Installation
Output:
Step 3: Create Terraform Configuration
Project Structure
For this tutorial, we're focusing on the AWS infrastructure setup:
cloud-resume-challenge/
├── docs/ # Website source (MkDocs)
├── aws/
│ └── frontend/ # AWS frontend
│ ├── backend.tf # Terraform & provider
│ ├── variables.tf # Input variables
│ └── outputs.tf # Output values
└── mkdocs.yml # MkDocs configuration
File 1: backend.tf
This file configures Terraform itself and the AWS provider.
# Terraform Backend Configuration
# Currently using local state (terraform.tfstate in this directory)
terraform {
required_version = ">= 1.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# AWS Provider Configuration
provider "aws" {
region = var.aws_region
profile = var.aws_profile
default_tags {
tags = {
Project = "cloud-resume-challenge"
Environment = "production"
ManagedBy = "terraform"
}
}
}
What this does:
required_version: Ensures Terraform 1.7 or newerrequired_providers: Downloads AWS provider pluginprovider "aws": Configures AWS connection with profile and regiondefault_tags: Automatically tags all resources
File 2: variables.tf
Input variables make your configuration reusable.
variable "aws_region" {
description = "AWS region for resources"
type = string
default = "us-east-1"
}
variable "aws_profile" {
description = "AWS CLI profile to use"
type = string
default = "ramsi_admin_access"
}
variable "domain_name" {
description = "Domain name for the website (apex domain)"
type = string
default = "ramsi.dev"
}
variable "domain_name_www" {
description = "WWW subdomain (will redirect to apex)"
type = string
default = "www.ramsi.dev"
}
variable "project_name" {
description = "Project name for resource naming"
type = string
default = "cloud-resume-challenge"
}
Why variables?
- Easy to change values without editing multiple files
- Can override defaults:
terraform apply -var="aws_region=us-west-2" - Makes code reusable across environments
File 3: outputs.tf
Outputs display values after Terraform runs.
output "aws_region" {
description = "AWS region used"
value = var.aws_region
}
output "project_name" {
description = "Project name"
value = var.project_name
}
Use cases:
- Display important values (bucket names, URLs)
- Pass values to other Terraform modules
- Use in scripts:
terraform output -raw aws_region
Step 4: Initialize Terraform
What happens:
- Terraform reads
backend.tf - Downloads AWS provider plugin (~200MB)
- Creates
.terraform/directory with plugins - Creates
.terraform.lock.hcl(dependency lock file)
Output:
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.100.0...
- Installed hashicorp/aws v5.100.0 (signed by HashiCorp)
Terraform has been successfully initialized!
You can now run terraform plan and terraform apply!
Understanding Terraform State
What is Terraform State?
The state file (terraform.tfstate) is Terraform's memory. It tracks:
- What resources exist in AWS
- Resource IDs and attributes
- Dependencies between resources
Example state content:
{
"resources": [
{
"type": "aws_s3_bucket",
"name": "website",
"instances": [
{
"attributes": {
"id": "ramsi-resume-site",
"arn": "arn:aws:s3:::ramsi-resume-site",
"region": "us-east-1"
}
}
]
}
]
}
Local vs Remote State
Local State (What I'm Using)
Location: aws/frontend/terraform.tfstate (on your computer)
Pros:
- Simple setup (no extra configuration)
- Works immediately
- No additional AWS costs
- Good for solo projects and learning
Cons:
- Only accessible from your computer
- Risk of loss if computer fails
- Can't collaborate easily
- Manual backup needed
When to use:
- Learning Terraform
- Solo projects
- Quick experiments
- When you commit state to git
Remote State (Production Best Practice)
Location: S3 bucket in AWS
Pros:
- Accessible from any computer
- Automatic backup and versioning
- Team collaboration (with locking)
- Secure and encrypted
Cons:
- Requires initial setup
- Small AWS costs (~$0.01/month)
- More complex configuration
When to use:
- Production environments
- Team projects
- Working from multiple computers
- CI/CD pipelines
Common Issues and Solutions
Issue 1: "command not found: terraform"
Solution: Restart your terminal after installation.
Issue 2: "Error: No valid credential sources found"
Solution: Configure AWS credentials:
Issue 3: "Error: Failed to get existing workspaces"
Solution: Check your AWS profile is correct in variables.tf.
Issue 4: State file conflicts
Solution: Use remote state with DynamoDB locking.
Next Steps
Now that Terraform is configured, the next tasks are:
- Create S3 bucket for website hosting
- Configure CloudFront CDN
- Set up Route 53 DNS
- Request ACM certificate for HTTPS
Each of these will be defined in separate .tf files in the aws/frontend/ directory.
Key Takeaways
- AWS SSO is more secure than static access keys
- Terraform state is not your website - it's just tracking metadata
- Local state works fine for solo projects and learning
- Remote state is better for production and teams
- The
-chdirflag lets you run Terraform from any directory
Resources
- Terraform AWS Provider Documentation
- Terraform Backend Configuration
- AWS CLI Configuration
- My GitHub Repository