diff --git a/internal/services/batch/batch_pool.go b/internal/services/batch/batch_pool.go index f9c2103cf513..6970e1a460da 100644 --- a/internal/services/batch/batch_pool.go +++ b/internal/services/batch/batch_pool.go @@ -411,6 +411,22 @@ func flattenBatchPoolIdentityReferenceToIdentityID(ref *pool.ComputeNodeIdentity return "" } +func flattenBatchPoolSecurityProfile(configProfile *pool.SecurityProfile) []interface{} { + securityProfile := make([]interface{}, 0) + securityConfig := make(map[string]interface{}) + + securityConfig["host_encryption_enabled"] = pointer.From(configProfile.EncryptionAtHost) + securityConfig["security_type"] = string(pointer.From(configProfile.SecurityType)) + + if configProfile.UefiSettings != nil { + securityConfig["secure_boot_enabled"] = pointer.From(configProfile.UefiSettings.SecureBootEnabled) + securityConfig["vtpm_enabled"] = pointer.From(configProfile.UefiSettings.VTpmEnabled) + } + + securityProfile = append(securityProfile, securityConfig) + return securityProfile +} + func flattenBatchPoolUserAccount(d *pluginsdk.ResourceData, account *pool.UserAccount) map[string]interface{} { userAccount := make(map[string]interface{}) userAccount["name"] = account.Name @@ -791,6 +807,10 @@ func expandBatchPoolVirtualMachineConfig(d *pluginsdk.ResourceData) (*pool.Virtu result.OsDisk = expandBatchPoolOSDisk(v) } + if v, ok := d.GetOk("security_profile"); ok { + result.SecurityProfile = expandBatchPoolSecurityProfile(v.([]interface{})) + } + if v, ok := d.GetOk("windows"); ok { result.WindowsConfiguration = expandBatchPoolWindowsConfiguration(v.([]interface{})) } @@ -798,6 +818,35 @@ func expandBatchPoolVirtualMachineConfig(d *pluginsdk.ResourceData) (*pool.Virtu return &result, nil } +func expandBatchPoolSecurityProfile(profile []interface{}) *pool.SecurityProfile { + if len(profile) == 0 { + return nil + } + + item := profile[0].(map[string]interface{}) + securityProfile := &pool.SecurityProfile{ + UefiSettings: &pool.UefiSettings{}, + } + + if v, ok := item["host_encryption_enabled"]; ok { + securityProfile.EncryptionAtHost = pointer.To(v.(bool)) + } + + if v, ok := item["security_type"]; ok { + securityProfile.SecurityType = pointer.To(pool.SecurityTypes(v.(string))) + } + + if v, ok := item["secure_boot_enabled"]; ok { + securityProfile.UefiSettings.SecureBootEnabled = pointer.To(v.(bool)) + } + + if v, ok := item["vtpm_enabled"]; ok { + securityProfile.UefiSettings.VTpmEnabled = pointer.To(v.(bool)) + } + + return securityProfile +} + func expandBatchPoolOSDisk(ref interface{}) *pool.OSDisk { if ref == nil { return nil diff --git a/internal/services/batch/batch_pool_resource.go b/internal/services/batch/batch_pool_resource.go index fd2fcaef1890..6d479f908c79 100644 --- a/internal/services/batch/batch_pool_resource.go +++ b/internal/services/batch/batch_pool_resource.go @@ -724,6 +724,40 @@ func resourceBatchPool() *pluginsdk.Resource { }, false), }, + "security_profile": { + Type: pluginsdk.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "host_encryption_enabled": { + Type: pluginsdk.TypeBool, + ForceNew: true, + Optional: true, + }, + "security_type": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice(pool.PossibleValuesForSecurityTypes(), false), + }, + "secure_boot_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + RequiredWith: []string{"security_profile.0.security_type"}, + }, + "vtpm_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + RequiredWith: []string{"security_profile.0.security_type"}, + }, + }, + }, + }, + "target_node_communication_mode": { Type: pluginsdk.TypeString, Optional: true, @@ -1246,11 +1280,17 @@ func resourceBatchPoolRead(d *pluginsdk.ResourceData, meta interface{}) error { nodePlacementConfiguration = append(nodePlacementConfiguration, nodePlacementConfig) d.Set("node_placement", nodePlacementConfiguration) } + osDiskPlacement := "" if config.OsDisk != nil && config.OsDisk.EphemeralOSDiskSettings != nil && config.OsDisk.EphemeralOSDiskSettings.Placement != nil { osDiskPlacement = string(*config.OsDisk.EphemeralOSDiskSettings.Placement) } d.Set("os_disk_placement", osDiskPlacement) + + if config.SecurityProfile != nil { + d.Set("security_profile", flattenBatchPoolSecurityProfile(config.SecurityProfile)) + } + if config.WindowsConfiguration != nil { windowsConfig := []interface{}{ map[string]interface{}{ diff --git a/internal/services/batch/batch_pool_resource_test.go b/internal/services/batch/batch_pool_resource_test.go index 1b92c844db93..b8d3779ead11 100644 --- a/internal/services/batch/batch_pool_resource_test.go +++ b/internal/services/batch/batch_pool_resource_test.go @@ -740,6 +740,24 @@ func TestAccBatchPool_interNodeCommunicationWithTaskSchedulingPolicy(t *testing. }) } +func TestAccBatchPool_securityProfileWithUEFISettings(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_batch_pool", "test") + r := BatchPoolResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.securityProfileWithUEFISettings(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("security_profile.0.host_encryption_enabled").HasValue("false"), + check.That(data.ResourceName).Key("security_profile.0.security_type").HasValue("trustedLaunch"), + check.That(data.ResourceName).Key("security_profile.0.secure_boot_enabled").HasValue("true"), + check.That(data.ResourceName).Key("security_profile.0.vtpm_enabled").HasValue("false"), + ), + }, + data.ImportStep("stop_pending_resize_operation"), + }) +} + func TestAccBatchPool_linuxUserAccounts(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_batch_pool", "test") r := BatchPoolResource{} @@ -2653,3 +2671,37 @@ resource "azurerm_subnet_network_security_group_association" "test" { } `, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString, data.RandomString) } + +func (BatchPoolResource) securityProfileWithUEFISettings(data acceptance.TestData) string { + template := BatchPoolResource{}.template(data) + return fmt.Sprintf(` +%s +resource "azurerm_batch_account" "test" { + name = "acctestbatch%s" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location +} +resource "azurerm_batch_pool" "test" { + name = "acctestpool%s" + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_batch_account.test.name + node_agent_sku_id = "batch.node.ubuntu 22.04" + vm_size = "Standard_A1" + fixed_scale { + target_dedicated_nodes = 1 + } + security_profile { + host_encryption_enabled = false + security_type = "trustedLaunch" + secure_boot_enabled = true + vtpm_enabled = false + } + storage_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} +`, template, data.RandomString, data.RandomString) +} diff --git a/website/docs/r/batch_pool.html.markdown b/website/docs/r/batch_pool.html.markdown index 7b63efadd1a7..6f0bb340934d 100644 --- a/website/docs/r/batch_pool.html.markdown +++ b/website/docs/r/batch_pool.html.markdown @@ -165,6 +165,8 @@ The following arguments are supported: * `os_disk_placement` - (Optional) Specifies the ephemeral disk placement for operating system disk for all VMs in the pool. This property can be used by user in the request to choose which location the operating system should be in. e.g., cache disk space for Ephemeral OS disk provisioning. For more information on Ephemeral OS disk size requirements, please refer to Ephemeral OS disk size requirements for Windows VMs at and Linux VMs at . The only possible value is `CacheDisk`. +* `security_profile` - (Optional) A `security_profile` block that describes the security settings for the Batch pool as defined below. Changing this forces a new resource to be created. + * `target_node_communication_mode` - (Optional) The desired node communication mode for the pool. Possible values are `Classic`, `Default` and `Simplified`. * `task_scheduling_policy` - (Optional) A `task_scheduling_policy` block that describes how tasks are distributed across compute nodes in a pool as defined below. If not specified, the default is spread as defined below. @@ -502,6 +504,21 @@ A `task_scheduling_policy` block supports the following: * `node_fill_type` - (Optional) Supported values are "Pack" and "Spread". "Pack" means as many tasks as possible (taskSlotsPerNode) should be assigned to each node in the pool before any tasks are assigned to the next node in the pool. "Spread" means that tasks should be assigned evenly across all nodes in the pool. +--- +A `security_profile` block supports the following: + +* `host_encryption_enabled` - (Optional) Whether to enable host encryption for the Virtual Machine or Virtual Machine Scale Set. This will enable the encryption for all the disks including Resource/Temp disk at host itself. Possible values are `true` and `false`. Changing this forces a new resource to be created. + +* `security_type` - (Optional) The security type of the Virtual Machine. Possible values are `confidentialVM` and `trustedLaunch`. Changing this forces a new resource to be created. + +* `secure_boot_enabled` - (Optional) Whether to enable secure boot for the Virtual Machine or Virtual Machine Scale Set. Possible values are `true` and `false`. Changing this forces a new resource to be created. + +* `vtpm_enabled` - (Optional) Whether to enable virtual trusted platform module (vTPM) for the Virtual Machine or Virtual Machine Scale Set. Possible values are `true` and `false`. Changing this forces a new resource to be created. + +~> **NOTE:** `security_profile` block can only be specified during creation and does not support updates. + +~> **NOTE:** `security_type` must be specified to set UEFI related properties including `secure_boot_enabled` and `vtpm_enabled`. + --- A `user_accounts` block supports the following: