File Structure

tf-multi-resources/
├── main.tf           # VPC, subnet, EC2 resources
├── variables.tf      # variable definitions
└── terraform.tfvars  # actual values

What We Learn Here


Goal

subnet-0 → ec2-0 (ubuntu)
subnet-1 → ec2-1 (amazon-linux)

Subnet count  = driven by ec2_config list length
EC2 count     = driven by ec2_config list length
AMI per EC2   = from ec2_config[index].ami

Variable - List of Objects

variables.tf — defines the structure:

variable "ec2_config" {
  type = list(object({
    ami           = string
    instance_type = string
  }))
}

terraform.tfvars — actual values:

ec2_config = [
  {
    ami           = "ami-ubuntu-xxxx"    # ec2-0 → ubuntu
    instance_type = "t3.micro"
  },
  {
    ami           = "ami-amazon-xxxx"    # ec2-1 → amazon linux
    instance_type = "t3.micro"
  }
]

Complete Code

locals {
  project = "project-01"
}

resource "aws_vpc" "my-vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "${local.project}-vpc"
  }
}

# Subnet count driven by ec2_config list length - no hardcoding
resource "aws_subnet" "main" {
  vpc_id     = aws_vpc.my-vpc.id
  count      = length(var.ec2_config)           # 2 subnets (list has 2 items)
  cidr_block = "10.0.${count.index}.0/24"

  tags = {
    Name = "${local.project}-subnet-${count.index}"
  }
}

# Each EC2 gets config from its matching index in ec2_config
resource "aws_instance" "name" {
  count         = length(var.ec2_config)                    # 2 instances
  ami           = var.ec2_config[count.index].ami           # different per instance
  instance_type = var.ec2_config[count.index].instance_type # different per instance
  subnet_id     = element(aws_subnet.main[*].id, count.index % length(aws_subnet.main))

  tags = {
    Name = "${local.project}-instance-${count.index}"
  }
}