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: