diff --git a/aws/data_source_aws_network_interface.go b/aws/data_source_aws_network_interface.go index 76a44ec9791..e836bf310de 100644 --- a/aws/data_source_aws_network_interface.go +++ b/aws/data_source_aws_network_interface.go @@ -33,6 +33,14 @@ func dataSourceAwsNetworkInterface() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "carrier_ip": { + 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 1822ef1c669..f5f101db7b3 100644 --- a/aws/data_source_aws_network_interface_test.go +++ b/aws/data_source_aws_network_interface_test.go @@ -9,46 +9,156 @@ 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"), ), }, }, }) } -func testAccDataSourceAwsNetworkInterface_basic(rName string) string { - return fmt.Sprintf(` -data "aws_availability_zones" "available" { - state = "available" +func TestAccDataSourceAwsNetworkInterface_filters(t *testing.T) { + datasourceName := "data.aws_network_interface.test" + rName := acctest.RandomWithPrefix("tf-acc-test") - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkInterfaceConfigFilters(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(datasourceName, "private_ips.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "security_groups.#", "1"), + ), + }, + }, + }) +} + +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"), + 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", ""), + 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_PublicIPAssociation(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: testAccDataSourceAwsNetworkInterfaceConfigPublicIPAssociation(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", ""), + 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", ""), + 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 composeConfig( + testAccAvailableAZsNoOptInConfig(), + fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" tags = { - Name = "terraform-testacc-eni-data-source-basic" + Name = %[1]q } } @@ -58,12 +168,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 } @@ -71,47 +181,33 @@ 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 + tags = { + Name = %[1]q + } } -`, rName) +`, 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 testAccDataSourceAwsNetworkInterfaceConfigBasic(rName string) string { + return composeConfig( + testAccDataSourceAwsNetworkInterfaceConfigBase(rName), + ` +data "aws_network_interface" "test" { + id = aws_network_interface.test.id } - -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"] - } +`) } +func testAccDataSourceAwsNetworkInterfaceConfigCarrierIPAssociation(rName string) string { + return composeConfig( + testAccAvailableAZsWavelengthZonesDefaultExcludeConfig(), + fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" tags = { - Name = "terraform-testacc-eni-data-source-filters" + Name = %[1]q } } @@ -121,26 +217,97 @@ resource "aws_subnet" "test" { vpc_id = aws_vpc.test.id tags = { - Name = "tf-acc-eni-data-source-filters" + Name = %[1]q } } resource "aws_security_group" "test" { - name = "tf-sg-%s" + 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.60"] + 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 + + 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 testAccDataSourceAwsNetworkInterfaceConfigPublicIPAssociation(rName string) string { + return composeConfig( + 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( + testAccDataSourceAwsNetworkInterfaceConfigBase(rName), + ` data "aws_network_interface" "test" { filter { name = "network-interface-id" values = [aws_network_interface.test.id] } } -`, rName) +`) } diff --git a/aws/structure.go b/aws/structure.go index c6cdddc44d3..10a7f881773 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1158,23 +1158,31 @@ func flattenEc2AttributeValues(l []*ec2.AttributeValue) []string { } func flattenEc2NetworkInterfaceAssociation(a *ec2.NetworkInterfaceAssociation) []interface{} { - att := make(map[string]interface{}) + tfMap := map[string]interface{}{} + if a.AllocationId != nil { - att["allocation_id"] = *a.AllocationId + tfMap["allocation_id"] = aws.StringValue(a.AllocationId) } if a.AssociationId != nil { - att["association_id"] = *a.AssociationId + 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 { - att["ip_owner_id"] = *a.IpOwnerId + tfMap["ip_owner_id"] = aws.StringValue(a.IpOwnerId) } if a.PublicDnsName != nil { - att["public_dns_name"] = *a.PublicDnsName + tfMap["public_dns_name"] = aws.StringValue(a.PublicDnsName) } if a.PublicIp != nil { - att["public_ip"] = *a.PublicIp + tfMap["public_ip"] = aws.StringValue(a.PublicIp) } - return []interface{}{att} + + return []interface{}{tfMap} } func flattenEc2NetworkInterfaceIpv6Address(niia []*ec2.NetworkInterfaceIpv6Address) []string { diff --git a/website/docs/d/network_interface.html.markdown b/website/docs/d/network_interface.html.markdown index 3510a6ab001..d1436d78831 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,8 @@ 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.