Add 'aws_vpc_endpoint' data source. (#11323)

This commit is contained in:
Kit Ewbank 2017-01-23 16:50:38 -05:00 committed by Paul Stack
parent de329712cb
commit c5f94d2999
5 changed files with 284 additions and 0 deletions

View File

@ -0,0 +1,103 @@
package aws
import (
"fmt"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/schema"
)
func dataSourceAwsVpcEndpoint() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsVpcEndpointRead,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"state": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"vpc_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"service_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"policy": {
Type: schema.TypeString,
Computed: true,
},
"route_table_ids": &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
}
}
func dataSourceAwsVpcEndpointRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn
log.Printf("[DEBUG] Reading VPC Endpoints.")
req := &ec2.DescribeVpcEndpointsInput{}
if id, ok := d.GetOk("id"); ok {
req.VpcEndpointIds = aws.StringSlice([]string{id.(string)})
}
req.Filters = buildEC2AttributeFilterList(
map[string]string{
"vpc-endpoint-state": d.Get("state").(string),
"vpc-id": d.Get("vpc_id").(string),
"service-name": d.Get("service_name").(string),
},
)
if len(req.Filters) == 0 {
// Don't send an empty filters list; the EC2 API won't accept it.
req.Filters = nil
}
resp, err := conn.DescribeVpcEndpoints(req)
if err != nil {
return err
}
if resp == nil || len(resp.VpcEndpoints) == 0 {
return fmt.Errorf("no matching VPC endpoint found")
}
if len(resp.VpcEndpoints) > 1 {
return fmt.Errorf("multiple VPC endpoints matched; use additional constraints to reduce matches to a single VPC endpoint")
}
vpce := resp.VpcEndpoints[0]
policy, err := normalizeJsonString(*vpce.PolicyDocument)
if err != nil {
return errwrap.Wrapf("policy contains an invalid JSON: {{err}}", err)
}
d.SetId(aws.StringValue(vpce.VpcEndpointId))
d.Set("id", vpce.VpcEndpointId)
d.Set("state", vpce.State)
d.Set("vpc_id", vpce.VpcId)
d.Set("service_name", vpce.ServiceName)
d.Set("policy", policy)
if err := d.Set("route_table_ids", aws.StringValueSlice(vpce.RouteTableIds)); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,129 @@
// make testacc TEST=./builtin/providers/aws/ TESTARGS='-run=TestAccDataSourceAwsVpcEndpoint_'
package aws
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccDataSourceAwsVpcEndpoint_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDataSourceAwsVpcEndpointConfig,
Check: resource.ComposeTestCheckFunc(
testAccDataSourceAwsVpcEndpointCheckExists("data.aws_vpc_endpoint.s3"),
),
ExpectNonEmptyPlan: true,
},
},
})
}
func TestAccDataSourceAwsVpcEndpoint_withRouteTable(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDataSourceAwsVpcEndpointWithRouteTableConfig,
Check: resource.ComposeTestCheckFunc(
testAccDataSourceAwsVpcEndpointCheckExists("data.aws_vpc_endpoint.s3"),
resource.TestCheckResourceAttr(
"data.aws_vpc_endpoint.s3", "route_table_ids.#", "1"),
),
ExpectNonEmptyPlan: true,
},
},
})
}
func testAccDataSourceAwsVpcEndpointCheckExists(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)
}
vpceRs, ok := s.RootModule().Resources["aws_vpc_endpoint.s3"]
if !ok {
return fmt.Errorf("can't find aws_vpc_endpoint.s3 in state")
}
attr := rs.Primary.Attributes
if attr["id"] != vpceRs.Primary.Attributes["id"] {
return fmt.Errorf(
"id is %s; want %s",
attr["id"],
vpceRs.Primary.Attributes["id"],
)
}
return nil
}
}
const testAccDataSourceAwsVpcEndpointConfig = `
provider "aws" {
region = "us-west-2"
}
resource "aws_vpc" "foo" {
cidr_block = "10.1.0.0/16"
tags {
Name = "terraform-testacc-vpc-endpoint-data-source-foo"
}
}
resource "aws_vpc_endpoint" "s3" {
vpc_id = "${aws_vpc.foo.id}"
service_name = "com.amazonaws.us-west-2.s3"
}
data "aws_vpc_endpoint" "s3" {
vpc_id = "${aws_vpc.foo.id}"
service_name = "com.amazonaws.us-west-2.s3"
state = "available"
depends_on = ["aws_vpc_endpoint.s3"]
}
`
const testAccDataSourceAwsVpcEndpointWithRouteTableConfig = `
provider "aws" {
region = "us-west-2"
}
resource "aws_vpc" "foo" {
cidr_block = "10.1.0.0/16"
tags {
Name = "terraform-testacc-vpc-endpoint-data-source-foo"
}
}
resource "aws_route_table" "rt" {
vpc_id = "${aws_vpc.foo.id}"
}
resource "aws_vpc_endpoint" "s3" {
vpc_id = "${aws_vpc.foo.id}"
service_name = "com.amazonaws.us-west-2.s3"
route_table_ids = ["${aws_route_table.rt.id}"]
}
data "aws_vpc_endpoint" "s3" {
vpc_id = "${aws_vpc.foo.id}"
service_name = "com.amazonaws.us-west-2.s3"
state = "available"
depends_on = ["aws_vpc_endpoint.s3"]
}
`

View File

@ -181,6 +181,7 @@ func Provider() terraform.ResourceProvider {
"aws_subnet": dataSourceAwsSubnet(), "aws_subnet": dataSourceAwsSubnet(),
"aws_security_group": dataSourceAwsSecurityGroup(), "aws_security_group": dataSourceAwsSecurityGroup(),
"aws_vpc": dataSourceAwsVpc(), "aws_vpc": dataSourceAwsVpc(),
"aws_vpc_endpoint": dataSourceAwsVpcEndpoint(),
"aws_vpc_endpoint_service": dataSourceAwsVpcEndpointService(), "aws_vpc_endpoint_service": dataSourceAwsVpcEndpointService(),
"aws_vpc_peering_connection": dataSourceAwsVpcPeeringConnection(), "aws_vpc_peering_connection": dataSourceAwsVpcPeeringConnection(),
}, },

View File

@ -0,0 +1,48 @@
---
layout: "aws"
page_title: "AWS: aws_vpc_endpoint"
sidebar_current: "docs-aws-datasource-vpc-endpoint"
description: |-
Provides details about a specific VPC endpoint.
---
# aws\_vpc\_endpoint
The VPC Endpoint data source provides details about
a specific VPC endpoint.
## Example Usage
```
# Declare the data source
data "aws_vpc_endpoint" "s3" {
vpc_id = "${aws_vpc.foo.id}"
service_name = "com.amazonaws.us-west-2.s3"
}
resource "aws_vpc_endpoint_route_table_association" "private_s3" {
vpc_endpoint_id = "${data.aws_vpc_endpoint.s3.id}"
route_table_id = "${aws_route_table.private.id}"
}
```
## Argument Reference
The arguments of this data source act as filters for querying the available VPC endpoints.
The given filters must match exactly one VPC endpoint whose data will be exported as attributes.
* `id` - (Optional) The ID of the specific VPC Endpoint to retrieve.
* `state` - (Optional) The state of the specific VPC Endpoint to retrieve.
* `vpc_id` - (Optional) The ID of the VPC in which the specific VPC Endpoint is used.
* `service_name` - (Optional) The AWS service name of the specific VPC Endpoint to retrieve.
## Attributes Reference
All of the argument attributes are also exported as result attributes.
* `policy` - The policy document associated with the VPC Endpoint.
* `route_table_ids` - One or more route tables associated with the VPC Endpoint.

View File

@ -98,6 +98,9 @@
<li<%= sidebar_current("docs-aws-datasource-vpc") %>> <li<%= sidebar_current("docs-aws-datasource-vpc") %>>
<a href="/docs/providers/aws/d/vpc.html">aws_vpc</a> <a href="/docs/providers/aws/d/vpc.html">aws_vpc</a>
</li> </li>
<li<%= sidebar_current("docs-aws-datasource-vpc-endpoint") %>>
<a href="/docs/providers/aws/d/vpc_endpoint.html">aws_vpc_endpoint</a>
</li>
<li<%= sidebar_current("docs-aws-datasource-vpc-endpoint-service") %>> <li<%= sidebar_current("docs-aws-datasource-vpc-endpoint-service") %>>
<a href="/docs/providers/aws/d/vpc_endpoint_service.html">aws_vpc_endpoint_service</a> <a href="/docs/providers/aws/d/vpc_endpoint_service.html">aws_vpc_endpoint_service</a>
</li> </li>