From c9a8f863c24f2147401de60a7ac080acb814f47e Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Tue, 5 Mar 2024 16:48:36 -0600 Subject: [PATCH 1/9] Fix replicant vms not being deleted --- ibm/service/power/ibm_pi_constants.go | 82 +++++++++---------- ibm/service/power/resource_ibm_pi_instance.go | 42 +++++----- 2 files changed, 63 insertions(+), 61 deletions(-) diff --git a/ibm/service/power/ibm_pi_constants.go b/ibm/service/power/ibm_pi_constants.go index d564ce2586e..dd365013352 100644 --- a/ibm/service/power/ibm_pi_constants.go +++ b/ibm/service/power/ibm_pi_constants.go @@ -14,21 +14,21 @@ const ( Arg_PlacementGroupName = "pi_placement_group_name" Arg_SAP = "sap" Arg_SAPProfileID = "pi_sap_profile_id" - Arg_SPPPlacementGroupID = "pi_spp_placement_group_id" - Arg_SPPPlacementGroupName = "pi_spp_placement_group_name" - Arg_SPPPlacementGroupPolicy = "pi_spp_placement_group_policy" Arg_SharedProcessorPoolHostGroup = "pi_shared_processor_pool_host_group" Arg_SharedProcessorPoolID = "pi_shared_processor_pool_id" Arg_SharedProcessorPoolName = "pi_shared_processor_pool_name" Arg_SharedProcessorPoolPlacementGroupID = "pi_shared_processor_pool_placement_group_id" Arg_SharedProcessorPoolReservedCores = "pi_shared_processor_pool_reserved_cores" Arg_SnapshotID = "pi_snapshot_id" + Arg_SPPPlacementGroupID = "pi_spp_placement_group_id" + Arg_SPPPlacementGroupName = "pi_spp_placement_group_name" + Arg_SPPPlacementGroupPolicy = "pi_spp_placement_group_policy" Arg_StoragePool = "pi_storage_pool" Arg_StorageType = "pi_storage_type" - Arg_VTL = "vtl" Arg_VolumeGroupID = "pi_volume_group_id" Arg_VolumeID = "pi_volume_id" Arg_VolumeOnboardingID = "pi_volume_onboarding_id" + Arg_VTL = "vtl" // Attributes Attr_AccessConfig = "access_config" @@ -42,14 +42,12 @@ const ( Attr_AvailabilityZone = "availability_zone" Attr_AvailableCores = "available_cores" Attr_AvailableIPCount = "available_ip_count" - Attr_BootVolumeID = "boot_volume_id" Attr_Bootable = "bootable" - Attr_CIDR = "cidr" - Attr_CPUs = "cpus" - Attr_CRN = "crn" + Attr_BootVolumeID = "boot_volume_id" Attr_Capabilities = "capabilities" Attr_Capacity = "capacity" Attr_Certified = "certified" + Attr_CIDR = "cidr" Attr_ClassicEnabled = "classic_enabled" Attr_CloudConnectionID = "cloud_connection_id" Attr_CloudInstanceID = "cloud_instance_id" @@ -64,11 +62,12 @@ const ( Attr_CopyType = "copy_type" Attr_CoreMemoryRatio = "core_memory_ratio" Attr_Cores = "cores" + Attr_CPUs = "cpus" Attr_CreateTime = "create_time" Attr_CreationDate = "creation_date" + Attr_CRN = "crn" Attr_CyclePeriodSeconds = "cycle_period_seconds" Attr_CyclingMode = "cycling_mode" - Attr_DNS = "dns" Attr_Datacenters = "datacenters" Attr_Default = "default" Attr_DeploymentType = "deployment_type" @@ -76,6 +75,7 @@ const ( Attr_DisasterRecoveryLocations = "disaster_recovery_locations" Attr_DiskFormat = "disk_format" Attr_DiskType = "disk_type" + Attr_DNS = "dns" Attr_Enabled = "enabled" Attr_Endianness = "endianness" Attr_ExternalIP = "external_ip" @@ -95,17 +95,17 @@ const ( Attr_HypervisorType = "hypervisor_type" Attr_IBMIPAddress = "ibm_ip_address" Attr_ID = "id" - Attr_IP = "ip" - Attr_IPAddress = "ipaddress" - Attr_IPOctet = "ipoctet" Attr_ImageID = "image_id" Attr_ImageInfo = "image_info" - Attr_ImageType = "image_type" Attr_Images = "images" + Attr_ImageType = "image_type" Attr_InputVolumes = "input_volumes" + Attr_Instances = "instances" Attr_InstanceSnapshots = "instance_snapshots" Attr_InstanceVolumes = "instance_volumes" - Attr_Instances = "instances" + Attr_IP = "ip" + Attr_IPAddress = "ipaddress" + Attr_IPOctet = "ipoctet" Attr_IsActive = "is_active" Attr_Jumbo = "jumbo" Attr_Key = "key" @@ -119,7 +119,6 @@ const ( Attr_Leases = "leases" Attr_LicenseRepositoryCapacity = "license_repository_capacity" Attr_Location = "location" - Attr_MTU = "mtu" Attr_MacAddress = "macaddress" Attr_MasterChangedVolumeName = "master_changed_volume_name" Attr_MasterVolumeName = "master_volume_name" @@ -127,11 +126,11 @@ const ( Attr_MaxAllocationSize = "max_allocation_size" Attr_MaxAvailable = "max_available" Attr_MaxCoresAvailable = "max_cores_available" + Attr_MaximumStorageAllocation = "max_storage_allocation" Attr_MaxMem = "maxmem" Attr_MaxMemoryAvailable = "max_memory_available" Attr_MaxProc = "maxproc" Attr_MaxVirtualCores = "max_virtual_cores" - Attr_MaximumStorageAllocation = "max_storage_allocation" Attr_Members = "members" Attr_Memory = "memory" Attr_Message = "message" @@ -141,6 +140,7 @@ const ( Attr_MinProc = "minproc" Attr_MinVirtualCores = "min_virtual_cores" Attr_MirroringState = "mirroring_state" + Attr_MTU = "mtu" Attr_Name = "name" Attr_NetworkID = "network_id" Attr_NetworkName = "network_name" @@ -149,9 +149,6 @@ const ( Attr_NumberOfVolumes = "number_of_volumes" Attr_Onboardings = "onboardings" Attr_OperatingSystem = "operating_system" - Attr_PVMInstanceID = "pvm_instance_id" - Attr_PVMInstances = "pvm_instances" - Attr_PVMSnapshots = "pvm_snapshots" Attr_PercentComplete = "percent_complete" Attr_PinPolicy = "pin_policy" Attr_PlacementGroupID = "placement_group_id" @@ -162,12 +159,15 @@ const ( Attr_Port = "port" Attr_PortID = "portid" Attr_PrimaryRole = "primary_role" - Attr_ProcType = "proctype" Attr_Processors = "processors" + Attr_ProcType = "proctype" Attr_ProfileID = "profile_id" Attr_Profiles = "profiles" Attr_Progress = "progress" Attr_PublicIP = "public_ip" + Attr_PVMInstanceID = "pvm_instance_id" + Attr_PVMInstances = "pvm_instances" + Attr_PVMSnapshots = "pvm_snapshots" Attr_Region = "region" Attr_RemoteCopyID = "remote_copy_id" Attr_RemoteCopyRelationshipNames = "remote_copy_relationship_names" @@ -179,33 +179,33 @@ const ( Attr_ReservedCores = "reserved_cores" Attr_ResultsOnboardedVolumes = "results_onboarded_volumes" Attr_ResultsVolumeOnboardingFailures = "results_volume_onboarding_failures" - Attr_SPPPlacementGroups = "spp_placement_groups" - Attr_SSHKey = "ssh_key" Attr_Shareable = "shreable" Attr_SharedCoreRatio = "shared_core_ratio" Attr_SharedProcessorPool = "shared_processor_pool" - Attr_SharedProcessorPoolID = "shared_processor_pool_id" - Attr_SharedProcessorPoolPlacementGroups = "spp_placement_groups" - Attr_SharedProcessorPoolStatus = "status" - Attr_SharedProcessorPools = "shared_processor_pools" - Attr_SharedProcessorPoolName = "name" - Attr_SharedProcessorPoolHostID = "host_id" - Attr_SharedProcessorPoolReservedCores = "reserved_cores" - Attr_SharedProcessorPoolAvailableCores = "available_cores" Attr_SharedProcessorPoolAllocatedCores = "allocated_cores" - Attr_SharedProcessorPoolStatusDetail = "status_detail" - Attr_SharedProcessorPoolInstances = "instances" - Attr_SharedProcessorPoolInstanceCpus = "cpus" - Attr_SharedProcessorPoolInstanceUncapped = "uncapped" + Attr_SharedProcessorPoolAvailableCores = "available_cores" + Attr_SharedProcessorPoolHostID = "host_id" + Attr_SharedProcessorPoolID = "shared_processor_pool_id" Attr_SharedProcessorPoolInstanceAvailabilityZone = "availability_zone" + Attr_SharedProcessorPoolInstanceCpus = "cpus" Attr_SharedProcessorPoolInstanceId = "id" Attr_SharedProcessorPoolInstanceMemory = "memory" Attr_SharedProcessorPoolInstanceName = "name" + Attr_SharedProcessorPoolInstances = "instances" Attr_SharedProcessorPoolInstanceStatus = "status" + Attr_SharedProcessorPoolInstanceUncapped = "uncapped" Attr_SharedProcessorPoolInstanceVcpus = "vcpus" + Attr_SharedProcessorPoolName = "name" + Attr_SharedProcessorPoolPlacementGroups = "spp_placement_groups" + Attr_SharedProcessorPoolReservedCores = "reserved_cores" + Attr_SharedProcessorPools = "shared_processor_pools" + Attr_SharedProcessorPoolStatus = "status" + Attr_SharedProcessorPoolStatusDetail = "status_detail" Attr_Size = "size" Attr_SourceVolumeName = "source_volume_name" Attr_Speed = "speed" + Attr_SPPPlacementGroups = "spp_placement_groups" + Attr_SSHKey = "ssh_key" Attr_StartTime = "start_time" Attr_State = "state" Attr_Status = "status" @@ -217,10 +217,10 @@ const ( Attr_StorageType = "storage_type" Attr_StorageTypesCapacity = "storage_types_capacity" Attr_Synchronized = "synchronized" - Attr_SysType = "systype" Attr_SystemPoolName = "system_pool_name" Attr_SystemPools = "system_pools" Attr_Systems = "systems" + Attr_SysType = "systype" Attr_TargetVolumeName = "target_volume_name" Attr_TenantID = "tenant_id" Attr_TenantName = "tenant_name" @@ -231,24 +231,24 @@ const ( Attr_TotalSSDStorageConsumed = "total_ssd_storage_consumed" Attr_TotalStandardStorageConsumed = "total_standard_storage_consumed" Attr_Type = "type" - Attr_URL = "url" Attr_Uncapped = "uncapped" + Attr_URL = "url" Attr_UsedIPCount = "used_ip_count" Attr_UsedIPPercent = "used_ip_percent" Attr_UserIPAddress = "user_ip_address" Attr_VCPUs = "vcpus" - Attr_VLanID = "vlan_id" - Attr_VPCCRNs = "vpc_crns" - Attr_VPCEnabled = "vpc_enabled" Attr_VirtualCoresAssigned = "virtual_cores_assigned" + Attr_VLanID = "vlan_id" Attr_VolumeGroupName = "volume_group_name" Attr_VolumeGroups = "volume_groups" Attr_VolumeIDs = "volume_ids" Attr_VolumePool = "volume_pool" - Attr_VolumeSnapshots = "volume_snapshots" Attr_Volumes = "volumes" - Attr_WWN = "wwn" + Attr_VolumeSnapshots = "volume_snapshots" + Attr_VPCCRNs = "vpc_crns" + Attr_VPCEnabled = "vpc_enabled" Attr_Workspaces = "workspaces" + Attr_WWN = "wwn" // TODO: Second Half Cleanup, remove extra variables diff --git a/ibm/service/power/resource_ibm_pi_instance.go b/ibm/service/power/resource_ibm_pi_instance.go index 368cc554e37..886803854b2 100644 --- a/ibm/service/power/resource_ibm_pi_instance.go +++ b/ibm/service/power/resource_ibm_pi_instance.go @@ -405,7 +405,13 @@ func resourceIBMPIInstanceCreate(ctx context.Context, d *schema.ResourceData, me instanceReadyStatus = r.(string) } - d.SetId(fmt.Sprintf("%s/%s", cloudInstanceID, *(*pvmList)[0].PvmInstanceID)) + // id is a combination of the cloud instance id and all of the pvm instance ids + id := cloudInstanceID + for _, pvm := range *pvmList { + id += "/" + *pvm.PvmInstanceID + } + + d.SetId(id) for _, s := range *pvmList { if dt, ok := d.GetOk(PIInstanceDeploymentType); ok && dt.(string) == "VMNoStorage" { @@ -419,7 +425,6 @@ func resourceIBMPIInstanceCreate(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } } - } // If Storage Pool Affinity is given as false we need to update the vm instance. @@ -454,7 +459,6 @@ func resourceIBMPIInstanceCreate(ctx context.Context, d *schema.ResourceData, me } return resourceIBMPIInstanceRead(ctx, d, meta) - } func resourceIBMPIInstanceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -463,10 +467,9 @@ func resourceIBMPIInstanceRead(ctx context.Context, d *schema.ResourceData, meta return diag.FromErr(err) } - cloudInstanceID, instanceID, err := splitID(d.Id()) - if err != nil { - return diag.FromErr(err) - } + idArr := strings.Split(d.Id(), "/") + cloudInstanceID := idArr[0] + instanceID := idArr[1] client := st.NewIBMPIInstanceClient(ctx, sess, cloudInstanceID) powervmdata, err := client.Get(instanceID) @@ -840,20 +843,19 @@ func resourceIBMPIInstanceDelete(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } - cloudInstanceID, instanceID, err := splitID(d.Id()) - if err != nil { - return diag.FromErr(err) - } - - client := st.NewIBMPIInstanceClient(ctx, sess, cloudInstanceID) - err = client.Delete(instanceID) - if err != nil { - return diag.FromErr(err) - } + idArr := strings.Split(d.Id(), "/") + cloudInstanceID := idArr[0] + for _, instanceID := range idArr[1:] { + client := st.NewIBMPIInstanceClient(ctx, sess, cloudInstanceID) + err = client.Delete(instanceID) + if err != nil { + return diag.FromErr(err) + } - _, err = isWaitForPIInstanceDeleted(ctx, client, instanceID) - if err != nil { - return diag.FromErr(err) + _, err = isWaitForPIInstanceDeleted(ctx, client, instanceID) + if err != nil { + return diag.FromErr(err) + } } d.SetId("") From cea3934f17e7f59bc0e15d4ec63cfaa1956494bb Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Tue, 5 Mar 2024 16:48:47 -0600 Subject: [PATCH 2/9] Update documentation --- website/docs/r/pi_instance.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/pi_instance.html.markdown b/website/docs/r/pi_instance.html.markdown index d3136858347..b76ab5a41f5 100644 --- a/website/docs/r/pi_instance.html.markdown +++ b/website/docs/r/pi_instance.html.markdown @@ -113,7 +113,7 @@ In addition to all argument reference list, you can access the following attribu - `health_status` - (String) The health status of the VM. - `ibmi_rds` - (Boolean) IBM i Rational Dev Studio. -- `id` - (String) The unique identifier of the instance. The ID is composed of `/`. +- `id` - (String) The unique identifier of the instance. The ID is composed of `//.../`. - `instance_id` - (String) The unique identifier of the instance. - `max_processors`- (Float) The maximum number of processors that can be allocated to the instance with shutting down or rebooting the `LPAR`. - `max_virtual_cores` - (Integer) The maximum number of virtual cores. @@ -135,7 +135,7 @@ In addition to all argument reference list, you can access the following attribu - `status` - (String) The status of the instance. ## Import -The `ibm_pi_instance` can be imported using `power_instance_id` and `instance_id`. +The `ibm_pi_instance` can be imported using `cloud_instance_id` and `instance_id`. **Example** From 0f81cc1a35e3cc44643d4318bcb3d6b13141c4e3 Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Tue, 5 Mar 2024 17:19:50 -0600 Subject: [PATCH 3/9] Use flex function instead of strings --- ibm/service/power/resource_ibm_pi_instance.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ibm/service/power/resource_ibm_pi_instance.go b/ibm/service/power/resource_ibm_pi_instance.go index 886803854b2..485e26881f0 100644 --- a/ibm/service/power/resource_ibm_pi_instance.go +++ b/ibm/service/power/resource_ibm_pi_instance.go @@ -467,7 +467,11 @@ func resourceIBMPIInstanceRead(ctx context.Context, d *schema.ResourceData, meta return diag.FromErr(err) } - idArr := strings.Split(d.Id(), "/") + idArr, err := flex.IdParts(d.Id()) + if err != nil { + return diag.FromErr(err) + } + cloudInstanceID := idArr[0] instanceID := idArr[1] @@ -843,7 +847,11 @@ func resourceIBMPIInstanceDelete(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } - idArr := strings.Split(d.Id(), "/") + idArr, err := flex.IdParts(d.Id()) + if err != nil { + return diag.FromErr(err) + } + cloudInstanceID := idArr[0] for _, instanceID := range idArr[1:] { client := st.NewIBMPIInstanceClient(ctx, sess, cloudInstanceID) From cf2cd9e8fd4b0aace60a08227f519d66a330820c Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Fri, 8 Mar 2024 13:39:33 -0600 Subject: [PATCH 4/9] Change placement group to be a computed value --- ibm/service/power/resource_ibm_pi_instance.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ibm/service/power/resource_ibm_pi_instance.go b/ibm/service/power/resource_ibm_pi_instance.go index 485e26881f0..4921994a719 100644 --- a/ibm/service/power/resource_ibm_pi_instance.go +++ b/ibm/service/power/resource_ibm_pi_instance.go @@ -183,7 +183,7 @@ func ResourceIBMPIInstance() *schema.Resource { }, helpers.PIPlacementGroupID: { Type: schema.TypeString, - ForceNew: true, + Computed: true, Optional: true, Description: "Placement group ID", }, From 73a8ae0afd6bb8da663b4d45e25df8ede25270c0 Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Fri, 8 Mar 2024 14:53:23 -0600 Subject: [PATCH 5/9] Update resource instance tests --- ibm/service/power/resource_ibm_pi_instance_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ibm/service/power/resource_ibm_pi_instance_test.go b/ibm/service/power/resource_ibm_pi_instance_test.go index 4711fd423b3..46ed264c429 100644 --- a/ibm/service/power/resource_ibm_pi_instance_test.go +++ b/ibm/service/power/resource_ibm_pi_instance_test.go @@ -85,7 +85,7 @@ func testAccCheckIBMPIInstanceDeploymentTypeConfig(name, instanceHealthStatus, e pi_instance_name = "%[2]s" pi_proc_type = "dedicated" pi_image_id = data.ibm_pi_image.power_image.id - pi_key_pair_name = ibm_pi_key.key.key_id + pi_key_pair_name = ibm_pi_key.key.name pi_sys_type = "%[7]s" pi_cloud_instance_id = "%[1]s" pi_storage_type = "%[8]s" @@ -157,17 +157,17 @@ func testAccIBMPIInstanceNetworkConfig(name, privateNetIP string) string { pi_processors = "0.25" pi_instance_name = "%[2]s" pi_proc_type = "shared" - pi_image_id = "f4501cad-d0f4-4517-9eea-85402309d90d" - pi_key_pair_name = ibm_pi_key.key.key_id + pi_image_id = "%[4]s" + pi_key_pair_name = ibm_pi_key.key.name pi_sys_type = "e980" pi_storage_type = "tier3" pi_cloud_instance_id = "%[1]s" pi_network { - network_id = resource.ibm_pi_network.power_networks.id + network_id = resource.ibm_pi_network.power_networks.network_id ip_address = "%[3]s" } } - `, acc.Pi_cloud_instance_id, name, privateNetIP) + `, acc.Pi_cloud_instance_id, name, privateNetIP, acc.Pi_image) } func testAccIBMPIInstanceVTLConfig(name string) string { @@ -191,7 +191,7 @@ func testAccIBMPIInstanceVTLConfig(name string) string { pi_license_repository_capacity = "3" pi_proc_type = "shared" pi_image_id = "%[3]s" - pi_key_pair_name = ibm_pi_key.vtl_key.key_id + pi_key_pair_name = ibm_pi_key.vtl_key.name pi_sys_type = "s922" pi_cloud_instance_id = "%[1]s" pi_storage_type = "tier1" @@ -467,7 +467,7 @@ func testAccIBMPIInstanceMixedStorage(name string) string { pi_instance_name = "%[2]s" pi_proc_type = "shared" pi_image_id = "ca4ea55f-b329-4cf5-bdce-d2f38cfc6da3" - pi_key_pair_name = ibm_pi_key.key.key_id + pi_key_pair_name = ibm_pi_key.key.name pi_sys_type = "s922" pi_storage_type = "tier1" pi_storage_pool_affinity = false From 6bf81db1b2983b5f7a88d67048a4698ddb66d74a Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Tue, 12 Mar 2024 09:26:16 -0500 Subject: [PATCH 6/9] Add replicant instance test --- .../power/resource_ibm_pi_instance_test.go | 79 ++++++++++++++++--- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/ibm/service/power/resource_ibm_pi_instance_test.go b/ibm/service/power/resource_ibm_pi_instance_test.go index 46ed264c429..115ff5fd9de 100644 --- a/ibm/service/power/resource_ibm_pi_instance_test.go +++ b/ibm/service/power/resource_ibm_pi_instance_test.go @@ -12,6 +12,7 @@ import ( acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -203,6 +204,27 @@ func testAccIBMPIInstanceVTLConfig(name string) string { `, acc.Pi_cloud_instance_id, name, acc.Pi_image) } +func testAccCheckIBMPIInstanceReplicantConfig(name string) string { + return fmt.Sprintf(` + resource "ibm_pi_instance" "power_instance" { + pi_cloud_instance_id = "%[1]s" + pi_memory = "2" + pi_processors = "1" + pi_instance_name = "%[2]s" + pi_proc_type = "shared" + pi_image_id = "%[3]s" + pi_sys_type = "s922" + pi_volume_ids = ["%[5]s"] + pi_network { + network_id = "%[4]s" + } + pi_replicants = 3 + pi_replication_policy = "affinity" + pi_replication_scheme = "suffix" + } + `, acc.Pi_cloud_instance_id, name, acc.Pi_image, acc.Pi_network_name, acc.Pi_volume_name) +} + func testAccCheckIBMPIInstanceDestroy(s *terraform.State) error { sess, err := acc.TestAccProvider.Meta().(conns.ClientSession).IBMPISession() if err != nil { @@ -213,19 +235,25 @@ func testAccCheckIBMPIInstanceDestroy(s *terraform.State) error { if rs.Type != "ibm_pi_instance" { continue } - cloudInstanceID, instanceID, err := splitID(rs.Primary.ID) - if err == nil { + + idArr, err := flex.IdParts(rs.Primary.ID) + if err != nil { return err } - client := st.NewIBMPIInstanceClient(context.Background(), sess, cloudInstanceID) - _, err = client.Get(instanceID) - if err == nil { - return fmt.Errorf("PI Instance still exists: %s", rs.Primary.ID) + + cloudInstanceID := idArr[0] + for _, instanceID := range idArr[1:] { + client := st.NewIBMPIInstanceClient(context.Background(), sess, cloudInstanceID) + _, err = client.Get(instanceID) + if err == nil { + return fmt.Errorf("PI Instance still exists: %s", rs.Primary.ID) + } } } return nil } + func testAccCheckIBMPIInstanceExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -241,15 +269,18 @@ func testAccCheckIBMPIInstanceExists(n string) resource.TestCheckFunc { return err } - cloudInstanceID, instanceID, err := splitID(rs.Primary.ID) - if err == nil { + idArr, err := flex.IdParts(rs.Primary.ID) + if err != nil { return err } - client := st.NewIBMPIInstanceClient(context.Background(), sess, cloudInstanceID) - _, err = client.Get(instanceID) - if err != nil { - return err + cloudInstanceID := idArr[0] + for _, instanceID := range idArr[1:] { + client := st.NewIBMPIInstanceClient(context.Background(), sess, cloudInstanceID) + _, err = client.Get(instanceID) + if err != nil { + return err + } } return nil @@ -328,6 +359,28 @@ func TestAccIBMPIInstanceIBMiLicense(t *testing.T) { }) } +func TestAccIBMPIInstanceReplicant(t *testing.T) { + instanceRes := "ibm_pi_instance.power_instance" + name := fmt.Sprintf("tf-pi-instance-%d", acctest.RandIntRange(10, 100)) + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMPIInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMPIInstanceReplicantConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMPIInstanceExists(instanceRes), + resource.TestCheckResourceAttr(instanceRes, "pi_replicants", "3"), + resource.TestCheckResourceAttr(instanceRes, "pi_replication_policy", "affinity"), + resource.TestCheckResourceAttr(instanceRes, "pi_replication_scheme", "suffix"), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func TestAccIBMPIInstanceNetwork(t *testing.T) { instanceRes := "ibm_pi_instance.power_instance" name := fmt.Sprintf("tf-pi-instance-%d", acctest.RandIntRange(10, 100)) @@ -609,7 +662,7 @@ func testAccCheckIBMPIStoppedInstanceConfigUpdate(name, instanceHealthStatus, pr network_id = data.ibm_pi_network.power_networks.id } } - resource "ibm_pi_instance_action" "example" { + resource "ibm_pi_instance_action" "power_instance_action" { pi_cloud_instance_id = "%[1]s" pi_instance_id = ibm_pi_instance.power_instance.instance_id pi_action = "%[8]s" From 587118de92b1907eb391f134b523e6694ccf7078 Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Thu, 14 Mar 2024 14:18:26 -0500 Subject: [PATCH 7/9] Fix compilation error --- ibm/service/power/ibm_pi_constants.go | 1 + 1 file changed, 1 insertion(+) diff --git a/ibm/service/power/ibm_pi_constants.go b/ibm/service/power/ibm_pi_constants.go index dd365013352..f1bea4bb357 100644 --- a/ibm/service/power/ibm_pi_constants.go +++ b/ibm/service/power/ibm_pi_constants.go @@ -179,6 +179,7 @@ const ( Attr_ReservedCores = "reserved_cores" Attr_ResultsOnboardedVolumes = "results_onboarded_volumes" Attr_ResultsVolumeOnboardingFailures = "results_volume_onboarding_failures" + Attr_ServerName = "server_name" Attr_Shareable = "shreable" Attr_SharedCoreRatio = "shared_core_ratio" Attr_SharedProcessorPool = "shared_processor_pool" From 5e69a367f0799a5351e5fcb18e083a166f26548b Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Mon, 1 Apr 2024 12:02:11 -0500 Subject: [PATCH 8/9] Separate command from checking --- ibm/service/power/resource_ibm_pi_instance.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ibm/service/power/resource_ibm_pi_instance.go b/ibm/service/power/resource_ibm_pi_instance.go index 4921994a719..20594e5fd72 100644 --- a/ibm/service/power/resource_ibm_pi_instance.go +++ b/ibm/service/power/resource_ibm_pi_instance.go @@ -853,13 +853,15 @@ func resourceIBMPIInstanceDelete(ctx context.Context, d *schema.ResourceData, me } cloudInstanceID := idArr[0] + client := st.NewIBMPIInstanceClient(ctx, sess, cloudInstanceID) for _, instanceID := range idArr[1:] { - client := st.NewIBMPIInstanceClient(ctx, sess, cloudInstanceID) err = client.Delete(instanceID) if err != nil { return diag.FromErr(err) } + } + for _, instanceID := range idArr[1:] { _, err = isWaitForPIInstanceDeleted(ctx, client, instanceID) if err != nil { return diag.FromErr(err) From 1073c7b62f365cadf628155916c9e80ed3672b33 Mon Sep 17 00:00:00 2001 From: Axel Ismirlian Date: Tue, 9 Apr 2024 08:15:25 -0500 Subject: [PATCH 9/9] Add replicant warning --- website/docs/r/pi_instance.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/r/pi_instance.html.markdown b/website/docs/r/pi_instance.html.markdown index b76ab5a41f5..ab2ecf0e42e 100644 --- a/website/docs/r/pi_instance.html.markdown +++ b/website/docs/r/pi_instance.html.markdown @@ -1,5 +1,4 @@ --- - subcategory: "Power Systems" layout: "ibm" page_title: "IBM: pi_instance" @@ -31,14 +30,15 @@ resource "ibm_pi_instance" "test-instance" { } ``` +~> **WARNING:** Updating a ibm_pi_instance resource with `pi_replicants` set does not update replicant vms! + **Note** * Please find [supported Regions](https://cloud.ibm.com/apidocs/power-cloud#endpoint) for endpoints. * If a Power cloud instance is provisioned at `lon04`, The provider level attributes should be as follows: * `region` - `lon` * `zone` - `lon04` - Example usage: - +Example usage: ```terraform provider "ibm" { region = "lon" @@ -141,4 +141,4 @@ The `ibm_pi_instance` can be imported using `cloud_instance_id` and `instance_id ``` $ terraform import ibm_pi_instance.example d7bec597-4726-451f-8a63-e62e6f19c32c/cea6651a-bc0a-4438-9f8a-a0770b112ebb -``` +``` \ No newline at end of file