Terraform Providers & Resources
Providers are plugins that Terraform uses to interact with cloud providers and services. Resources are the building blocks that represent infrastructure objects.
What are Providers?
Provider Purpose
Providers are plugins that Terraform uses to interact with cloud providers, SaaS providers, and other APIs. Each provider adds a set of resource types and data sources that Terraform can manage.
Common Providers
Cloud Providers
- AWS -
hashicorp/aws - Azure -
hashicorp/azurerm - GCP -
hashicorp/google - Alibaba Cloud -
aliyun/alicloud - Oracle Cloud -
oracle/oci
Infrastructure Providers
- Docker -
kreuzwerker/docker - Kubernetes -
hashicorp/kubernetes - VMware vSphere -
hashicorp/vsphere
Configuring Providers
Required Providers Block
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
}
}
Provider Configuration
# AWS Provider
provider "aws" {
region = "us-east-1"
# Authentication methods:
# 1. Environment variables
# AWS_ACCESS_KEY_ID
# AWS_SECRET_ACCESS_KEY
# AWS_REGION
# 2. AWS credentials file (~/.aws/credentials)
# shared_credentials_files = ["~/.aws/credentials"]
# profile = "production"
# 3. Direct configuration (not recommended)
# access_key = var.aws_access_key
# secret_key = var.aws_secret_key
}
# Multiple provider instances
provider "aws" {
alias = "us-east"
region = "us-east-1"
}
provider "aws" {
alias = "us-west"
region = "us-west-2"
}
Resources
Resource Block Syntax
resource "resource_type" "resource_name" {
argument1 = value1
argument2 = value2
# Nested blocks
nested_block {
nested_argument = value
}
# Multiple instances with count
count = 3
# Multiple instances with for_each
for_each = var.instances
}
AWS Resource Examples
EC2 Instance
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
}
}
S3 Bucket
resource "aws_s3_bucket" "website" {
bucket = "my-website-bucket"
tags = {
Name = "Website Bucket"
}
}
resource "aws_s3_bucket_versioning" "website" {
bucket = aws_s3_bucket.website.id
versioning_configuration {
status = "Enabled"
}
}
VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
Data Sources
What are Data Sources?
Data sources allow Terraform to fetch information from outside Terraform:
AWS Data Source Examples
# Get AMI
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
# Get VPC
data "aws_vpc" "existing" {
id = "vpc-12345678"
}
# Get availability zones
data "aws_availability_zones" "available" {
state = "available"
}
# Use data sources
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t2.micro"
subnet_id = data.aws_subnet.main.id
}
Resource Dependencies
Implicit Dependencies
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "web" {
vpc_id = aws_vpc.main.id # Implicit dependency
cidr_block = "10.0.0.0/24"
}
Explicit Dependencies
resource "aws_instance" "web" {
# ...
depends_on = [
aws_iam_role.example,
aws_security_group.example
]
}
Multiple Resource Instances
Using count
resource "aws_instance" "web" {
count = 3
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer-${count.index + 1}"
}
}
# Access
aws_instance.web[0].id
aws_instance.web[1].id
Using for_each
variable "instances" {
type = map(string)
default = {
web1 = "t2.micro"
web2 = "t2.small"
web3 = "t3.medium"
}
}
resource "aws_instance" "web" {
for_each = var.instances
ami = "ami-0c55b159cbfafe1f0"
instance_type = each.value
tags = {
Name = each.key
}
}
# Access
aws_instance.web["web1"].id
Next Steps
- AWS Setup - Complete AWS setup guide
- Modules - Creating reusable modules
- Core Concepts - Deep dive into fundamentals