From 7399401b64cb88af3b285331c1011f38bee4e965 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Wed, 11 Jan 2017 10:47:15 -0500 Subject: [PATCH] provider/aws: Fix panic caused by main route table lookup A VPC's main route table has an implicit subnet association, not an explicit subnet association. This caused a Terraform panic when using the `data_source_aws_route_table` resource to query the main route table for a VPC. This fixes the Terraform panic, and allows the data lookup to complete successfully. Also added an acceptance test to verify the bugfix. Fixes: #11134 --- .../aws/data_source_aws_route_table.go | 5 +- .../aws/data_source_aws_route_table_test.go | 57 ++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/builtin/providers/aws/data_source_aws_route_table.go b/builtin/providers/aws/data_source_aws_route_table.go index df0dc7eea553..c09d7ce8fb3d 100644 --- a/builtin/providers/aws/data_source_aws_route_table.go +++ b/builtin/providers/aws/data_source_aws_route_table.go @@ -197,7 +197,10 @@ func dataSourceAssociationsRead(ec2Assocations []*ec2.RouteTableAssociation) []m m := make(map[string]interface{}) m["route_table_id"] = *a.RouteTableId m["route_table_association_id"] = *a.RouteTableAssociationId - m["subnet_id"] = *a.SubnetId + // GH[11134] + if a.SubnetId != nil { + m["subnet_id"] = *a.SubnetId + } m["main"] = *a.Main associations = append(associations, m) } diff --git a/builtin/providers/aws/data_source_aws_route_table_test.go b/builtin/providers/aws/data_source_aws_route_table_test.go index 743f5b17518e..9a5696b66967 100644 --- a/builtin/providers/aws/data_source_aws_route_table_test.go +++ b/builtin/providers/aws/data_source_aws_route_table_test.go @@ -25,6 +25,21 @@ func TestAccDataSourceAwsRouteTable(t *testing.T) { }) } +func TestAccDataSourceAwsRouteTable_main(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourceAwsRouteTableMainRoute, + Check: resource.ComposeTestCheckFunc( + testAccDataSourceAwsRouteTableCheckMain("data.aws_route_table.by_filter"), + ), + }, + }, + }) +} + func testAccDataSourceAwsRouteTableCheck(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] @@ -68,7 +83,7 @@ func testAccDataSourceAwsRouteTableCheck(name string) resource.TestCheckFunc { } if attr["associations.0.subnet_id"] != subnetRs.Primary.Attributes["id"] { return fmt.Errorf( - "subnet_id is %v; want %s", + "subnet_id is %v; want %s", attr["associations.0.subnet_id"], subnetRs.Primary.Attributes["id"], ) @@ -78,6 +93,32 @@ func testAccDataSourceAwsRouteTableCheck(name string) resource.TestCheckFunc { } } +func testAccDataSourceAwsRouteTableCheckMain(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + + if !ok { + return fmt.Errorf("root module has no resource called %s", name) + } + + attr := rs.Primary.Attributes + + // Verify attributes are set + if _, ok := attr["id"]; !ok { + return fmt.Errorf("id not set for main route table") + } + if _, ok := attr["vpc_id"]; !ok { + return fmt.Errorf("vpc_id not set for main route table") + } + // Verify it's actually the main route table that's returned + if attr["associations.0.main"] != "true" { + return fmt.Errorf("main route table not found") + } + + return nil + } +} + const testAccDataSourceAwsRouteTableGroupConfig = ` provider "aws" { region = "eu-central-1" @@ -130,3 +171,17 @@ data "aws_route_table" "by_subnet" { } ` + +// Uses us-east-2, as region only has a single main route table +const testAccDataSourceAwsRouteTableMainRoute = ` +provider "aws" { + region = "us-east-2" +} + +data "aws_route_table" "by_filter" { + filter { + name = "association.main" + values = ["true"] + } +} +`