From a424fffd48562d82cb029729bfccef9f2f3856d6 Mon Sep 17 00:00:00 2001 From: Colin Wood Date: Wed, 29 Mar 2017 18:23:29 -0700 Subject: [PATCH 1/3] Add support for aws_subnet_ids as a data source --- .../aws/data_source_aws_subnet_ids.go | 60 ++++++++++++++ .../aws/data_source_aws_subnet_ids_test.go | 79 +++++++++++++++++++ builtin/providers/aws/provider.go | 1 + 3 files changed, 140 insertions(+) create mode 100644 builtin/providers/aws/data_source_aws_subnet_ids.go create mode 100644 builtin/providers/aws/data_source_aws_subnet_ids_test.go diff --git a/builtin/providers/aws/data_source_aws_subnet_ids.go b/builtin/providers/aws/data_source_aws_subnet_ids.go new file mode 100644 index 0000000000..efe6c75a48 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_subnet_ids.go @@ -0,0 +1,60 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceAwsSubnetIDs() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsSubnetIDsRead, + Schema: map[string]*schema.Schema{ + "vpc_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "ids": &schema.Schema{ + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + } +} + +func dataSourceAwsSubnetIDsRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + req := &ec2.DescribeSubnetsInput{} + + req.Filters = buildEC2AttributeFilterList( + map[string]string{ + "vpc-id": d.Get("vpc_id").(string), + }, + ) + + log.Printf("[DEBUG] DescribeSubnets %s\n", req) + resp, err := conn.DescribeSubnets(req) + if err != nil { + return err + } + + if resp == nil || len(resp.Subnets) == 0 { + return fmt.Errorf("no matching subnet found for vpc with id %s", d.Get("vpc_id").(string)) + } + + subnets := make([]string, 0) + + for _, subnet := range resp.Subnets { + subnets = append(subnets, *subnet.SubnetId) + } + + d.SetId(d.Get("vpc_id").(string)) + d.Set("ids", subnets) + + return nil +} diff --git a/builtin/providers/aws/data_source_aws_subnet_ids_test.go b/builtin/providers/aws/data_source_aws_subnet_ids_test.go new file mode 100644 index 0000000000..acc3090004 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_subnet_ids_test.go @@ -0,0 +1,79 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccDataSourceAwsSubnetIDs(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourceAwsSubnetIDsConfig, + Check: resource.ComposeTestCheckFunc( + testAccDataSourceAwsSubnetIDsCheck("data.aws_subnet_ids.selected"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsSubnetIDsCheck(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) + } + + vpcRs, ok := s.RootModule().Resources["aws_vpc.test"] + if !ok { + return fmt.Errorf("can't find aws_vpc.test in state") + } + _, ok = s.RootModule().Resources["aws_subnet.test"] + if !ok { + return fmt.Errorf("can't find aws_subnet.test in state") + } + + attr := rs.Primary.Attributes + + if rs.Primary.ID != vpcRs.Primary.ID { + return fmt.Errorf("ID of this resource should be the vpc id") + } + + return nil + } +} + +const testAccDataSourceAwsSubnetIDsConfig = ` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "test" { + cidr_block = "172.16.0.0/16" + + tags { + Name = "terraform-testacc-subnet-ids-data-source" + } +} + +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.16.123.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "terraform-testacc-subnet-ids-data-source" + } +} + +data "aws_subnet_ids" "selected" { + vpc_id = "${aws_vpc.test.id}" + depends_on = ["aws_subnet.test"] +} +` diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 0ad5817858..b412cc007b 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -188,6 +188,7 @@ func Provider() terraform.ResourceProvider { "aws_s3_bucket_object": dataSourceAwsS3BucketObject(), "aws_sns_topic": dataSourceAwsSnsTopic(), "aws_subnet": dataSourceAwsSubnet(), + "aws_subnet_ids": dataSourceAwsSubnetIDs(), "aws_security_group": dataSourceAwsSecurityGroup(), "aws_vpc": dataSourceAwsVpc(), "aws_vpc_endpoint": dataSourceAwsVpcEndpoint(), From d7a319f239df0e010a29ae7cf05c4f2c9bd6c25b Mon Sep 17 00:00:00 2001 From: Colin Wood Date: Fri, 31 Mar 2017 10:57:07 -0700 Subject: [PATCH 2/3] Fix accpetence test to work --- .../aws/data_source_aws_subnet_ids_test.go | 61 ++++++++----------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/builtin/providers/aws/data_source_aws_subnet_ids_test.go b/builtin/providers/aws/data_source_aws_subnet_ids_test.go index acc3090004..53c26aa371 100644 --- a/builtin/providers/aws/data_source_aws_subnet_ids_test.go +++ b/builtin/providers/aws/data_source_aws_subnet_ids_test.go @@ -1,11 +1,9 @@ package aws import ( - "fmt" "testing" "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" ) func TestAccDataSourceAwsSubnetIDs(t *testing.T) { @@ -13,47 +11,20 @@ func TestAccDataSourceAwsSubnetIDs(t *testing.T) { PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccDataSourceAwsSubnetIDsConfig, + }, + { + Config: testAccDataSourceAwsSubnetIDsConfigWithDataSource, Check: resource.ComposeTestCheckFunc( - testAccDataSourceAwsSubnetIDsCheck("data.aws_subnet_ids.selected"), + resource.TestCheckResourceAttr("data.aws_subnet_ids.selected", "ids.#", "1"), ), }, }, }) } -func testAccDataSourceAwsSubnetIDsCheck(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) - } - - vpcRs, ok := s.RootModule().Resources["aws_vpc.test"] - if !ok { - return fmt.Errorf("can't find aws_vpc.test in state") - } - _, ok = s.RootModule().Resources["aws_subnet.test"] - if !ok { - return fmt.Errorf("can't find aws_subnet.test in state") - } - - attr := rs.Primary.Attributes - - if rs.Primary.ID != vpcRs.Primary.ID { - return fmt.Errorf("ID of this resource should be the vpc id") - } - - return nil - } -} - -const testAccDataSourceAwsSubnetIDsConfig = ` -provider "aws" { - region = "us-west-2" -} - +const testAccDataSourceAwsSubnetIDsConfigWithDataSource = ` resource "aws_vpc" "test" { cidr_block = "172.16.0.0/16" @@ -74,6 +45,24 @@ resource "aws_subnet" "test" { data "aws_subnet_ids" "selected" { vpc_id = "${aws_vpc.test.id}" - depends_on = ["aws_subnet.test"] +} +` +const testAccDataSourceAwsSubnetIDsConfig = ` +resource "aws_vpc" "test" { + cidr_block = "172.16.0.0/16" + + tags { + Name = "terraform-testacc-subnet-ids-data-source" + } +} + +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.16.123.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "terraform-testacc-subnet-ids-data-source" + } } ` From 1ce0776c51291933f9350731757f67b52021cb18 Mon Sep 17 00:00:00 2001 From: Colin Wood Date: Fri, 31 Mar 2017 11:21:44 -0700 Subject: [PATCH 3/3] Add documentation about aws_subnet_ids --- .../providers/aws/d/subnet_ids.html.markdown | 40 +++++++++++++++++++ website/source/layouts/aws.erb | 3 ++ 2 files changed, 43 insertions(+) create mode 100644 website/source/docs/providers/aws/d/subnet_ids.html.markdown diff --git a/website/source/docs/providers/aws/d/subnet_ids.html.markdown b/website/source/docs/providers/aws/d/subnet_ids.html.markdown new file mode 100644 index 0000000000..883d056754 --- /dev/null +++ b/website/source/docs/providers/aws/d/subnet_ids.html.markdown @@ -0,0 +1,40 @@ +--- +layout: "aws" +page_title: "AWS: aws_subnet_ids" +sidebar_current: "docs-aws-datasource-subnet-ids" +description: |- + Provides a list of subnet Ids for a VPC +--- + +# aws\_subnet\_ids + +`aws_subnet_ids` provides a list of ids for a vpc_id + +This resource can be useful for getting back a list of subnet ids for a vpc. + +## Example Usage + +The following shows outputing all cidr blocks for every subnet id in a vpc. + +``` +data "aws_subnet_ids" "example" { + vpc_id = "${var.vpc_id}" +} + +data "aws_subnet" "example" { + count = "${length(data.aws_subnet_ids.example.ids)}" + id = "${aws_subnet_ids.example.ids[count.index]}" +} + +output "subnet_cidr_blocks" { + value = ["${data.aws_subnet.example.*.cidr_block}"] +} +``` + +## Argument Reference + +* `vpc_id` - (Required) The VPC ID that you want to filter from. + +## Attributes Reference + +* `ids` - Is a list of all the subnet ids found. If none found. This data source will fail out. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index d3e39f97d5..f7b66a1a5d 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -119,6 +119,9 @@ > aws_subnet + > + aws_subnet_ids + > aws_vpc