From 06c159738eb0f04ddc9e85f2f490176903618bae Mon Sep 17 00:00:00 2001
From: Jason-Zhang <jasonzhang9309@163.com>
Date: Tue, 5 Nov 2024 10:54:42 +0800
Subject: [PATCH] feat(cce): add new resource autopilot cluster (#5803)

---
 docs/resources/cce_autopilot_cluster.md       | 304 ++++++
 huaweicloud/provider.go                       |   3 +
 ..._huaweicloud_cce_autopilot_cluster_test.go | 116 +++
 ...ource_huaweicloud_cce_autopilot_cluster.go | 927 ++++++++++++++++++
 4 files changed, 1350 insertions(+)
 create mode 100644 docs/resources/cce_autopilot_cluster.md
 create mode 100644 huaweicloud/services/acceptance/cceautopilot/resource_huaweicloud_cce_autopilot_cluster_test.go
 create mode 100644 huaweicloud/services/cceautopilot/resource_huaweicloud_cce_autopilot_cluster.go

diff --git a/docs/resources/cce_autopilot_cluster.md b/docs/resources/cce_autopilot_cluster.md
new file mode 100644
index 0000000000..7ec60ec9b3
--- /dev/null
+++ b/docs/resources/cce_autopilot_cluster.md
@@ -0,0 +1,304 @@
+---
+subcategory: "Cloud Container Engine Autopilot (CCE Autopilot)"
+layout: "huaweicloud"
+page_title: "HuaweiCloud: huaweicloud_cce_autopilot_cluster"
+description: |-
+  Manages a CCE Autopilot cluster resource within huaweicloud.
+---
+
+# huaweicloud_cce_autopilot_cluster
+
+Manages a CCE Autopilot cluster resource within huaweicloud.
+
+## Example Usage
+
+### Basic Usage
+
+```hcl
+resource "huaweicloud_vpc" "myvpc" {
+  name = "vpc"
+  cidr = "192.168.0.0/16"
+}
+
+resource "huaweicloud_vpc_subnet" "mysubnet" {
+  name       = "subnet"
+  cidr       = "192.168.0.0/16"
+  gateway_ip = "192.168.0.1"
+  vpc_id     = huaweicloud_vpc.myvpc.id
+}
+
+resource "huaweicloud_cce_autopilot_cluster" "mycluster" {
+  name        = "cluster"
+  flavor      = "cce.autopilot.cluster"
+  description = "created by terraform"
+
+  host_network {
+    vpc    = huaweicloud_vpc.myvpc.id
+    subnet = huaweicloud_vpc_subnet.mysubnet.id
+  }
+
+  container_network {
+    mode = "eni"
+  }
+
+  eni_network {
+    subnets {
+      subnet_id = huaweicloud_vpc_subnet.mysubnet.ipv4_subnet_id
+    }
+  }
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `region` - (Optional, String, ForceNew) Specifies the region in which to create the CCE autopilot cluster resource.
+  If omitted, the provider-level region will be used. Changing this parameter will create a new cluster resource.
+
+* `name` - (Required, String, NonUpdatable) Specifies the cluster name. Enter 4 to 128 characters starting with a lowercase
+  letter and not ending with a hyphen (-). Only lowercase letters, digits, and hyphens (-) are allowed.
+
+* `flavor` - (Required, String, NonUpdatable) Specifies the cluster flavor. Only **cce.autopilot.cluster** is supported.
+
+* `host_network` - (Required, List, NonUpdatable) Specifies the host network of the cluster.
+  The [host_network](#autopilot_cluster_host_networks) structure is documented below.
+
+* `container_network` - (Required, List, NonUpdatable) Specifies the container network of the cluster.
+  The [container_network](#autopilot_cluster_container_network) structure is documented below.
+
+* `alias` - (Optional, String, NonUpdatable) Specifies the alias of the cluster. Enter 4 to 128 characters starting
+  with a lowercase letter and not ending with a hyphen (-). Only lowercase letters, digits, and hyphens (-) are allowed.
+  If not specified, the alias is the same as the cluster name.
+
+* `annotations` - (Optional, Map, NonUpdatable) Specifies the cluster annotations in the format of key-value pairs.
+
+* `category` - (Optional, String, NonUpdatable) Specifies the cluster type. Only **Turbo** is supported.
+
+* `type` - (Optional, String, NonUpdatable) Specifies the master node architecture. The value can be:
+  + **VirtualMachine**: Indicates the master node is an x86 server.
+
+* `description` - (Optional, String, NonUpdatable) Specifies the description of the cluster.
+
+* `version` - (Optional, String, NonUpdatable) Specifies the version of the cluster.
+  If not specified, a cluster of the latest version will be created.
+
+* `custom_san` - (Optional, List, NonUpdatable) Specifies the custom SAN field in the API server certificate of the cluster.
+
+* `enable_snat` - (Optional, Bool, NonUpdatable) Specifies whether SNAT is configured for the cluster.
+  After this function is enabled, the cluster can access the Internet through a NAT gateway.
+  By default, the existing NAT gateway in the selected VPC is used. Otherwise,
+  the system automatically creates a NAT gateway of the default specifications,
+  binds an EIP to the NAT gateway, and configures SNAT rules.
+
+* `enable_swr_image_access` - (Optional, Bool, NonUpdatable) Specifies whether the cluster is interconnected with SWR.
+  To ensure that your cluster nodes can pull images from SWR, the existing SWR and OBS endpoints in the selected
+  VPC are used by default. If not, new SWR and OBS endpoints will be automatically created.
+
+* `enable_autopilot` - (Optional, Bool, NonUpdatable) Specifies whether the cluster is an Autopilot cluster,
+  defaults to **true**.
+
+* `ipv6_enable` - (Optional, Bool, NonUpdatable) Specifies whether the cluster uses the IPv6 mode.
+
+* `eni_network` - (Optional, List, NonUpdatable) Specifies the ENI network of the cluster.
+  The [eni_network](#autopilot_cluster_eni_network) structure is documented below.
+
+* `service_network` - (Optional, List, NonUpdatable) Specifies the service network of the cluster.
+  The [service_network](#autopilot_cluster_service_network) structure is documented below.
+
+* `authentication` - (Optional, List, NonUpdatable) Specifies the configurations of the cluster authentication mode.
+  The [authentication](#autopilot_cluster_authentication) structure is documented below.
+
+* `tags` - (Optional, Map, NonUpdatable) Specifies the cluster tags in the format of key-value pairs.
+
+* `kube_proxy_mode` - (Optional, String, NonUpdatable) Specifies the kube proxy mode of the cluster.
+  The value can be: **iptables**.
+
+* `extend_param` - (Optional, List, NonUpdatable) Specifies the extend param of the cluster.
+  The [extend_param](#autopilot_cluster_extend_param) structure is documented below.
+
+* `configurations_override` - (Optional, List, NonUpdatable) Specifies the this parameter to override
+  the default component configurations in the cluster.
+  The [configurations_override](#autopilot_cluster_configurations_override) structure is documented below.
+
+* `deletion_protection` - (Optional, Bool, NonUpdatable) Specifies whether to enable deletion protection for the cluster.
+
+* `delete_efs` - (Optional, String) Specifies whether to delete the SFS Turbo volume.
+  The value can be:
+  + **true** or **block**: The system starts to delete the object. If the deletion fails, subsequent processes are blocked.
+
+  + **try**: The system starts to delete the object. If the deletion fails, no deletion retry is performed,
+    and subsequent processes will proceed.
+
+  + **false** or **skip**: The deletion is skipped. This is the default option.
+
+* `delete_eni` - (Optional, String) Specifies whether to delete the ENI port.
+  The value can be:
+  + **true** or **block**: The system starts to delete the object. If the deletion fails, subsequent processes are blocked.
+    This is the default option.
+
+  + **try**: The system starts to delete the object. If the deletion fails, no deletion retry is performed,
+    and subsequent processes will proceed.
+
+  + **false** or **skip**: The deletion is skipped.
+
+* `delete_net` - (Optional, String) Specifies whether to delete the cluster service or ingress resources,
+  such as a load balancer. The value can be:
+  + **true** or **block**: The system starts to delete the object. If the deletion fails, subsequent processes are blocked.
+    This is the default option.
+
+  + **try**: The system starts to delete the object. If the deletion fails, no deletion retry is performed,
+    and subsequent processes will proceed.
+
+  + **false** or **skip**: The deletion is skipped.
+
+* `delete_obs` - (Optional, String) Specifies whether to delete the OBS volume.
+  The value can be:
+  + **true** or **block**: The system starts to delete the object. If the deletion fails, subsequent processes are blocked.
+
+  + **try**: The system starts to delete the object. If the deletion fails, no deletion retry is performed,
+    and subsequent processes will proceed.
+
+  + **false** or **skip**: The deletion is skipped. This is the default option.
+
+* `delete_sfs30` - (Optional, String) Specifies whether to delete the SFS 3.0 volume.
+  The value can be:
+  + **true** or **block**: The system starts to delete the object. If the deletion fails, subsequent processes are blocked.
+
+  + **try**: The system starts to delete the object. If the deletion fails, no deletion retry is performed,
+    and subsequent processes will proceed.
+
+  + **false** or **skip**: The deletion is skipped. This is the default option.
+
+* `lts_reclaim_policy` - (Optional, String) Specifies whether to delete the LTS resource, such as a log group or
+  a log stream. The value can be:
+  + **Delete_Log_Group**: The system starts to delete a log group. If the deletion fails, no deletion retry is performed,
+    and subsequent processes will proceed.
+
+  + **Delete_Master_Log_Stream**: The system starts to delete a master log stream. If the deletion fails,
+    no deletion retry is performed, and subsequent processes will proceed. This is the default option.
+
+  + **Retain**: The deletion is skipped.
+
+<a name="autopilot_cluster_host_networks"></a>
+The `host_network` block supports:
+
+* `vpc` - (Required, String, NonUpdatable) Specifies the ID of the VPC used to create a master node.
+
+* `subnet` - (Required, String, NonUpdatable) Specifies ID of the subnet used to create a master node.
+
+<a name="autopilot_cluster_container_network"></a>
+The `container_network` block supports:
+
+* `mode` - (Required, String, NonUpdatable) Specifies the container network type. The value can be: **eni**.
+
+<a name="autopilot_cluster_eni_network"></a>
+The `eni_network` block supports:
+
+* `subnets` - (Required, List, NonUpdatable) Specifies the list of ENI subnets.
+  The [subnets](#autopilot_cluster_eni_network_subnets) structure is documented below.
+
+<a name="autopilot_cluster_eni_network_subnets"></a>
+The `subnets` block supports:
+
+* `subnet_id` - (Required, String, NonUpdatable) Specifies the IPv4 subnet ID of the subnet used to create control
+  nodes and containers.
+
+<a name="autopilot_cluster_service_network"></a>
+The `service_network` block supports:
+
+* `ipv4_cidr` - (Optional, String, NonUpdatable) Specifies the IPv4 CIDR of the service network.
+  If not specified, the default value 10.247.0.0/16 will be used.
+
+<a name="autopilot_cluster_authentication"></a>
+The `authentication` block supports:
+
+* `mode` - (Optional, String, NonUpdatable) Specifies the cluster authentication mode.
+  The default value is **rbac**.
+
+<a name="autopilot_cluster_extend_param"></a>
+The `extend_param` block supports:
+
+* `enterprise_project_id` - (Optional, String, NonUpdatable) Specifies the ID of the enterprise project to which the
+  cluster belongs.
+
+<a name="autopilot_cluster_configurations_override"></a>
+The `configurations_override` block supports:
+
+* `name` - (Optional, String, NonUpdatable) Specifies the component name.
+
+* `configurations` - (Optional, List, NonUpdatable) Specifies the component configuration items.
+  The [configurations](#autopilot_cluster_configurations_override_configurations) structure is documented below.
+
+<a name="autopilot_cluster_configurations_override_configurations"></a>
+The `configurations` block supports:
+
+* `name` - (Optional, String, NonUpdatable) Specifies the component configuration item name.
+
+* `value` - (Optional, String, NonUpdatable) Specifies the component configuration item value.
+
+## Attribute Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+* `id` - ID of the cluster resource.
+  
+* `platform_version` - The cluster platform version.
+
+* `created_at` - The time when the cluster was created.
+
+* `updated_at` - The time when the cluster was updated.
+
+* `az` - The AZ of the cluster.
+
+* `status` - The status of the cluster.
+  The [status](#autopilot_cluster_status) structure is documented below.
+
+<a name="autopilot_cluster_status"></a>
+The `status` block supports:
+
+* `phase` - The phase of the cluster.
+
+* `endpoints` - The access address of kube-apiserver in the cluster.
+  The [endpoints](#autopilot_cluster_status_endpoints) structure is documented below.
+
+<a name="autopilot_cluster_status_endpoints"></a>
+The `endpoints` block supports:
+
+* `url` - The phase of the cluster.
+
+* `type` - The access address of kube-apiserver in the cluster.
+
+## Timeouts
+
+This resource provides the following timeouts configuration options:
+
+* `create` - Default is 30 minutes.
+* `delete` - Default is 30 minutes.
+
+## Import
+
+The autopilot cluster can be imported using the cluster ID, e.g.
+
+```bash
+ $ terraform import huaweicloud_cce_autopilot_cluster.mycluster <cluster_id>
+```
+
+Note that the imported state may not be identical to your resource definition, due to some attributes missing from the
+API response, security or some other reason. The missing attributes include:
+`delete_efs`, `delete_eni`, `delete_net`, `delete_obs`, `delete_sfs30` and `lts_reclaim_policy`. It is generally
+recommended running `terraform plan` after importing a cluster. You can then decide if changes should be applied to
+the cluster, or the resource definition should be updated to align with the cluster. Also you can ignore changes as
+below.
+
+```hcl
+resource "huaweicloud_cce_autopilot_cluster" "mycluster" {
+    ...
+
+  lifecycle {
+    ignore_changes = [
+      delete_efs, delete_obs,
+    ]
+  }
+}
+```
diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go
index a5e29c3f74..36990f788d 100644
--- a/huaweicloud/provider.go
+++ b/huaweicloud/provider.go
@@ -30,6 +30,7 @@ import (
 	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/cbr"
 	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/cc"
 	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/cce"
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/cceautopilot"
 	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/cci"
 	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/ccm"
 	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/cdm"
@@ -1313,6 +1314,8 @@ func Provider() *schema.Provider {
 			"huaweicloud_cc_global_connection_bandwidth":                    cc.ResourceGlobalConnectionBandwidth(),
 			"huaweicloud_cc_global_connection_bandwidth_associate":          cc.ResourceGlobalConnectionBandwidthAssociate(),
 
+			"huaweicloud_cce_autopilot_cluster": cceautopilot.ResourceAutopilotCluster(),
+
 			"huaweicloud_cce_cluster":             cce.ResourceCluster(),
 			"huaweicloud_cce_cluster_log_config":  cce.ResourceClusterLogConfig(),
 			"huaweicloud_cce_cluster_upgrade":     cce.ResourceClusterUpgrade(),
diff --git a/huaweicloud/services/acceptance/cceautopilot/resource_huaweicloud_cce_autopilot_cluster_test.go b/huaweicloud/services/acceptance/cceautopilot/resource_huaweicloud_cce_autopilot_cluster_test.go
new file mode 100644
index 0000000000..25652682cb
--- /dev/null
+++ b/huaweicloud/services/acceptance/cceautopilot/resource_huaweicloud_cce_autopilot_cluster_test.go
@@ -0,0 +1,116 @@
+package cceautopilot
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
+
+	"github.com/chnsz/golangsdk"
+
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance/common"
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
+)
+
+func getAutopilotClusterFunc(cfg *config.Config, state *terraform.ResourceState) (interface{}, error) {
+	region := acceptance.HW_REGION_NAME
+
+	var (
+		getClusterHttpUrl = "autopilot/v3/projects/{project_id}/clusters/{cluster_id}"
+		getClusterProduct = "cce"
+	)
+	getClusterClient, err := cfg.NewServiceClient(getClusterProduct, region)
+	if err != nil {
+		return nil, fmt.Errorf("error creating CCE Client: %s", err)
+	}
+
+	getClusterPath := getClusterClient.Endpoint + getClusterHttpUrl
+	getClusterPath = strings.ReplaceAll(getClusterPath, "{project_id}", getClusterClient.ProjectID)
+	getClusterPath = strings.ReplaceAll(getClusterPath, "{cluster_id}", state.Primary.ID)
+
+	getClusterOpt := golangsdk.RequestOpts{
+		KeepResponseBody: true,
+	}
+
+	getClusterResp, err := getClusterClient.Request("GET", getClusterPath, &getClusterOpt)
+	if err != nil {
+		return nil, fmt.Errorf("error retrieving CCE autopolit cluster: %s", err)
+	}
+
+	return utils.FlattenResponse(getClusterResp)
+}
+
+func TestAccAutopilotCluster_basic(t *testing.T) {
+	var (
+		cluster      interface{}
+		resourceName = "huaweicloud_cce_autopilot_cluster.test"
+		rName        = acceptance.RandomAccResourceNameWithDash()
+
+		rc = acceptance.InitResourceCheck(
+			resourceName,
+			&cluster,
+			getAutopilotClusterFunc,
+		)
+	)
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:          func() { acceptance.TestAccPreCheck(t) },
+		ProviderFactories: acceptance.TestAccProviderFactories,
+		CheckDestroy:      rc.CheckResourceDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testAccCluster_basic(rName),
+				Check: resource.ComposeTestCheckFunc(
+					rc.CheckResourceExists(),
+					resource.TestCheckResourceAttr(resourceName, "name", rName),
+					resource.TestCheckResourceAttr(resourceName, "flavor", "cce.autopilot.cluster"),
+					resource.TestCheckResourceAttr(resourceName, "description", "created by terraform"),
+					resource.TestCheckResourceAttr(resourceName, "container_network.0.mode", "eni"),
+					resource.TestCheckResourceAttrPair(resourceName, "host_network.0.vpc", "huaweicloud_vpc.test", "id"),
+					resource.TestCheckResourceAttrPair(resourceName, "host_network.0.subnet", "huaweicloud_vpc_subnet.test", "id"),
+					resource.TestCheckResourceAttrPair(resourceName, "eni_network.0.subnets.0.subnet_id",
+						"huaweicloud_vpc_subnet.test", "ipv4_subnet_id"),
+					resource.TestCheckResourceAttr(resourceName, "status.0.phase", "Available"),
+					resource.TestCheckResourceAttrSet(resourceName, "created_at"),
+					resource.TestCheckResourceAttrSet(resourceName, "updated_at"),
+				),
+			},
+			{
+				ResourceName:      resourceName,
+				ImportState:       true,
+				ImportStateVerify: true,
+			},
+		},
+	})
+}
+
+func testAccCluster_basic(rName string) string {
+	return fmt.Sprintf(`
+%[1]s
+
+resource "huaweicloud_cce_autopilot_cluster" "test" {
+  name        = "%[2]s"
+  flavor      = "cce.autopilot.cluster"
+  description = "created by terraform"
+
+  host_network {
+    vpc    = huaweicloud_vpc.test.id
+    subnet = huaweicloud_vpc_subnet.test.id
+  }
+
+  container_network {
+    mode = "eni"
+  }
+
+  eni_network {
+    subnets {
+      subnet_id = huaweicloud_vpc_subnet.test.ipv4_subnet_id
+    }
+  }
+}
+`, common.TestVpc(rName), rName)
+}
diff --git a/huaweicloud/services/cceautopilot/resource_huaweicloud_cce_autopilot_cluster.go b/huaweicloud/services/cceautopilot/resource_huaweicloud_cce_autopilot_cluster.go
new file mode 100644
index 0000000000..39cf8e9dae
--- /dev/null
+++ b/huaweicloud/services/cceautopilot/resource_huaweicloud_cce_autopilot_cluster.go
@@ -0,0 +1,927 @@
+package cceautopilot
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+
+	"github.com/hashicorp/go-multierror"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+
+	"github.com/chnsz/golangsdk"
+
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/common"
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
+	"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
+)
+
+var autopilotClusterNonUpdatableParams = []string{
+	"name", "flavor",
+	"host_network", "host_network.*.vpc", "host_network.*.subnet",
+	"container_network", "container_network.*.mode",
+	"alias", "annotations", "category", "type", "version", "description", "custom_san", "enable_snat",
+	"enable_swr_image_access", "enable_autopilot", "ipv6_enable",
+	"eni_network", "eni_network.*.subnets", "eni_network.*.subnets.*.subnet_id",
+	"service_network", "service_network.*.ipv4_cidr",
+	"authentication", "authentication.*.mode",
+	"tags", "kube_proxy_mode",
+	"extend_param", "extend_param.*.enterprise_project_id",
+	"configurations_override", "configurations_override.*.name", "configurations_override.*.configurations",
+	"configurations_override.*.configurations.*.name", "configurations_override.*.configurations.*.value",
+	"deletion_protection",
+}
+
+// @API CCE POST /autopilot/v3/projects/{project_id}/clusters
+// @API CCE GET /autopilot/v3/projects/{project_id}/jobs/{job_id}
+// @API CCE GET /autopilot/v3/projects/{project_id}/clusters/{cluster_id}
+// @API CCE DELETE /autopilot/v3/projects/{project_id}/clusters/{cluster_id}
+func ResourceAutopilotCluster() *schema.Resource {
+	return &schema.Resource{
+		CreateContext: resourceAutopilotClusterCreate,
+		ReadContext:   resourceAutopilotClusterRead,
+		UpdateContext: resourceAutopilotClusterUpdate,
+		DeleteContext: resourceAutopilotClusterDelete,
+		Importer: &schema.ResourceImporter{
+			StateContext: schema.ImportStatePassthroughContext,
+		},
+
+		Timeouts: &schema.ResourceTimeout{
+			Create: schema.DefaultTimeout(30 * time.Minute),
+			Delete: schema.DefaultTimeout(30 * time.Minute),
+		},
+
+		CustomizeDiff: config.FlexibleForceNew(autopilotClusterNonUpdatableParams),
+
+		Schema: map[string]*schema.Schema{
+			"region": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Computed: true,
+				ForceNew: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"flavor": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"host_network": {
+				Type:     schema.TypeList,
+				Required: true,
+				MaxItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"vpc": {
+							Type:     schema.TypeString,
+							Required: true,
+						},
+						"subnet": {
+							Type:     schema.TypeString,
+							Required: true,
+						},
+					},
+				},
+			},
+			"container_network": {
+				Type:     schema.TypeList,
+				Required: true,
+				MaxItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"mode": {
+							Type:     schema.TypeString,
+							Required: true,
+						},
+					},
+				},
+			},
+			"alias": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Computed: true,
+			},
+			"annotations": {
+				Type:     schema.TypeMap,
+				Optional: true,
+				Computed: true,
+				Elem:     &schema.Schema{Type: schema.TypeString},
+			},
+			"category": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Computed: true,
+			},
+			"type": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Computed: true,
+			},
+			"version": {
+				Type:             schema.TypeString,
+				Optional:         true,
+				Computed:         true,
+				DiffSuppressFunc: utils.SuppressVersionDiffs,
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"custom_san": {
+				Type:     schema.TypeList,
+				Elem:     &schema.Schema{Type: schema.TypeString},
+				Optional: true,
+				Computed: true,
+			},
+			"enable_snat": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				Computed: true,
+			},
+			"enable_swr_image_access": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				Computed: true,
+			},
+			"enable_autopilot": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				Default:  true,
+			},
+			"ipv6_enable": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				Computed: true,
+			},
+			"eni_network": {
+				Type:     schema.TypeList,
+				Optional: true,
+				Computed: true,
+				MaxItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"subnets": {
+							Type:     schema.TypeList,
+							Required: true,
+							Elem: &schema.Resource{
+								Schema: map[string]*schema.Schema{
+									"subnet_id": {
+										Type:     schema.TypeString,
+										Required: true,
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+			"service_network": {
+				Type:     schema.TypeList,
+				Optional: true,
+				Computed: true,
+				MaxItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"ipv4_cidr": {
+							Type:     schema.TypeString,
+							Optional: true,
+							Computed: true,
+						},
+					},
+				},
+			},
+			"authentication": {
+				Type:     schema.TypeList,
+				Optional: true,
+				Computed: true,
+				MaxItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"mode": {
+							Type:     schema.TypeString,
+							Optional: true,
+							Computed: true,
+						},
+					},
+				},
+			},
+			"tags": common.TagsSchema(),
+			"kube_proxy_mode": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Computed: true,
+			},
+			"extend_param": {
+				Type:     schema.TypeList,
+				Optional: true,
+				Computed: true,
+				MaxItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"enterprise_project_id": {
+							Type:     schema.TypeString,
+							Optional: true,
+							Computed: true,
+						},
+					},
+				},
+			},
+			"configurations_override": {
+				Type:     schema.TypeList,
+				Optional: true,
+				Computed: true,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"name": {
+							Type:     schema.TypeString,
+							Optional: true,
+							Computed: true,
+						},
+						"configurations": {
+							Type:     schema.TypeList,
+							Optional: true,
+							Computed: true,
+							Elem: &schema.Resource{
+								Schema: map[string]*schema.Schema{
+									"name": {
+										Type:     schema.TypeString,
+										Optional: true,
+										Computed: true,
+									},
+									"value": {
+										Type:     schema.TypeString,
+										Optional: true,
+										Computed: true,
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+			"deletion_protection": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				Computed: true,
+			},
+			"delete_efs": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"delete_eni": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"delete_net": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"delete_obs": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"delete_sfs30": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"lts_reclaim_policy": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"platform_version": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"created_at": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"updated_at": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"az": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"status": {
+				Type:     schema.TypeList,
+				Computed: true,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"phase": {
+							Type:     schema.TypeString,
+							Computed: true,
+						},
+						"endpoints": {
+							Type:     schema.TypeList,
+							Computed: true,
+							Elem: &schema.Resource{
+								Schema: map[string]*schema.Schema{
+									"url": {
+										Type:     schema.TypeString,
+										Computed: true,
+									},
+									"type": {
+										Type:     schema.TypeString,
+										Computed: true,
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func buildClusterBodyParams(d *schema.ResourceData) map[string]interface{} {
+	bodyParams := map[string]interface{}{
+		"kind":       "Cluster",
+		"apiVersion": "v3",
+		"metadata":   buildMetadataBodyParams(d),
+		"spec":       buildSpecBodyParams(d),
+	}
+
+	return bodyParams
+}
+
+func buildMetadataBodyParams(d *schema.ResourceData) map[string]interface{} {
+	bodyParams := map[string]interface{}{
+		"name":        d.Get("name"),
+		"alias":       utils.ValueIgnoreEmpty(d.Get("alias")),
+		"annotations": utils.ValueIgnoreEmpty(d.Get("annotations")),
+	}
+
+	return bodyParams
+}
+
+func buildSpecBodyParams(d *schema.ResourceData) map[string]interface{} {
+	bodyParams := map[string]interface{}{
+		"category":               utils.ValueIgnoreEmpty(d.Get("category")),
+		"type":                   utils.ValueIgnoreEmpty(d.Get("type")),
+		"flavor":                 d.Get("flavor"),
+		"description":            utils.ValueIgnoreEmpty(d.Get("description")),
+		"customSan":              utils.ValueIgnoreEmpty(d.Get("custom_san")),
+		"enableSnat":             d.Get("enable_snat"),
+		"enableSWRImageAccess":   d.Get("enable_swr_image_access"),
+		"enableAutopilot":        d.Get("enable_autopilot"),
+		"ipv6enable":             d.Get("ipv6_enable"),
+		"hostNetwork":            buildHostNetworkBodyParams(d),
+		"containerNetwork":       buildContainerNetworkBodyParams(d),
+		"eniNetwork":             buildEniNetworkBodyParams(d),
+		"serviceNetwork":         buildServiceNetworkBodyParams(d),
+		"authentication":         buildAuthenticationBodyParams(d),
+		"clusterTags":            utils.ExpandResourceTagsMap(d.Get("tags").(map[string]interface{})),
+		"kubeProxyMode":          utils.ValueIgnoreEmpty(d.Get("kube_proxy_mode")),
+		"extendParam":            buildExtendParamBodyParams(d),
+		"configurationsOverride": buildConfigurationsOverrideBodyParams(d),
+		"deleteProtection":       d.Get("delete_protection"),
+	}
+
+	return bodyParams
+}
+
+func buildHostNetworkBodyParams(d *schema.ResourceData) map[string]interface{} {
+	hostNetwork := d.Get("host_network").([]interface{})
+	if len(hostNetwork) == 0 {
+		return nil
+	}
+
+	bodyParams := map[string]interface{}{
+		"vpc":    utils.PathSearch("vpc", hostNetwork[0], nil),
+		"subnet": utils.PathSearch("subnet", hostNetwork[0], nil),
+	}
+
+	return bodyParams
+}
+
+func buildContainerNetworkBodyParams(d *schema.ResourceData) map[string]interface{} {
+	containerNetwork := d.Get("container_network").([]interface{})
+	if len(containerNetwork) == 0 {
+		return nil
+	}
+
+	bodyParams := map[string]interface{}{
+		"mode": utils.PathSearch("mode", containerNetwork[0], nil),
+	}
+
+	return bodyParams
+}
+
+func buildEniNetworkBodyParams(d *schema.ResourceData) map[string]interface{} {
+	eniNetwork := d.Get("eni_network").([]interface{})
+	if len(eniNetwork) == 0 {
+		return nil
+	}
+
+	subnetsRaw := utils.PathSearch("subnets", eniNetwork[0], []interface{}{}).([]interface{})
+	subnets := make([]map[string]interface{}, len(subnetsRaw))
+	for i, v := range subnetsRaw {
+		subnets[i] = map[string]interface{}{
+			"subnetID": utils.PathSearch("subnet_id", v, nil),
+		}
+	}
+
+	bodyParams := map[string]interface{}{
+		"subnets": subnets,
+	}
+
+	return bodyParams
+}
+
+func buildServiceNetworkBodyParams(d *schema.ResourceData) map[string]interface{} {
+	serviceNetwork := d.Get("service_network").([]interface{})
+	if len(serviceNetwork) == 0 {
+		return nil
+	}
+
+	bodyParams := map[string]interface{}{
+		"IPv4CIDR": utils.PathSearch("ipv4_cidr", serviceNetwork[0], nil),
+	}
+
+	return bodyParams
+}
+
+func buildAuthenticationBodyParams(d *schema.ResourceData) map[string]interface{} {
+	authentication := d.Get("authentication").([]interface{})
+	if len(authentication) == 0 {
+		return nil
+	}
+
+	bodyParams := map[string]interface{}{
+		"mode": utils.PathSearch("mode", authentication[0], nil),
+	}
+
+	return bodyParams
+}
+
+func buildExtendParamBodyParams(d *schema.ResourceData) map[string]interface{} {
+	extendParam := d.Get("extend_param").([]interface{})
+	if len(extendParam) == 0 {
+		return nil
+	}
+
+	bodyParams := map[string]interface{}{
+		"enterpriseProjectId": utils.PathSearch("enterprise_project_id", extendParam[0], nil),
+	}
+
+	return bodyParams
+}
+
+func buildConfigurationsOverrideBodyParams(d *schema.ResourceData) []map[string]interface{} {
+	configurationsOverrideRaw := d.Get("configurations_override").([]interface{})
+	if len(configurationsOverrideRaw) == 0 {
+		return nil
+	}
+
+	bodyParams := make([]map[string]interface{}, len(configurationsOverrideRaw))
+
+	for i, v := range configurationsOverrideRaw {
+		bodyParams[i] = map[string]interface{}{
+			"name":           utils.PathSearch("name", v, nil),
+			"configurations": buildConfigurationsBodyParams(v),
+		}
+	}
+
+	return bodyParams
+}
+
+func buildConfigurationsBodyParams(configurationsOverride interface{}) []map[string]interface{} {
+	configurationsRaw := utils.PathSearch("configurations", configurationsOverride, []interface{}{}).([]interface{})
+	if len(configurationsRaw) == 0 {
+		return nil
+	}
+
+	bodyParams := make([]map[string]interface{}, len(configurationsRaw))
+
+	for i, v := range configurationsRaw {
+		bodyParams[i] = map[string]interface{}{
+			"name":  utils.PathSearch("name", v, nil),
+			"value": utils.PathSearch("value", v, nil),
+		}
+	}
+
+	return bodyParams
+}
+
+func resourceAutopilotClusterCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	cfg := meta.(*config.Config)
+	region := cfg.GetRegion(d)
+
+	var (
+		createClusterHttpUrl = "autopilot/v3/projects/{project_id}/clusters"
+		createClusterProduct = "cce"
+	)
+	createClusterClient, err := cfg.NewServiceClient(createClusterProduct, region)
+	if err != nil {
+		return diag.Errorf("error creating CCE Client: %s", err)
+	}
+
+	createClusterPath := createClusterClient.Endpoint + createClusterHttpUrl
+	createClusterPath = strings.ReplaceAll(createClusterPath, "{project_id}", createClusterClient.ProjectID)
+
+	createClusterOpt := golangsdk.RequestOpts{
+		KeepResponseBody: true,
+	}
+
+	createOpts := buildClusterBodyParams(d)
+	createClusterOpt.JSONBody = utils.RemoveNil(createOpts)
+	createClusterResp, err := createClusterClient.Request("POST", createClusterPath, &createClusterOpt)
+	if err != nil {
+		return diag.Errorf("error creating CCE autopolit cluster: %s", err)
+	}
+
+	createClusterRespBody, err := utils.FlattenResponse(createClusterResp)
+	if err != nil {
+		return diag.FromErr(err)
+	}
+
+	id := utils.PathSearch("metadata.uid", createClusterRespBody, "").(string)
+	if id == "" {
+		return diag.Errorf("error creating CCE autopilot cluster: ID is not found in API response")
+	}
+	d.SetId(id)
+
+	jobID := utils.PathSearch("status.jobID", createClusterRespBody, "").(string)
+	if jobID == "" {
+		return diag.Errorf("error creating CCE autopilot cluster: jobID is not found in API response")
+	}
+
+	err = clusterJobWaitingForStateCompleted(ctx, d, meta, d.Timeout(schema.TimeoutCreate), jobID)
+	if err != nil {
+		return diag.Errorf("error waiting for creating CCE autopilot cluster (%s) to complete: %s", id, err)
+	}
+
+	return resourceAutopilotClusterRead(ctx, d, meta)
+}
+
+func resourceAutopilotClusterRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	cfg := meta.(*config.Config)
+	region := cfg.GetRegion(d)
+
+	var (
+		getClusterHttpUrl = "autopilot/v3/projects/{project_id}/clusters/{cluster_id}"
+		getClusterProduct = "cce"
+	)
+	getClusterClient, err := cfg.NewServiceClient(getClusterProduct, region)
+	if err != nil {
+		return diag.Errorf("error creating CCE Client: %s", err)
+	}
+
+	getClusterPath := getClusterClient.Endpoint + getClusterHttpUrl
+	getClusterPath = strings.ReplaceAll(getClusterPath, "{project_id}", getClusterClient.ProjectID)
+	getClusterPath = strings.ReplaceAll(getClusterPath, "{cluster_id}", d.Id())
+
+	getClusterOpt := golangsdk.RequestOpts{
+		KeepResponseBody: true,
+	}
+
+	getClusterResp, err := getClusterClient.Request("GET", getClusterPath, &getClusterOpt)
+	if err != nil {
+		return common.CheckDeletedDiag(d, err, "error retrieving CCE autopolit cluster")
+	}
+
+	getClusterRespBody, err := utils.FlattenResponse(getClusterResp)
+	if err != nil {
+		return diag.FromErr(err)
+	}
+
+	mErr := multierror.Append(nil,
+		d.Set("region", cfg.GetRegion(d)),
+		d.Set("name", utils.PathSearch("metadata.name", getClusterRespBody, nil)),
+		d.Set("alias", utils.PathSearch("metadata.alias", getClusterRespBody, nil)),
+		d.Set("annotations", utils.PathSearch("metadata.annotations", getClusterRespBody, nil)),
+		d.Set("category", utils.PathSearch("spec.category", getClusterRespBody, nil)),
+		d.Set("type", utils.PathSearch("spec.type", getClusterRespBody, nil)),
+		d.Set("flavor", utils.PathSearch("spec.flavor", getClusterRespBody, nil)),
+		d.Set("version", utils.PathSearch("spec.version", getClusterRespBody, nil)),
+		d.Set("description", utils.PathSearch("spec.description", getClusterRespBody, nil)),
+		d.Set("custom_san", utils.PathSearch("spec.customSan", getClusterRespBody, nil)),
+		d.Set("enable_snat", utils.PathSearch("spec.enableSnat", getClusterRespBody, nil)),
+		d.Set("enable_swr_image_access", utils.PathSearch("spec.enableSWRImageAccess", getClusterRespBody, nil)),
+		d.Set("enable_autopilot", utils.PathSearch("spec.enableAutopilot", getClusterRespBody, nil)),
+		d.Set("ipv6_enable", utils.PathSearch("spec.ipv6enable", getClusterRespBody, nil)),
+		d.Set("host_network", flattenHostNetwork(getClusterRespBody)),
+		d.Set("container_network", flattenContainerNetwork(getClusterRespBody)),
+		d.Set("eni_network", flattenEniNetwork(getClusterRespBody)),
+		d.Set("service_network", flattenServiceNetwork(getClusterRespBody)),
+		d.Set("authentication", flattenAuthentication(getClusterRespBody)),
+		d.Set("tags", utils.FlattenTagsToMap(utils.PathSearch("spec.clusterTags", getClusterRespBody, nil))),
+		d.Set("kube_proxy_mode", utils.PathSearch("spec.kubeProxyMode", getClusterRespBody, nil)),
+		d.Set("az", utils.PathSearch("spec.az", getClusterRespBody, nil)),
+		d.Set("extend_param", flattenExtendParam(getClusterRespBody)),
+		d.Set("configurations_override", flattenConfigurationsOverride(getClusterRespBody)),
+		d.Set("deletion_protection", utils.PathSearch("spec.deletionProtection", getClusterRespBody, nil)),
+		d.Set("platform_version", utils.PathSearch("spec.platformVersion", getClusterRespBody, nil)),
+		d.Set("created_at", utils.PathSearch("metadata.creationTimestamp", getClusterRespBody, nil)),
+		d.Set("updated_at", utils.PathSearch("metadata.updateTimestamp", getClusterRespBody, nil)),
+		d.Set("status", flattenStatus(getClusterRespBody)),
+	)
+
+	return diag.FromErr(mErr.ErrorOrNil())
+}
+
+func flattenHostNetwork(getClusterRespBody interface{}) []map[string]interface{} {
+	hostNetwork := utils.PathSearch("spec.hostNetwork", getClusterRespBody, nil)
+	if hostNetwork == nil {
+		return nil
+	}
+
+	res := []map[string]interface{}{
+		{
+			"vpc":    utils.PathSearch("vpc", hostNetwork, nil),
+			"subnet": utils.PathSearch("subnet", hostNetwork, nil),
+		},
+	}
+
+	return res
+}
+
+func flattenContainerNetwork(getClusterRespBody interface{}) []map[string]interface{} {
+	containerNetwork := utils.PathSearch("spec.containerNetwork", getClusterRespBody, nil)
+	if containerNetwork == nil {
+		return nil
+	}
+
+	res := []map[string]interface{}{
+		{
+			"mode": utils.PathSearch("mode", containerNetwork, nil),
+		},
+	}
+
+	return res
+}
+
+func flattenEniNetwork(getClusterRespBody interface{}) []map[string]interface{} {
+	eniNetwork := utils.PathSearch("spec.eniNetwork", getClusterRespBody, nil)
+	if eniNetwork == nil {
+		return nil
+	}
+
+	subnetsRaw := utils.PathSearch("subnets", eniNetwork, []interface{}{}).([]interface{})
+	subnets := make([]map[string]interface{}, len(subnetsRaw))
+	for i, v := range subnetsRaw {
+		subnets[i] = map[string]interface{}{
+			"subnet_id": utils.PathSearch("subnetID", v, nil),
+		}
+	}
+
+	res := []map[string]interface{}{
+		{
+			"subnets": subnets,
+		},
+	}
+
+	return res
+}
+
+func flattenServiceNetwork(getClusterRespBody interface{}) []map[string]interface{} {
+	serviceNetwork := utils.PathSearch("spec.serviceNetwork", getClusterRespBody, nil)
+	if serviceNetwork == nil {
+		return nil
+	}
+
+	res := []map[string]interface{}{
+		{
+			"ipv4_cidr": utils.PathSearch("IPv4CIDR", serviceNetwork, nil),
+		},
+	}
+
+	return res
+}
+
+func flattenAuthentication(getClusterRespBody interface{}) []map[string]interface{} {
+	authentication := utils.PathSearch("spec.authentication", getClusterRespBody, nil)
+	if authentication == nil {
+		return nil
+	}
+
+	res := []map[string]interface{}{
+		{
+			"mode": utils.PathSearch("mode", authentication, nil),
+		},
+	}
+
+	return res
+}
+
+func flattenExtendParam(getClusterRespBody interface{}) []map[string]interface{} {
+	extendParam := utils.PathSearch("spec.extendParam", getClusterRespBody, nil)
+	if extendParam == nil {
+		return nil
+	}
+
+	res := []map[string]interface{}{
+		{
+			"enterprise_project_id": utils.PathSearch("enterpriseProjectId", extendParam, nil),
+		},
+	}
+
+	return res
+}
+
+func flattenConfigurationsOverride(getClusterRespBody interface{}) []map[string]interface{} {
+	configurationsOverrideRaw := utils.PathSearch("spec.configurationsOverride", getClusterRespBody, []interface{}{}).([]interface{})
+	if len(configurationsOverrideRaw) == 0 {
+		return nil
+	}
+
+	res := make([]map[string]interface{}, len(configurationsOverrideRaw))
+	for i, v := range configurationsOverrideRaw {
+		res[i] = map[string]interface{}{
+			"name":           utils.PathSearch("name", v, nil),
+			"configurations": flattenConfigurations(v),
+		}
+	}
+
+	return res
+}
+
+func flattenConfigurations(configurationsOverride interface{}) []map[string]interface{} {
+	configurationsRaw := utils.PathSearch("configurations", configurationsOverride, []interface{}{}).([]interface{})
+	if len(configurationsRaw) == 0 {
+		return nil
+	}
+
+	res := make([]map[string]interface{}, len(configurationsRaw))
+	for i, v := range configurationsRaw {
+		res[i] = map[string]interface{}{
+			"name":  utils.PathSearch("name", v, nil),
+			"value": utils.PathSearch("value", v, nil),
+		}
+	}
+
+	return res
+}
+
+func flattenStatus(getClusterRespBody interface{}) []map[string]interface{} {
+	status := utils.PathSearch("status", getClusterRespBody, nil)
+	if status == nil {
+		return nil
+	}
+
+	endpointsRaw := utils.PathSearch("endpoints", status, []interface{}{}).([]interface{})
+	endpoints := make([]map[string]interface{}, len(endpointsRaw))
+	for i, v := range endpointsRaw {
+		endpoints[i] = map[string]interface{}{
+			"url":  utils.PathSearch("url", v, nil),
+			"type": utils.PathSearch("type", v, nil),
+		}
+	}
+
+	res := []map[string]interface{}{
+		{
+			"endpoints": endpoints,
+			"phase":     utils.PathSearch("phase", status, nil),
+		},
+	}
+
+	return res
+}
+
+func resourceAutopilotClusterUpdate(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
+	return nil
+}
+
+func resourceAutopilotClusterDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	cfg := meta.(*config.Config)
+	region := cfg.GetRegion(d)
+
+	var (
+		deleteClusterHttpUrl = "autopilot/v3/projects/{project_id}/clusters/{cluster_id}"
+		deleteClusterProduct = "cce"
+	)
+	deleteClusterClient, err := cfg.NewServiceClient(deleteClusterProduct, region)
+	if err != nil {
+		return diag.Errorf("error creating CCE Client: %s", err)
+	}
+
+	deleteClusterPath := deleteClusterClient.Endpoint + deleteClusterHttpUrl
+	deleteClusterPath = strings.ReplaceAll(deleteClusterPath, "{project_id}", deleteClusterClient.ProjectID)
+	deleteClusterPath = strings.ReplaceAll(deleteClusterPath, "{cluster_id}", d.Id())
+
+	deleteClusterOpt := golangsdk.RequestOpts{
+		KeepResponseBody: true,
+	}
+
+	deleteClusteQueryParams := buildDeleteClusteQueryParams(d)
+	deleteClusterPath += deleteClusteQueryParams
+
+	deleteClusterResp, err := deleteClusterClient.Request("DELETE", deleteClusterPath, &deleteClusterOpt)
+	if err != nil {
+		return common.CheckDeletedDiag(d, err, "error deleting CCE autopolit cluster")
+	}
+
+	deleteClusterRespBody, err := utils.FlattenResponse(deleteClusterResp)
+	if err != nil {
+		return diag.FromErr(err)
+	}
+
+	jobID := utils.PathSearch("status.jobID", deleteClusterRespBody, "").(string)
+	if jobID == "" {
+		return diag.Errorf("error deleting CCE autopilot cluster: jobID is not found in API response")
+	}
+
+	err = clusterJobWaitingForStateCompleted(ctx, d, meta, d.Timeout(schema.TimeoutDelete), jobID)
+	if err != nil {
+		return diag.Errorf("error waiting for deleting CCE autopilot cluster (%s) to complete: %s", d.Id(), err)
+	}
+
+	return nil
+}
+
+func buildDeleteClusteQueryParams(d *schema.ResourceData) string {
+	res := ""
+
+	if v, ok := d.GetOk("delete_efs"); ok {
+		res = fmt.Sprintf("%s&delete_efs=%v", res, v)
+	}
+	if v, ok := d.GetOk("delete_eni"); ok {
+		res = fmt.Sprintf("%s&delete_eni=%v", res, v)
+	}
+	if v, ok := d.GetOk("delete_net"); ok {
+		res = fmt.Sprintf("%s&delete_net=%v", res, v)
+	}
+	if v, ok := d.GetOk("delete_obs"); ok {
+		res = fmt.Sprintf("%s&delete_obs=%v", res, v)
+	}
+	if v, ok := d.GetOk("delete_sfs30"); ok {
+		res = fmt.Sprintf("%s&delete_sfs30=%v", res, v)
+	}
+	if v, ok := d.GetOk("lts_reclaim_policy"); ok {
+		res = fmt.Sprintf("%s&lts_reclaim_policy=%v", res, v)
+	}
+
+	if res != "" {
+		res = "?" + res[1:]
+	}
+
+	return res
+}
+
+func clusterJobWaitingForStateCompleted(ctx context.Context, d *schema.ResourceData, meta interface{}, t time.Duration, jobID string) error {
+	stateConf := &resource.StateChangeConf{
+		Pending: []string{"PENDING"},
+		Target:  []string{"COMPLETED"},
+		Refresh: func() (interface{}, string, error) {
+			cfg := meta.(*config.Config)
+			region := cfg.GetRegion(d)
+			var (
+				clusterJobWaitingHttpUrl = "autopilot/v3/projects/{project_id}/jobs/{job_id}"
+				clusterJobWaitingProduct = "cce"
+			)
+			clusterJobWaitingClient, err := cfg.NewServiceClient(clusterJobWaitingProduct, region)
+			if err != nil {
+				return nil, "ERROR", fmt.Errorf("error creating CCE client: %s", err)
+			}
+
+			clusterJobWaitingPath := clusterJobWaitingClient.Endpoint + clusterJobWaitingHttpUrl
+			clusterJobWaitingPath = strings.ReplaceAll(clusterJobWaitingPath, "{project_id}", clusterJobWaitingClient.ProjectID)
+			clusterJobWaitingPath = strings.ReplaceAll(clusterJobWaitingPath, "{job_id}", jobID)
+
+			clusterJobWaitingOpt := golangsdk.RequestOpts{
+				KeepResponseBody: true,
+			}
+			clusterJobWaitingResp, err := clusterJobWaitingClient.Request("GET", clusterJobWaitingPath, &clusterJobWaitingOpt)
+			if err != nil {
+				return nil, "ERROR", err
+			}
+
+			clusterJobWaitingRespBody, err := utils.FlattenResponse(clusterJobWaitingResp)
+			if err != nil {
+				return nil, "ERROR", err
+			}
+			status := utils.PathSearch(`status.phase`, clusterJobWaitingRespBody, nil)
+			if status == nil {
+				return nil, "ERROR", fmt.Errorf("error parsing %s from response body", `status.phase`)
+			}
+
+			targetStatus := []string{
+				"Success",
+			}
+			if utils.StrSliceContains(targetStatus, status.(string)) {
+				return clusterJobWaitingRespBody, "COMPLETED", nil
+			}
+
+			unexpectedStatus := []string{
+				"Failed",
+			}
+			if utils.StrSliceContains(unexpectedStatus, status.(string)) {
+				return clusterJobWaitingRespBody, status.(string), nil
+			}
+
+			return clusterJobWaitingRespBody, "PENDING", nil
+		},
+		Timeout:      t,
+		Delay:        10 * time.Second,
+		PollInterval: 5 * time.Second,
+	}
+	_, err := stateConf.WaitForStateContext(ctx)
+	return err
+}