I'm having some trouble whilst importing existing AWS routing tables into Terraform. They import, and their routes are recorded in the state file, but running plan
or apply
afterwards always wants to delete those routes, even if they are also defined in Terraform.
I define an existing AWS routing table in Terraform like this:
resource "aws_route_table" "public_staging" {
vpc_id = "${aws_vpc.staging.id}"
route {
cidr_block = "${aws_vpc.management.cidr_block}"
vpc_peering_connection_id = "${aws_vpc_peering_connection.management_to_staging.id}"
}
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.staging.id}"
}
tags {
Name = "public staging (igw)"
environment = "staging"
}
}
Then import it like this; terraform import aws_route_table.public_management rtb-abc123
.
Which outputs:
aws_route_table.public_staging: Importing from ID "rtb-abc123"...
aws_route_table.public_staging: Import complete!
Imported aws_route_table (ID: rtb-abc123)
Imported aws_route (ID: r-rtb-abc123123456)
Imported aws_route (ID: r-rtb-abc123654321)
Imported aws_route_table_association (ID: rtbassoc-qwert765)
Imported aws_main_route_table_association (ID: rtbassoc-asdf9876)
aws_route.public_staging: Refreshing state... (ID: r-rtb-abc123123456)
aws_route_table.public_staging: Refreshing state... (ID: rtb-abc123)
aws_route.public_staging-1: Refreshing state... (ID: r-rtb-abc123654321)
aws_route_table_association.public_staging: Refreshing state... (ID: rtbassoc-qwert765)
aws_main_route_table_association.public_staging: Refreshing state... (ID: rtbassoc-asdf9876)
When then running terraform plan
, Terraform wants to delete all the aws_route
resource states it generated in the state file and create the route table we just imported:
Terraform will perform the following actions:
- aws_route.public_staging
- aws_route.public_staging-1
+ aws_route_table.public_management
...
I've also tried defining the routes separately, outside of the aws_route_table
resource and attaching them to the routing table by ID, like this:
resource "aws_route" "management_to_staging" {
route_table_id = "${aws_route_table.public_management.id}"
cidr_block = "${aws_vpc.staging.cidr_block}"
vpc_peering_connection_id = "${aws_vpc_peering_connection.management_to_staging.id}"
}
The only thing that will result in a no-change state is if I run the import on the routing table, also define the routes outside of the routing table (as aws_route
resources), and then go in and manually change the generated names in the state file to those I've defined the the tf file. However, I believe this would not actually work on a fresh run, since the routes defined in the aws_route_table
, and those as separate aws_route
resources, would conflict.
EDIT:
Most likely explanation as far as I can see, is that on importing, Terraform is quite happily imports the routes inside the route table, but then on plan
, it expects them to be declared explicitly using aws_route
resources.
Problem with that is; you can't import aws_route
resources, so you can never have your current infrastructure state match your terraform state.
I think the reason explicitly declaring them afterwards doesn't work either is that the state file records imported routes differently if it got them from an import aws_route_table ...
command to if it generates them from an apply
with explicit aws_route
definitions.
And now I'm out of breath.