diff --git a/alicloud/resource_alicloud_instance.go b/alicloud/resource_alicloud_instance.go index d11d18cf9852..d713b7594a35 100644 --- a/alicloud/resource_alicloud_instance.go +++ b/alicloud/resource_alicloud_instance.go @@ -755,6 +755,21 @@ func resourceAliCloudInstance() *schema.Resource { Computed: true, Removed: "Field `io_optimized` has been removed from provider version 1.213.1.", }, + "security_options": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "confidential_computing_mode": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: StringInSlice([]string{"TDX", "Enclave"}, false), + }, + }, + }, + }, }, } } @@ -1219,6 +1234,18 @@ func resourceAliCloudInstanceCreate(d *schema.ResourceData, meta interface{}) er request["CpuOptions.TopologyType"] = topologyType } + if v, ok := d.GetOk("security_options"); ok { + if securityOptionsList, ok := v.([]interface{}); ok { + for _, raw := range securityOptionsList { + if securityOptionsArg, ok := raw.(map[string]interface{}); ok { + if v, ok := securityOptionsArg["confidential_computing_mode"]; ok { + request["SecurityOptions.ConfidentialComputingMode"] = v + } + } + } + } + } + wait := incrementalWait(1*time.Second, 1*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { response, err = client.RpcPost("Ecs", "2014-05-26", action, nil, request, false) diff --git a/alicloud/resource_alicloud_instance_test.go b/alicloud/resource_alicloud_instance_test.go index d634cbc1129a..e927db4a006c 100644 --- a/alicloud/resource_alicloud_instance_test.go +++ b/alicloud/resource_alicloud_instance_test.go @@ -4770,3 +4770,145 @@ var tags0 = map[string]string{ "tagY": "valueY", "tagZ": "valueZ", } + +func TestAccAliCloudECSInstanceSecurityOptions(t *testing.T) { + var v ecs.Instance + resourceId := "alicloud_instance.default" + ra := resourceAttrInit(resourceId, testAccInstanceCheckMap) + serviceFunc := func() interface{} { + return &EcsService{testAccProvider.Meta().(*connectivity.AliyunClient)} + } + rc := resourceCheckInit(resourceId, &v, serviceFunc) + rac := resourceAttrCheckInit(rc, ra) + + rand := acctest.RandIntRange(1000, 9999) + testAccCheck := rac.resourceAttrMapUpdateSet() + name := fmt.Sprintf("tf-testAccEcsInstanceSecurityOptions%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, resourceInstanceSecurityOptionsConfigDependence) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "image_id": "${data.alicloud_images.default.images.0.id}", + "security_groups": []string{"${alicloud_security_group.default.0.id}"}, + "instance_type": "${data.alicloud_instance_types.default.instance_types.0.id}", + "availability_zone": "${data.alicloud_instance_types.default.instance_types.0.availability_zones.0}", + "system_disk_category": "cloud_efficiency", + "instance_name": "${var.name}", + "vswitch_id": "${alicloud_vswitch.default.id}", + "security_options": []map[string]interface{}{ + { + "confidential_computing_mode": "TDX", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_name": name, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"security_enhancement_strategy", "dry_run"}, + }, + }, + }) +} + +func TestAccAliCloudECSInstanceSecurityOptionsEnclave(t *testing.T) { + var v ecs.Instance + resourceId := "alicloud_instance.default" + ra := resourceAttrInit(resourceId, testAccInstanceCheckMap) + serviceFunc := func() interface{} { + return &EcsService{testAccProvider.Meta().(*connectivity.AliyunClient)} + } + rc := resourceCheckInit(resourceId, &v, serviceFunc) + rac := resourceAttrCheckInit(rc, ra) + + rand := acctest.RandIntRange(1000, 9999) + testAccCheck := rac.resourceAttrMapUpdateSet() + name := fmt.Sprintf("tf-testAccEcsInstanceSecurityOptionsEnclave%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, resourceInstanceSecurityOptionsConfigDependence) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "image_id": "${data.alicloud_images.default.images.0.id}", + "security_groups": []string{"${alicloud_security_group.default.0.id}"}, + "instance_type": "${data.alicloud_instance_types.default.instance_types.0.id}", + "availability_zone": "${data.alicloud_instance_types.default.instance_types.0.availability_zones.0}", + "system_disk_category": "cloud_efficiency", + "instance_name": "${var.name}", + "vswitch_id": "${alicloud_vswitch.default.id}", + "security_options": []map[string]interface{}{ + { + "confidential_computing_mode": "Enclave", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_name": name, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"security_enhancement_strategy", "dry_run"}, + }, + }, + }) +} + +func resourceInstanceSecurityOptionsConfigDependence(name string) string { + return fmt.Sprintf(` +data "alicloud_instance_types" "default" { + instance_type_family = "ecs.gn7i-c8g1.2xlarge" +} + +data "alicloud_images" "default" { + name_regex = "^ubuntu_[0-9]+_[0-9]+_x64*" + most_recent = true + owners = "system" +} + +resource "alicloud_vpc" "default" { + vpc_name = var.name + cidr_block = "172.16.0.0/16" +} + +resource "alicloud_vswitch" "default" { + vpc_id = alicloud_vpc.default.id + zone_id = data.alicloud_instance_types.default.instance_types.0.availability_zones.0 + cidr_block = cidrsubnet(alicloud_vpc.default.cidr_block, 8, 8) + vswitch_name = var.name +} + +resource "alicloud_security_group" "default" { + count = "1" + name = "${var.name}" + vpc_id = alicloud_vpc.default.id +} + +variable "name" { + default = "%s" +} +`, name) +} diff --git a/website/docs/r/instance.html.markdown b/website/docs/r/instance.html.markdown index 7743dddbad08..02c5cfc791d3 100644 --- a/website/docs/r/instance.html.markdown +++ b/website/docs/r/instance.html.markdown @@ -252,6 +252,7 @@ The following arguments are supported: * `image_options` - (Optional, Set, Available since v1.237.0) The options of images. See [`image_options`](#image_options) below. * `cpu_options` - (Optional, Set, Available since v1.267.0) The options of cpu. See [`cpu_options`](#cpu_options) below. +* `security_options` - (Optional) The security options of the instance. See [`security_options`](#security_options) below. * `allocate_public_ip` - (Optional, Bool, Deprecated since v1.7.0) Field `allocate_public_ip` has been deprecated from provider version 1.7.0. Setting `internet_max_bandwidth_out` larger than 0 will allocate public ip for instance. * `internet_max_bandwidth_in` - (Optional, Int, Deprecated since v1.121.2) Maximum incoming bandwidth from the public network, measured in Mbps (Mega bit per second). Value range: [1, 200]. If this value is not specified, then automatically sets it to 200 Mbps. * `role_name` - (Optional, Deprecated since v1.275.0) The name of the Resource Access Management (RAM) role. **NOTE:** From version 1.250.0, If you want to use `role_name`, We recommend you to use the resource [alicloud_ecs_ram_role_attachment](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_ram_role_attachment). Field `role_name` has been deprecated from provider version 1.275.0. New resource [alicloud_ecs_ram_role_attachment](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_ram_role_attachment) instead. From version 1.276.0, `role_name` can be modified. @@ -344,6 +345,14 @@ The cpu_options supports the following: * `threads_per_core` - (Optional, Int) The number of threads per CPU core. * `topology_type` - (Optional) The CPU topology type of the instance. Valid values: `ContinuousCoreToHTMapping`, `DiscreteCoreToHTMapping`. +### `security_options` + +The security_options supports the following: + +* `confidential_computing_mode` - (Optional, ForceNew) The confidential computing mode of the instance. Valid values: `TDX`, `Enclave`. + - `TDX`: Enable Intel TDX confidential computing mode. + - `Enclave`: Use Enclave to build confidential computing environment. + ## Attributes Reference The following attributes are exported: