Skip to main content

Command Palette

Search for a command to run...

Day 2: Installing Terraform & Your First Configuration

Updated
8 min read
Day 2: Installing Terraform & Your First Configuration
S

I'm a cloud-native enthusiast and tech blogger, sharing insights on Kubernetes, AWS, CI/CD, and Linux across my blog and Facebook page. Passionate about modern infrastructure and microservices, I aim to help others understand and leverage cloud-native technologies for scalable, efficient solutions.

Welcome to Day 2! Today is an exciting day—you’ll install Terraform on your computer and write your very first configuration file. By the end of this lesson, you’ll have created actual cloud infrastructure using code!

🎯 Today’s Goals

  • Install Terraform on your system

  • Set up AWS CLI and configure credentials

  • Understand Terraform file structure

  • Write and execute your first Terraform configuration

  • Create your first AWS resource!

📥 Installing Terraform

Terraform is a single binary that runs on Windows, macOS, and Linux. Let’s install it!

Option 1: macOS (using Homebrew)

# Install Terraform
brew tap hashicorp/tap
brew install hashicorp/tap/terraform

# Verify installation terraform version
terraform --version

Option 2: Linux (Ubuntu/Debian)

# Update package list
sudo apt-get update

# Install required packages
sudo apt-get install -y gnupg software-properties-common

# Add HashiCorp GPG key
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

# Add HashiCorp repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list

# Update and install Terraform
sudo apt-get update
sudo apt-get install terraform

# Verify installation terraform version
terraform --version

Option 3: Windows

# Using Chocolatey
choco install terraform

# Verify installation terraform version
terraform --version

Or download manually:

  1. Visit: https://developer.hashicorp.com/terraform/downloads

  2. Download the ZIP for your OS

  3. Extract and add to your PATH

  4. Open new terminal and run terraform -v

✅ Verify Terraform Installation

You should see output like:

Terraform v1.6.0
on linux_amd64

🔑 Setting Up AWS CLI and Credentials

Terraform needs credentials to interact with AWS. Let’s set that up!

Step 1: Install AWS CLI

macOS:

brew install awscli
aws --version

Linux:

curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

Step 2: Create AWS Access Keys

  1. Log into AWS Console

  2. Click your username (top right) → “Security credentials”

  3. Scroll to “Access keys” section

  4. Click “Create access key”

  5. Choose “CLI” use case

  6. Save your:

    • Access Key ID (e.g., AIAXAMPLSLEISE)

    • Secret Access Key (e.g., wJalr/bPxRfiCYEXPPSSAAAMPLEKEY)

⚠️ Important: Never share or commit these keys to version control!

Step 3: Configure AWS CLI

aws configure

You’ll be prompted to enter:

AWS Access Key ID [None]: your access key
AWS Secret Access Key [None]: your secret access key
Default region name [None]: your default region - example (us-east-1)
Default output format [None]: json

This creates two files:

  • ~/.aws/credentials (your keys)

  • ~/.aws/config (configuration)

Step 4: Test AWS Access

aws sts get-caller-identity

You should see your AWS account information!

📁 Terraform File Structure

Terraform uses files with .tf extensions. Here’s a typical structure:

my-terraform-project/
├── main.tf           # Main configuration file
├── variables.tf      # Input variables
├── outputs.tf        # Output values
├── providers.tf      # Provider configurations
└── terraform.tfstate # State file (created automatically)

For now, we’ll keep it simple with just a main.tf file.

📝 Your First Terraform Configuration

Let’s create a simple S3 bucket—AWS’s object storage service.

Understanding the Structure

# This is a comment in HCL

# Provider block - which cloud platform to use
provider "provider_name" {
  # provider configuration
}

# Resource block - what to create
resource "resource_type" "resource_name" {
  # resource configuration
}

The Terraform Block Structure

┌─────────────────────────────────────────┐
│ resource "aws_s3_bucket" "my_bucket" {  │
│          ─┬──  ────┬────── ────┬─────   │
│           │        │           │        │
│      Resource   Resource   Local name   │
│      Type       Provider   (your choice)│
│                                         │
│   bucket = "my-unique-bucket-name"      │
│   ──┬───   ─────────┬────────────       │
│     │               │                   │
│  Argument        Value                  │
│ }                                       │
└─────────────────────────────────────────┘

🧪 Hands-On Lab: Create Your First S3 Bucket

Let’s create infrastructure! Follow these steps carefully.

Step 1: Create a Project Directory

# Create a new directory
mkdir my-first-terraform
cd my-first-terraform

Step 2: Create main.tf

Create a file named main.tf with this content:

# Configure the AWS Provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

# Create an S3 bucket
resource "aws_s3_bucket" "my_first_bucket" {
  bucket = "my-terraform-learning-bucket-12345"  # Must be globally unique!

  tags = {
    Name        = "My First Bucket"
    Environment = "Learning"
    ManagedBy   = "Terraform"
  }
}

⚠️ Important: S3 bucket names must be globally unique across ALL AWS accounts. Change 12345 to something unique (like your name + date).

Step 3: Initialize Terraform

terraform init

What happens:

  • Terraform downloads the AWS provider plugin

  • Creates .terraform directory

  • Sets up the backend

Expected output:

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.x.x...
- Installed hashicorp/aws v5.x.x

Terraform has been successfully initialized!

Step 4: Format Your Code

terraform fmt

This automatically formats your .tf files to follow best practices.

Step 5: Validate Your Configuration

terraform validate

Expected output:

Success! The configuration is valid.

Step 6: Plan Your Changes

terraform plan

What this does:

  • Analyzes your configuration

  • Compares with current state (empty for now)

  • Shows what will be created

Expected output:

Terraform will perform the following actions:

  # aws_s3_bucket.my_first_bucket will be created
  + resource "aws_s3_bucket" "my_first_bucket" {
      + bucket                      = "my-terraform-learning-bucket-12345"
      + bucket_domain_name          = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + tags                        = {
          + "Environment" = "Learning"
          + "ManagedBy"   = "Terraform"
          + "Name"        = "My First Bucket"
        }
      + tags_all                    = {
          + "Environment" = "Learning"
          + "ManagedBy"   = "Terraform"
          + "Name"        = "My First Bucket"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Understanding the output:

  • + means “will be created”

  • (known after apply) means AWS will generate that value

  • Plan: 1 to add confirms one resource will be created

Step 7: Apply Your Configuration

terraform apply

Terraform will show the plan again and ask for confirmation:

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:

Type yes and press Enter.

Expected output:

aws_s3_bucket.my_first_bucket: Creating...
aws_s3_bucket.my_first_bucket: Creation complete after 3s [id=my-terraform-learning-bucket-12345]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Step 8: Verify in AWS Console

  1. Log into AWS Console

  2. Go to S3 service

  3. You should see your bucket listed!

Step 9: Check Terraform State

terraform show

This displays the current state of your infrastructure.

# Or view the state file directly
cat terraform.tfstate

You’ll see detailed JSON about your bucket.

Step 10: Destroy Your Resources

Important: Always clean up resources to avoid charges!

terraform destroy

Type yes when prompted.

Expected output:

aws_s3_bucket.my_first_bucket: Destroying... [id=my-terraform-learning-bucket-12345]
aws_s3_bucket.my_first_bucket: Destruction complete after 1s

Destroy complete! Resources: 1 destroyed.

Verify in the AWS Console that your bucket is gone!

🎓 Understanding What Just Happened

Let’s break down each command:

CommandPurpose
terraform initInitialize the project and download providers
terraform fmtFormat code to standard style
terraform validateCheck syntax and configuration
terraform planPreview changes without applying
terraform applyCreate/update infrastructure
terraform showDisplay current state
terraform destroyDelete all managed infrastructure

🔍 Examining the Files Created

After running Terraform, you’ll see these files:

my-first-terraform/
├── .terraform/              # Provider plugins (don't commit)
├── .terraform.lock.hcl      # Provider version lock file (commit this)
├── main.tf                  # Your configuration
├── terraform.tfstate        # Current state (don't commit - sensitive!)
└── terraform.tfstate.backup # Previous state backup

📚 Key Concepts Review

Terraform Block

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}
  • Specifies Terraform settings

  • Defines required providers and versions

  • ~> 5.0 means “version 5.x.x” (any minor/patch version)

Provider Block

provider "aws" {
  region = "us-east-1"
}
  • Configures the AWS provider

  • Sets default region

  • Uses credentials from ~/.aws/credentials

Resource Block

resource "aws_s3_bucket" "my_first_bucket" {
  bucket = "unique-bucket-name"
  tags = {
    Name = "MyBucket"
  }
}
  • Creates actual infrastructure

  • Format: resource "TYPE" "NAME"

  • Contains configuration arguments

💡 Best Practices You Just Learned

  1. ✅ Always run terraform plan before apply

  2. ✅ Use unique, descriptive resource names

  3. ✅ Add tags to all resources for organization

  4. ✅ Destroy resources when done practicing

  5. ✅ Keep credentials secure (never in code)

🐛 Troubleshooting Common Issues

Error: “InvalidBucketName”

  • Bucket names must be globally unique

  • Use lowercase, numbers, and hyphens only

  • Change your bucket name and try again

Error: “No valid credential sources”

  • AWS credentials not configured

  • Run aws configure again

  • Verify with aws sts get-caller-identity

Error: “Unauthorized operation”

  • Your AWS user lacks permissions

  • Add AmazonS3FullAccess policy to your user

📝 Summary

Today you:

  • ✅ Installed Terraform on your system

  • ✅ Configured AWS CLI and credentials

  • ✅ Learned Terraform file structure

  • ✅ Understood HCL syntax basics

  • ✅ Created your first infrastructure with code!

  • ✅ Used all core Terraform commands

  • ✅ Properly cleaned up resources

🚀 Tomorrow’s Preview

Day 3: Understanding Providers & AWS Setup

Tomorrow we’ll:

  • Deep dive into Terraform providers

  • Explore the AWS provider in detail

  • Learn about provider versioning

  • Create multiple AWS resources

  • Build a simple VPC network

💭 Challenge Exercise

Before Day 3, try this:

  1. Create a new directory my-second-terraform

  2. Write a configuration to create TWO S3 buckets

  3. Apply it, verify it in the AWS Console, then destroy it.

Hint: Just duplicate the resource block with different names!

resource "aws_s3_bucket" "bucket_one" {
  bucket = "my-first-practice-bucket-12345"
}

resource "aws_s3_bucket" "bucket_two" {
  bucket = "my-second-practice-bucket-12345"
}

Happy Learning! 🎉

Thanks For Reading, Follow Me For More

Subscribe youtube channel for the recap videos

Have a great day!..

← Day 1: What is IaC & Terraform | Day 3: Understanding Providers →


Remember: Always run terraform destroy after practice to avoid unexpected AWS charges!

T

Thank you!

More from this blog

S

StackOps - Diary

33 posts

Welcome to the StackOps - Diary. We’re dedicated to empowering the tech community. We delve into cloud-native and microservices technologies, sharing knowledge to build modern, scalable solutions.