diff --git a/.changelog/21555.txt b/.changelog/21555.txt new file mode 100644 index 00000000000..f775636f02c --- /dev/null +++ b/.changelog/21555.txt @@ -0,0 +1,11 @@ +```release-note:enhancement +resource/aws_launch_template: Add `network_card_index` argument to `network_interfaces` configuration block +``` + +```release-note:enhancement +data-source/aws_launch_template: Add `network_card_index` attribute to `network_interfaces` configuration block +``` + +```release-note:bug +resource/aws_placement_group: `partition_count` argument is Computed, preventing spurious resource diffs +``` \ No newline at end of file diff --git a/internal/service/ec2/launch_template.go b/internal/service/ec2/launch_template.go index 77a2da63978..1efc63391df 100644 --- a/internal/service/ec2/launch_template.go +++ b/internal/service/ec2/launch_template.go @@ -491,6 +491,10 @@ func ResourceLaunchTemplate() *schema.Resource { ValidateFunc: validation.IsIPv6Address, }, }, + "network_card_index": { + Type: schema.TypeInt, + Optional: true, + }, "network_interface_id": { Type: schema.TypeString, Optional: true, @@ -1190,6 +1194,7 @@ func getNetworkInterfaces(n []*ec2.LaunchTemplateInstanceNetworkInterfaceSpecifi "interface_type": aws.StringValue(v.InterfaceType), "ipv4_address_count": aws.Int64Value(v.SecondaryPrivateIpAddressCount), "ipv6_address_count": aws.Int64Value(v.Ipv6AddressCount), + "network_card_index": aws.Int64Value(v.NetworkCardIndex), "network_interface_id": aws.StringValue(v.NetworkInterfaceId), "private_ip_address": aws.StringValue(v.PrivateIpAddress), "subnet_id": aws.StringValue(v.SubnetId), @@ -1614,6 +1619,10 @@ func readNetworkInterfacesFromConfig(ni map[string]interface{}) (*ec2.LaunchTemp networkInterface.DeviceIndex = aws.Int64(int64(v)) } + if v, ok := ni["network_card_index"].(int); ok { + networkInterface.NetworkCardIndex = aws.Int64(int64(v)) + } + if v, ok := ni["network_interface_id"].(string); ok && v != "" { networkInterface.NetworkInterfaceId = aws.String(v) } diff --git a/internal/service/ec2/launch_template_data_source.go b/internal/service/ec2/launch_template_data_source.go index 5a36579b3e6..04131f3804c 100644 --- a/internal/service/ec2/launch_template_data_source.go +++ b/internal/service/ec2/launch_template_data_source.go @@ -300,6 +300,10 @@ func DataSourceLaunchTemplate() *schema.Resource { Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "network_card_index": { + Type: schema.TypeInt, + Optional: true, + }, "network_interface_id": { Type: schema.TypeString, Computed: true, diff --git a/internal/service/ec2/launch_template_test.go b/internal/service/ec2/launch_template_test.go index e52795c8325..f2a49b23dc1 100644 --- a/internal/service/ec2/launch_template_test.go +++ b/internal/service/ec2/launch_template_test.go @@ -815,6 +815,35 @@ func TestAccEC2LaunchTemplate_networkInterfaceType(t *testing.T) { }) } +func TestAccEC2LaunchTemplate_networkInterfaceCardIndex(t *testing.T) { + var template ec2.LaunchTemplate + resourceName := "aws_launch_template.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, autoscaling.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckLaunchTemplateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLaunchTemplateConfig_networkInterfaceCardIndex(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckLaunchTemplateExists(resourceName, &template), + resource.TestCheckResourceAttrSet(resourceName, "instance_type"), + resource.TestCheckResourceAttr(resourceName, "network_interfaces.#", "1"), + resource.TestCheckResourceAttr(resourceName, "network_interfaces.0.network_card_index", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccEC2LaunchTemplate_associatePublicIPAddress(t *testing.T) { var template ec2.LaunchTemplate rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2023,6 +2052,19 @@ resource "aws_launch_template" "test" { `, rName) } +func testAccLaunchTemplateConfig_networkInterfaceCardIndex(rName string) string { + return fmt.Sprintf(` +resource "aws_launch_template" "test" { + name = %[1]q + instance_type = "p4d.24xlarge" + + network_interfaces { + network_card_index = 1 + } +} +`, rName) +} + const testAccLaunchTemplateConfig_asg_basic = ` data "aws_ami" "test_ami" { most_recent = true diff --git a/internal/service/ec2/placement_group.go b/internal/service/ec2/placement_group.go index 60bf15b831f..5ccbe59e07a 100644 --- a/internal/service/ec2/placement_group.go +++ b/internal/service/ec2/placement_group.go @@ -40,8 +40,9 @@ func ResourcePlacementGroup() *schema.Resource { }, "partition_count": { Type: schema.TypeInt, - ForceNew: true, Optional: true, + Computed: true, + ForceNew: true, // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html#placement-groups-limitations-partition. ValidateFunc: validation.IntBetween(0, 7), }, diff --git a/website/docs/r/launch_template.html.markdown b/website/docs/r/launch_template.html.markdown index f98c354dc1b..7be97163325 100644 --- a/website/docs/r/launch_template.html.markdown +++ b/website/docs/r/launch_template.html.markdown @@ -301,6 +301,7 @@ Each `network_interfaces` block supports the following: * `ipv6_addresses` - One or more specific IPv6 addresses from the IPv6 CIDR block range of your subnet. Conflicts with `ipv6_address_count` * `ipv6_address_count` - The number of IPv6 addresses to assign to a network interface. Conflicts with `ipv6_addresses` * `network_interface_id` - The ID of the network interface to attach. +* `network_card_index` - The index of the network card. Some instance types support multiple network cards. The primary network interface must be assigned to network card index 0. The default is network card index 0. * `private_ip_address` - The primary private IPv4 address. * `ipv4_address_count` - The number of secondary private IPv4 addresses to assign to a network interface. Conflicts with `ipv4_addresses` * `ipv4_addresses` - One or more private IPv4 addresses to associate. Conflicts with `ipv4_address_count`