-
Notifications
You must be signed in to change notification settings - Fork 9.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18803 from farhanangullia/f-data_source_aws_subnets
New data source: aws_subnets
- Loading branch information
Showing
5 changed files
with
357 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-data-source | ||
aws_subnets | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" | ||
) | ||
|
||
func dataSourceAwsSubnets() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceAwsSubnetsRead, | ||
Schema: map[string]*schema.Schema{ | ||
"filter": dataSourceFiltersSchema(), | ||
"tags": tagsSchemaComputed(), | ||
|
||
"ids": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceAwsSubnetsRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).ec2conn | ||
|
||
input := &ec2.DescribeSubnetsInput{} | ||
|
||
if tags, tagsOk := d.GetOk("tags"); tagsOk { | ||
input.Filters = append(input.Filters, buildEC2TagFilterList( | ||
keyvaluetags.New(tags.(map[string]interface{})).Ec2Tags(), | ||
)...) | ||
} | ||
|
||
if filters, filtersOk := d.GetOk("filter"); filtersOk { | ||
input.Filters = append(input.Filters, | ||
buildAwsDataSourceFilters(filters.(*schema.Set))...) | ||
} | ||
|
||
if len(input.Filters) == 0 { | ||
input.Filters = nil | ||
} | ||
|
||
var subnetIDs []*string | ||
err := conn.DescribeSubnetsPages(input, func(page *ec2.DescribeSubnetsOutput, lastPage bool) bool { | ||
if page == nil { | ||
return !lastPage | ||
} | ||
|
||
for _, subnet := range page.Subnets { | ||
subnetIDs = append(subnetIDs, subnet.SubnetId) | ||
} | ||
|
||
return !lastPage | ||
}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error reading Subnets: %w", err) | ||
} | ||
|
||
d.SetId(meta.(*AWSClient).region) | ||
d.Set("ids", aws.StringValueSlice(subnetIDs)) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
) | ||
|
||
func TestAccDataSourceAwsSubnets_basic(t *testing.T) { | ||
rName := acctest.RandomWithPrefix("tf-acc-test") | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccDataSourceAwsSubnetsConfig(rName), | ||
}, | ||
{ | ||
Config: testAccDataSourceAwsSubnetsConfigWithDataSource(rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.aws_subnets.selected", "ids.#", "4"), | ||
resource.TestCheckResourceAttr("data.aws_subnets.private", "ids.#", "2"), | ||
testCheckResourceAttrGreaterThanValue("data.aws_subnets.all", "ids.#", "0"), | ||
resource.TestCheckResourceAttr("data.aws_subnets.none", "ids.#", "0"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccDataSourceAwsSubnets_filter(t *testing.T) { | ||
rName := acctest.RandomWithPrefix("tf-acc-test") | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccDataSourceAwsSubnets_filter(rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.aws_subnets.test", "ids.#", "2"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccDataSourceAwsSubnetsConfig(rName string) string { | ||
return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf(` | ||
resource "aws_vpc" "test" { | ||
cidr_block = "172.16.0.0/16" | ||
tags = { | ||
Name = %[1]q | ||
} | ||
} | ||
resource "aws_subnet" "test_public_a" { | ||
vpc_id = aws_vpc.test.id | ||
cidr_block = "172.16.123.0/24" | ||
availability_zone = data.aws_availability_zones.available.names[0] | ||
tags = { | ||
Name = "%[1]s-public-a" | ||
Tier = "Public" | ||
} | ||
} | ||
resource "aws_subnet" "test_public_b" { | ||
vpc_id = aws_vpc.test.id | ||
cidr_block = "172.16.124.0/24" | ||
availability_zone = data.aws_availability_zones.available.names[0] | ||
tags = { | ||
Name = "%[1]s-public-b" | ||
Tier = "Public" | ||
} | ||
} | ||
resource "aws_subnet" "test_private_a" { | ||
vpc_id = aws_vpc.test.id | ||
cidr_block = "172.16.125.0/24" | ||
availability_zone = data.aws_availability_zones.available.names[0] | ||
tags = { | ||
Name = "%[1]s-private-a" | ||
Tier = "Private" | ||
} | ||
} | ||
resource "aws_subnet" "test_private_b" { | ||
vpc_id = aws_vpc.test.id | ||
cidr_block = "172.16.126.0/24" | ||
availability_zone = data.aws_availability_zones.available.names[1] | ||
tags = { | ||
Name = "%[1]s-private-b" | ||
Tier = "Private" | ||
} | ||
} | ||
`, rName)) | ||
} | ||
|
||
func testAccDataSourceAwsSubnetsConfigWithDataSource(rName string) string { | ||
return composeConfig(testAccDataSourceAwsSubnetsConfig(rName), ` | ||
data "aws_subnets" "selected" { | ||
filter { | ||
name = "vpc-id" | ||
values = [aws_vpc.test.id] | ||
} | ||
} | ||
data "aws_subnets" "private" { | ||
filter { | ||
name = "vpc-id" | ||
values = [aws_vpc.test.id] | ||
} | ||
tags = { | ||
Tier = "Private" | ||
} | ||
} | ||
data "aws_subnets" "all" {} | ||
data "aws_subnets" "none" { | ||
filter { | ||
name = "vpc-id" | ||
values = [aws_vpc.test.id] | ||
} | ||
filter { | ||
name = "cidr-block" | ||
values = ["172.16.127.0/24"] | ||
} | ||
} | ||
`) | ||
} | ||
|
||
func testAccDataSourceAwsSubnets_filter(rName string) string { | ||
return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf(` | ||
resource "aws_vpc" "test" { | ||
cidr_block = "172.16.0.0/16" | ||
tags = { | ||
Name = %[1]q | ||
} | ||
} | ||
resource "aws_subnet" "test_a_one" { | ||
vpc_id = aws_vpc.test.id | ||
cidr_block = "172.16.1.0/24" | ||
availability_zone = data.aws_availability_zones.available.names[0] | ||
tags = { | ||
Name = "%[1]s-a1" | ||
} | ||
} | ||
resource "aws_subnet" "test_a_two" { | ||
vpc_id = aws_subnet.test_b.vpc_id | ||
cidr_block = "172.16.2.0/24" | ||
availability_zone = data.aws_availability_zones.available.names[0] | ||
tags = { | ||
Name = "%[1]s-a2" | ||
} | ||
} | ||
resource "aws_subnet" "test_b" { | ||
vpc_id = aws_vpc.test.id | ||
cidr_block = "172.16.3.0/24" | ||
availability_zone = data.aws_availability_zones.available.names[1] | ||
tags = { | ||
Name = "%[1]s-b" | ||
} | ||
} | ||
data "aws_subnets" "test" { | ||
filter { | ||
name = "availabilityZone" | ||
values = [aws_subnet.test_a_one.availability_zone] | ||
} | ||
filter { | ||
name = "vpc-id" | ||
values = [aws_subnet.test_a_two.vpc_id] | ||
} | ||
} | ||
`, rName)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
--- | ||
subcategory: "VPC" | ||
layout: "aws" | ||
page_title: "AWS: aws_subnets" | ||
description: |- | ||
Get information about a set of subnets. | ||
--- | ||
|
||
# Data Source: aws_subnets | ||
|
||
This resource can be useful for getting back a set of subnet IDs. | ||
|
||
## Example Usage | ||
|
||
The following shows outputing all CIDR blocks for every subnet ID in a VPC. | ||
|
||
```terraform | ||
data "aws_subnets" "example" { | ||
filter { | ||
name = "vpc-id" | ||
values = [var.vpc_id] | ||
} | ||
} | ||
data "aws_subnet" "example" { | ||
for_each = data.aws_subnets.example.ids | ||
id = each.value | ||
} | ||
output "subnet_cidr_blocks" { | ||
value = [for s in data.aws_subnet.example : s.cidr_block] | ||
} | ||
``` | ||
|
||
The following example retrieves a set 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. | ||
|
||
```terraform | ||
data "aws_subnets" "private" { | ||
filter { | ||
name = "vpc-id" | ||
values = [var.vpc_id] | ||
} | ||
tags = { | ||
Tier = "Private" | ||
} | ||
} | ||
resource "aws_instance" "app" { | ||
for_each = data.aws_subnets.example.ids | ||
ami = var.ami | ||
instance_type = "t2.micro" | ||
subnet_id = each.value | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
* `filter` - (Optional) Custom filter block as described below. | ||
* `tags` - (Optional) A map of tags, each pair of which must exactly match | ||
a pair on the desired subnets. | ||
|
||
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](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html). | ||
For example, if matching against tag `Name`, use: | ||
|
||
```terraform | ||
data "aws_subnets" "selected" { | ||
filter { | ||
name = "tag:Name" | ||
values = [""] # insert values here | ||
} | ||
} | ||
``` | ||
|
||
* `values` - (Required) Set of values that are accepted for the given field. | ||
Subnet IDs will be selected if any one of the given values match. | ||
|
||
## Attributes Reference | ||
|
||
* `ids` - A list of all the subnet ids found. |