Search code examples
amazon-ec2terraform

Terraform - Create ec2 instances in each availability zone


I am trying to create multiple ec2 instance with this script

resource "aws_instance" "my-instance" {
  count = 3
  ami           = ...
  instance_type = ...
  key_name = ...
  security_groups = ...

  tags = {
    Name = "my-instance - ${count.index + 1}"
  }
}

This creates 3 instances. But all three are in same availability zones. I want to create one instance in each availability zone or one in each of the availability zone that I provide. How can I do it?

I read that I can use

 subnet_id = ...

option to specify the availability zone where the instance should be created. But I am not able to figure out how to loop through instance creation (which is currently being handled by count parameter) and specifiy different subnet_id

Can someone help please.


Solution

  • There are several ways of accomplishing this. What I would recommend is to create a VPC with 3 subnets and place an instance in each subnet:

    # Specify the region in which we would want to deploy our stack
    variable "region" {
      default = "us-east-1"
    }
    
    # Specify 3 availability zones from the region
    variable "availability_zones" {
      default = ["us-east-1a", "us-east-1b", "us-east-1c"]
    }
    
    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 3.0"
        }
      }
    }
    
    # Configure the AWS Provider
    provider "aws" {
      region = var.region
    }
    
    # Create a VPC
    resource "aws_vpc" "my_vpc" {
      cidr_block = "10.0.0.0/16"
    
      tags = {
        Name = "my_vpc"
      }
    }
    
    # Create a subnet in each availability zone in the VPC. Keep in mind that at this point these subnets are private without internet access. They would need other networking resources for making them accesible
    resource "aws_subnet" "my_subnet" {
      count             = length(var.availability_zones)
      vpc_id            = aws_vpc.my_vpc.id
      cidr_block        = cidrsubnet("10.0.0.0/16", 8, count.index)
      availability_zone = var.availability_zones[count.index]
    
      tags = {
        Name = "my-subnet-${count.index}"
      }
    }
    
    # Put an instance in each subnet
    resource "aws_instance" "foo" {
      count         = length(var.availability_zones)
      ami           = ...
      instance_type = "t2.micro"
      subnet_id     = aws_subnet.my_subnet[count.index].id
    
      tags = {
        Name = "my-instance-${count.index}"
      }
    }