From bc46b1cbf948a656583fb1d36c63ee82dc70662b Mon Sep 17 00:00:00 2001 From: Tom Elliff Date: Tue, 25 Apr 2017 14:46:51 +0100 Subject: [PATCH] Allow filtering of aws_subnet_ids by tags This is the minimal amount of work needed to be able to create a list of a subset of subnet IDs in a VPC, allowing people to loop through them easily when creating EC2 instances or provide a list straight to an ELB. --- .../aws/data_source_aws_subnet_ids.go | 8 +++ .../aws/data_source_aws_subnet_ids_test.go | 68 +++++++++++++++++-- .../providers/aws/d/subnet_ids.html.markdown | 23 +++++++ 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/builtin/providers/aws/data_source_aws_subnet_ids.go b/builtin/providers/aws/data_source_aws_subnet_ids.go index efe6c75a4..c1a495aa1 100644 --- a/builtin/providers/aws/data_source_aws_subnet_ids.go +++ b/builtin/providers/aws/data_source_aws_subnet_ids.go @@ -12,10 +12,14 @@ func dataSourceAwsSubnetIDs() *schema.Resource { return &schema.Resource{ Read: dataSourceAwsSubnetIDsRead, Schema: map[string]*schema.Schema{ + + "tags": tagsSchemaComputed(), + "vpc_id": &schema.Schema{ Type: schema.TypeString, Required: true, }, + "ids": &schema.Schema{ Type: schema.TypeSet, Computed: true, @@ -37,6 +41,10 @@ func dataSourceAwsSubnetIDsRead(d *schema.ResourceData, meta interface{}) error }, ) + req.Filters = append(req.Filters, buildEC2TagFilterList( + tagsFromMap(d.Get("tags").(map[string]interface{})), + )...) + log.Printf("[DEBUG] DescribeSubnets %s\n", req) resp, err := conn.DescribeSubnets(req) if err != 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 index 36f6c4b91..5d752a25e 100644 --- a/builtin/providers/aws/data_source_aws_subnet_ids_test.go +++ b/builtin/providers/aws/data_source_aws_subnet_ids_test.go @@ -21,7 +21,8 @@ func TestAccDataSourceAwsSubnetIDs(t *testing.T) { { Config: testAccDataSourceAwsSubnetIDsConfigWithDataSource(rInt), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_subnet_ids.selected", "ids.#", "1"), + resource.TestCheckResourceAttr("data.aws_subnet_ids.selected", "ids.#", "3"), + resource.TestCheckResourceAttr("data.aws_subnet_ids.private", "ids.#", "2"), ), }, }, @@ -39,20 +40,50 @@ func testAccDataSourceAwsSubnetIDsConfigWithDataSource(rInt int) string { } } - resource "aws_subnet" "test" { + resource "aws_subnet" "test_public_a" { vpc_id = "${aws_vpc.test.id}" cidr_block = "172.%d.123.0/24" availability_zone = "us-west-2a" tags { - Name = "terraform-testacc-subnet-ids-data-source" + Name = "terraform-testacc-subnet-ids-data-source-public-a" + Tier = "Public" + } + } + + resource "aws_subnet" "test_private_a" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.125.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-a" + Tier = "Private" + } + } + + resource "aws_subnet" "test_private_b" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.126.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-b" + Tier = "Private" } } data "aws_subnet_ids" "selected" { vpc_id = "${aws_vpc.test.id}" } - `, rInt, rInt) + + data "aws_subnet_ids" "private" { + vpc_id = "${aws_vpc.test.id}" + tags { + Tier = "Private" + } + } + `, rInt, rInt, rInt, rInt) } func testAccDataSourceAwsSubnetIDsConfig(rInt int) string { @@ -65,14 +96,37 @@ func testAccDataSourceAwsSubnetIDsConfig(rInt int) string { } } - resource "aws_subnet" "test" { + resource "aws_subnet" "test_public_a" { vpc_id = "${aws_vpc.test.id}" cidr_block = "172.%d.123.0/24" availability_zone = "us-west-2a" tags { - Name = "terraform-testacc-subnet-ids-data-source" + Name = "terraform-testacc-subnet-ids-data-source-public-a" + Tier = "Public" } } - `, rInt, rInt) + + resource "aws_subnet" "test_private_a" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.125.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-a" + Tier = "Private" + } + } + + resource "aws_subnet" "test_private_b" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.126.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-b" + Tier = "Private" + } + } + `, rInt, rInt, rInt, rInt) } diff --git a/website/source/docs/providers/aws/d/subnet_ids.html.markdown b/website/source/docs/providers/aws/d/subnet_ids.html.markdown index 7cf34ffa6..871da0ca2 100644 --- a/website/source/docs/providers/aws/d/subnet_ids.html.markdown +++ b/website/source/docs/providers/aws/d/subnet_ids.html.markdown @@ -31,10 +31,33 @@ output "subnet_cidr_blocks" { } ``` +The following example retrieves a list of all subnets in a VPC with a custom +tag of `Tier` set to a value of "Private" so that the `aws_instance` resource +can loop through the subnets, putting instances across availability zones. + +```hcl +data "aws_subnet_ids" "private" { + vpc_id = "${var.vpc_id}" + tags { + Tier = "Private" + } +} + +resource "aws_instance" "app" { + count = "3" + ami = "${var.ami}" + instance_type = "t2.micro" + subnet_id = "${element(data.aws_subnet_ids.private.ids, count.index)}" +} +``` + ## Argument Reference * `vpc_id` - (Required) The VPC ID that you want to filter from. +* `tags` - (Optional) A mapping of tags, each pair of which must exactly match + a pair on the desired subnets. + ## Attributes Reference * `ids` - Is a list of all the subnet ids found. If none found. This data source will fail out.