From 72a14ef2bb4344a3acc1677732ba2a65e40c7b9b Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Fri, 21 Apr 2017 16:54:55 +0300 Subject: [PATCH] provider/aws: Add IPv6 outputs to aws_subnet datasource (#13841) Fixes: #13595 ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccDataSourceAwsSubnet' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/04/21 13:52:43 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccDataSourceAwsSubnet -timeout 120m === RUN TestAccDataSourceAwsSubnetIDs --- PASS: TestAccDataSourceAwsSubnetIDs (81.05s) === RUN TestAccDataSourceAwsSubnet --- PASS: TestAccDataSourceAwsSubnet (57.48s) === RUN TestAccDataSourceAwsSubnetIpv6ByIpv6Filter --- PASS: TestAccDataSourceAwsSubnetIpv6ByIpv6Filter (82.63s) === RUN TestAccDataSourceAwsSubnetIpv6ByIpv6CidrBlock --- PASS: TestAccDataSourceAwsSubnetIpv6ByIpv6CidrBlock (82.43s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 303.625s ``` --- .../providers/aws/data_source_aws_subnet.go | 67 +++++++-- .../aws/data_source_aws_subnet_test.go | 130 +++++++++++++++++- builtin/providers/aws/ec2_filters.go | 4 +- builtin/providers/aws/resource_aws_subnet.go | 11 +- .../docs/providers/aws/d/subnet.html.markdown | 2 + .../docs/providers/aws/r/subnet.html.markdown | 2 + 6 files changed, 194 insertions(+), 22 deletions(-) diff --git a/builtin/providers/aws/data_source_aws_subnet.go b/builtin/providers/aws/data_source_aws_subnet.go index ddd178a30..188a09dd2 100644 --- a/builtin/providers/aws/data_source_aws_subnet.go +++ b/builtin/providers/aws/data_source_aws_subnet.go @@ -14,19 +14,25 @@ func dataSourceAwsSubnet() *schema.Resource { Read: dataSourceAwsSubnetRead, Schema: map[string]*schema.Schema{ - "availability_zone": &schema.Schema{ + "availability_zone": { Type: schema.TypeString, Optional: true, Computed: true, }, - "cidr_block": &schema.Schema{ + "cidr_block": { Type: schema.TypeString, Optional: true, Computed: true, }, - "default_for_az": &schema.Schema{ + "ipv6_cidr_block": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "default_for_az": { Type: schema.TypeBool, Optional: true, Computed: true, @@ -34,13 +40,13 @@ func dataSourceAwsSubnet() *schema.Resource { "filter": ec2CustomFiltersSchema(), - "id": &schema.Schema{ + "id": { Type: schema.TypeString, Optional: true, Computed: true, }, - "state": &schema.Schema{ + "state": { Type: schema.TypeString, Optional: true, Computed: true, @@ -48,11 +54,26 @@ func dataSourceAwsSubnet() *schema.Resource { "tags": tagsSchemaComputed(), - "vpc_id": &schema.Schema{ + "vpc_id": { Type: schema.TypeString, Optional: true, Computed: true, }, + + "assign_ipv6_address_on_creation": { + Type: schema.TypeBool, + Computed: true, + }, + + "map_public_ip_on_launch": { + Type: schema.TypeBool, + Computed: true, + }, + + "ipv6_cidr_block_association_id": { + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -76,15 +97,22 @@ func dataSourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error { defaultForAzStr = "true" } - req.Filters = buildEC2AttributeFilterList( - map[string]string{ - "availabilityZone": d.Get("availability_zone").(string), - "cidrBlock": d.Get("cidr_block").(string), - "defaultForAz": defaultForAzStr, - "state": d.Get("state").(string), - "vpc-id": d.Get("vpc_id").(string), - }, - ) + filters := map[string]string{ + "availabilityZone": d.Get("availability_zone").(string), + "defaultForAz": defaultForAzStr, + "state": d.Get("state").(string), + "vpc-id": d.Get("vpc_id").(string), + } + + if v, ok := d.GetOk("cidr_block"); ok { + filters["cidrBlock"] = v.(string) + } + + if v, ok := d.GetOk("ipv6_cidr_block"); ok { + filters["ipv6-cidr-block-association.ipv6-cidr-block"] = v.(string) + } + + req.Filters = buildEC2AttributeFilterList(filters) req.Filters = append(req.Filters, buildEC2TagFilterList( tagsFromMap(d.Get("tags").(map[string]interface{})), )...) @@ -118,6 +146,15 @@ func dataSourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error { d.Set("default_for_az", subnet.DefaultForAz) d.Set("state", subnet.State) d.Set("tags", tagsToMap(subnet.Tags)) + d.Set("assign_ipv6_address_on_creation", subnet.AssignIpv6AddressOnCreation) + d.Set("map_public_ip_on_launch", subnet.MapPublicIpOnLaunch) + + for _, a := range subnet.Ipv6CidrBlockAssociationSet { + if *a.Ipv6CidrBlockState.State == "associated" { //we can only ever have 1 IPv6 block associated at once + d.Set("ipv6_cidr_block_association_id", a.AssociationId) + d.Set("ipv6_cidr_block", a.Ipv6CidrBlock) + } + } return nil } diff --git a/builtin/providers/aws/data_source_aws_subnet_test.go b/builtin/providers/aws/data_source_aws_subnet_test.go index c6234ac39..3c9c5ed6f 100644 --- a/builtin/providers/aws/data_source_aws_subnet_test.go +++ b/builtin/providers/aws/data_source_aws_subnet_test.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccDataSourceAwsSubnet_basic(t *testing.T) { +func TestAccDataSourceAwsSubnet(t *testing.T) { rInt := acctest.RandIntRange(0, 256) resource.Test(t, resource.TestCase{ @@ -17,7 +17,7 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckVpcDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccDataSourceAwsSubnetConfig(rInt), Check: resource.ComposeTestCheckFunc( testAccDataSourceAwsSubnetCheck("data.aws_subnet.by_id", rInt), @@ -31,6 +31,48 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { }) } +func TestAccDataSourceAwsSubnetIpv6ByIpv6Filter(t *testing.T) { + rInt := acctest.RandIntRange(0, 256) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsSubnetConfigIpv6(rInt), + }, + { + Config: testAccDataSourceAwsSubnetConfigIpv6WithDataSourceFilter(rInt), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.aws_subnet.by_ipv6_cidr", "ipv6_cidr_block_association_id"), + resource.TestCheckResourceAttrSet( + "data.aws_subnet.by_ipv6_cidr", "ipv6_cidr_block"), + ), + }, + }, + }) +} + +func TestAccDataSourceAwsSubnetIpv6ByIpv6CidrBlock(t *testing.T) { + rInt := acctest.RandIntRange(0, 256) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsSubnetConfigIpv6(rInt), + }, + { + Config: testAccDataSourceAwsSubnetConfigIpv6WithDataSourceIpv6CidrBlock(rInt), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.aws_subnet.by_ipv6_cidr", "ipv6_cidr_block_association_id"), + ), + }, + }, + }) +} + func testAccDataSourceAwsSubnetCheck(name string, rInt int) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] @@ -103,6 +145,7 @@ func testAccDataSourceAwsSubnetConfig(rInt int) string { } } + data "aws_subnet" "by_id" { id = "${aws_subnet.test.id}" } @@ -129,3 +172,86 @@ func testAccDataSourceAwsSubnetConfig(rInt int) string { } `, rInt, rInt, rInt) } + +func testAccDataSourceAwsSubnetConfigIpv6(rInt int) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "172.%d.0.0/16" + assign_generated_ipv6_cidr_block = true + + tags { + Name = "terraform-testacc-subnet-data-source-ipv6" + } +} + +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.123.0/24" + availability_zone = "us-west-2a" + ipv6_cidr_block = "${cidrsubnet(aws_vpc.test.ipv6_cidr_block, 8, 1)}" + + tags { + Name = "terraform-testacc-subnet-data-sourceipv6-%d" + } +} +`, rInt, rInt, rInt) +} + +func testAccDataSourceAwsSubnetConfigIpv6WithDataSourceFilter(rInt int) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "172.%d.0.0/16" + assign_generated_ipv6_cidr_block = true + + tags { + Name = "terraform-testacc-subnet-data-source-ipv6" + } +} + +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.123.0/24" + availability_zone = "us-west-2a" + ipv6_cidr_block = "${cidrsubnet(aws_vpc.test.ipv6_cidr_block, 8, 1)}" + + tags { + Name = "terraform-testacc-subnet-data-sourceipv6-%d" + } +} + +data "aws_subnet" "by_ipv6_cidr" { + filter { + name = "ipv6-cidr-block-association.ipv6-cidr-block" + values = ["${aws_subnet.test.ipv6_cidr_block}"] + } +} +`, rInt, rInt, rInt) +} + +func testAccDataSourceAwsSubnetConfigIpv6WithDataSourceIpv6CidrBlock(rInt int) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "172.%d.0.0/16" + assign_generated_ipv6_cidr_block = true + + tags { + Name = "terraform-testacc-subnet-data-source-ipv6" + } +} + +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.123.0/24" + availability_zone = "us-west-2a" + ipv6_cidr_block = "${cidrsubnet(aws_vpc.test.ipv6_cidr_block, 8, 1)}" + + tags { + Name = "terraform-testacc-subnet-data-sourceipv6-%d" + } +} + +data "aws_subnet" "by_ipv6_cidr" { + ipv6_cidr_block = "${aws_subnet.test.ipv6_cidr_block}" +} +`, rInt, rInt, rInt) +} diff --git a/builtin/providers/aws/ec2_filters.go b/builtin/providers/aws/ec2_filters.go index 4263d6efa..743d28224 100644 --- a/builtin/providers/aws/ec2_filters.go +++ b/builtin/providers/aws/ec2_filters.go @@ -111,11 +111,11 @@ func ec2CustomFiltersSchema() *schema.Schema { Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, - "values": &schema.Schema{ + "values": { Type: schema.TypeSet, Required: true, Elem: &schema.Schema{ diff --git a/builtin/providers/aws/resource_aws_subnet.go b/builtin/providers/aws/resource_aws_subnet.go index 87dc01e71..c431af73f 100644 --- a/builtin/providers/aws/resource_aws_subnet.go +++ b/builtin/providers/aws/resource_aws_subnet.go @@ -141,9 +141,14 @@ func resourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error { d.Set("cidr_block", subnet.CidrBlock) d.Set("map_public_ip_on_launch", subnet.MapPublicIpOnLaunch) d.Set("assign_ipv6_address_on_creation", subnet.AssignIpv6AddressOnCreation) - if subnet.Ipv6CidrBlockAssociationSet != nil { - d.Set("ipv6_cidr_block", subnet.Ipv6CidrBlockAssociationSet[0].Ipv6CidrBlock) - d.Set("ipv6_cidr_block_association_id", subnet.Ipv6CidrBlockAssociationSet[0].AssociationId) + for _, a := range subnet.Ipv6CidrBlockAssociationSet { + if *a.Ipv6CidrBlockState.State == "associated" { //we can only ever have 1 IPv6 block associated at once + d.Set("ipv6_cidr_block_association_id", a.AssociationId) + d.Set("ipv6_cidr_block", a.Ipv6CidrBlock) + } else { + d.Set("ipv6_cidr_block_association_id", "") // we blank these out to remove old entries + d.Set("ipv6_cidr_block", "") + } } d.Set("tags", tagsToMap(subnet.Tags)) diff --git a/website/source/docs/providers/aws/d/subnet.html.markdown b/website/source/docs/providers/aws/d/subnet.html.markdown index 9e9b22aa7..ea412400c 100644 --- a/website/source/docs/providers/aws/d/subnet.html.markdown +++ b/website/source/docs/providers/aws/d/subnet.html.markdown @@ -50,6 +50,8 @@ subnet whose data will be exported as attributes. * `cidr_block` - (Optional) The cidr block of the desired subnet. +* `ipv6_cidr_block` - (Optional) The Ipv6 cidr block of the desired subnet + * `default_for_az` - (Optional) Boolean constraint for whether the desired subnet must be the default subnet for its associated availability zone. diff --git a/website/source/docs/providers/aws/r/subnet.html.markdown b/website/source/docs/providers/aws/r/subnet.html.markdown index 8fb8aebff..7ff7ed900 100644 --- a/website/source/docs/providers/aws/r/subnet.html.markdown +++ b/website/source/docs/providers/aws/r/subnet.html.markdown @@ -48,6 +48,8 @@ The following attributes are exported: * `availability_zone`- The AZ for the subnet. * `cidr_block` - The CIDR block for the subnet. * `vpc_id` - The VPC ID. +* `ipv6_association_id` - The association ID for the IPv6 CIDR block. +* `ipv6_cidr_block` - The IPv6 CIDR block. ## Import