From db5f450a3ef4e09592745a4dcaca3198b8fb0afa Mon Sep 17 00:00:00 2001 From: stevehorsfield Date: Mon, 6 Jun 2016 12:02:07 +0200 Subject: [PATCH] Add 'prefix_list_id' exported attribute to AWS VPC Endpoint 'prefix_list_id' can be used in egress rules in VPC security groups. --- .../aws/resource_aws_vpc_endpoint.go | 28 +++++++++++++++++++ .../aws/resource_aws_vpc_endpoint_test.go | 21 ++++++++++++++ .../aws/r/vpc_endpoint.html.markdown | 1 + 3 files changed, 50 insertions(+) diff --git a/builtin/providers/aws/resource_aws_vpc_endpoint.go b/builtin/providers/aws/resource_aws_vpc_endpoint.go index 882572d26..d324983c6 100644 --- a/builtin/providers/aws/resource_aws_vpc_endpoint.go +++ b/builtin/providers/aws/resource_aws_vpc_endpoint.go @@ -43,6 +43,10 @@ func resourceAwsVpcEndpoint() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, + "prefix_list_id": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -101,12 +105,36 @@ func resourceAwsVPCEndpointRead(d *schema.ResourceData, meta interface{}) error vpce := output.VpcEndpoints[0] + // A VPC Endpoint is associated with exactly one prefix list name (also called Service Name). + // The prefix list ID can be used in security groups, so retrieve it to support that capability. + prefixListServiceName := *vpce.ServiceName + prefixListInput := &ec2.DescribePrefixListsInput{ + Filters: []*ec2.Filter{ + {Name: aws.String("prefix-list-name"), Values: []*string{aws.String(prefixListServiceName)}}, + }, + } + + log.Printf("[DEBUG] Reading VPC Endpoint prefix list: %s", prefixListServiceName) + prefixListsOutput, err := conn.DescribePrefixLists(prefixListInput) + + if err != nil { + _, ok := err.(awserr.Error) + if !ok { + return fmt.Errorf("Error reading VPC Endpoint prefix list: %s", err.Error()) + } + } + + if len(prefixListsOutput.PrefixLists) != 1 { + return fmt.Errorf("There are multiple prefix lists associated with the service name '%s'. Unexpected", prefixListServiceName) + } + d.Set("vpc_id", vpce.VpcId) d.Set("policy", normalizeJson(*vpce.PolicyDocument)) d.Set("service_name", vpce.ServiceName) if err := d.Set("route_table_ids", aws.StringValueSlice(vpce.RouteTableIds)); err != nil { return err } + d.Set("prefix_list_id", prefixListsOutput.PrefixLists[0].PrefixListId) return nil } diff --git a/builtin/providers/aws/resource_aws_vpc_endpoint_test.go b/builtin/providers/aws/resource_aws_vpc_endpoint_test.go index c39162588..829fa2de7 100644 --- a/builtin/providers/aws/resource_aws_vpc_endpoint_test.go +++ b/builtin/providers/aws/resource_aws_vpc_endpoint_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "strings" "testing" "github.com/aws/aws-sdk-go/aws" @@ -25,6 +26,7 @@ func TestAccAWSVpcEndpoint_basic(t *testing.T) { Config: testAccVpcEndpointWithRouteTableAndPolicyConfig, Check: resource.ComposeTestCheckFunc( testAccCheckVpcEndpointExists("aws_vpc_endpoint.second-private-s3", &endpoint), + testAccCheckVpcEndpointPrefixListAvailable("aws_vpc_endpoint.second-private-s3"), ), }, }, @@ -118,6 +120,25 @@ func testAccCheckVpcEndpointExists(n string, endpoint *ec2.VpcEndpoint) resource } } +func testAccCheckVpcEndpointPrefixListAvailable(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + prefixListID := rs.Primary.Attributes["prefix_list_id"] + if prefixListID == "" { + return fmt.Errorf("Prefix list ID not available") + } + if !strings.HasPrefix(prefixListID, "pl") { + return fmt.Errorf("Prefix list ID does not appear to be a valid value: '%s'", prefixListID) + } + + return nil + } +} + const testAccVpcEndpointWithRouteTableAndPolicyConfig = ` resource "aws_vpc" "foo" { cidr_block = "10.0.0.0/16" diff --git a/website/source/docs/providers/aws/r/vpc_endpoint.html.markdown b/website/source/docs/providers/aws/r/vpc_endpoint.html.markdown index 51fdbf5ee..c67c757a5 100644 --- a/website/source/docs/providers/aws/r/vpc_endpoint.html.markdown +++ b/website/source/docs/providers/aws/r/vpc_endpoint.html.markdown @@ -35,3 +35,4 @@ The following arguments are supported: The following attributes are exported: * `id` - The ID of the VPC endpoint. +* `prefix_list_id` - The prefix list ID of the exposed service.