0

For a school project, we are currently trying to set up an AMD SEV confidential VM utilizing Terraform with Azure. However, we cannot find any documentation on how to create a confidential VM within this environment. Presumably, we should be able to achieve this by setting the security type to Confidential in the Terraform code. However, it is defaulting to a <NULL> value. Our goal is to find the argument responsible for setting this value.

Our 'main.tf' file looks like this:

# Create virtual machine
resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
  name                  = "ccAmdVM"
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
  size                  = "Standard_DC2as_v5"

  os_disk {
    name                     = "myOsDisk"
    caching                  = "ReadWrite"
    storage_account_type     = "StandardSSD_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-confidential-vm-focal"
    sku       = "20_04-lts-cvm"
    version   = "latest"
  }

However, when we tried to apply this code with Terraform, we got the following error:

│ Error: creating Linux Virtual Machine: (Name "ccAmdVM" / Resource Group "rg-gorgeous-lynx"): compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest" Message="The VM size 'Standard_DC2as_v5' is not supported for creation of VMs and Virtual Machine Scale Set with '<NULL>' security type."
│ 
│   with azurerm_linux_virtual_machine.my_terraform_vm,
│   on main.tf line 111, in resource "azurerm_linux_virtual_machine" "my_terraform_vm":
│  111: resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
│ 

A few sources suggested using the security_encryption_type argument with the value VMGuestStateOnly under the os_disk block, but this generated the following error:

╷
│ Error: Unsupported argument
│ 
│   on main.tf line 122, in resource "azurerm_linux_virtual_machine" "my_terraform_vm":
│  122:     security_encryption_type = "VMGuestStateOnly"
│ 
│ An argument named "security_encryption_type" is not expected here.

We tried to create a confidential VM using the Azure GUI, which was successful. Here it was possible to set security type to Standard, Trusted Launch Virtual Machines or Confidential Virtual Machines of which the latter value was used. After successfully creating the VM we could see that it was set to Confidential in the overview tab.

One would think the expected solution is fairly simple, e.g. by using the argument security_type with a value such as confidential. However, since confidential computing is a relatively new concept, there appears to be no answer or documentation on this anywhere.

Kabuto
  • 3
  • 3
  • AFAIK, Creating confidential VM is not yet supported by azurerm terraform resource provider as securityType: setting is not yet available, Refer here- https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine , Also, The configuration [`security_encryption_type`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine#security_encryption_type) Is part of **os_disk** and its just a mandatory to have Disk encryption enabled for the Confidential VM to work. – SiddheshDesai Mar 15 '23 at 05:56
  • As a workaround, you can make use of Portal, CLI or ARM template and then use Terraform to manage the confidential VM that is being created, If its fine for you I can provide you with the ARM Code – SiddheshDesai Mar 15 '23 at 05:57
  • Thank you for the response. That makes sense since we could not find anything in the Terraform documentation. Therefore, using an ARM template is something we considered already. We have looked at this documentation: https://learn.microsoft.com/en-us/azure/confidential-computing/quick-create-confidential-vm-arm-amd Does your ARM code differ from this? – Kabuto Mar 15 '23 at 11:40

1 Answers1

0

AFAIK, Creating confidential VM is not yet supported by azurerm terraform resource provider as securityType: setting is not available yet.

The configuration security_encryption_type Is part of os_disk and its just a mandatory to have Disk encryption enabled for the Confidential VM to work.

For now terraform does not have security_type: Standard, Confidential virtual machines, Trusted Launch virtual machines setting available.

As, a workaround you can use ARM Template to create a confidential VM refer below:-


{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vmName": {
      "type": "string",
      "metadata": {
        "description": "Name of the VM."
      }
    },
    "vmLocation": {
      "type": "string",
      "allowedValues": [
        "West US",
        "North Europe"
      ],
      "metadata": {
        "description": "Location of the VM."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_DC2as_v5",
      "allowedValues": [
        "Standard_DC2as_v5",
        "Standard_DC4as_v5",
        "Standard_DC8as_v5",
        "Standard_DC16as_v5",
        "Standard_DC32as_v5",
        "Standard_DC48as_v5",
        "Standard_DC64as_v5",
        "Standard_DC96as_v5",
        "Standard_DC2ads_v5",
        "Standard_DC4ads_v5",
        "Standard_DC8ads_v5",
        "Standard_DC16ads_v5",
        "Standard_DC32ads_v5",
        "Standard_DC48ads_v5",
        "Standard_DC64ads_v5",
        "Standard_DC96ads_v5",
        "Standard_EC2as_v5",
        "Standard_EC4as_v5",
        "Standard_EC8as_v5",
        "Standard_EC16as_v5",
        "Standard_EC20as_v5",
        "Standard_EC32as_v5",
        "Standard_EC48as_v5",
        "Standard_EC64as_v5",
        "Standard_EC96as_v5",
        "Standard_EC96ias_v5",
        "Standard_EC2ads_v5",
        "Standard_EC4ads_v5",
        "Standard_EC8ads_v5",
        "Standard_EC16ads_v5",
        "Standard_EC20ads_v5",
        "Standard_EC32ads_v5",
        "Standard_EC48ads_v5",
        "Standard_EC64ads_v5",
        "Standard_EC96ads_v5",
        "Standard_EC96iads_v5"
      ],
      "metadata": {
        "description": "Size of the VM."
      }
    },
    "osImageName": {
      "type": "string",
      "defaultValue": "Windows Server 2022 Gen 2",
      "allowedValues": [
        "Windows Server 2022 Gen 2",
        "Windows Server 2019 Gen 2",
        "Ubuntu 20.04 LTS Gen 2"
      ],
      "metadata": {
        "description": "OS Image for the Virtual Machine"
      }
    },
    "osDiskType": {
      "type": "string",
      "defaultValue": "Standard_LRS",
      "allowedValues": [
        "Premium_LRS",
        "Standard_LRS",
        "StandardSSD_LRS"
      ],
      "metadata": {
        "description": "OS disk type of the VM."
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Admin User Name of the VM."
      }
    },
    "authenticationType": {
      "type": "string",
      "defaultValue": "password",
      "allowedValues": [
        "password",
        "sshPublicKey"
      ],
      "metadata": {
        "description": "Type of authentication to use on the Virtual Machine."
      }
    },
    "adminPasswordOrKey": {
      "type": "securestring",
      "metadata": {
        "description": "Password or ssh key for the Virtual Machine."
      }
    },
    "bootDiagnostics": {
      "type": "string",
      "defaultValue": "false",
      "allowedValues": [
        "true",
        "false"
      ],
      "metadata": {
        "description": "Boot diagnostics setting of the VM."
      }
    },
    "securityType": {
      "type": "string",
      "defaultValue": "DiskWithVMGuestState",
      "allowedValues": [
        "VMGuestStateOnly",
        "DiskWithVMGuestState"
      ],
      "metadata": {
          "description": "VM security type."
      }
    },
    "secureBootEnabled": {
      "type": "string",
      "defaultValue": "true",
      "allowedValues": [
        "true"
      ],
      "metadata": {
        "description": "Secure Boot setting of the VM."
      }
    }
  },

  "variables": {
    "imageList": {
      "Windows Server 2022 Gen 2": {
        "publisher": "microsoftwindowsserver",
        "offer": "windowsserver",
        "sku":  "2022-datacenter-smalldisk-g2",
        "version": "latest"
      },
      "Windows Server 2019 Gen 2": {
        "publisher": "microsoftwindowsserver",
        "offer": "windowsserver",
        "sku": "2019-datacenter-smalldisk-g2",
        "version": "latest"
      },
      "Ubuntu 20.04 LTS Gen 2": {
        "publisher": "Canonical",
        "offer": "0001-com-ubuntu-confidential-vm-focal",
        "sku": "20_04-lts-cvm",
        "version": "latest"
      }
    },
    "imageReference": "[variables('imageList')[parameters('osImageName')]]",
    "networkInterfaceName": "[concat(parameters('vmName'), '-nic')]",
    "publicIPAddressName": "[concat(parameters('vmName'), '-ip')]",
    "networkSecurityGroupName": "[concat(parameters('vmName'), '-nsg')]",
    "networkSecurityGroupId": "[resourceId(resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]",
    "virtualNetworkName": "[concat(parameters('vmName'), '-vnet')]",
    "virtualNetworkId": "[resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
    "addressPrefix": "10.0.0.0/16",
    "subnetPrefix": "10.0.0.0/24",
    "subnetName": "[concat(parameters('vmName'), 'Subnet')]",
    "subnetRef": "[concat(variables('virtualNetworkId'), '/subnets/', variables('subnetName'))]",
    "isWindows": "[contains(parameters('osImageName'), 'Windows')]",
    "linuxConfiguration": {
      "disablePasswordAuthentication": "true",
      "ssh": {
        "publicKeys": [
          {
            "keyData": "[parameters('adminPasswordOrKey')]",
            "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]"
          }
        ]
      }
    },
    "windowsConfiguration": {
      "enableAutomaticUpdates": "true",
      "provisionVmAgent": "true"
    }
  },

  "resources": [
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2019-02-01",
      "name": "[variables('publicIPAddressName')]",
      "location": "[parameters('vmLocation')]",
      "sku": {
        "name": "Basic"
      },
      "properties": {
        "publicIpAllocationMethod": "Dynamic"
      }
    },
    {
      "type": "Microsoft.Network/networkSecurityGroups",
      "apiVersion": "2019-02-01",
      "name": "[variables('networkSecurityGroupName')]",
      "location": "[parameters('vmLocation')]",
      "properties": {
        "securityRules": [
          {
            "name": "[if(variables('isWindows'), 'RDP', 'SSH')]",
            "properties": {
              "priority": 100,
              "protocol": "TCP",
              "access": "Allow",
              "direction": "Inbound",
              "sourceAddressPrefix": "*",
              "sourcePortRange": "*",
              "destinationAddressPrefix": "*",
              "destinationPortRange": "[if(variables('isWindows'), '3389', '22')]"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2019-09-01",
      "name": "[variables('virtualNetworkName')]",
      "location": "[parameters('vmLocation')]",
      "dependsOn": [
        "[variables('networkSecurityGroupId')]"
      ],
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('addressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "[variables('subnetPrefix')]",
              "networkSecurityGroup": {
                "id": "[variables('networkSecurityGroupId')]"
              }
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2019-07-01",
      "name": "[variables('networkInterfaceName')]",
      "location": "[parameters('vmLocation')]",
      "dependsOn": [
        "[variables('networkSecurityGroupId')]",
        "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
        "[concat('Microsoft.Network/publicIpAddresses/', variables('publicIpAddressName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipConfigNode",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[variables('subnetRef')]"
              },
              "publicIpAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
              }
            }
          }
        ],
        "networkSecurityGroup": {
          "id": "[variables('networkSecurityGroupId')]"
        }
      }
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-07-01",
      "name": "[parameters('vmName')]",
      "location": "[parameters('vmLocation')]",
      "dependsOn": [
        "[concat('Microsoft.Network/networkInterfaces/', variables('networkInterfaceName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "storageProfile": {
          "osDisk": {
            "createOption": "fromImage",
            "managedDisk": {
              "storageAccountType": "[parameters('osDiskType')]",
              "securityProfile": {
                  "securityEncryptionType" : "[parameters('securityType')]"
              }
            }
          },
          "imageReference": "[variables('imageReference')]"
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
            }
          ]
        },
        "osProfile": {
          "computerName": "[parameters('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPasswordOrKey')]",
          "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('linuxConfiguration'))]",
          "windowsConfiguration": "[if(variables('isWindows'), variables('windowsConfiguration'), json('null'))]"
        },
        "securityProfile": {
          "uefiSettings" : {
            "secureBootEnabled": "[parameters('secureBootEnabled')]",
            "vTpmEnabled": "true"
          },
          "securityType" : "ConfidentialVM"
        }
      }
    }
  ]
}

Complete ARM Reference:- https://cvmprivatepreviewsa.blob.core.windows.net/cvmpublicpreviewcontainer/deploymentTemplate/deployCPSCVM2.json

In ARM template securityType: "confidentialVM" is available where as azurerm terraform resource provider does not have securityType configuration. Refer here:-

azurerm_virtual_machine | Resources | hashicorp/azurerm | Terraform Registry

To deploy the ARM Template:-

Go to your Azure Portal > All services > Deploy a custom template:-

enter image description here

Copy the above template And select the default value for the Image and size required for your confidential Vm from allowed values:-

enter image description here

Click Save:-

enter image description here

Fill up the appropriate parameters and deploy your confidential VM.

SiddheshDesai
  • 3,668
  • 1
  • 2
  • 11