diff --git a/.changelog/27165.txt b/.changelog/27165.txt new file mode 100644 index 00000000000..d567c3de944 --- /dev/null +++ b/.changelog/27165.txt @@ -0,0 +1,11 @@ +```release-note:enhancement +resource/aws_vpc: Add `enable_network_address_usage_metrics` argument +``` + +```release-note:enhancement +resource/aws_default_vpc: Add `enable_network_address_usage_metrics` argument +``` + +```release-note:enhancement +data-source/aws_vpc: Add `enable_network_address_usage_metrics` attribute +``` \ No newline at end of file diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index df9c0f66062..7f3cc74a389 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -2428,6 +2428,8 @@ func FindVPCAttribute(conn *ec2.EC2, vpcID string, attribute string) (bool, erro v = output.EnableDnsHostnames case ec2.VpcAttributeNameEnableDnsSupport: v = output.EnableDnsSupport + case ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics: + v = output.EnableNetworkAddressUsageMetrics default: return false, fmt.Errorf("unsupported VPC attribute: %s", attribute) } diff --git a/internal/service/ec2/vpc_.go b/internal/service/ec2/vpc_.go index 2a3349a645c..7c9ae65ed1b 100644 --- a/internal/service/ec2/vpc_.go +++ b/internal/service/ec2/vpc_.go @@ -104,6 +104,11 @@ func ResourceVPC() *schema.Resource { Optional: true, Default: true, }, + "enable_network_address_usage_metrics": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, "instance_tenancy": { Type: schema.TypeString, Optional: true, @@ -238,11 +243,12 @@ func resourceVPCCreate(d *schema.ResourceData, meta interface{}) error { } vpcInfo := vpcInfo{ - vpc: vpc, - enableClassicLink: false, - enableClassicLinkDNSSupport: false, - enableDnsHostnames: false, - enableDnsSupport: true, + vpc: vpc, + enableClassicLink: false, + enableClassicLinkDNSSupport: false, + enableDnsHostnames: false, + enableDnsSupport: true, + enableNetworkAddressUsageMetrics: false, } if err := modifyVPCAttributesOnCreate(conn, d, &vpcInfo); err != nil { @@ -319,6 +325,12 @@ func resourceVPCRead(d *schema.ResourceData, meta interface{}) error { d.Set("enable_dns_support", v) } + if v, err := FindVPCAttribute(conn, d.Id(), ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics); err != nil { + return fmt.Errorf("error reading EC2 VPC (%s) Attribute (%s): %w", d.Id(), ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics, err) + } else { + d.Set("enable_network_address_usage_metrics", v) + } + if v, err := FindVPCDefaultNetworkACL(conn, d.Id()); err != nil { log.Printf("[WARN] Error reading EC2 VPC (%s) default NACL: %s", d.Id(), err) } else { @@ -405,6 +417,12 @@ func resourceVPCUpdate(d *schema.ResourceData, meta interface{}) error { } } + if d.HasChange("enable_network_address_usage_metrics") { + if err := modifyVPCNetworkAddressUsageMetrics(conn, d.Id(), d.Get("enable_network_address_usage_metrics").(bool)); err != nil { + return err + } + } + if d.HasChange("enable_classiclink") { if err := modifyVPCClassicLink(conn, d.Id(), d.Get("enable_classiclink").(bool)); err != nil { return err @@ -559,11 +577,12 @@ func defaultIPv6CIDRBlockAssociation(vpc *ec2.Vpc, associationID string) *ec2.Vp } type vpcInfo struct { - vpc *ec2.Vpc - enableClassicLink bool - enableClassicLinkDNSSupport bool - enableDnsHostnames bool - enableDnsSupport bool + vpc *ec2.Vpc + enableClassicLink bool + enableClassicLinkDNSSupport bool + enableDnsHostnames bool + enableDnsSupport bool + enableNetworkAddressUsageMetrics bool } // modifyVPCAttributesOnCreate sets VPC attributes on resource Create. @@ -581,6 +600,12 @@ func modifyVPCAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, vpcInfo } } + if new, old := d.Get("enable_network_address_usage_metrics").(bool), vpcInfo.enableNetworkAddressUsageMetrics; old != new { + if err := modifyVPCNetworkAddressUsageMetrics(conn, d.Id(), new); err != nil { + return err + } + } + if new, old := d.Get("enable_classiclink").(bool), vpcInfo.enableClassicLink; old != new { if err := modifyVPCClassicLink(conn, d.Id(), new); err != nil { return err @@ -678,6 +703,25 @@ func modifyVPCDNSSupport(conn *ec2.EC2, vpcID string, v bool) error { return nil } +func modifyVPCNetworkAddressUsageMetrics(conn *ec2.EC2, vpcID string, v bool) error { + input := &ec2.ModifyVpcAttributeInput{ + EnableNetworkAddressUsageMetrics: &ec2.AttributeBooleanValue{ + Value: aws.Bool(v), + }, + VpcId: aws.String(vpcID), + } + + if _, err := conn.ModifyVpcAttribute(input); err != nil { + return fmt.Errorf("error modifying EC2 VPC (%s) EnableNetworkAddressUsageMetrics: %w", vpcID, err) + } + + if _, err := WaitVPCAttributeUpdated(conn, vpcID, ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics, v); err != nil { + return fmt.Errorf("error waiting for EC2 VPC (%s) EnableNetworkAddressUsageMetrics update: %w", vpcID, err) + } + + return nil +} + // modifyVPCIPv6CIDRBlockAssociation modify's a VPC's IPv6 CIDR block association. // Any exiting association is deleted and any new association's ID is returned. func modifyVPCIPv6CIDRBlockAssociation(conn *ec2.EC2, vpcID, associationID string, amazonProvidedCIDRBlock bool, cidrBlock, ipamPoolID string, netmaskLength int, networkBorderGroup string) (string, error) { diff --git a/internal/service/ec2/vpc_data_source.go b/internal/service/ec2/vpc_data_source.go index d3444e55ae9..c370991a0eb 100644 --- a/internal/service/ec2/vpc_data_source.go +++ b/internal/service/ec2/vpc_data_source.go @@ -70,6 +70,10 @@ func DataSourceVPC() *schema.Resource { Type: schema.TypeBool, Computed: true, }, + "enable_network_address_usage_metrics": { + Type: schema.TypeBool, + Computed: true, + }, "filter": CustomFiltersSchema(), "id": { Type: schema.TypeString, @@ -183,6 +187,12 @@ func dataSourceVPCRead(d *schema.ResourceData, meta interface{}) error { d.Set("enable_dns_support", v) } + if v, err := FindVPCAttribute(conn, d.Id(), ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics); err != nil { + return fmt.Errorf("error reading EC2 VPC (%s) Attribute (%s): %w", d.Id(), ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics, err) + } else { + d.Set("enable_network_address_usage_metrics", v) + } + if v, err := FindVPCMainRouteTable(conn, d.Id()); err != nil { log.Printf("[WARN] Error reading EC2 VPC (%s) main Route Table: %s", d.Id(), err) d.Set("main_route_table_id", nil) diff --git a/internal/service/ec2/vpc_data_source_test.go b/internal/service/ec2/vpc_data_source_test.go index 89be1379f46..131a1ecae5d 100644 --- a/internal/service/ec2/vpc_data_source_test.go +++ b/internal/service/ec2/vpc_data_source_test.go @@ -34,6 +34,7 @@ func TestAccVPCDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr(ds1ResourceName, "cidr_block", cidr), resource.TestCheckResourceAttr(ds1ResourceName, "enable_dns_hostnames", "false"), resource.TestCheckResourceAttr(ds1ResourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(ds1ResourceName, "enable_network_address_usage_metrics", "false"), resource.TestCheckResourceAttrPair(ds1ResourceName, "id", vpcResourceName, "id"), resource.TestCheckResourceAttrPair(ds1ResourceName, "ipv6_association_id", vpcResourceName, "ipv6_association_id"), resource.TestCheckResourceAttrPair(ds1ResourceName, "ipv6_cidr_block", vpcResourceName, "ipv6_cidr_block"), diff --git a/internal/service/ec2/vpc_default_vpc.go b/internal/service/ec2/vpc_default_vpc.go index 7db94a05853..8d4ccd6edd4 100644 --- a/internal/service/ec2/vpc_default_vpc.go +++ b/internal/service/ec2/vpc_default_vpc.go @@ -92,6 +92,11 @@ func ResourceDefaultVPC() *schema.Resource { Optional: true, Default: true, }, + "enable_network_address_usage_metrics": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, "existing_default_vpc": { Type: schema.TypeBool, Computed: true, @@ -203,6 +208,11 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { } else { vpcInfo.enableDnsSupport = v } + if v, err := FindVPCAttribute(conn, d.Id(), ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics); err != nil { + return fmt.Errorf("error reading EC2 VPC (%s) Attribute (%s): %w", d.Id(), ec2.VpcAttributeNameEnableNetworkAddressUsageMetrics, err) + } else { + vpcInfo.enableNetworkAddressUsageMetrics = v + } } else if tfresource.NotFound(err) { input := &ec2.CreateDefaultVpcInput{} @@ -229,6 +239,7 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { vpcInfo.enableClassicLinkDNSSupport = false vpcInfo.enableDnsHostnames = true vpcInfo.enableDnsSupport = true + vpcInfo.enableNetworkAddressUsageMetrics = false } else { return fmt.Errorf("error reading EC2 Default VPC (%s): %w", d.Id(), err) } diff --git a/internal/service/ec2/vpc_default_vpc_test.go b/internal/service/ec2/vpc_default_vpc_test.go index 801bf99871e..f4221daf65f 100644 --- a/internal/service/ec2/vpc_default_vpc_test.go +++ b/internal/service/ec2/vpc_default_vpc_test.go @@ -107,6 +107,7 @@ func testAccDefaultVPC_Existing_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_network_address_usage_metrics", "true"), resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "true"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), @@ -154,6 +155,7 @@ func testAccDefaultVPC_Existing_assignGeneratedIPv6CIDRBlock(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_network_address_usage_metrics", "true"), resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "true"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), @@ -228,6 +230,7 @@ func testAccDefaultVPC_NotFound_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_network_address_usage_metrics", "true"), resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "false"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), @@ -275,6 +278,7 @@ func testAccDefaultVPC_NotFound_assignGeneratedIPv6CIDRBlock(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_network_address_usage_metrics", "true"), resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "false"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), diff --git a/internal/service/ec2/vpc_test.go b/internal/service/ec2/vpc_test.go index 686de472660..0fc1b79b135 100644 --- a/internal/service/ec2/vpc_test.go +++ b/internal/service/ec2/vpc_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/service/ec2" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -42,6 +43,7 @@ func TestAccVPC_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_network_address_usage_metrics", "false"), resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), resource.TestCheckNoResourceAttr(resourceName, "ipv4_ipam_pool_id"), resource.TestCheckNoResourceAttr(resourceName, "ipv4_netmask_length"), @@ -709,6 +711,33 @@ func TestAccVPC_disabledDNSSupport(t *testing.T) { }) } +func TestAccVPC_enableNetworkAddressUsageMetrics(t *testing.T) { + var vpc ec2.Vpc + resourceName := "aws_vpc.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckPartitionNot(t, endpoints.AwsUsGovPartitionID) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckVPCDestroy, + Steps: []resource.TestStep{ + { + Config: testAccVPCConfig_enableNetworkAddressUsageMetrics(rName), + Check: resource.ComposeTestCheckFunc( + acctest.CheckVPCExists(resourceName, &vpc), + resource.TestCheckResourceAttr(resourceName, "enable_network_address_usage_metrics", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { var vpc ec2.Vpc resourceName := "aws_vpc.test" @@ -1104,6 +1133,19 @@ resource "aws_vpc" "test" { `, rName) } +func testAccVPCConfig_enableNetworkAddressUsageMetrics(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.2.0.0/16" + enable_network_address_usage_metrics = true + + tags = { + Name = %[1]q + } +} +`, rName) +} + func testAccIPAMIPv4Config_base(rName string) string { return fmt.Sprintf(` data "aws_region" "current" {} diff --git a/website/docs/d/vpc.html.markdown b/website/docs/d/vpc.html.markdown index a7c4f5a0c02..1f3189f60f3 100644 --- a/website/docs/d/vpc.html.markdown +++ b/website/docs/d/vpc.html.markdown @@ -77,6 +77,7 @@ The following attribute is additionally exported: * `arn` - ARN of VPC * `enable_dns_support` - Whether or not the VPC has DNS support +* `enable_network_address_usage_metrics` - Whether Network Address Usage metrics are enabled for your VPC * `enable_dns_hostnames` - Whether or not the VPC has DNS hostname support * `instance_tenancy` - Allowed tenancy of instances launched into the selected VPC. May be any of `"default"`, `"dedicated"`, or `"host"`. diff --git a/website/docs/r/default_vpc.html.markdown b/website/docs/r/default_vpc.html.markdown index 5acd0b443ca..09297c57602 100644 --- a/website/docs/r/default_vpc.html.markdown +++ b/website/docs/r/default_vpc.html.markdown @@ -38,6 +38,7 @@ The arguments of an `aws_default_vpc` differ slightly from those of [`aws_vpc`]( * The `cidr_block` and `instance_tenancy` arguments become computed attributes * The default value for `enable_dns_hostnames` is `true` +* The default value for `enable_network_address_usage_metrics` is `true` The following additional arguments are supported: diff --git a/website/docs/r/vpc.html.markdown b/website/docs/r/vpc.html.markdown index 5cc25f3d904..6f0b9b26e9e 100644 --- a/website/docs/r/vpc.html.markdown +++ b/website/docs/r/vpc.html.markdown @@ -76,7 +76,8 @@ The following arguments are supported: * `ipv6_ipam_pool_id` - (Optional) IPAM Pool ID for a IPv6 pool. Conflicts with `assign_generated_ipv6_cidr_block`. * `ipv6_netmask_length` - (Optional) Netmask length to request from IPAM Pool. Conflicts with `ipv6_cidr_block`. This can be omitted if IPAM pool as a `allocation_default_netmask_length` set. Valid values: `56`. * `ipv6_cidr_block_network_border_group` - (Optional) By default when an IPv6 CIDR is assigned to a VPC a default ipv6_cidr_block_network_border_group will be set to the region of the VPC. This can be changed to restrict advertisement of public addresses to specific Network Border Groups such as LocalZones. -* `enable_dns_support` - (Optional) A boolean flag to enable/disable DNS support in the VPC. Defaults true. +* `enable_dns_support` - (Optional) A boolean flag to enable/disable DNS support in the VPC. Defaults to true. +* `enable_network_address_usage_metrics` - (Optional) Indicates whether Network Address Usage metrics are enabled for your VPC. Defaults to false. * `enable_dns_hostnames` - (Optional) A boolean flag to enable/disable DNS hostnames in the VPC. Defaults false. * `enable_classiclink` - (Optional) A boolean flag to enable/disable ClassicLink for the VPC. Only valid in regions and accounts that support EC2 Classic. @@ -92,8 +93,9 @@ In addition to all arguments above, the following attributes are exported: * `arn` - Amazon Resource Name (ARN) of VPC * `id` - The ID of the VPC -* `instance_tenancy` - Tenancy of instances spin up within VPC. +* `instance_tenancy` - Tenancy of instances spin up within VPC * `enable_dns_support` - Whether or not the VPC has DNS support +* `enable_network_address_usage_metrics` - Whether Network Address Usage metrics are enabled for the VPC * `enable_dns_hostnames` - Whether or not the VPC has DNS hostname support * `enable_classiclink` - Whether or not the VPC has Classiclink enabled * `main_route_table_id` - The ID of the main route table associated with