Merge #8403: name_regex attribute on aws_ami data source

This commit is contained in:
Martin Atkins 2016-08-27 13:06:37 -07:00
commit 4f906dba7a
4 changed files with 67 additions and 9 deletions

View File

@ -11,6 +11,7 @@ IMPROVEMENTS:
* provider/aws: Add MemoryReservation To `aws_ecs_container_definition` data source [GH-8437]
* provider/aws: Export `arn` of `aws_autoscaling_group` [GH-8503]
* provider/aws: More robust handling of Lambda function archives hosted on S3 [GH-6860]
* provider/aws: `name_regex` attribute for local post-filtering of `aws_ami` data source results [GH-8403]
BUG FIXES:
* core: JSON configuration with resources with a single key parse properly [GH-8485]

View File

@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"log"
"regexp"
"sort"
"time"
@ -43,6 +44,11 @@ func dataSourceAwsAmi() *schema.Resource {
},
},
},
"name_regex": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"most_recent": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
@ -206,10 +212,11 @@ func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error {
executableUsers, executableUsersOk := d.GetOk("executable_users")
filters, filtersOk := d.GetOk("filter")
nameRegex, nameRegexOk := d.GetOk("name_regex")
owners, ownersOk := d.GetOk("owners")
if executableUsersOk == false && filtersOk == false && ownersOk == false {
return fmt.Errorf("One of executable_users, filters, or owners must be assigned")
if executableUsersOk == false && filtersOk == false && nameRegexOk == false && ownersOk == false {
return fmt.Errorf("One of executable_users, filters, name_regex, or owners must be assigned")
}
params := &ec2.DescribeImagesInput{}
@ -227,20 +234,33 @@ func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error {
if err != nil {
return err
}
var filteredImages []*ec2.Image
if nameRegexOk == true {
r := regexp.MustCompile(nameRegex.(string))
for _, image := range resp.Images {
if r.MatchString(*image.Name) == true {
filteredImages = append(filteredImages, image)
}
}
} else {
filteredImages = resp.Images[:]
}
var image *ec2.Image
if len(resp.Images) < 1 {
if len(filteredImages) < 1 {
return fmt.Errorf("Your query returned no results. Please change your filters and try again.")
} else if len(resp.Images) > 1 {
} else if len(filteredImages) > 1 {
if (d.Get("most_recent").(bool)) == true {
log.Printf("[DEBUG] aws_ami - multiple results found and most_recent is set")
image = mostRecentAmi(resp.Images)
image = mostRecentAmi(filteredImages)
} else {
log.Printf("[DEBUG] aws_ami - multiple results found and most_recent not set")
return fmt.Errorf("Your query returned more than one result. Please try a more specific search, or set most_recent to true.")
}
} else {
log.Printf("[DEBUG] aws_ami - Single AMI found: %s", *resp.Images[0].ImageId)
image = resp.Images[0]
log.Printf("[DEBUG] aws_ami - Single AMI found: %s", *filteredImages[0].ImageId)
image = filteredImages[0]
}
return amiDescriptionAttributes(d, image)
}

View File

@ -139,6 +139,22 @@ func TestAccAWSAmiDataSource_owners(t *testing.T) {
})
}
func TestAccAWSAmiDataSource_localNameFilter(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckAwsAmiDataSourceNameRegexConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsAmiDataSourceID("data.aws_ami.name_regex_filtered_ami"),
resource.TestMatchResourceAttr("data.aws_ami.name_regex_filtered_ami", "image_id", regexp.MustCompile("^ami-")),
),
},
},
})
}
func testAccCheckAwsAmiDataSourceDestroy(s *terraform.State) error {
return nil
}
@ -245,3 +261,16 @@ data "aws_ami" "amazon_ami" {
owners = ["amazon"]
}
`
// Testing name_regex parameter
const testAccCheckAwsAmiDataSourceNameRegexConfig = `
data "aws_ami" "name_regex_filtered_ami" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn-ami-*"]
}
name_regex = "^amzn-ami-\\d{3}[5].*-ecs-optimized"
}
`

View File

@ -8,7 +8,7 @@ description: |-
# aws\_ami
Use this data source to get the ID of a registered AMI for use in other
Use this data source to get the ID of a registered AMI for use in other
resources.
## Example Usage
@ -25,6 +25,7 @@ data "aws_ami" "nat_ami" {
name = "name"
values = ["amzn-ami-vpc-nat*"]
}
name_regex = "^myami-\\d{3}"
owners = ["self"]
}
```
@ -44,7 +45,14 @@ several valid keys, for a full reference, check out
* `owners` - (Optional) Limit search to specific AMI owners. Valid items are the numeric
account ID, `amazon`, or `self`.
~> **NOTE:** At least one of `executable_users`, `filter`, or `owners` must be specified.
* `name_regex` - (Optional) A regex string to apply to the AMI list returned
by AWS. This allows more advanced filtering not supported from the AWS API. This
filtering is done locally on what AWS returns, and could have a performance
impact if the result is large. It is recommended to combine this with other
options to narrow down the list AWS returns.
~> **NOTE:** At least one of `executable_users`, `filter`, `owners`, or
`name_regex` 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