From bfb0f4b7a6e1a8b2b2ba85cfeb94e92693257420 Mon Sep 17 00:00:00 2001 From: saravanan30erd Date: Sat, 23 Jun 2018 17:28:57 +0400 Subject: [PATCH 1/4] issue #4260 New datasource: aws_network_acls --- aws/data_source_aws_network_acls.go | 88 +++++++++++++++++++++++++++++ aws/provider.go | 1 + 2 files changed, 89 insertions(+) create mode 100644 aws/data_source_aws_network_acls.go diff --git a/aws/data_source_aws_network_acls.go b/aws/data_source_aws_network_acls.go new file mode 100644 index 00000000000..b698d929395 --- /dev/null +++ b/aws/data_source_aws_network_acls.go @@ -0,0 +1,88 @@ +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 dataSourceAwsNetworkAcls() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsNetworkAclsRead, + Schema: map[string]*schema.Schema{ + "filter": ec2CustomFiltersSchema(), + + "tags": tagsSchemaComputed(), + + "vpc_id": { + Type: schema.TypeString, + Required: true, + }, + + "ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + } +} + +func dataSourceAwsNetworkAclsRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + req := &ec2.DescribeNetworkAclsInput{} + + filters, filtersOk := d.GetOk("filter") + tags, tagsOk := d.GetOk("tags") + + req.Filters = buildEC2AttributeFilterList( + map[string]string{ + "vpc-id": d.Get("vpc_id").(string), + }, + ) + + if tagsOk { + req.Filters = append(req.Filters, buildEC2TagFilterList( + tagsFromMap(tags.(map[string]interface{})), + )...) + } + + if filtersOk { + req.Filters = append(req.Filters, buildEC2CustomFilterList( + filters.(*schema.Set), + )...) + } + + if len(req.Filters) == 0 { + // Don't send an empty filters list; the EC2 API won't accept it. + req.Filters = nil + } + + log.Printf("[DEBUG] DescribeNetworkAcls %s\n", req) + resp, err := conn.DescribeNetworkAcls(req) + if err != nil { + return err + } + + if resp == nil || len(resp.NetworkAcls) == 0 { + return fmt.Errorf("no matching network ACL found for vpc with id %s", d.Get("vpc_id").(string)) + } + + networkAcls := make([]string, 0) + + for _, networkAcl := range resp.NetworkAcls { + networkAcls = append(networkAcls, aws.StringValue(networkAcl.NetworkAclId)) + } + + d.SetId(d.Get("vpc_id").(string)) + if err := d.Set("ids", networkAcls); err != nil { + return fmt.Errorf("Error setting network ACL ids: %s", err) + } + + return nil +} diff --git a/aws/provider.go b/aws/provider.go index a27aa307ed4..d15b226f2e2 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -226,6 +226,7 @@ func Provider() terraform.ResourceProvider { "aws_lambda_invocation": dataSourceAwsLambdaInvocation(), "aws_mq_broker": dataSourceAwsMqBroker(), "aws_nat_gateway": dataSourceAwsNatGateway(), + "aws_network_acls": dataSourceAwsNetworkAcls(), "aws_network_interface": dataSourceAwsNetworkInterface(), "aws_partition": dataSourceAwsPartition(), "aws_prefix_list": dataSourceAwsPrefixList(), From d126fad2dbc3580a5c87d81769424e1791a1a301 Mon Sep 17 00:00:00 2001 From: saravanan30erd Date: Sat, 23 Jun 2018 22:12:34 +0400 Subject: [PATCH 2/4] add acceptance test --- aws/data_source_aws_network_acls_test.go | 122 +++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 aws/data_source_aws_network_acls_test.go diff --git a/aws/data_source_aws_network_acls_test.go b/aws/data_source_aws_network_acls_test.go new file mode 100644 index 00000000000..1ef2c72e419 --- /dev/null +++ b/aws/data_source_aws_network_acls_test.go @@ -0,0 +1,122 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccDataSourceAwsNetworkAcls_basic(t *testing.T) { + rName := acctest.RandString(5) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVpcDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkAclsConfig(rName), + }, + { + Config: testAccDataSourceAwsNetworkAclsConfigWithDataSource(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_network_acls.all", "ids.#", "3"), + resource.TestCheckResourceAttr("data.aws_network_acls.with_tags", "ids.#", "2"), + resource.TestCheckResourceAttr("data.aws_network_acls.with_filter", "ids.#", "1"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsNetworkAclsConfigWithDataSource(rName string) string { + return fmt.Sprintf(` + resource "aws_vpc" "test-vpc" { + cidr_block = "10.0.0.0/16" + } + + resource "aws_network_acl" "acl1" { + vpc_id = "${aws_vpc.test-vpc.id}" + + tags { + Name = "testacc-acl-%s" + } + } + + resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test-vpc.id}" + cidr_block = "10.0.0.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "tf-acc-subnet" + } + } + + resource "aws_network_acl" "acl2" { + vpc_id = "${aws_vpc.test-vpc.id}" + subnet_ids = ["${aws_subnet.test.id}"] + + tags { + Name = "testacc-acl-%s" + } + } + + data "aws_network_acls" "all" { + vpc_id = "${aws_vpc.test-vpc.id}" + } + + data "aws_network_acls" "with_tags" { + vpc_id = "${aws_vpc.test-vpc.id}" + + tags { + Name = "testacc-acl-%s" + } + } + + data "aws_network_acls" "with_filter" { + vpc_id = "${aws_vpc.test-vpc.id}" + + filter { + name = "association.subnet-id" + values = ["${aws_subnet.test.id}"] + } + } + `, rName, rName, rName) +} + +func testAccDataSourceAwsNetworkAclsConfig(rName string) string { + return fmt.Sprintf(` + resource "aws_vpc" "test-vpc" { + cidr_block = "10.0.0.0/16" + } + + resource "aws_network_acl" "acl1" { + vpc_id = "${aws_vpc.test-vpc.id}" + + tags { + Name = "testacc-acl-%s" + } + } + + resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test-vpc.id}" + cidr_block = "10.0.0.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "tf-acc-subnet" + } + } + + resource "aws_network_acl" "acl2" { + vpc_id = "${aws_vpc.test-vpc.id}" + subnet_ids = ["${aws_subnet.test.id}"] + + tags { + Name = "testacc-acl-%s" + } + } + `, rName, rName) +} From b9e05560fa99e57356de20817b05feac6cd9171a Mon Sep 17 00:00:00 2001 From: saravanan30erd Date: Sat, 23 Jun 2018 22:30:25 +0400 Subject: [PATCH 3/4] add documentation for datasource network_acls --- website/aws.erb | 3 + website/docs/d/network_acls.html.markdown | 70 +++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 website/docs/d/network_acls.html.markdown diff --git a/website/aws.erb b/website/aws.erb index fe18e6d8e60..f2fd9f8619a 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -241,6 +241,9 @@ > aws_nat_gateway + > + aws_network_acls + > aws_network_interface diff --git a/website/docs/d/network_acls.html.markdown b/website/docs/d/network_acls.html.markdown new file mode 100644 index 00000000000..c4b9efe22d5 --- /dev/null +++ b/website/docs/d/network_acls.html.markdown @@ -0,0 +1,70 @@ +--- +layout: "aws" +page_title: "AWS: aws_network_acls" +sidebar_current: "docs-aws-datasource-network-acls" +description: |- + Provides a list of network ACL ids for a VPC +--- + +# Data Source: aws_network_acls + +## Example Usage + +The following shows outputing all network ACL ids in a vpc. + +```hcl +data "aws_network_acls" "example" { + vpc_id = "${var.vpc_id}" +} + +output "example" { + value = "${data.aws_network_acls.example.ids}" +} +``` + +The following example retrieves a list of all network ACL ids in a VPC with a custom +tag of `Tier` set to a value of "Private". + +```hcl +data "aws_network_acls" "example" { + vpc_id = "${var.vpc_id}" + tags { + Tier = "Private" + } +} +``` + +The following example retrieves a network ACL id in a VPC which associated +with specific subnet. + +```hcl +data "aws_network_acls" "example" { + vpc_id = "${var.vpc_id}" + filter { + name = "association.subnet-id" + values = ["${aws_subnet.test.id}"] + } +} +``` + +## 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 network ACLs. + +* `filter` - (Optional) Custom filter block as described below. + +More complex filters can be expressed using one or more `filter` sub-blocks, +which take the following arguments: + +* `name` - (Required) The name of the field to filter by, as defined by + [the underlying AWS API](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkAcls.html). + +* `values` - (Required) Set of values that are accepted for the given field. + A VPC will be selected if any one of the given values matches. + +## Attributes Reference + +* `ids` - A list of all the network ACL ids found. This data source will fail if none are found. From d05c3a0232faade5b8334e996952e4173f810c27 Mon Sep 17 00:00:00 2001 From: saravanan30erd Date: Mon, 25 Jun 2018 22:27:25 +0400 Subject: [PATCH 4/4] correction based on feedback --- aws/data_source_aws_network_acls.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/aws/data_source_aws_network_acls.go b/aws/data_source_aws_network_acls.go index b698d929395..88454f894a0 100644 --- a/aws/data_source_aws_network_acls.go +++ b/aws/data_source_aws_network_acls.go @@ -19,7 +19,7 @@ func dataSourceAwsNetworkAcls() *schema.Resource { "vpc_id": { Type: schema.TypeString, - Required: true, + Optional: true, }, "ids": { @@ -37,15 +37,17 @@ func dataSourceAwsNetworkAclsRead(d *schema.ResourceData, meta interface{}) erro req := &ec2.DescribeNetworkAclsInput{} + if v, ok := d.GetOk("vpc_id"); ok { + req.Filters = buildEC2AttributeFilterList( + map[string]string{ + "vpc-id": v.(string), + }, + ) + } + filters, filtersOk := d.GetOk("filter") tags, tagsOk := d.GetOk("tags") - req.Filters = buildEC2AttributeFilterList( - map[string]string{ - "vpc-id": d.Get("vpc_id").(string), - }, - ) - if tagsOk { req.Filters = append(req.Filters, buildEC2TagFilterList( tagsFromMap(tags.(map[string]interface{})),