From ace6c32caa59013148380025ac12d1c79ffb0f0e Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 6 May 2020 15:38:56 -0400 Subject: [PATCH] service/ec2: Add customer_owned_ipv4_pool and map_customer_owned_ip_on_launch attributes to aws_subnet data source and resource Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/13170 Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/13171 Output from acceptance testing: ``` Pending us-west-2 deployment of EC2 API. ``` --- aws/data_source_aws_subnet.go | 12 ++ aws/data_source_aws_subnet_test.go | 96 ++++++++++++++ aws/resource_aws_subnet.go | 63 +++++++++ aws/resource_aws_subnet_test.go | 191 +++++++++++++++++++++++++++- website/docs/d/subnet.html.markdown | 3 + website/docs/r/subnet.html.markdown | 2 + 6 files changed, 366 insertions(+), 1 deletion(-) diff --git a/aws/data_source_aws_subnet.go b/aws/data_source_aws_subnet.go index 35d669b40a4..912e731bf23 100644 --- a/aws/data_source_aws_subnet.go +++ b/aws/data_source_aws_subnet.go @@ -77,6 +77,16 @@ func dataSourceAwsSubnet() *schema.Resource { Computed: true, }, + "customer_owned_ipv4_pool": { + Type: schema.TypeString, + Computed: true, + }, + + "map_customer_owned_ip_on_launch": { + Type: schema.TypeBool, + Computed: true, + }, + "map_public_ip_on_launch": { Type: schema.TypeBool, Computed: true, @@ -180,6 +190,8 @@ func dataSourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error { } d.Set("assign_ipv6_address_on_creation", subnet.AssignIpv6AddressOnCreation) + d.Set("customer_owned_ipv4_pool", subnet.CustomerOwnedIpv4Pool) + d.Set("map_customer_owned_ip_on_launch", subnet.MapCustomerOwnedIpOnLaunch) d.Set("map_public_ip_on_launch", subnet.MapPublicIpOnLaunch) for _, a := range subnet.Ipv6CidrBlockAssociationSet { diff --git a/aws/data_source_aws_subnet_test.go b/aws/data_source_aws_subnet_test.go index 7d414324548..16a7299a7d4 100644 --- a/aws/data_source_aws_subnet_test.go +++ b/aws/data_source_aws_subnet_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "os" "testing" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" @@ -38,6 +39,8 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { resource.TestCheckResourceAttr(ds1ResourceName, "cidr_block", cidr), resource.TestCheckResourceAttr(ds1ResourceName, "tags.Name", tag), resource.TestCheckResourceAttrPair(ds1ResourceName, "arn", snResourceName, "arn"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "customer_owned_ipv4_pool", snResourceName, "customer_owned_ipv4_pool"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "map_customer_owned_ip_on_launch", snResourceName, "map_customer_owned_ip_on_launch"), resource.TestCheckResourceAttrPair(ds1ResourceName, "outpost_arn", snResourceName, "outpost_arn"), resource.TestCheckResourceAttrPair(ds2ResourceName, "id", snResourceName, "id"), @@ -48,6 +51,8 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { resource.TestCheckResourceAttr(ds2ResourceName, "cidr_block", cidr), resource.TestCheckResourceAttr(ds2ResourceName, "tags.Name", tag), resource.TestCheckResourceAttrPair(ds2ResourceName, "arn", snResourceName, "arn"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "customer_owned_ipv4_pool", snResourceName, "customer_owned_ipv4_pool"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "map_customer_owned_ip_on_launch", snResourceName, "map_customer_owned_ip_on_launch"), resource.TestCheckResourceAttrPair(ds2ResourceName, "outpost_arn", snResourceName, "outpost_arn"), resource.TestCheckResourceAttrPair(ds3ResourceName, "id", snResourceName, "id"), @@ -58,6 +63,8 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { resource.TestCheckResourceAttr(ds3ResourceName, "cidr_block", cidr), resource.TestCheckResourceAttr(ds3ResourceName, "tags.Name", tag), resource.TestCheckResourceAttrPair(ds3ResourceName, "arn", snResourceName, "arn"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "customer_owned_ipv4_pool", snResourceName, "customer_owned_ipv4_pool"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "map_customer_owned_ip_on_launch", snResourceName, "map_customer_owned_ip_on_launch"), resource.TestCheckResourceAttrPair(ds3ResourceName, "outpost_arn", snResourceName, "outpost_arn"), resource.TestCheckResourceAttrPair(ds4ResourceName, "id", snResourceName, "id"), @@ -68,6 +75,8 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { resource.TestCheckResourceAttr(ds4ResourceName, "cidr_block", cidr), resource.TestCheckResourceAttr(ds4ResourceName, "tags.Name", tag), resource.TestCheckResourceAttrPair(ds4ResourceName, "arn", snResourceName, "arn"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "customer_owned_ipv4_pool", snResourceName, "customer_owned_ipv4_pool"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "map_customer_owned_ip_on_launch", snResourceName, "map_customer_owned_ip_on_launch"), resource.TestCheckResourceAttrPair(ds4ResourceName, "outpost_arn", snResourceName, "outpost_arn"), resource.TestCheckResourceAttrPair(ds5ResourceName, "id", snResourceName, "id"), @@ -78,6 +87,8 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { resource.TestCheckResourceAttr(ds5ResourceName, "cidr_block", cidr), resource.TestCheckResourceAttr(ds5ResourceName, "tags.Name", tag), resource.TestCheckResourceAttrPair(ds5ResourceName, "arn", snResourceName, "arn"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "customer_owned_ipv4_pool", snResourceName, "customer_owned_ipv4_pool"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "map_customer_owned_ip_on_launch", snResourceName, "map_customer_owned_ip_on_launch"), resource.TestCheckResourceAttrPair(ds5ResourceName, "outpost_arn", snResourceName, "outpost_arn"), resource.TestCheckResourceAttrPair(ds6ResourceName, "id", snResourceName, "id"), @@ -88,6 +99,8 @@ func TestAccDataSourceAwsSubnet_basic(t *testing.T) { resource.TestCheckResourceAttr(ds6ResourceName, "cidr_block", cidr), resource.TestCheckResourceAttr(ds6ResourceName, "tags.Name", tag), resource.TestCheckResourceAttrPair(ds6ResourceName, "arn", snResourceName, "arn"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "customer_owned_ipv4_pool", snResourceName, "customer_owned_ipv4_pool"), + resource.TestCheckResourceAttrPair(ds1ResourceName, "map_customer_owned_ip_on_launch", snResourceName, "map_customer_owned_ip_on_launch"), resource.TestCheckResourceAttrPair(ds6ResourceName, "outpost_arn", snResourceName, "outpost_arn"), ), }, @@ -134,6 +147,45 @@ func TestAccDataSourceAwsSubnet_ipv6ByIpv6CidrBlock(t *testing.T) { }) } +func TestAccDataSourceAwsSubnet_CustomerOwnedIpv4Pool(t *testing.T) { + // Hide Outposts testing behind consistent environment variable + outpostArn := os.Getenv("AWS_OUTPOST_ARN") + if outpostArn == "" { + t.Skip( + "Environment variable AWS_OUTPOST_ARN is not set. " + + "This environment variable must be set to the ARN of " + + "a deployed Outpost to enable this test.") + } + + // Local Gateway Route Table ID filtering in DescribeCoipPools is not currently working + poolId := os.Getenv("AWS_COIP_POOL_ID") + if poolId == "" { + t.Skip( + "Environment variable AWS_COIP_POOL_ID is not set. " + + "This environment variable must be set to the ID of " + + "a deployed Coip Pool to enable this test.") + } + + dataSourceName := "data.aws_subnet.test" + resourceName := "aws_subnet.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: resourceName, + Providers: testAccProviders, + CheckDestroy: testAccCheckSubnetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceSubnetConfigCustomerOwnedIpv4Pool(outpostArn, poolId), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(resourceName, "customer_owned_ipv4_pool", dataSourceName, "customer_owned_ipv4_pool"), + resource.TestCheckResourceAttrPair(resourceName, "map_customer_owned_ip_on_launch", dataSourceName, "map_customer_owned_ip_on_launch"), + ), + }, + }, + }) +} + func testAccDataSourceAwsSubnetConfig(rInt int) string { return fmt.Sprintf(` data "aws_availability_zones" "available" { @@ -307,3 +359,47 @@ data "aws_subnet" "by_ipv6_cidr" { } `, rInt, rInt) } + +func testAccDataSourceSubnetConfigCustomerOwnedIpv4Pool(outpostArn string, customerOwnedIpv4Pool string) string { + return fmt.Sprintf(` +# TODO: This should be replaced with aws_outposts_outpost data source, when available. +data "aws_availability_zones" "current" { + # Exclude Availability Zones with limited Outposts functionality. + blacklisted_zone_ids = ["usw2-az4"] + + # Exclude Local Zones + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +data "aws_ec2_coip_pool" "test" { + pool_id = %[2]q +} + +resource "aws_vpc" "test" { + cidr_block = "10.1.0.0/16" + + tags = { + Name = "tf-acc-test-subnet-customer-owned-ipv4-pool" + } +} + +resource "aws_subnet" "test" { + availability_zone = data.aws_availability_zones.current.names[0] + cidr_block = "10.1.1.0/24" + customer_owned_ipv4_pool = data.aws_ec2_coip_pool.test.id + outpost_arn = %[1]q + vpc_id = aws_vpc.test.id + + tags = { + Name = aws_vpc.test.tags["Name"] + } +} + +data "aws_subnet" "test" { + id = aws_subnet.test.id +} +`, outpostArn, customerOwnedIpv4Pool) +} diff --git a/aws/resource_aws_subnet.go b/aws/resource_aws_subnet.go index 17730e188e8..7888f29497b 100644 --- a/aws/resource_aws_subnet.go +++ b/aws/resource_aws_subnet.go @@ -67,6 +67,16 @@ func resourceAwsSubnet() *schema.Resource { ConflictsWith: []string{"availability_zone"}, }, + "customer_owned_ipv4_pool": { + Type: schema.TypeString, + Optional: true, + }, + + "map_customer_owned_ip_on_launch": { + Type: schema.TypeBool, + Optional: true, + }, + "map_public_ip_on_launch": { Type: schema.TypeBool, Optional: true, @@ -175,6 +185,30 @@ func resourceAwsSubnetCreate(d *schema.ResourceData, meta interface{}) error { } } + if v, ok := d.GetOk("customer_owned_ipv4_pool"); ok { + input := &ec2.ModifySubnetAttributeInput{ + CustomerOwnedIpv4Pool: aws.String(v.(string)), + SubnetId: aws.String(d.Id()), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) customer owned IPv4 pool: %w", d.Id(), err) + } + } + + if d.Get("map_customer_owned_ip_on_launch").(bool) { + input := &ec2.ModifySubnetAttributeInput{ + MapCustomerOwnedIpOnLaunch: &ec2.AttributeBooleanValue{ + Value: aws.Bool(true), + }, + SubnetId: aws.String(d.Id()), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error enabling EC2 Subnet (%s) map customer owned IP on launch: %w", d.Id(), err) + } + } + if d.Get("map_public_ip_on_launch").(bool) { input := &ec2.ModifySubnetAttributeInput{ MapPublicIpOnLaunch: &ec2.AttributeBooleanValue{ @@ -217,6 +251,8 @@ func resourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error { d.Set("availability_zone", subnet.AvailabilityZone) d.Set("availability_zone_id", subnet.AvailabilityZoneId) d.Set("cidr_block", subnet.CidrBlock) + d.Set("customer_owned_ipv4_pool", subnet.CustomerOwnedIpv4Pool) + d.Set("map_customer_owned_ip_on_launch", subnet.MapCustomerOwnedIpOnLaunch) d.Set("map_public_ip_on_launch", subnet.MapPublicIpOnLaunch) d.Set("assign_ipv6_address_on_creation", subnet.AssignIpv6AddressOnCreation) d.Set("outpost_arn", subnet.OutpostArn) @@ -255,6 +291,33 @@ func resourceAwsSubnetUpdate(d *schema.ResourceData, meta interface{}) error { } } + // You cannot modify multiple subnet attributes in the same request. + // Reference: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifySubnetAttribute.html + + if d.HasChange("customer_owned_ipv4_pool") { + input := &ec2.ModifySubnetAttributeInput{ + CustomerOwnedIpv4Pool: aws.String(d.Get("customer_owned_ipv4_pool").(string)), + SubnetId: aws.String(d.Id()), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error updating EC2 Subnet (%s) customer owned IPv4 pool: %w", d.Id(), err) + } + } + + if d.HasChange("map_customer_owned_ip_on_launch") { + input := &ec2.ModifySubnetAttributeInput{ + MapCustomerOwnedIpOnLaunch: &ec2.AttributeBooleanValue{ + Value: aws.Bool(d.Get("map_customer_owned_ip_on_launch").(bool)), + }, + SubnetId: aws.String(d.Id()), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error updating EC2 Subnet (%s) map customer owned IP on launch: %w", d.Id(), err) + } + } + if d.HasChange("map_public_ip_on_launch") { modifyOpts := &ec2.ModifySubnetAttributeInput{ SubnetId: aws.String(d.Id()), diff --git a/aws/resource_aws_subnet_test.go b/aws/resource_aws_subnet_test.go index ba90171670a..b3a6c9a198f 100644 --- a/aws/resource_aws_subnet_test.go +++ b/aws/resource_aws_subnet_test.go @@ -333,6 +333,107 @@ func TestAccAWSSubnet_outpost(t *testing.T) { }) } +func TestAccAWSSubnet_CustomerOwnedIpv4Pool(t *testing.T) { + // Hide Outposts testing behind consistent environment variable + outpostArn := os.Getenv("AWS_OUTPOST_ARN") + if outpostArn == "" { + t.Skip( + "Environment variable AWS_OUTPOST_ARN is not set. " + + "This environment variable must be set to the ARN of " + + "a deployed Outpost to enable this test.") + } + + // Local Gateway Route Table ID filtering in DescribeCoipPools is not currently working + poolId := os.Getenv("AWS_COIP_POOL_ID") + if poolId == "" { + t.Skip( + "Environment variable AWS_COIP_POOL_ID is not set. " + + "This environment variable must be set to the ID of " + + "a deployed Coip Pool to enable this test.") + } + + var subnet1 ec2.Subnet + resourceName := "aws_subnet.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: resourceName, + Providers: testAccProviders, + CheckDestroy: testAccCheckSubnetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSubnetConfigCustomerOwnedIpv4Pool(outpostArn, poolId), + Check: resource.ComposeTestCheckFunc( + testAccCheckSubnetExists(resourceName, &subnet1), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", poolId), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", outpostArn), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSSubnet_MapCustomerOwnedIpOnLaunch(t *testing.T) { + // Hide Outposts testing behind consistent environment variable + outpostArn := os.Getenv("AWS_OUTPOST_ARN") + if outpostArn == "" { + t.Skip( + "Environment variable AWS_OUTPOST_ARN is not set. " + + "This environment variable must be set to the ARN of " + + "a deployed Outpost to enable this test.") + } + + // Local Gateway Route Table ID filtering in DescribeCoipPools is not currently working + poolId := os.Getenv("AWS_COIP_POOL_ID") + if poolId == "" { + t.Skip( + "Environment variable AWS_COIP_POOL_ID is not set. " + + "This environment variable must be set to the ID of " + + "a deployed Coip Pool to enable this test.") + } + + var subnet1 ec2.Subnet + resourceName := "aws_subnet.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: resourceName, + Providers: testAccProviders, + CheckDestroy: testAccCheckSubnetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSubnetConfigMapCustomerOwnedIpOnLaunch(outpostArn, poolId, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckSubnetExists(resourceName, &subnet1), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", poolId), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "true"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", outpostArn), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccSubnetConfigMapCustomerOwnedIpOnLaunch(outpostArn, poolId, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckSubnetExists(resourceName, &subnet1), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", poolId), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", outpostArn), + ), + }, + }, + }) +} + func testAccCheckAwsSubnetIpv6BeforeUpdate(subnet *ec2.Subnet) resource.TestCheckFunc { return func(s *terraform.State) error { if subnet.Ipv6CidrBlockAssociationSet == nil { @@ -556,9 +657,16 @@ resource "aws_subnet" "test" { func testAccSubnetConfigOutpost(outpostArn string) string { return fmt.Sprintf(` +# TODO: This should be replaced with aws_outposts_outpost data source, when available. data "aws_availability_zones" "current" { - # Exclude usw2-az4 (us-west-2d) as it has limited instance types. + # Exclude Availability Zones with limited Outposts functionality. blacklisted_zone_ids = ["usw2-az4"] + + # Exclude Local Zones + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } } resource "aws_vpc" "test" { @@ -579,3 +687,84 @@ resource "aws_subnet" "test" { } `, outpostArn) } + +func testAccSubnetConfigCustomerOwnedIpv4Pool(outpostArn string, customerOwnedIpv4Pool string) string { + return fmt.Sprintf(` +# TODO: This should be replaced with aws_outposts_outpost data source, when available. +data "aws_availability_zones" "current" { + # Exclude Availability Zones with limited Outposts functionality. + blacklisted_zone_ids = ["usw2-az4"] + + # Exclude Local Zones + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +data "aws_ec2_coip_pool" "test" { + pool_id = %[2]q +} + +resource "aws_vpc" "test" { + cidr_block = "10.1.0.0/16" + + tags = { + Name = "tf-acc-test-subnet-customer-owned-ipv4-pool" + } +} + +resource "aws_subnet" "test" { + availability_zone = data.aws_availability_zones.current.names[0] + cidr_block = "10.1.1.0/24" + customer_owned_ipv4_pool = data.aws_ec2_coip_pool.test.id + outpost_arn = %[1]q + vpc_id = aws_vpc.test.id + + tags = { + Name = aws_vpc.test.tags["Name"] + } +} +`, outpostArn, customerOwnedIpv4Pool) +} + +func testAccSubnetConfigMapCustomerOwnedIpOnLaunch(outpostArn string, customerOwnedIpv4Pool string, mapCustomerOwnedIpOnLaunch bool) string { + return fmt.Sprintf(` +# TODO: This should be replaced with aws_outposts_outpost data source, when available. +data "aws_availability_zones" "current" { + # Exclude Availability Zones with limited Outposts functionality. + blacklisted_zone_ids = ["usw2-az4"] + + # Exclude Local Zones + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +data "aws_ec2_coip_pool" "test" { + pool_id = %[2]q +} + +resource "aws_vpc" "test" { + cidr_block = "10.1.0.0/16" + + tags = { + Name = "tf-acc-test-subnet-customer-owned-ipv4-pool" + } +} + +resource "aws_subnet" "test" { + availability_zone = data.aws_availability_zones.current.names[0] + cidr_block = "10.1.1.0/24" + customer_owned_ipv4_pool = data.aws_ec2_coip_pool.test.id + map_customer_owned_ip_on_launch = %[3]t + outpost_arn = %[1]q + vpc_id = aws_vpc.test.id + + tags = { + Name = aws_vpc.test.tags["Name"] + } +} +`, outpostArn, customerOwnedIpv4Pool, mapCustomerOwnedIpOnLaunch) +} diff --git a/website/docs/d/subnet.html.markdown b/website/docs/d/subnet.html.markdown index fe1e110be62..777449c26df 100644 --- a/website/docs/d/subnet.html.markdown +++ b/website/docs/d/subnet.html.markdown @@ -97,5 +97,8 @@ the selected subnet. In addition the following attributes are exported: * `arn` - The ARN of the subnet. +* `customer_owned_ipv4_pool` - Identifier of customer owned IPv4 address pool. +* `map_customer_owned_ip_on_launch` - Whether customer owned IP addresses are assigned on network interface creation. +* `map_public_ip_on_launch` - Whether public IP addresses are assigned on instance launch. * `owner_id` - The ID of the AWS account that owns the subnet. * `outpost_arn` - The Amazon Resource Name (ARN) of the Outpost. diff --git a/website/docs/r/subnet.html.markdown b/website/docs/r/subnet.html.markdown index 3f98c1f1093..512be35fad9 100644 --- a/website/docs/r/subnet.html.markdown +++ b/website/docs/r/subnet.html.markdown @@ -51,8 +51,10 @@ The following arguments are supported: * `availability_zone` - (Optional) The AZ for the subnet. * `availability_zone_id` - (Optional) The AZ ID of the subnet. * `cidr_block` - (Required) The CIDR block for the subnet. +* `customer_owned_ipv4_pool` - (Optional) The customer owned IPv4 address pool. Typically used with the `map_customer_owned_ip_on_launch` argument. The `outpost_arn` argument must be specified when configured. * `ipv6_cidr_block` - (Optional) The IPv6 network range for the subnet, in CIDR notation. The subnet size must use a /64 prefix length. +* `map_customer_owned_ip_on_launch` - (Optional) Specify `true` to indicate that network interfaces created in the subnet should be assigned a customer owned IP address. The `customer_owned_ipv4_pool` and `outpost_arn` arguments must be specified when set to `true`. Default is `false`. * `map_public_ip_on_launch` - (Optional) Specify true to indicate that instances launched into the subnet should be assigned a public IP address. Default is `false`.