Abhishek Bhola
Abhishek Bhola

Reputation: 13

How do I create multiple ec2 instances so that each ec2 can be attached to different subnets

I am trying to attach subnet A to the first ec2 instance and subnet B to the second ec2 instance.

I am not sure how to make that loop. Please suggest.

Below is the main.tf file of my ec2 module.

resource "aws_instance" "web_pub_servers" {
    
    for_each = var.web_vm_attribute
    ami = var.ami
    instance_type = var.instance_type
    vpc_security_group_ids = [var.ssh_security_group_id]
    key_name = each.value.key_name
    **subnet_id =** ??
    tags = {
      Name =  "web_${each.value.name}"
    }
}

and this is the Variables.tf file of the ec2 module

variable "ami" {}
variable "instance_type" {}
variable "ssh_security_group_id" {}
variable "public_subnet_a_id" {}
variable "public_subnet_b_id" {}
variable "web_vm_attribute" {
    type = map(object({
     name = string
     key_name = string
    }))
    default = {}
 }
variable "pri_vm_attribute" {
    type = map(object({
      name = string
      key_name = string
    }))
    default = {}
}

This is the output file of my VPC module.

output "region" {
    value = var.region
}
output "project_name" {
    value = var.project_name
}
output "vpc_id" {
    value = aws_vpc.vpc.id
}
output "public_subnet_a_id" {
    value = aws_subnet.public_subnet_a.id
}
output "public_subnet_b_id" {
    value = aws_subnet.public_subnet_b.id
}
output "internet_gateway" {
    value = aws_internet_gateway.internet_gateway
}

I want to achieve this using for_each only. I don't want to use count. None of my resources are present in the AWS. I want to create VPC, Subnets, Internet gateway, Nat gateway and ec2 instances in one go.

Upvotes: 1

Views: 133

Answers (1)

Helder Sepulveda
Helder Sepulveda

Reputation: 17604

Here is a quick trick you can use to alternate between the subnets:

  • Put all subnets in a list using a local
    subnets = [var.public_subnet_a_id, var.public_subnet_b_id]
  • Use the remainder of dividing the index of the VM by the amount of subnets
    local.subnets[index(keys(var.web_vm_attribute), each.key) % length(local.subnets)]

Here is some sample code

variable "web_vm_attribute" {
  default = {
    "a" = {}
    "b" = {}
    "c" = {}
    "d" = {}
  }
}

variable "public_subnet_a_id" {
    default = "abc11"
}
variable "public_subnet_b_id" {
    default = "def22"
}

locals {
  subnets = [var.public_subnet_a_id, var.public_subnet_b_id]
}

resource "null_resource" "test" {
  for_each = var.web_vm_attribute

  triggers = {
    id     = index(keys(var.web_vm_attribute), each.key)
    key    = each.key
    subnet = local.subnets[index(keys(var.web_vm_attribute), each.key) % length(local.subnets)]
  }
}

the output of terraform plan on that code is:

Terraform will perform the following actions:

  # null_resource.test["a"] will be created
  + resource "null_resource" "test" {
      + id       = (known after apply)
      + triggers = {
          + "id"     = "0"
          + "key"    = "a"
          + "subnet" = "abc11"
        }
    }

  # null_resource.test["b"] will be created
  + resource "null_resource" "test" {
      + id       = (known after apply)
      + triggers = {
          + "id"     = "1"
          + "key"    = "b"
          + "subnet" = "def22"
        }
    }

  # null_resource.test["c"] will be created
  + resource "null_resource" "test" {
      + id       = (known after apply)
      + triggers = {
          + "id"     = "2"
          + "key"    = "c"
          + "subnet" = "abc11"
        }
    }

  # null_resource.test["d"] will be created
  + resource "null_resource" "test" {
      + id       = (known after apply)
      + triggers = {
          + "id"     = "3"
          + "key"    = "d"
          + "subnet" = "def22"
        }
    }

You can see in the output how the subnet alternates between the values of two public_subnet_a_id and public_subnet_b_id ...

And of course these are just sample values, and I'm using a null_resource you can do the same with your resource "aws_instance"

Upvotes: 0

Related Questions