From c99bc8a8076df50088ff58a2c86697ddc59899ff Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Wed, 18 Jan 2017 13:14:49 -0500 Subject: [PATCH] Add instance_tags as an additional filter --- .../providers/aws/data_source_aws_instance.go | 15 ++++++-- .../aws/data_source_aws_instance_test.go | 38 +++++++++++++++++++ .../providers/aws/d/instance.html.markdown | 7 +++- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/builtin/providers/aws/data_source_aws_instance.go b/builtin/providers/aws/data_source_aws_instance.go index 09d74d0602..617a5c2575 100644 --- a/builtin/providers/aws/data_source_aws_instance.go +++ b/builtin/providers/aws/data_source_aws_instance.go @@ -14,8 +14,9 @@ func dataSourceAwsInstance() *schema.Resource { Read: dataSourceAwsInstanceRead, Schema: map[string]*schema.Schema{ - "filter": dataSourceFiltersSchema(), - "tags": dataSourceTagsSchema(), + "filter": dataSourceFiltersSchema(), + "tags": dataSourceTagsSchema(), + "instance_tags": tagsSchemaComputed(), "instance_id": { Type: schema.TypeString, Optional: true, @@ -208,9 +209,10 @@ func dataSourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { filters, filtersOk := d.GetOk("filter") instanceID, instanceIDOk := d.GetOk("instance_id") + tags, tagsOk := d.GetOk("instance_tags") - if filtersOk == false && instanceIDOk == false { - return fmt.Errorf("One of filters, or instance_id must be assigned") + if filtersOk == false && instanceIDOk == false && tagsOk == false { + return fmt.Errorf("One of filters, instance_tags, or instance_id must be assigned") } // Build up search parameters @@ -221,6 +223,11 @@ func dataSourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { if instanceIDOk { params.InstanceIds = []*string{aws.String(instanceID.(string))} } + if tagsOk { + params.Filters = append(params.Filters, buildEC2TagFilterList( + tagsFromMap(tags.(map[string]interface{})), + )...) + } // Perform the lookup resp, err := conn.DescribeInstances(params) diff --git a/builtin/providers/aws/data_source_aws_instance_test.go b/builtin/providers/aws/data_source_aws_instance_test.go index 0d6d2cfd0c..7116c11854 100644 --- a/builtin/providers/aws/data_source_aws_instance_test.go +++ b/builtin/providers/aws/data_source_aws_instance_test.go @@ -26,6 +26,26 @@ func TestAccAWSInstanceDataSource_basic(t *testing.T) { }) } +func TestAccAWSInstanceDataSource_tags(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccInstanceDataSourceConfig_Tags, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "data.aws_instance.web-instance", "ami", "ami-4fccb37f"), + resource.TestCheckResourceAttr( + "data.aws_instance.web-instance", "tags.#", "1"), + resource.TestCheckResourceAttr( + "data.aws_instance.web-instance", "instance_type", "m1.small"), + ), + }, + }, + }) +} + func TestAccAWSInstanceDataSource_AzUserData(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -259,6 +279,24 @@ data "aws_instance" "web-instance" { } ` +// Use the tags attribute to filter +const testAccInstanceDataSourceConfig_Tags = ` +resource "aws_instance" "web" { + # us-west-2 + ami = "ami-4fccb37f" + instance_type = "m1.small" + tags { + Name = "HelloWorld" + } +} + +data "aws_instance" "web-instance" { + instance_tags { + Name = "${aws_instance.web.tags["Name"]}" + } +} +` + // filter on tag, populate more attributes const testAccInstanceDataSourceConfig_AzUserData = ` resource "aws_instance" "foo" { diff --git a/website/source/docs/providers/aws/d/instance.html.markdown b/website/source/docs/providers/aws/d/instance.html.markdown index f459fe8779..8487f398ca 100644 --- a/website/source/docs/providers/aws/d/instance.html.markdown +++ b/website/source/docs/providers/aws/d/instance.html.markdown @@ -29,13 +29,16 @@ data "aws_instance" "foo" { ## Argument Reference -* `instance_id` - (Optional) Specify the exact Instance ID to populate the data source with. +* `instance_id` - (Optional) Specify the exact Instance ID to populate the data source with. + +* `instance_tags` - (Optional) A mapping of tags, each pair of which must +exactly match a pair on the desired Instance. * `filter` - (Optional) One or more name/value pairs to filter off of. There are several valid keys, for a full reference, check out [describe-instances in the AWS CLI reference][1]. -~> **NOTE:** At least one of `filter` or `instance_id` must be specified. +~> **NOTE:** At least one of `filter`, `instance_tags`, or `instance_id` must be specified. ~> **NOTE:** If more or less than a single match is returned by the search, Terraform will fail. Ensure that your search is specific enough to return