Terraform: Re-applying a route definition fails

Created on 2 Nov 2016  ยท  3Comments  ยท  Source: hashicorp/terraform

Version

$ terraform -v
Terraform v0.7.8

Resource: aws_route

Config

resource "aws_route_table" "app-hosts1-priv" {
  vpc_id = "${aws_vpc.outer-district.id}"
}
resource "aws_route" "app-hosts1-priv-to-internet" {
  route_table_id = "${aws_route_table.app-hosts1-priv.id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id = "${aws_nat_gateway.nat-gw1.id}"
}
resource "aws_route" "app-hosts1-priv-to-sibling-env" {
  count = "${var.route_to_sibling_env}"
  route_table_id = "${aws_route_table.app-hosts1-priv.id}"
  destination_cidr_block = "${var.sibling_env_cidr_block}"
  gateway_id = "${var.sibling_env_vpc_id}"
}
resource "aws_route_table_association" "app-hosts1-priv" {
  subnet_id = "${aws_subnet.app-hosts1.id}"
  route_table_id = "${aws_route_table.app-hosts1-priv.id}"
}

Expected Behaviour

Running terraform apply multiple times should not create errors or modify routing tables.

Actual Behaviour

Error message upon second and consecutive terraform apply. Also the error message contains false information: it should not list route_table_id as a target type. route_table_id is a required attribute of the resource.

* aws_route.app-hosts1-priv-to-internet: Error: more than 1 target specified. Only 1 of gateway_id, nat_gateway_id, instance_id, network_interface_id, route_table_id or vpc_peering_connection_id is allowed.

Steps to Reproduce

  1. terraform apply
  2. terraform apply

Workaround

Add this to the first route:

  lifecycle {
    ignore_changes = ["gateway_id"]
  }

This I suppose how ever prevents modifying the target so the workaround can be kept there only when there are no changes to the routes (which is most of the time in our environment).

Most helpful comment

Hey @yareeh

it looks like you're supplying a NAT Gateway ID to the gateway_id parameter:

resource "aws_route" "app-hosts1-priv-to-internet" {
  route_table_id = "${aws_route_table.app-hosts1-priv.id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id = "${aws_nat_gateway.nat-gw1.id}"
}

Can you try using nat_gateway_id instead?

resource "aws_route" "app-hosts1-priv-to-internet" {
  route_table_id = "${aws_route_table.app-hosts1-priv.id}"
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id = "${aws_nat_gateway.nat-gw1.id}" # <--
}

Unfortunately we don't have validation around these, but AWS will accept the wrong id in these parameters and then apply them to the correct attribute on their side, without throwing an error :(

All 3 comments

Hey @yareeh

it looks like you're supplying a NAT Gateway ID to the gateway_id parameter:

resource "aws_route" "app-hosts1-priv-to-internet" {
  route_table_id = "${aws_route_table.app-hosts1-priv.id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id = "${aws_nat_gateway.nat-gw1.id}"
}

Can you try using nat_gateway_id instead?

resource "aws_route" "app-hosts1-priv-to-internet" {
  route_table_id = "${aws_route_table.app-hosts1-priv.id}"
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id = "${aws_nat_gateway.nat-gw1.id}" # <--
}

Unfortunately we don't have validation around these, but AWS will accept the wrong id in these parameters and then apply them to the correct attribute on their side, without throwing an error :(

Thanks! You are correct. This fixed it!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings