AWS Resource Types in Terraform – 25 Essential Examples You Can Copy and Use
Updated Jun 2026 · originally published Jun 2026 · Tested on Linux, Unix
Terraform is an open-source infrastructure-as-code (IaC) tool from HashiCorp that lets you define and provision cloud infrastructure using declarative configuration files. When you work with AWS, every piece of infrastructure — a server, a network, a bucket, a database — is created using a resource type .
Every AWS resource type in Terraform starts with the aws_ prefix and is managed by the official AWS provider. In this guide we cover the 25 most-used AWS resource types, grouped by category, each with a working copy-paste example.
If you are new to Terraform commands first, check out our post on Terraform – 7 Essential Commands for Managing Infrastructure .
What is an AWS Resource Type in Terraform?
A resource type tells Terraform what to create. The syntax is always:
resource "<resource_type>" "<local_name>" {
# arguments
}
resource— the block keyword<resource_type>— the AWS object, e.g.aws_instance<local_name>— a name you choose to reference it elsewhere (e.g.aws_instance.web.id)
Before any resource works, you need the provider configured:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-west-1"
}
Compute Resources
aws_instance – Launch an EC2 virtual machine
resource "aws_instance" "web" {
ami = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
tags = {
Name = "web-server"
Environment = "prod"
}
}
aws_launch_template – Reusable instance configuration
resource "aws_launch_template" "app" {
name_prefix = "app-"
image_id = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
tag_specifications {
resource_type = "instance"
tags = {
Name = "app-from-template"
}
}
}
aws_autoscaling_group – Auto-scale an EC2 fleet
resource "aws_autoscaling_group" "app" {
name = "app-asg"
min_size = 1
max_size = 5
desired_capacity = 2
vpc_zone_identifier = [aws_subnet.public.id]
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
}
aws_lambda_function – Serverless function
resource "aws_lambda_function" "processor" {
function_name = "data-processor"
runtime = "python3.12"
handler = "main.handler"
filename = "lambda.zip"
role = aws_iam_role.lambda.arn
timeout = 30
memory_size = 256
}
aws_eks_cluster – Managed Kubernetes control plane
resource "aws_eks_cluster" "prod" {
name = "prod-cluster"
role_arn = aws_iam_role.eks.arn
version = "1.30"
vpc_config {
subnet_ids = [aws_subnet.public.id, aws_subnet.private.id]
}
}
If you are comparing orchestration vs provisioning, see Terraform vs Kubernetes – Key Differences .
aws_ecs_service – Run containers on ECS
resource "aws_ecs_service" "app" {
name = "app-service"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = [aws_subnet.private.id]
assign_public_ip = false
}
}
Networking Resources
aws_vpc – Isolated virtual network
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "main-vpc"
}
}
aws_subnet – IP range inside a VPC
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-1a"
map_public_ip_on_launch = true
tags = {
Name = "public-subnet"
}
}
aws_internet_gateway – Public internet access for a VPC
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-igw"
}
}
aws_route_table – Routing rules for subnets
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-rt"
}
}
aws_nat_gateway – Outbound internet for private subnets
resource "aws_eip" "nat" {
domain = "vpc"
}
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public.id
tags = {
Name = "main-nat"
}
}
aws_security_group – Virtual firewall
resource "aws_security_group" "web" {
name = "web-sg"
description = "Allow HTTP and SSH"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
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"]
}
}
aws_lb – Application/Network Load Balancer
resource "aws_lb" "app" {
name = "app-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.web.id]
subnets = [aws_subnet.public.id]
}
If load balancing concepts are new, read What is a Load Balancer and How it Works .
Storage Resources
aws_s3_bucket – Object storage
resource "aws_s3_bucket" "assets" {
bucket = "adminschoice-app-assets-2026"
tags = {
Environment = "prod"
}
}
aws_s3_bucket_versioning – Enable versioning on a bucket
resource "aws_s3_bucket_versioning" "assets" {
bucket = aws_s3_bucket.assets.id
versioning_configuration {
status = "Enabled"
}
}
aws_ebs_volume – Block storage for EC2
resource "aws_ebs_volume" "data" {
availability_zone = "us-west-1a"
size = 100
type = "gp3"
encrypted = true
tags = {
Name = "app-data-volume"
}
}
aws_efs_file_system – Shared NFS file system
resource "aws_efs_file_system" "shared" {
creation_token = "app-shared-fs"
encrypted = true
tags = {
Name = "shared-efs"
}
}
Database Resources
aws_db_instance – Managed RDS database
resource "aws_db_instance" "main" {
identifier = "app-postgres"
engine = "postgres"
engine_version = "16.3"
instance_class = "db.t3.micro"
allocated_storage = 20
db_name = "appdb"
username = "dbadmin"
password = var.db_password
skip_final_snapshot = true
}
Tip: never hardcode passwords. Use a Terraform variable (
var.db_password) and pass it through a secrets manager or environment variable.
aws_dynamodb_table – NoSQL key-value table
resource "aws_dynamodb_table" "users" {
name = "users"
billing_mode = "PAY_PER_REQUEST"
hash_key = "user_id"
attribute {
name = "user_id"
type = "S"
}
}
aws_elasticache_cluster – Redis / Memcached cache
resource "aws_elasticache_cluster" "redis" {
cluster_id = "app-redis"
engine = "redis"
node_type = "cache.t3.micro"
num_cache_nodes = 1
parameter_group_name = "default.redis7"
port = 6379
}
IAM and Security Resources
aws_iam_role – Assumable role with a trust policy
resource "aws_iam_role" "lambda" {
name = "lambda-exec-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
}]
})
}
aws_iam_policy – Standalone permission document
resource "aws_iam_policy" "s3_read" {
name = "s3-read-only"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject", "s3:ListBucket"]
Resource = ["${aws_s3_bucket.assets.arn}", "${aws_s3_bucket.assets.arn}/*"]
}]
})
}
aws_kms_key – Encryption key
resource "aws_kms_key" "app" {
description = "App data encryption key"
deletion_window_in_days = 10
enable_key_rotation = true
}
DNS, CDN and Monitoring Resources
aws_route53_record – DNS record
resource "aws_route53_record" "www" {
zone_id = "Z1234567890ABC"
name = "www.example.com"
type = "A"
alias {
name = aws_lb.app.dns_name
zone_id = aws_lb.app.zone_id
evaluate_target_health = true
}
}
aws_cloudwatch_metric_alarm – Metric-based alarm
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "high-cpu-utilization"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = 300
statistic = "Average"
threshold = 80
alarm_description = "Triggers when CPU exceeds 80%"
}
Resource Types vs Data Sources
Resources create and manage infrastructure. Data sources only read existing infrastructure. A data source uses the data keyword instead of resource :
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
# Use it inside a resource:
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
}
Quick Reference Table
Category Resource Type Purpose Compute aws_instance EC2 virtual machine Compute aws_autoscaling_group Auto-scaling EC2 fleet Compute aws_lambda_function Serverless function Compute aws_eks_cluster Managed Kubernetes Networking aws_vpc Isolated network Networking aws_subnet Network subdivision Networking aws_security_group Firewall rules Networking aws_lb Load balancer Storage aws_s3_bucket Object storage Storage aws_ebs_volume Block storage Database aws_db_instance Managed RDS Database aws_dynamodb_table NoSQL table IAM aws_iam_role Assumable role IAM aws_kms_key Encryption key DNS aws_route53_record DNS record Monitoring aws_cloudwatch_metric_alarm Metric alarm
Conclusion
AWS resource types are the building blocks of every Terraform configuration. Once you understand the resource "aws_xxx" "name" {} pattern, the AWS provider’s hundreds of resource types all follow the same shape. Start with the provider block, add the resources you need from the examples above, then run terraform init , terraform plan , and terraform apply .
For the full list of resource types, refer to the official Terraform AWS Provider documentation .
Related posts on Admin’s Choice: