diff --git a/aws/data_source_aws_nat_gateway.go b/aws/data_source_aws_nat_gateway.go new file mode 100644 index 000000000000..852976252401 --- /dev/null +++ b/aws/data_source_aws_nat_gateway.go @@ -0,0 +1,114 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceAwsNatGateway() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsNatGatewayRead, + + 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, + }, + "subnet_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "tags": tagsSchemaComputed(), + + "filter": ec2CustomFiltersSchema(), + }, + } +} + +func dataSourceAwsNatGatewayRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + req := &ec2.DescribeNatGatewaysInput{} + + if id, ok := d.GetOk("id"); ok { + req.NatGatewayIds = aws.StringSlice([]string{id.(string)}) + } + + if vpc_id, ok := d.GetOk("vpc_id"); ok { + req.Filter = append(req.Filter, buildEC2AttributeFilterList( + map[string]string{ + "vpc-id": vpc_id.(string), + }, + )...) + } + + if state, ok := d.GetOk("state"); ok { + req.Filter = append(req.Filter, buildEC2AttributeFilterList( + map[string]string{ + "state": state.(string), + }, + )...) + } + + if subnet_id, ok := d.GetOk("subnet_id"); ok { + req.Filter = append(req.Filter, buildEC2AttributeFilterList( + map[string]string{ + "subnet-id": subnet_id.(string), + }, + )...) + } + + req.Filter = append(req.Filter, buildEC2CustomFilterList( + d.Get("filter").(*schema.Set), + )...) + if len(req.Filter) == 0 { + // Don't send an empty filters list; the EC2 API won't accept it. + req.Filter = nil + } + log.Printf("[DEBUG] Reading NAT Gateway: %s", req) + resp, err := conn.DescribeNatGateways(req) + if err != nil { + return err + } + if resp == nil || len(resp.NatGateways) == 0 { + return fmt.Errorf("no matching NAT gateway found: %#v", req) + } + if len(resp.NatGateways) > 1 { + return fmt.Errorf("multiple NAT gateways matched; use additional constraints to reduce matches to a single NAT gateway") + } + + ngw := resp.NatGateways[0] + + d.SetId(aws.StringValue(ngw.NatGatewayId)) + d.Set("state", ngw.State) + d.Set("subnet_id", ngw.SubnetId) + d.Set("vpc_id", ngw.VpcId) + + for _, address := range ngw.NatGatewayAddresses { + if *address.AllocationId != "" { + d.Set("allocation_id", address.AllocationId) + d.Set("network_interface_id", address.NetworkInterfaceId) + d.Set("private_ip", address.PrivateIp) + d.Set("public_ip", address.PublicIp) + break + } + } + + return nil +} diff --git a/aws/data_source_aws_nat_gateway_test.go b/aws/data_source_aws_nat_gateway_test.go new file mode 100644 index 000000000000..e1e516e288dd --- /dev/null +++ b/aws/data_source_aws_nat_gateway_test.go @@ -0,0 +1,89 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccDataSourceAwsNatGateway(t *testing.T) { + // This is used as a portion of CIDR network addresses. + rInt := acctest.RandIntRange(4, 254) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourceAwsNatGatewayConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair( + "data.aws_nat_gateway.test_by_id", "id", + "aws_nat_gateway.test", "id"), + resource.TestCheckResourceAttrPair( + "data.aws_nat_gateway.test_by_subnet_id", "subnet_id", + "aws_nat_gateway.test", "subnet_id"), + resource.TestCheckResourceAttrSet("data.aws_nat_gateway.test_by_id", "state"), + resource.TestCheckNoResourceAttr("data.aws_nat_gateway.test_by_id", "attached_vpc_id"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsNatGatewayConfig(rInt int) string { + return fmt.Sprintf(` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "test" { + cidr_block = "172.%d.0.0/16" + tags { + Name = "terraform-testacc-nat-gateway-data-source-%d" + } +} + +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.123.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "terraform-testacc-nat-gateway-data-source-%d" + } +} + +# EIPs are not taggable +resource "aws_eip" "test" { + vpc = true +} + +# IGWs are required for an NGW to spin up; manual dependency +resource "aws_internet_gateway" "test" { + vpc_id = "${aws_vpc.test.id}" + tags { + Name = "terraform-testacc-nat-gateway-data-source-%d" + } +} + +# NGWs are not taggable, either +resource "aws_nat_gateway" "test" { + subnet_id = "${aws_subnet.test.id}" + allocation_id = "${aws_eip.test.id}" + + depends_on = ["aws_internet_gateway.test"] +} + +data "aws_nat_gateway" "test_by_id" { + id = "${aws_nat_gateway.test.id}" +} + +data "aws_nat_gateway" "test_by_subnet_id" { + subnet_id = "${aws_nat_gateway.test.subnet_id}" +} + +`, rInt, rInt, rInt, rInt, rInt) +} diff --git a/aws/provider.go b/aws/provider.go index b0dab0f5576a..3079f4ffd968 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -200,6 +200,7 @@ func Provider() terraform.ResourceProvider { "aws_kms_alias": dataSourceAwsKmsAlias(), "aws_kms_ciphertext": dataSourceAwsKmsCiphertext(), "aws_kms_secret": dataSourceAwsKmsSecret(), + "aws_nat_gateway": dataSourceAwsNatGateway(), "aws_partition": dataSourceAwsPartition(), "aws_prefix_list": dataSourceAwsPrefixList(), "aws_redshift_service_account": dataSourceAwsRedshiftServiceAccount(), diff --git a/website/aws.erb b/website/aws.erb index d2cbf0efe199..d9ec207c7fdf 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -143,6 +143,8 @@