From 3818720fd4ffdf926b21a6615637e15d4e05bd5d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 27 Oct 2016 09:58:24 -0400 Subject: [PATCH] provider/aws: Data source to provides details about a specific AWS prefix list (#9566) * Add AWS Prefix List data source. AWS Prefix List data source acceptance test. AWS Prefix List data source documentation. * Improve error message when PL not matched. --- .../aws/data_source_aws_prefix_list.go | 70 +++++++++++++++++++ .../aws/data_source_aws_prefix_list_test.go | 67 ++++++++++++++++++ builtin/providers/aws/provider.go | 1 + .../providers/aws/d/prefix_list.html.markdown | 63 +++++++++++++++++ website/source/layouts/aws.erb | 3 + 5 files changed, 204 insertions(+) create mode 100644 builtin/providers/aws/data_source_aws_prefix_list.go create mode 100644 builtin/providers/aws/data_source_aws_prefix_list_test.go create mode 100644 website/source/docs/providers/aws/d/prefix_list.html.markdown diff --git a/builtin/providers/aws/data_source_aws_prefix_list.go b/builtin/providers/aws/data_source_aws_prefix_list.go new file mode 100644 index 000000000..3dafdecfd --- /dev/null +++ b/builtin/providers/aws/data_source_aws_prefix_list.go @@ -0,0 +1,70 @@ +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 dataSourceAwsPrefixList() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsPrefixListRead, + + Schema: map[string]*schema.Schema{ + "prefix_list_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + // Computed values. + "id": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "cidr_blocks": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceAwsPrefixListRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + req := &ec2.DescribePrefixListsInput{} + + if prefixListID := d.Get("prefix_list_id"); prefixListID != "" { + req.PrefixListIds = []*string{aws.String(prefixListID.(string))} + } + + log.Printf("[DEBUG] DescribePrefixLists %s\n", req) + resp, err := conn.DescribePrefixLists(req) + if err != nil { + return err + } + if resp == nil || len(resp.PrefixLists) == 0 { + return fmt.Errorf("no matching prefix list found; the prefix list ID may be invalid or not exist in the current region") + } + + pl := resp.PrefixLists[0] + + d.SetId(*pl.PrefixListId) + d.Set("id", pl.PrefixListId) + d.Set("name", pl.PrefixListName) + + cidrs := make([]string, len(pl.Cidrs)) + for i, v := range pl.Cidrs { + cidrs[i] = *v + } + d.Set("cidr_blocks", cidrs) + + return nil +} diff --git a/builtin/providers/aws/data_source_aws_prefix_list_test.go b/builtin/providers/aws/data_source_aws_prefix_list_test.go new file mode 100644 index 000000000..27da3776b --- /dev/null +++ b/builtin/providers/aws/data_source_aws_prefix_list_test.go @@ -0,0 +1,67 @@ +package aws + +import ( + "fmt" + "strconv" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccDataSourceAwsPrefixList(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourceAwsPrefixListConfig, + Check: resource.ComposeTestCheckFunc( + testAccDataSourceAwsPrefixListCheck("data.aws_prefix_list.s3"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsPrefixListCheck(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) + } + + attr := rs.Primary.Attributes + + if attr["name"] != "com.amazonaws.us-west-2.s3" { + return fmt.Errorf("bad name %s", attr["name"]) + } + if attr["id"] != "pl-68a54001" { + return fmt.Errorf("bad id %s", attr["id"]) + } + + var ( + cidrBlockSize int + err error + ) + + if cidrBlockSize, err = strconv.Atoi(attr["cidr_blocks.#"]); err != nil { + return err + } + if cidrBlockSize < 1 { + return fmt.Errorf("cidr_blocks seem suspiciously low: %d", cidrBlockSize) + } + + return nil + } +} + +const testAccDataSourceAwsPrefixListConfig = ` +provider "aws" { + region = "us-west-2" +} + +data "aws_prefix_list" "s3" { + prefix_list_id = "pl-68a54001" +} +` diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 495c15af4..f552c1341 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -153,6 +153,7 @@ func Provider() terraform.ResourceProvider { "aws_elb_service_account": dataSourceAwsElbServiceAccount(), "aws_iam_policy_document": dataSourceAwsIamPolicyDocument(), "aws_ip_ranges": dataSourceAwsIPRanges(), + "aws_prefix_list": dataSourceAwsPrefixList(), "aws_redshift_service_account": dataSourceAwsRedshiftServiceAccount(), "aws_region": dataSourceAwsRegion(), "aws_s3_bucket_object": dataSourceAwsS3BucketObject(), diff --git a/website/source/docs/providers/aws/d/prefix_list.html.markdown b/website/source/docs/providers/aws/d/prefix_list.html.markdown new file mode 100644 index 000000000..94de7397f --- /dev/null +++ b/website/source/docs/providers/aws/d/prefix_list.html.markdown @@ -0,0 +1,63 @@ +--- +layout: "aws" +page_title: "AWS: aws_prefix-list" +sidebar_current: "docs-aws-datasource-prefix-list" +description: |- + Provides details about a specific prefix list +--- + +# aws\_prefix\_list + +`aws_prefix_list` provides details about a specific prefix list (PL) +in the current region. + +This can be used both to validate a prefix list given in a variable +and to obtain the CIDR blocks (IP address ranges) for the associated +AWS service. The latter may be useful e.g. for adding network ACL +rules. + +## Example Usage + +``` +resource "aws_vpc_endpoint" "private_s3" { + vpc_id = "${aws_vpc.foo.id}" + service_name = "com.amazonaws.us-west-2.s3" +} + +data "aws_prefix_list" "private_s3" { + prefix_list_id = "${aws_vpc_endpoint.private_s3.prefix_list_id}" +} + +resource "aws_network_acl" "bar" { + vpc_id = "${aws_vpc.foo.id}" +} +resource "aws_network_acl_rule" "private_s3" { + network_acl_id = "${aws_network_acl.bar.id}" + rule_number = 200 + egress = false + protocol = "tcp" + rule_action = "allow" + cidr_block = "${data.aws_prefix_list.private_s3.cidr_blocks[0]}" + from_port = 443 + to_port = 443 +} +``` + +## Argument Reference + +The arguments of this data source act as filters for querying the available +prefix lists. The given filters must match exactly one prefix list +whose data will be exported as attributes. + +* `prefix_list_id` - (Required) The ID of the prefix list to select. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the selected prefix list. + +* `name` - The name of the selected prefix list. + +* `cidr_blocks` - The list of CIDR blocks for the AWS service associated +with the prefix list. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index fd5f7c8ed..a0fb0539d 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -41,6 +41,9 @@ > aws_ip_ranges + > + aws_prefix_list + > aws_redshift_service_account