Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_route Error: more than 1 targe specified if you change the destination type #684

Closed
hashibot opened this issue Jun 13, 2017 · 9 comments · Fixed by #16930
Closed

aws_route Error: more than 1 targe specified if you change the destination type #684

hashibot opened this issue Jun 13, 2017 · 9 comments · Fixed by #16930
Assignees
Labels
bug Addresses a defect in current functionality. service/ec2 Issues and PRs that pertain to the ec2 service.
Milestone

Comments

@hashibot
Copy link

This issue was originally opened by @peteromoon as hashicorp/terraform#13530. It was migrated here as part of the provider split. The original body of the issue is below.


If you change the destination type of an aws_route, for example from a network interface (network_interface_id) to an internet gateway (gateway_id), when you run terraform apply it fails with:

* aws_route.test: 1 error(s) occurred:

* aws_route.test: Error: more than 1 target specified. Only 1 of gateway_id, egress_only_gateway_id, nat_gateway_id, instance_id, network_interface_id, route_table_id or vpc_peering_connection_id is allowed.

This type of change could occur if you change a subnet from being "private" to "public" or change from using an instance as a NAT gateway to using an AWS NAT gateway.

Terraform Version

$ terraform -v
Terraform v0.9.2

Affected Resource(s)

Please list the resources as a list, for example:

  • aws_route

Terraform Configuration Files

Step 1, Terraform config

{
  "provider" : {
    "aws" : {
      "region" : "eu-west-1"
    },
  },
  "resource" : {
    "aws_route_table" : {
      "test" : {
        "vpc_id" : "${aws_vpc.test.id}",
        "propagating_vgws" : [ ],
      }
    },
    "aws_route" : {
      "test" : {
        "destination_cidr_block" : "0.0.0.0/0",
        "network_interface_id" : "${aws_network_interface.test.id}",
        "route_table_id" : "${aws_route_table.test.id}"
      }
    },
    "aws_route_table_association" : {
      "test" : {
        "subnet_id" : "${aws_subnet.test.id}",
        "route_table_id" : "${aws_route_table.test.id}"
      }
    },
    "aws_internet_gateway" : {
      "test" : {
        "vpc_id" : "${aws_vpc.test.id}",
      }
    },
    "aws_vpc" : {
      "test" : {
        "cidr_block" : "10.247.0.0/17",
        "instance_tenancy" : "default",
        "enable_dns_support" : true,
        "enable_dns_hostnames" : true,
      }
    },
    "aws_subnet" : {
      "test" : {
        "vpc_id" : "${aws_vpc.test.id}",
        "availability_zone" : "eu-west-1a",
        "cidr_block" : "10.247.0.0/23",
      }
    },
    "aws_network_interface" : {
      "test" : {
        "source_dest_check" : false,
        "subnet_id": "${aws_subnet.test.id}"
      }
    }
  }
}

Step 2, Terraform config

{
  "provider" : {
    "aws" : {
      "region" : "eu-west-1"
    },
  },
  "resource" : {
    "aws_route_table" : {
      "test" : {
        "vpc_id" : "${aws_vpc.test.id}",
        "propagating_vgws" : [ ],
      }
    },
    "aws_route" : {
      "test" : {
        "destination_cidr_block" : "0.0.0.0/0",
        "gateway_id" : "${aws_internet_gateway.test.id}",
        "route_table_id" : "${aws_route_table.test.id}"
      }
    },
    "aws_route_table_association" : {
      "test" : {
        "subnet_id" : "${aws_subnet.test.id}",
        "route_table_id" : "${aws_route_table.test.id}"
      }
    },
    "aws_internet_gateway" : {
      "test" : {
        "vpc_id" : "${aws_vpc.test.id}",
      }
    },
    "aws_vpc" : {
      "test" : {
        "cidr_block" : "10.247.0.0/17",
        "instance_tenancy" : "default",
        "enable_dns_support" : true,
        "enable_dns_hostnames" : true,
      }
    },
    "aws_subnet" : {
      "test" : {
        "vpc_id" : "${aws_vpc.test.id}",
        "availability_zone" : "eu-west-1a",
        "cidr_block" : "10.247.0.0/23",
      }
    },
    "aws_network_interface" : {
      "test" : {
        "source_dest_check" : false,
        "subnet_id": "${aws_subnet.test.id}"
      }
    }
  }
}

Expected Behavior

The route to destination 0.0.0.0/0 is changed from a network interface to the internet gateway when the terraform config is changed and terraform apply is run.

Actual Behavior

terraform apply failed with an error when route is changed in terraform config from a network interface destination to an internet gateway destination.

Steps to Reproduce

To reproduce:

  1. Using Step 1 terraform config (see above) run: terraform apply
  2. Change route destination from network interface to internet gateway to produce Step 2 terraform config (see above)
  3. Run terraform apply
  4. Fails with error above.

References

I found this issue that is similar

@hashibot hashibot added the bug Addresses a defect in current functionality. label Jun 13, 2017
@dcloud9
Copy link

dcloud9 commented Jul 3, 2017

We're having the same issue as well even simply replacing from one ENI to another ENI in a route table. Terraform version is 0.9.9

aws_route.route_private1_vpn_Internet: Modifying... (ID: r-rtb-79cdf01eZZZ)
  network_interface_id: "eni-f637XXX" =0> "eni-1a52YYY"
aws_route.route_private3_vpn_Internet: Modifying... (ID: r-rtb-79cdf01eZZZ)
  network_interface_id: "eni-f637XXX" => "eni-1a52YYY"
aws_route.route_private2_vpn_Internet: Modifying... (ID: r-rtb-79cdf01eZZZ)
  network_interface_id: "eni-f637XXX" => "eni-1a52YYY"
Error applying plan:

3 error(s) occurred:

* aws_route.route_private2_vpn_Internet: 1 error(s) occurred:

* aws_route.route_private2_vpn_Internet: InvalidInstanceID: There are multiple interfaces attached to instance 'i-XXXd2700dd'. Please specify an interface ID for the operation instead.
	status code: 400, request id: 7705eb5c-e8e4-4b02-8cc2-40ea7c72d4da
* aws_route.route_private1_vpn_Internet: 1 error(s) occurred:

* aws_route.route_private1_vpn_Internet: InvalidInstanceID: There are multiple interfaces attached to instance 'i-XXXd2700dd'. Please specify an interface ID for the operation instead.
	status code: 400, request id: d20164d3-d07b-4601-a2f6-4222d4639577
* aws_route.route_private3_vpn_Internet: 1 error(s) occurred:

* aws_route.route_private3_vpn_Internet: InvalidInstanceID: There are multiple interfaces attached to instance 'i-XXXd2700dd'. Please specify an interface ID for the operation instead.
	status code: 400, request id: 05867acf-b4be-407f-a8ab-5fe9c04240f8

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

@radeksimko radeksimko added the service/ec2 Issues and PRs that pertain to the ec2 service. label Jan 27, 2018
@tamirble
Copy link

We're having the same issue with Terraform v0.11.7 and provider.aws v1.10.0
Anything new about that?

@b-dean
Copy link
Contributor

b-dean commented Feb 15, 2019

This is still a bug in newer versions:

Terraform v0.11.11
+ provider.aws v1.59.0

As a workaround you can rename your aws_route resource so it will want to delete the old one pointed at an instance_id and make the new one pointed at nat_gateway_id.

@swedstrom
Copy link

I am having the same issue.
Anyone able to dig into this?

@tagirb
Copy link

tagirb commented Apr 24, 2019

I've run into the same error recently. In my case Terraform tried creating a duplicate route instead of changing it. It helped to just terraform taint the respective resource, so that it would be re-created instead. Maybe a lifecycle issue..

@kellersyf
Copy link

I'm having multiple issues with updating existing routes. Is there any reason we shouldn't just unconditionally replace a route when it needs to change, rather than attempting an in-place update? The API call is fast, and delete/create works 100% of the time. Is there a downside?

@sosheskaz
Copy link

I am not a contributor, so am unfamiliar with the core codebase, but initially looking at it (terraform 0.12.6):

Looking at the code, specifically the resourceAwsRouteUpdate function, the issue is that the argument spec is interpreted as a combination of the existing settings and the new settings.

Normally, this would serve to carry existing settings over from tfstate to the new resource if they are not explicitly specified. However, since there are multiple arguments, all of which are mutually exclusive, it will be the old gateway and the new gateway are both considered to be parameters when changing the route.

Thus, you may be able to do some sort of check like:

If one and only one of [gateway_id, nat_gateway_id, ...] is provided in the specification, unset all other variables in the list that are provided by state.

I don't see where they are combined though, so I assume terraform is doing it at a lower level.

One thing that could be done is adding a new field which allows the user to override the behavior of "fail if two gateways are provided" with an option to manually specify the type to provide, which then, under the hood, unsets all gateways other than the one specified and fails if the specified is not set.

ex:

resource "aws_route" "one" {
  route_table_id = var.rtb
  destination_cidr_block = var.cidr
  nat_gateway_id = var.nat_gw_id
  force_type = "nat_gateway"
}

@ghost
Copy link

ghost commented Mar 26, 2021

This has been released in version 3.34.0 of the Terraform AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template for triage. Thanks!

@ghost
Copy link

ghost commented Apr 25, 2021

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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked as resolved and limited conversation to collaborators Apr 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.