From 5c5e3eaa8ae2f875f82ab6a17e00a422535ec614 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Dec 2020 10:29:09 -0500 Subject: [PATCH 1/9] d/aws_network_interface: Add 'association.carrier_ip' attribute. --- aws/data_source_aws_network_interface.go | 4 ++++ aws/structure.go | 3 +++ website/docs/d/network_interface.html.markdown | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/aws/data_source_aws_network_interface.go b/aws/data_source_aws_network_interface.go index 76a44ec9791..e2fc3882194 100644 --- a/aws/data_source_aws_network_interface.go +++ b/aws/data_source_aws_network_interface.go @@ -33,6 +33,10 @@ func dataSourceAwsNetworkInterface() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "carrier_ip": { + Type: schema.TypeString, + Computed: true, + }, "ip_owner_id": { Type: schema.TypeString, Computed: true, diff --git a/aws/structure.go b/aws/structure.go index c6cdddc44d3..a28575029b9 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1165,6 +1165,9 @@ func flattenEc2NetworkInterfaceAssociation(a *ec2.NetworkInterfaceAssociation) [ if a.AssociationId != nil { att["association_id"] = *a.AssociationId } + if a.CarrierIp != nil { + att["carrier_ip"] = *a.CarrierIp + } if a.IpOwnerId != nil { att["ip_owner_id"] = *a.IpOwnerId } diff --git a/website/docs/d/network_interface.html.markdown b/website/docs/d/network_interface.html.markdown index 3510a6ab001..e69aaadfd14 100644 --- a/website/docs/d/network_interface.html.markdown +++ b/website/docs/d/network_interface.html.markdown @@ -2,7 +2,7 @@ subcategory: "VPC" layout: "aws" page_title: "AWS: aws_network_interface" -description: |- +description: |- Get information on a Network Interface resource. --- @@ -52,6 +52,7 @@ Additionally, the following attributes are exported: * `allocation_id` - The allocation ID. * `association_id` - The association ID. +* `carrier_ip` - The carrier IP address associated with the network interface. This attribute is only set when the network interface is in a subnet which is associated with a Wavelength Zone. * `ip_owner_id` - The ID of the Elastic IP address owner. * `public_dns_name` - The public DNS name. * `public_ip` - The address of the Elastic IP address bound to the network interface. From 05c2b7ac5a24dc30c83f74c83550008c54f7cc19 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Dec 2020 10:32:14 -0500 Subject: [PATCH 2/9] d/aws_network_interface: Move all configurations below acceptance tests. --- aws/data_source_aws_network_interface_test.go | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/aws/data_source_aws_network_interface_test.go b/aws/data_source_aws_network_interface_test.go index 1822ef1c669..7aee038a4e4 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -33,6 +33,23 @@ func TestAccDataSourceAwsNetworkInterface_basic(t *testing.T) { }) } +func TestAccDataSourceAwsNetworkInterface_filters(t *testing.T) { + rName := acctest.RandString(5) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkInterface_filters(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_network_interface.test", "private_ips.#", "1"), + resource.TestCheckResourceAttr("data.aws_network_interface.test", "security_groups.#", "1"), + ), + }, + }, + }) +} + func testAccDataSourceAwsNetworkInterface_basic(rName string) string { return fmt.Sprintf(` data "aws_availability_zones" "available" { @@ -79,23 +96,6 @@ data "aws_network_interface" "test" { `, rName) } -func TestAccDataSourceAwsNetworkInterface_filters(t *testing.T) { - rName := acctest.RandString(5) - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccDataSourceAwsNetworkInterface_filters(rName), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_network_interface.test", "private_ips.#", "1"), - resource.TestCheckResourceAttr("data.aws_network_interface.test", "security_groups.#", "1"), - ), - }, - }, - }) -} - func testAccDataSourceAwsNetworkInterface_filters(rName string) string { return fmt.Sprintf(` data "aws_availability_zones" "available" { From 73aba829034b4e6f42268a031e4821ea26c1766c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Dec 2020 10:50:37 -0500 Subject: [PATCH 3/9] d/aws_network_interface: Refactor existing acceptance tests before testing new functionality. Acceptance test output: $ make testacc TEST=./aws/ TESTARGS='-run=TestAccDataSourceAwsNetworkInterface_' ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 2 -run=TestAccDataSourceAwsNetworkInterface_ -timeout 120m === RUN TestAccDataSourceAwsNetworkInterface_basic === PAUSE TestAccDataSourceAwsNetworkInterface_basic === RUN TestAccDataSourceAwsNetworkInterface_filters === PAUSE TestAccDataSourceAwsNetworkInterface_filters === CONT TestAccDataSourceAwsNetworkInterface_basic === CONT TestAccDataSourceAwsNetworkInterface_filters --- PASS: TestAccDataSourceAwsNetworkInterface_filters (57.63s) --- PASS: TestAccDataSourceAwsNetworkInterface_basic (57.84s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 57.929s --- aws/data_source_aws_network_interface_test.go | 110 +++++++----------- 1 file changed, 41 insertions(+), 69 deletions(-) diff --git a/aws/data_source_aws_network_interface_test.go b/aws/data_source_aws_network_interface_test.go index 7aee038a4e4..55b80c78db8 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -9,24 +9,27 @@ import ( ) func TestAccDataSourceAwsNetworkInterface_basic(t *testing.T) { - rName := acctest.RandString(5) + datasourceName := "data.aws_network_interface.test" + resourceName := "aws_network_interface.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsNetworkInterface_basic(rName), + Config: testAccDataSourceAwsNetworkInterfaceConfigBasic(rName), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_network_interface.test", "private_ips.#", "1"), - resource.TestCheckResourceAttr("data.aws_network_interface.test", "security_groups.#", "1"), - resource.TestCheckResourceAttrPair("data.aws_network_interface.test", "private_ip", "aws_network_interface.test", "private_ip"), - resource.TestCheckResourceAttrSet("data.aws_network_interface.test", "availability_zone"), - resource.TestCheckResourceAttrPair("data.aws_network_interface.test", "description", "aws_network_interface.test", "description"), - resource.TestCheckResourceAttrSet("data.aws_network_interface.test", "interface_type"), - resource.TestCheckResourceAttrPair("data.aws_network_interface.test", "private_dns_name", "aws_network_interface.test", "private_dns_name"), - resource.TestCheckResourceAttrPair("data.aws_network_interface.test", "subnet_id", "aws_network_interface.test", "subnet_id"), - resource.TestCheckResourceAttr("data.aws_network_interface.test", "outpost_arn", ""), - resource.TestCheckResourceAttrSet("data.aws_network_interface.test", "vpc_id"), + resource.TestCheckResourceAttr(datasourceName, "private_ips.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "security_groups.#", "1"), + resource.TestCheckResourceAttrPair(datasourceName, "private_ip", resourceName, "private_ip"), + resource.TestCheckResourceAttrSet(datasourceName, "availability_zone"), + resource.TestCheckResourceAttrPair(datasourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrSet(datasourceName, "interface_type"), + resource.TestCheckResourceAttrPair(datasourceName, "private_dns_name", resourceName, "private_dns_name"), + resource.TestCheckResourceAttrPair(datasourceName, "subnet_id", resourceName, "subnet_id"), + resource.TestCheckResourceAttr(datasourceName, "outpost_arn", ""), + resource.TestCheckResourceAttrSet(datasourceName, "vpc_id"), ), }, }, @@ -34,38 +37,31 @@ func TestAccDataSourceAwsNetworkInterface_basic(t *testing.T) { } func TestAccDataSourceAwsNetworkInterface_filters(t *testing.T) { - rName := acctest.RandString(5) + datasourceName := "data.aws_network_interface.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsNetworkInterface_filters(rName), + Config: testAccDataSourceAwsNetworkInterfaceConfigFilters(rName), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_network_interface.test", "private_ips.#", "1"), - resource.TestCheckResourceAttr("data.aws_network_interface.test", "security_groups.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "private_ips.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "security_groups.#", "1"), ), }, }, }) } -func testAccDataSourceAwsNetworkInterface_basic(rName string) string { +func testAccDataSourceAwsNetworkInterfaceConfigBase(rName string) string { return fmt.Sprintf(` -data "aws_availability_zones" "available" { - state = "available" - - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } -} - resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" tags = { - Name = "terraform-testacc-eni-data-source-basic" + Name = %[1]q } } @@ -75,12 +71,12 @@ resource "aws_subnet" "test" { vpc_id = aws_vpc.test.id tags = { - Name = "tf-acc-eni-data-source-basic" + Name = %[1]q } } resource "aws_security_group" "test" { - name = "tf-sg-%s" + name = %[1]q vpc_id = aws_vpc.test.id } @@ -88,59 +84,35 @@ resource "aws_network_interface" "test" { subnet_id = aws_subnet.test.id private_ips = ["10.0.0.50"] security_groups = [aws_security_group.test.id] -} - -data "aws_network_interface" "test" { - id = aws_network_interface.test.id -} -`, rName) -} - -func testAccDataSourceAwsNetworkInterface_filters(rName string) string { - return fmt.Sprintf(` -data "aws_availability_zones" "available" { - state = "available" - - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } -} - -resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" tags = { - Name = "terraform-testacc-eni-data-source-filters" + Name = %[1]q } } - -resource "aws_subnet" "test" { - cidr_block = "10.0.0.0/24" - availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.test.id - - tags = { - Name = "tf-acc-eni-data-source-filters" - } +`, rName) } -resource "aws_security_group" "test" { - name = "tf-sg-%s" - vpc_id = aws_vpc.test.id +func testAccDataSourceAwsNetworkInterfaceConfigBasic(rName string) string { + return composeConfig( + testAccAvailableAZsNoOptInConfig(), + testAccDataSourceAwsNetworkInterfaceConfigBase(rName), + ` +data "aws_network_interface" "test" { + id = aws_network_interface.test.id } - -resource "aws_network_interface" "test" { - subnet_id = aws_subnet.test.id - private_ips = ["10.0.0.60"] - security_groups = [aws_security_group.test.id] +`) } +func testAccDataSourceAwsNetworkInterfaceConfigFilters(rName string) string { + return composeConfig( + testAccAvailableAZsNoOptInConfig(), + testAccDataSourceAwsNetworkInterfaceConfigBase(rName), + ` data "aws_network_interface" "test" { filter { name = "network-interface-id" values = [aws_network_interface.test.id] } } -`, rName) +`) } From 648cdb7371e053356dd55871a1c5d35e6b2900e9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Dec 2020 11:57:07 -0500 Subject: [PATCH 4/9] d/aws_network_interface: Add 'TestAccDataSourceAwsNetworkInterface_EIPAssociation'. Acceptance test output: $ make testacc TEST=./aws/ TESTARGS='-run=TestAccDataSourceAwsNetworkInterface_EIPAssociation' ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 2 -run=TestAccDataSourceAwsNetworkInterface_EIPAssociation -timeout 120m === RUN TestAccDataSourceAwsNetworkInterface_EIPAssociation === PAUSE TestAccDataSourceAwsNetworkInterface_EIPAssociation === CONT TestAccDataSourceAwsNetworkInterface_EIPAssociation --- PASS: TestAccDataSourceAwsNetworkInterface_EIPAssociation (67.86s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 67.946s --- aws/data_source_aws_network_interface_test.go | 80 +++++++++++++++++++ aws/structure.go | 28 ++----- 2 files changed, 88 insertions(+), 20 deletions(-) diff --git a/aws/data_source_aws_network_interface_test.go b/aws/data_source_aws_network_interface_test.go index 55b80c78db8..0297388bfd7 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -55,6 +55,54 @@ func TestAccDataSourceAwsNetworkInterface_filters(t *testing.T) { }) } +func TestAccDataSourceAwsNetworkInterface_EIPAssociation(t *testing.T) { + datasourceName := "data.aws_network_interface.test" + resourceName := "aws_network_interface.test" + eipResourceName := "aws_eip.test" + eipAssociationResourceName := "aws_eip_association.test" + securityGroupResourceName := "aws_security_group.test" + vpcResourceName := "aws_vpc.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkInterfaceConfigEIPAssociation(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(datasourceName, "association.#", "1"), + resource.TestCheckResourceAttrPair(datasourceName, "association.0.allocation_id", eipResourceName, "id"), + resource.TestCheckResourceAttrPair(datasourceName, "association.0.association_id", eipAssociationResourceName, "id"), + resource.TestCheckResourceAttr(datasourceName, "association.0.carrier_ip", ""), + testAccCheckResourceAttrAccountID(datasourceName, "association.0.ip_owner_id"), + // EIP does not really get a public DNS name until it's associated with an instance. + //resource.TestCheckResourceAttrPair(datasourceName, "association.0.public_dns_name", eipResourceName, "public_dns"), + resource.TestCheckResourceAttr(datasourceName, "association.0.public_dns_name", ""), + resource.TestCheckResourceAttrPair(datasourceName, "association.0.public_ip", eipResourceName, "public_ip"), + resource.TestCheckResourceAttr(datasourceName, "attachment.#", "0"), + resource.TestCheckResourceAttrSet(datasourceName, "availability_zone"), + resource.TestCheckResourceAttrPair(datasourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttr(datasourceName, "interface_type", "interface"), + resource.TestCheckResourceAttr(datasourceName, "ipv6_addresses.#", "0"), + resource.TestCheckResourceAttrSet(datasourceName, "mac_address"), + resource.TestCheckResourceAttr(datasourceName, "outpost_arn", ""), + testAccCheckResourceAttrAccountID(datasourceName, "owner_id"), + resource.TestCheckResourceAttrPair(datasourceName, "private_dns_name", resourceName, "private_dns_name"), + resource.TestCheckResourceAttrPair(datasourceName, "private_ip", resourceName, "private_ip"), + resource.TestCheckResourceAttrPair(datasourceName, "private_ips.#", resourceName, "private_ips.#"), + resource.TestCheckResourceAttrPair(datasourceName, "private_ips.0", resourceName, "private_ip"), + resource.TestCheckResourceAttrPair(datasourceName, "security_groups.#", resourceName, "security_groups.#"), + resource.TestCheckTypeSetElemAttrPair(datasourceName, "security_groups.*", securityGroupResourceName, "id"), + resource.TestCheckResourceAttrPair(datasourceName, "subnet_id", resourceName, "subnet_id"), + resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"), + resource.TestCheckResourceAttrPair(datasourceName, "vpc_id", vpcResourceName, "id"), + ), + }, + }, + }) +} + func testAccDataSourceAwsNetworkInterfaceConfigBase(rName string) string { return fmt.Sprintf(` resource "aws_vpc" "test" { @@ -103,6 +151,38 @@ data "aws_network_interface" "test" { `) } +func testAccDataSourceAwsNetworkInterfaceConfigEIPAssociation(rName string) string { + return composeConfig( + testAccAvailableAZsNoOptInConfig(), + testAccDataSourceAwsNetworkInterfaceConfigBase(rName), + fmt.Sprintf(` +resource "aws_internet_gateway" "test" { + vpc_id = aws_vpc.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_eip" "test" { + vpc = true + + tags = { + Name = %[1]q + } +} + +resource "aws_eip_association" "test" { + allocation_id = aws_eip.test.id + network_interface_id = aws_network_interface.test.id +} + +data "aws_network_interface" "test" { + id = aws_eip_association.test.network_interface_id +} +`, rName)) +} + func testAccDataSourceAwsNetworkInterfaceConfigFilters(rName string) string { return composeConfig( testAccAvailableAZsNoOptInConfig(), diff --git a/aws/structure.go b/aws/structure.go index a28575029b9..64c97ec5ebe 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1158,26 +1158,14 @@ func flattenEc2AttributeValues(l []*ec2.AttributeValue) []string { } func flattenEc2NetworkInterfaceAssociation(a *ec2.NetworkInterfaceAssociation) []interface{} { - att := make(map[string]interface{}) - if a.AllocationId != nil { - att["allocation_id"] = *a.AllocationId - } - if a.AssociationId != nil { - att["association_id"] = *a.AssociationId - } - if a.CarrierIp != nil { - att["carrier_ip"] = *a.CarrierIp - } - if a.IpOwnerId != nil { - att["ip_owner_id"] = *a.IpOwnerId - } - if a.PublicDnsName != nil { - att["public_dns_name"] = *a.PublicDnsName - } - if a.PublicIp != nil { - att["public_ip"] = *a.PublicIp - } - return []interface{}{att} + return []interface{}{map[string]interface{}{ + "allocation_id": aws.StringValue(a.AllocationId), + "association_id": aws.StringValue(a.AssociationId), + "carrier_ip": aws.StringValue(a.CarrierIp), + "ip_owner_id": aws.StringValue(a.IpOwnerId), + "public_dns_name": aws.StringValue(a.PublicDnsName), + "public_ip": aws.StringValue(a.PublicIp), + }} } func flattenEc2NetworkInterfaceIpv6Address(niia []*ec2.NetworkInterfaceIpv6Address) []string { From eb6f2fa98f137d8e6e15c898b91b44298fe9e2d8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Dec 2020 13:13:44 -0500 Subject: [PATCH 5/9] d/aws_network_interface: Add 'TestAccDataSourceAwsNetworkInterface_CarrierIPAssociation'. --- aws/data_source_aws_network_interface_test.go | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/aws/data_source_aws_network_interface_test.go b/aws/data_source_aws_network_interface_test.go index 0297388bfd7..60fb4eb7bc0 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -55,6 +55,52 @@ func TestAccDataSourceAwsNetworkInterface_filters(t *testing.T) { }) } +func TestAccDataSourceAwsNetworkInterface_CarrierIPAssociation(t *testing.T) { + datasourceName := "data.aws_network_interface.test" + resourceName := "aws_network_interface.test" + eipResourceName := "aws_eip.test" + eipAssociationResourceName := "aws_eip_association.test" + securityGroupResourceName := "aws_security_group.test" + vpcResourceName := "aws_vpc.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSWavelengthZoneAvailable(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkInterfaceConfigCarrierIPAssociation(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(datasourceName, "association.#", "1"), + resource.TestCheckResourceAttrPair(datasourceName, "association.0.allocation_id", eipResourceName, "id"), + resource.TestCheckResourceAttrPair(datasourceName, "association.0.association_id", eipAssociationResourceName, "id"), + resource.TestCheckResourceAttrPair(datasourceName, "association.0.carrier_ip", eipResourceName, "carrier_ip"), + testAccCheckResourceAttrAccountID(datasourceName, "association.0.ip_owner_id"), + resource.TestCheckResourceAttr(datasourceName, "association.0.public_dns_name", ""), + resource.TestCheckResourceAttr(datasourceName, "association.0.public_ip", ""), + resource.TestCheckResourceAttr(datasourceName, "attachment.#", "0"), + resource.TestCheckResourceAttrSet(datasourceName, "availability_zone"), + resource.TestCheckResourceAttrPair(datasourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttr(datasourceName, "interface_type", "interface"), + resource.TestCheckResourceAttr(datasourceName, "ipv6_addresses.#", "0"), + resource.TestCheckResourceAttrSet(datasourceName, "mac_address"), + resource.TestCheckResourceAttr(datasourceName, "outpost_arn", ""), + testAccCheckResourceAttrAccountID(datasourceName, "owner_id"), + resource.TestCheckResourceAttrPair(datasourceName, "private_dns_name", resourceName, "private_dns_name"), + resource.TestCheckResourceAttrPair(datasourceName, "private_ip", resourceName, "private_ip"), + resource.TestCheckResourceAttrPair(datasourceName, "private_ips.#", resourceName, "private_ips.#"), + resource.TestCheckResourceAttrPair(datasourceName, "private_ips.0", resourceName, "private_ip"), + resource.TestCheckResourceAttrPair(datasourceName, "security_groups.#", resourceName, "security_groups.#"), + resource.TestCheckTypeSetElemAttrPair(datasourceName, "security_groups.*", securityGroupResourceName, "id"), + resource.TestCheckResourceAttrPair(datasourceName, "subnet_id", resourceName, "subnet_id"), + resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"), + resource.TestCheckResourceAttrPair(datasourceName, "vpc_id", vpcResourceName, "id"), + ), + }, + }, + }) +} + func TestAccDataSourceAwsNetworkInterface_EIPAssociation(t *testing.T) { datasourceName := "data.aws_network_interface.test" resourceName := "aws_network_interface.test" @@ -151,6 +197,43 @@ data "aws_network_interface" "test" { `) } +func testAccDataSourceAwsNetworkInterfaceConfigCarrierIPAssociation(rName string) string { + return composeConfig( + testAccAvailableAZsWavelengthZonesDefaultExcludeConfig(), + testAccDataSourceAwsNetworkInterfaceConfigBase(rName), + fmt.Sprintf(` +resource "aws_ec2_carrier_gateway" "test" { + vpc_id = aws_vpc.test.id + + tags = { + Name = %[1]q + } +} + +data "aws_availability_zone" "available" { + name = data.aws_availability_zones.available.names[0] +} + +resource "aws_eip" "test" { + vpc = true + network_border_group = data.aws_availability_zone.available.network_border_group + + tags = { + Name = %[1]q + } +} + +resource "aws_eip_association" "test" { + allocation_id = aws_eip.test.id + network_interface_id = aws_network_interface.test.id +} + +data "aws_network_interface" "test" { + id = aws_eip_association.test.network_interface_id +} +`, rName)) +} + func testAccDataSourceAwsNetworkInterfaceConfigEIPAssociation(rName string) string { return composeConfig( testAccAvailableAZsNoOptInConfig(), From 2e3214437f94314da23f7e241cb0a7300fee3a40 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Dec 2020 15:35:46 -0500 Subject: [PATCH 6/9] Fix linter errors. --- aws/data_source_aws_network_interface_test.go | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/aws/data_source_aws_network_interface_test.go b/aws/data_source_aws_network_interface_test.go index 60fb4eb7bc0..309d2eda361 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -122,8 +122,7 @@ func TestAccDataSourceAwsNetworkInterface_EIPAssociation(t *testing.T) { resource.TestCheckResourceAttrPair(datasourceName, "association.0.association_id", eipAssociationResourceName, "id"), resource.TestCheckResourceAttr(datasourceName, "association.0.carrier_ip", ""), testAccCheckResourceAttrAccountID(datasourceName, "association.0.ip_owner_id"), - // EIP does not really get a public DNS name until it's associated with an instance. - //resource.TestCheckResourceAttrPair(datasourceName, "association.0.public_dns_name", eipResourceName, "public_dns"), + // Public DNS name is not set by the EC2 API. resource.TestCheckResourceAttr(datasourceName, "association.0.public_dns_name", ""), resource.TestCheckResourceAttrPair(datasourceName, "association.0.public_ip", eipResourceName, "public_ip"), resource.TestCheckResourceAttr(datasourceName, "attachment.#", "0"), @@ -150,7 +149,9 @@ func TestAccDataSourceAwsNetworkInterface_EIPAssociation(t *testing.T) { } func testAccDataSourceAwsNetworkInterfaceConfigBase(rName string) string { - return fmt.Sprintf(` + return composeConfig( + testAccAvailableAZsNoOptInConfig(), + fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" @@ -183,12 +184,11 @@ resource "aws_network_interface" "test" { Name = %[1]q } } -`, rName) +`, rName)) } func testAccDataSourceAwsNetworkInterfaceConfigBasic(rName string) string { return composeConfig( - testAccAvailableAZsNoOptInConfig(), testAccDataSourceAwsNetworkInterfaceConfigBase(rName), ` data "aws_network_interface" "test" { @@ -200,8 +200,40 @@ data "aws_network_interface" "test" { func testAccDataSourceAwsNetworkInterfaceConfigCarrierIPAssociation(rName string) string { return composeConfig( testAccAvailableAZsWavelengthZonesDefaultExcludeConfig(), - testAccDataSourceAwsNetworkInterfaceConfigBase(rName), fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test" { + cidr_block = "10.0.0.0/24" + availability_zone = data.aws_availability_zones.available.names[0] + vpc_id = aws_vpc.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_security_group" "test" { + name = %[1]q + vpc_id = aws_vpc.test.id +} + +resource "aws_network_interface" "test" { + subnet_id = aws_subnet.test.id + private_ips = ["10.0.0.50"] + security_groups = [aws_security_group.test.id] + + tags = { + Name = %[1]q + } +} + resource "aws_ec2_carrier_gateway" "test" { vpc_id = aws_vpc.test.id @@ -236,7 +268,6 @@ data "aws_network_interface" "test" { func testAccDataSourceAwsNetworkInterfaceConfigEIPAssociation(rName string) string { return composeConfig( - testAccAvailableAZsNoOptInConfig(), testAccDataSourceAwsNetworkInterfaceConfigBase(rName), fmt.Sprintf(` resource "aws_internet_gateway" "test" { @@ -268,7 +299,6 @@ data "aws_network_interface" "test" { func testAccDataSourceAwsNetworkInterfaceConfigFilters(rName string) string { return composeConfig( - testAccAvailableAZsNoOptInConfig(), testAccDataSourceAwsNetworkInterfaceConfigBase(rName), ` data "aws_network_interface" "test" { From 26447be515b4f6c962185cc6c43c9a9ffb979f7c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Dec 2020 08:28:15 -0500 Subject: [PATCH 7/9] 'EIPAssociation' -> 'PublicIPAssociation'. --- aws/data_source_aws_network_interface_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/data_source_aws_network_interface_test.go b/aws/data_source_aws_network_interface_test.go index 309d2eda361..a0e1bd6e850 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -101,7 +101,7 @@ func TestAccDataSourceAwsNetworkInterface_CarrierIPAssociation(t *testing.T) { }) } -func TestAccDataSourceAwsNetworkInterface_EIPAssociation(t *testing.T) { +func TestAccDataSourceAwsNetworkInterface_PublicIPAssociation(t *testing.T) { datasourceName := "data.aws_network_interface.test" resourceName := "aws_network_interface.test" eipResourceName := "aws_eip.test" @@ -115,7 +115,7 @@ func TestAccDataSourceAwsNetworkInterface_EIPAssociation(t *testing.T) { Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsNetworkInterfaceConfigEIPAssociation(rName), + Config: testAccDataSourceAwsNetworkInterfaceConfigPublicIPAssociation(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(datasourceName, "association.#", "1"), resource.TestCheckResourceAttrPair(datasourceName, "association.0.allocation_id", eipResourceName, "id"), @@ -266,7 +266,7 @@ data "aws_network_interface" "test" { `, rName)) } -func testAccDataSourceAwsNetworkInterfaceConfigEIPAssociation(rName string) string { +func testAccDataSourceAwsNetworkInterfaceConfigPublicIPAssociation(rName string) string { return composeConfig( testAccDataSourceAwsNetworkInterfaceConfigBase(rName), fmt.Sprintf(` From 7ca31b9996c76111e4d051e4ea2759bcac0aeaf5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Dec 2020 08:40:02 -0500 Subject: [PATCH 8/9] d/aws_network_interface: Add 'association.customer_owned_ip' attribute. Acceptance test output: $ make testacc TEST=./aws/ TESTARGS='-run=TestAccDataSourceAwsNetworkInterface_PublicIPAssociation' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccDataSourceAwsNetworkInterface_PublicIPAssociation -timeout 120m === RUN TestAccDataSourceAwsNetworkInterface_PublicIPAssociation === PAUSE TestAccDataSourceAwsNetworkInterface_PublicIPAssociation === CONT TestAccDataSourceAwsNetworkInterface_PublicIPAssociation --- PASS: TestAccDataSourceAwsNetworkInterface_PublicIPAssociation (67.42s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 67.484s --- aws/data_source_aws_network_interface.go | 4 ++++ aws/data_source_aws_network_interface_test.go | 2 ++ aws/structure.go | 13 +++++++------ website/docs/d/network_interface.html.markdown | 1 + 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/aws/data_source_aws_network_interface.go b/aws/data_source_aws_network_interface.go index e2fc3882194..e836bf310de 100644 --- a/aws/data_source_aws_network_interface.go +++ b/aws/data_source_aws_network_interface.go @@ -37,6 +37,10 @@ func dataSourceAwsNetworkInterface() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "customer_owned_ip": { + Type: schema.TypeString, + Computed: true, + }, "ip_owner_id": { Type: schema.TypeString, Computed: true, diff --git a/aws/data_source_aws_network_interface_test.go b/aws/data_source_aws_network_interface_test.go index a0e1bd6e850..f5f101db7b3 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -75,6 +75,7 @@ func TestAccDataSourceAwsNetworkInterface_CarrierIPAssociation(t *testing.T) { resource.TestCheckResourceAttrPair(datasourceName, "association.0.allocation_id", eipResourceName, "id"), resource.TestCheckResourceAttrPair(datasourceName, "association.0.association_id", eipAssociationResourceName, "id"), resource.TestCheckResourceAttrPair(datasourceName, "association.0.carrier_ip", eipResourceName, "carrier_ip"), + resource.TestCheckResourceAttr(datasourceName, "association.0.customer_owned_ip", ""), testAccCheckResourceAttrAccountID(datasourceName, "association.0.ip_owner_id"), resource.TestCheckResourceAttr(datasourceName, "association.0.public_dns_name", ""), resource.TestCheckResourceAttr(datasourceName, "association.0.public_ip", ""), @@ -121,6 +122,7 @@ func TestAccDataSourceAwsNetworkInterface_PublicIPAssociation(t *testing.T) { resource.TestCheckResourceAttrPair(datasourceName, "association.0.allocation_id", eipResourceName, "id"), resource.TestCheckResourceAttrPair(datasourceName, "association.0.association_id", eipAssociationResourceName, "id"), resource.TestCheckResourceAttr(datasourceName, "association.0.carrier_ip", ""), + resource.TestCheckResourceAttr(datasourceName, "association.0.customer_owned_ip", ""), testAccCheckResourceAttrAccountID(datasourceName, "association.0.ip_owner_id"), // Public DNS name is not set by the EC2 API. resource.TestCheckResourceAttr(datasourceName, "association.0.public_dns_name", ""), diff --git a/aws/structure.go b/aws/structure.go index 64c97ec5ebe..d4a487db8cb 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1159,12 +1159,13 @@ func flattenEc2AttributeValues(l []*ec2.AttributeValue) []string { func flattenEc2NetworkInterfaceAssociation(a *ec2.NetworkInterfaceAssociation) []interface{} { return []interface{}{map[string]interface{}{ - "allocation_id": aws.StringValue(a.AllocationId), - "association_id": aws.StringValue(a.AssociationId), - "carrier_ip": aws.StringValue(a.CarrierIp), - "ip_owner_id": aws.StringValue(a.IpOwnerId), - "public_dns_name": aws.StringValue(a.PublicDnsName), - "public_ip": aws.StringValue(a.PublicIp), + "allocation_id": aws.StringValue(a.AllocationId), + "association_id": aws.StringValue(a.AssociationId), + "carrier_ip": aws.StringValue(a.CarrierIp), + "customer_owned_ip": aws.StringValue(a.CustomerOwnedIp), + "ip_owner_id": aws.StringValue(a.IpOwnerId), + "public_dns_name": aws.StringValue(a.PublicDnsName), + "public_ip": aws.StringValue(a.PublicIp), }} } diff --git a/website/docs/d/network_interface.html.markdown b/website/docs/d/network_interface.html.markdown index e69aaadfd14..d1436d78831 100644 --- a/website/docs/d/network_interface.html.markdown +++ b/website/docs/d/network_interface.html.markdown @@ -53,6 +53,7 @@ Additionally, the following attributes are exported: * `allocation_id` - The allocation ID. * `association_id` - The association ID. * `carrier_ip` - The carrier IP address associated with the network interface. This attribute is only set when the network interface is in a subnet which is associated with a Wavelength Zone. +* `customer_owned_ip` - The customer-owned IP address. * `ip_owner_id` - The ID of the Elastic IP address owner. * `public_dns_name` - The public DNS name. * `public_ip` - The address of the Elastic IP address bound to the network interface. From 5842081835765c4aded26c7c5f1b82e822e1b748 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 15 Dec 2020 09:06:12 -0500 Subject: [PATCH 9/9] Modify 'flattenEc2NetworkInterfaceAssociation' to conform to suggested code pattern (#16748). --- aws/structure.go | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/aws/structure.go b/aws/structure.go index d4a487db8cb..10a7f881773 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1158,15 +1158,31 @@ func flattenEc2AttributeValues(l []*ec2.AttributeValue) []string { } func flattenEc2NetworkInterfaceAssociation(a *ec2.NetworkInterfaceAssociation) []interface{} { - return []interface{}{map[string]interface{}{ - "allocation_id": aws.StringValue(a.AllocationId), - "association_id": aws.StringValue(a.AssociationId), - "carrier_ip": aws.StringValue(a.CarrierIp), - "customer_owned_ip": aws.StringValue(a.CustomerOwnedIp), - "ip_owner_id": aws.StringValue(a.IpOwnerId), - "public_dns_name": aws.StringValue(a.PublicDnsName), - "public_ip": aws.StringValue(a.PublicIp), - }} + tfMap := map[string]interface{}{} + + if a.AllocationId != nil { + tfMap["allocation_id"] = aws.StringValue(a.AllocationId) + } + if a.AssociationId != nil { + tfMap["association_id"] = aws.StringValue(a.AssociationId) + } + if a.CarrierIp != nil { + tfMap["carrier_ip"] = aws.StringValue(a.CarrierIp) + } + if a.CustomerOwnedIp != nil { + tfMap["customer_owned_ip"] = aws.StringValue(a.CustomerOwnedIp) + } + if a.IpOwnerId != nil { + tfMap["ip_owner_id"] = aws.StringValue(a.IpOwnerId) + } + if a.PublicDnsName != nil { + tfMap["public_dns_name"] = aws.StringValue(a.PublicDnsName) + } + if a.PublicIp != nil { + tfMap["public_ip"] = aws.StringValue(a.PublicIp) + } + + return []interface{}{tfMap} } func flattenEc2NetworkInterfaceIpv6Address(niia []*ec2.NetworkInterfaceIpv6Address) []string {