简体   繁体   中英

Creating different EC2 instances in separate AZs using for each terraform

I am trying to deploy different EC2 instances in separate AZs using terraform. I am then associating the su.nets the EC2 instances are on to a route table with a NAT gateway. I am getting stuck on associating the su.nets with the nat gateway on the route table. Below is my code and error. Any advice would be helpful.

resource "aws_instance" "private" {
  for_each      = var.priv_subnet
  ami           = var.ec2_amis[var.region]
  instance_type = each.key
  key_name      = aws_key_pair.main.key_name
  subnet_id     = aws_subnet.private[each.key].id

  tags = {
    Name = each.value.tag
  }
}

resource "aws_route_table" "nat" {
  for_each = var.pub_subnet
  vpc_id   = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.main[each.key].id
  }

  tags = {
    Name = "${var.vpc_tags}_${each.key}_PrivRT"
  }
}

resource "aws_route_table_association" "nat" {
  for_each       = aws_subnet.private
  route_table_id = aws_route_table.nat[each.key].id
  subnet_id      = each.value.id
}
resource "aws_subnet" "private" {
  for_each                = var.priv_subnet
  vpc_id                  = aws_vpc.tableau.id
  cidr_block              = cidrsubnet(aws_vpc.main.cidr_block, 8, each.value.subnet)
  availability_zone       = each.value.availability_zone
  map_public_ip_on_launch = false
  tags = {
    Name = "PrivSub-${each.value.availability_zone}"
  }
}

resource "aws_eip" "main" {
  for_each = aws_subnet.public
  vpc      = true

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_nat_gateway" "tableau" {
  for_each      = aws_subnet.public
  subnet_id     = each.value.id
  allocation_id = aws_eip.main[each.key].id
}

resource "aws_subnet" "public" {
  for_each                = var.pub_subnet
  vpc_id                  = aws_vpc.main.id
  cidr_block              = cidrsubnet(aws_vpc.main.cidr_block, 8, each.value)
  availability_zone       = each.key
  map_public_ip_on_launch = true
  tags = {
    Name = "PubSub-${each.key}"
  }
}

Variables

variable "priv_subnet" {


 type = map(object({
    availability_zone = string
    subnet            = string
    tag               = string
  }))
  default = {
    "m5.2xlarge" = {
      availability_zone = "us-west-2a"
      subnet            = 4
      tag               = "Primary"
    }
    "m5.4xlarge" = {
      availability_zone = "us-west-2b"
      subnet            = 5
      tag               = "Worker1"
    }
    "m5.4xlarge" = {
      availability_zone = "us-west-2c"
      subnet            = 6
      tag               = "Worker2"
    }
  }
}

variable "pub_subnet" {
  default = {
    "us-west-2a" = 1
    "us-west-2b" = 2
    "us-west-2c" = 3
  }
}

Error

Error: Invalid index

  on vpc.tf line 99, in resource "aws_route_table_association" "nat":
  99:   route_table_id = aws_route_table.nat[each.key].id
    |----------------
    | aws_route_table.nat is object with 3 attributes
    | each.key is "m5.2xlarge"

The given key does not identify an element in this collection value.


Error: Invalid index

  on vpc.tf line 99, in resource "aws_route_table_association" "nat":
  99:   route_table_id = aws_route_table.nat[each.key].id
    |----------------
    | aws_route_table.nat is object with 3 attributes
    | each.key is "m5.4xlarge"

The given key does not identify an element in this collection value.

I understand the error message but am unsure how to appropriately assign the routes to this route table.

The each.key in the aws_route_table_association will be instance types from priv_su.net , eg m5.2xlarge . However, aws_route_table.nat keys will be AZ names, such as us-east-1a , from var.pub_su.net .

Obviously, this does not work. One way to overcome the issue would be to modify your priv_su.net variable to use su.net names as keys, not instance types. The change would probably require further changes to your code.

variable "priv_subnet" {

 type = map(object({
    instance_type     = string
    subnet            = string
    tag               = string
  }))

  default = {
    "us-west-2a" = {
      instance_type = "m5.2xlarge"
      subnet            = 4
      tag               = "Primary"
    }
    "us-west-2b" = {
      instance_type     = "m5.4xlarge"
      subnet            = 5
      tag               = "Worker1"
    }
    "us-west-2c" = {
      instance_type     = "m5.4xlarge"
      subnet            = 6
      tag               = "Worker2"
    }
  }
}

This way you would have one-to-one relationship between var.pub_su.net and var.priv_su.net , which would simplify things in my view.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM