Day 3: Understanding Providers & AWS Setup

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 3! Now that youβve created your first resource, letβs dive deeper into Providers - the plugins that allow Terraform to interact with cloud platforms, SaaS providers, and other APIs.
π― Todayβs Goals
Understand what Terraform providers are
Learn provider configuration in detail
Explore provider versioning and locking
Master the AWS provider
Create a complete VPC network infrastructure
π What Are Terraform Providers?
Providers are plugins that enable Terraform to interact with cloud platforms, SaaS services, and APIs.
ββββββββββββββββ
β Terraform β
β Core β
ββββββββ¬ββββββββ
β
β Uses plugins to communicate
β
βββββ΄βββββββββββββββββββββββββββββββββ
β β
ββββΌββββββ ββββββββββββ βββββββββββββ
β AWS β β Azure β β Google β
βProviderβ β Provider β β Provider β
βββββ¬βββββ βββββββ¬βββββ βββββββ¬ββββββ
β β β
βΌ βΌ βΌ
ββββββββββ ββββββββββ ββββββββββββ
β AWS β β Azure β β GCP β
β API β β API β β API β
ββββββββββ ββββββββββ ββββββββββββ
Think of providers as translatorsβthey translate your HCL code into API calls for the target platform.
π¦ Provider Types
1. Official Providers (by HashiCorp)
AWS, Azure, Google Cloud
Maintained by HashiCorp
Highest quality and reliability
2. Partner Providers
Datadog, Kubernetes, Docker
Maintained by the company
Verified by HashiCorp
3. Community Providers
Built by community members
Various quality levels
Use with caution in production
4. Archived Providers
No longer maintained
Avoid using these
ποΈ Provider Configuration Structure
Basic Provider Configuration
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
Breaking It Down
1. Terraform Block:
terraform {
required_providers {
# Provider requirements
}
}
Specifies Terraform settings
Defines which providers are needed
Sets version constraints
2. Provider Source:
source = "hashicorp/aws"
Format:
namespace/provider-namehashicorp= namespace (publisher)aws= provider nameTerraform downloads from: registry.terraform.io
3. Version Constraint:
version = "~> 5.0"
Version operators:
= 5.0.0- Exactly version 5.0.0!= 5.0.0- Any version except 5.0.0> 5.0.0- Greater than 5.0.0>= 5.0.0- Greater than or equal to 5.0.0< 5.0.0- Less than 5.0.0<= 5.0.0- Less than or equal to 5.0.0~> 5.0- Any 5.x version (pessimistic constraint)
Pessimistic Constraint Explained:
~> 5.0allows5.1,5.2, but NOT6.0~> 5.0.0allows5.0.1,5.0.2, but NOT5.1.0
π AWS Provider Configuration Methods
Method 1: Environment Variables (Recommended for CI/CD)
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-east-1"
provider "aws" {
# No explicit configuration needed
# Uses environment variables
}
Method 2: Shared Credentials File (Recommended for Local)
provider "aws" {
region = "us-east-1"
shared_credentials_files = ["~/.aws/credentials"]
profile = "default"
}
Method 3: Static Credentials (NOT Recommended)
provider "aws" {
region = "us-east-1"
access_key = "your-access-key" # β Never do this!
secret_key = "your-secret-access-key" # β Security risk!
}
β οΈ Never hardcode credentials in your code!
Method 4: IAM Role (Best for EC2/ECS)
When running Terraform on AWS resources:
provider "aws" {
region = "us-east-1"
# Automatically uses instance IAM role
}
π Multiple Provider Configurations
You can configure the same provider multiple times for different regions or accounts:
# Default provider (us-east-1)
provider "aws" {
region = "us-east-1"
}
# Additional provider for another region
provider "aws" {
alias = "west"
region = "us-west-2"
}
# Use in resources
resource "aws_s3_bucket" "east_bucket" {
bucket = "my-east-bucket"
# Uses default provider (us-east-1)
}
resource "aws_s3_bucket" "west_bucket" {
bucket = "my-west-bucket"
provider = aws.west # Explicitly use west provider
}
π Provider Version Locking
After running terraform init, Terraform creates .terraform.lock.hcl:
# This file is maintained automatically by "terraform init".
provider "registry.terraform.io/hashicorp/aws" {
version = "5.31.0"
constraints = "~> 5.0"
hashes = [
"h1:xxx...",
"zh:xxx...",
]
}
Why this matters:
Ensures team uses same provider version
Prevents unexpected changes from updates
Should be committed to version control
To update providers:
terraform init -upgrade
π§ͺ Hands-On Lab: Build a Complete VPC Network
Letβs build a real network infrastructure in AWS!
What Weβll Create
βββββββββββββββββββββββββββββββ
β VPC β
β 10.0.0.0/16 β
β β
β ββββββββββββββββββββββ β
β β Public Subnet β β
β β 10.0.1.0/24 β β
β β β β
β β ββββββββββββββββ β β
β β β EC2 Instanceβ β β
β β ββββββββββββββββ β β
β ββββββββββββββββββββββ β
β β β
ββββββββββββββΌβββββββββββββββββ
β
βββββββββΌβββββββββ
β Internet Gatewayβ
ββββββββββββββββββ
β
βΌ
Internet
Step 1: Create Project Directory
mkdir terraform-vpc-lab
cd terraform-vpc-lab
Step 2: Create main.tf
# Terraform configuration
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# AWS Provider configuration
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Project = "TerraformLearning"
ManagedBy = "Terraform"
Environment = "Development"
}
}
}
# Create a VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
# Create an Internet Gateway
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-igw"
}
}
# Create a Public Subnet
resource "aws_subnet" "public" {
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"
}
}
# Create a Route Table
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "public-route-table"
}
}
# Associate Route Table with Subnet
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
# Create a Security Group
resource "aws_security_group" "web" {
name = "web-security-group"
description = "Allow HTTP and SSH traffic"
vpc_id = aws_vpc.main.id
# Allow SSH from anywhere (for learning - restrict in production!)
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow HTTP from anywhere
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow all outbound traffic
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "web-sg"
}
}
Step 3: Initialize Terraform
terraform init
Youβll see Terraform download the AWS provider.
Step 4: Format and Validate
terraform fmt
terraform validate
Step 5: Plan the Deployment
terraform plan
Review the output carefully:
Count the resources to be created (should be 6)
Notice the dependencies (e.g., IGW depends on VPC)
See how resources reference each other
Step 6: Apply the Configuration
terraform apply
Type yes when prompted.
Expected output:
aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 3s [id=vpc-xxx]
aws_internet_gateway.main: Creating...
aws_subnet.public: Creating...
...
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
Step 7: Verify in AWS Console
Go to VPC Dashboard
Check:
VPCs: See βmain-vpcβ
Subnets: See βpublic-subnetβ
Internet Gateways: See βmain-igwβ
Route Tables: See βpublic-route-tableβ
Security Groups: See βweb-sgβ
Step 8: Examine Resource Dependencies
terraform graph
This shows the dependency graph. To visualize it:
terraform graph | dot -Tpng > graph.png
(Requires Graphviz: brew install graphviz or apt install graphviz)
Step 9: Inspect Specific Resources
# Show all resources
terraform show
# Show specific resource
terraform state show aws_vpc.main
Step 10: Understanding Resource References
Notice in our code:
vpc_id = aws_vpc.main.id
This creates an implicit dependency:
Terraform knows the subnet depends on the VPC
It creates the VPC first, then the subnet
Format:
resource_type.resource_name.attribute
Step 11: Clean Up
terraform destroy
Type yes to confirm.
Terraform will destroy resources in the correct order (reverse of creation).
π Understanding Default Tags
Notice this in our provider block:
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Project = "TerraformLearning"
ManagedBy = "Terraform"
Environment = "Development"
}
}
}
Default tags are automatically applied to ALL resources:
No need to repeat in each resource
Easy to update globally
Ensures consistent tagging
Individual resource tags merge with default tags.
π Provider Configuration Best Practices
β DO:
Always specify provider version constraints
Use
~>for flexibility with safetyCommit
.terraform.lock.hclto version controlUse environment variables or shared credentials
Set default tags for consistent resource tagging
Use separate providers for different regions
β DONβT:
Hardcode credentials in
.tffilesUse
>= 0.0.0(too permissive)Skip version constraints
Ignore the lock file
Use community providers without research
π Useful Provider Commands
# Show providers used in configuration
terraform providers
# Show dependency information
terraform providers schema
# Update providers to latest allowed version
terraform init -upgrade
# Download providers without other init steps
terraform providers mirror ./providers
π Summary
Today you learned:
β What Terraform providers are and how they work
β How to configure the AWS provider
β Provider versioning and version constraints
β Provider version locking with
.terraform.lock.hclβ Multiple provider configurations
β Default tags for consistent resource tagging
β How to reference resources (implicit dependencies)
β Built a complete VPC network infrastructure
π Tomorrowβs Preview
Day 4: Terraform Basics - Variables & Outputs
Tomorrow weβll:
Learn about input variables
Create reusable configurations
Use output values to share data
Build a parameterized infrastructure
Make our code more flexible and DRY
π Challenge Exercise
Modify todayβs VPC lab to:
Add a second public subnet in
us-east-1bCreate a private subnet in
10.0.2.0/24Add a security group for databases (port 3306)
Hints:
Copy the subnet resource and change values
Private subnets donβt need
map_public_ip_on_launchUse the same VPC ID for all resources
Happy Learning! π
Thanks For Reading, Follow Me For More
Subscribe youtube channel for the recap videos
Have a great day!..
β Day 2: Installing Terraform | Day 4: Variables & Outputs β
Remember: Understanding providers is crucialβtheyβre the foundation of all Terraform configurations!



