Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_linux_virtual_machine,azurerm_windows_virtual_machine - Support automatic_upgrade_enabled,disk_controller_type,os_image_notification,treat_failure_as_deployment_failure_enabled and vm_agent_platform_updates_enabled #23394

Merged
merged 10 commits into from
Feb 27, 2024
96 changes: 90 additions & 6 deletions internal/services/compute/linux_virtual_machine_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,16 @@ func resourceLinuxVirtualMachine() *pluginsdk.Resource {
Default: true,
},

"disk_controller_type": {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice([]string{
string(compute.DiskControllerTypesNVMe),
string(compute.DiskControllerTypesSCSI),
}, false),
},

"edge_zone": commonschema.EdgeZoneOptionalForceNew(),

"encryption_at_host_enabled": {
Expand Down Expand Up @@ -340,6 +350,12 @@ func resourceLinuxVirtualMachine() *pluginsdk.Resource {
ValidateFunc: computeValidate.VirtualMachineScaleSetID,
},

"vm_agent_platform_updates_enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: false,
katbyte marked this conversation as resolved.
Show resolved Hide resolved
},

"vtpm_enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
Expand All @@ -357,6 +373,8 @@ func resourceLinuxVirtualMachine() *pluginsdk.Resource {

"tags": tags.Schema(),

"os_image_notification": virtualMachineOsImageNotificationSchema(),

"termination_notification": virtualMachineTerminationNotificationSchema(),

"user_data": {
Expand Down Expand Up @@ -440,6 +458,7 @@ func resourceLinuxVirtualMachineCreate(d *pluginsdk.ResourceData, meta interface
computerName = id.Name
}
disablePasswordAuthentication := d.Get("disable_password_authentication").(bool)
vmAgentPlatformUpdatesEnabled := d.Get("vm_agent_platform_updates_enabled").(bool)
location := azure.NormalizeLocation(d.Get("location").(string))
identityRaw := d.Get("identity").([]interface{})
identity, err := expandVirtualMachineIdentity(identityRaw)
Expand Down Expand Up @@ -492,6 +511,7 @@ func resourceLinuxVirtualMachineCreate(d *pluginsdk.ResourceData, meta interface
AllowExtensionOperations: utils.Bool(allowExtensionOperations),
LinuxConfiguration: &compute.LinuxConfiguration{
DisablePasswordAuthentication: utils.Bool(disablePasswordAuthentication),
EnableVMAgentPlatformUpdates: utils.Bool(vmAgentPlatformUpdatesEnabled),
ProvisionVMAgent: utils.Bool(provisionVMAgent),
SSH: &compute.SSHConfiguration{
PublicKeys: &sshKeys,
Expand Down Expand Up @@ -520,6 +540,10 @@ func resourceLinuxVirtualMachineCreate(d *pluginsdk.ResourceData, meta interface
Tags: tags.Expand(t),
}

if diskControllerType, ok := d.GetOk("disk_controller_type"); ok {
params.StorageProfile.DiskControllerType = compute.DiskControllerTypes(diskControllerType.(string))
}

if encryptionAtHostEnabled, ok := d.GetOk("encryption_at_host_enabled"); ok {
if encryptionAtHostEnabled.(bool) {
if compute.SecurityEncryptionTypesDiskWithVMGuestState == compute.SecurityEncryptionTypes(securityEncryptionType) {
Expand Down Expand Up @@ -634,8 +658,22 @@ func resourceLinuxVirtualMachineCreate(d *pluginsdk.ResourceData, meta interface
}
}

var osImageNotificationProfile *compute.OSImageNotificationProfile
var terminateNotificationProfile *compute.TerminateNotificationProfile

if v, ok := d.GetOk("os_image_notification"); ok {
osImageNotificationProfile = expandOsImageNotificationProfile(v.([]interface{}))
}

if v, ok := d.GetOk("termination_notification"); ok {
params.VirtualMachineProperties.ScheduledEventsProfile = expandVirtualMachineScheduledEventsProfile(v.([]interface{}))
terminateNotificationProfile = expandTerminateNotificationProfile(v.([]interface{}))
}

if terminateNotificationProfile != nil || osImageNotificationProfile != nil {
params.VirtualMachineProperties.ScheduledEventsProfile = &compute.ScheduledEventsProfile{
OsImageNotificationProfile: osImageNotificationProfile,
TerminateNotificationProfile: terminateNotificationProfile,
}
}

if !provisionVMAgent && allowExtensionOperations {
Expand Down Expand Up @@ -875,6 +913,7 @@ func resourceLinuxVirtualMachineRead(d *pluginsdk.ResourceData, meta interface{}
if config := profile.LinuxConfiguration; config != nil {
d.Set("disable_password_authentication", config.DisablePasswordAuthentication)
d.Set("provision_vm_agent", config.ProvisionVMAgent)
d.Set("vm_agent_platform_updates_enabled", config.EnableVMAgentPlatformUpdates)

flattenedSSHKeys, err := FlattenSSHKeys(config.SSH)
if err != nil {
Expand Down Expand Up @@ -923,6 +962,8 @@ func resourceLinuxVirtualMachineRead(d *pluginsdk.ResourceData, meta interface{}
d.Set("proximity_placement_group_id", proximityPlacementGroupId)

if profile := props.StorageProfile; profile != nil {
d.Set("disk_controller_type", string(props.StorageProfile.DiskControllerType))

// the storage_account_type isn't returned so we need to look it up
flattenedOSDisk, err := flattenVirtualMachineOSDisk(ctx, disksClient, profile.OsDisk)
if err != nil {
Expand Down Expand Up @@ -951,7 +992,11 @@ func resourceLinuxVirtualMachineRead(d *pluginsdk.ResourceData, meta interface{}
}

if scheduleProfile := props.ScheduledEventsProfile; scheduleProfile != nil {
if err := d.Set("termination_notification", flattenVirtualMachineScheduledEventsProfile(scheduleProfile)); err != nil {
if err := d.Set("os_image_notification", flattenOsImageNotificationProfile(scheduleProfile.OsImageNotificationProfile)); err != nil {
return fmt.Errorf("setting `termination_notification`: %+v", err)
}

if err := d.Set("termination_notification", flattenTerminateNotificationProfile(scheduleProfile.TerminateNotificationProfile)); err != nil {
return fmt.Errorf("setting `termination_notification`: %+v", err)
}
}
Expand Down Expand Up @@ -1179,6 +1224,17 @@ func resourceLinuxVirtualMachineUpdate(d *pluginsdk.ResourceData, meta interface
}
}

if d.HasChange("disk_controller_type") {
shouldUpdate = true
shouldDeallocate = true

if update.VirtualMachineProperties.StorageProfile == nil {
update.VirtualMachineProperties.StorageProfile = &compute.StorageProfile{}
}

update.VirtualMachineProperties.StorageProfile.DiskControllerType = compute.DiskControllerTypes(d.Get("disk_controller_type").(string))
}

if d.HasChange("os_disk") {
shouldUpdate = true

Expand All @@ -1192,9 +1248,11 @@ func resourceLinuxVirtualMachineUpdate(d *pluginsdk.ResourceData, meta interface
return fmt.Errorf("expanding `os_disk`: %+v", err)
}

update.VirtualMachineProperties.StorageProfile = &compute.StorageProfile{
OsDisk: osDisk,
if update.VirtualMachineProperties.StorageProfile == nil {
update.VirtualMachineProperties.StorageProfile = &compute.StorageProfile{}
}

update.VirtualMachineProperties.StorageProfile.OsDisk = osDisk
}

if d.HasChange("proximity_placement_group_id") {
Expand Down Expand Up @@ -1256,6 +1314,19 @@ func resourceLinuxVirtualMachineUpdate(d *pluginsdk.ResourceData, meta interface
}
}

if d.HasChange("vm_agent_platform_updates_enabled") {
shouldUpdate = true
if update.VirtualMachineProperties.OsProfile == nil {
update.VirtualMachineProperties.OsProfile = &compute.OSProfile{}
}

if update.VirtualMachineProperties.OsProfile.LinuxConfiguration == nil {
update.VirtualMachineProperties.OsProfile.LinuxConfiguration = &compute.LinuxConfiguration{}
}

update.VirtualMachineProperties.OsProfile.LinuxConfiguration.EnableVMAgentPlatformUpdates = utils.Bool(d.Get("vm_agent_platform_updates_enabled").(bool))
}

if d.HasChange("patch_mode") {
shouldUpdate = true
patchSettings := &compute.LinuxPatchSettings{}
Expand Down Expand Up @@ -1369,11 +1440,24 @@ func resourceLinuxVirtualMachineUpdate(d *pluginsdk.ResourceData, meta interface
update.OsProfile.AllowExtensionOperations = utils.Bool(allowExtensionOperations)
}

var osImageNotificationProfile *compute.OSImageNotificationProfile
var terminateNotificationProfile *compute.TerminateNotificationProfile

if d.HasChange("os_image_notification") {
shouldUpdate = true
osImageNotificationProfile = expandOsImageNotificationProfile(d.Get("os_image_notification").([]interface{}))
}

if d.HasChange("termination_notification") {
shouldUpdate = true
terminateNotificationProfile = expandTerminateNotificationProfile(d.Get("termination_notification").([]interface{}))
}

notificationRaw := d.Get("termination_notification").([]interface{})
update.ScheduledEventsProfile = expandVirtualMachineScheduledEventsProfile(notificationRaw)
if osImageNotificationProfile != nil || terminateNotificationProfile != nil {
update.ScheduledEventsProfile = &compute.ScheduledEventsProfile{
OsImageNotificationProfile: osImageNotificationProfile,
TerminateNotificationProfile: terminateNotificationProfile,
}
}

if d.HasChange("tags") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,35 @@ func TestAccLinuxVirtualMachine_diskOSStorageTypeUpdate(t *testing.T) {
})
}

func TestAccLinuxVirtualMachine_diskOSControllerType(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine", "test")
r := LinuxVirtualMachineResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.diskOSControllerTypeNVMe(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.diskOSControllerTypeSCSI(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.diskOSControllerTypeNVMe(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccLinuxVirtualMachine_diskOSWriteAcceleratorEnabled(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine", "test")
r := LinuxVirtualMachineResource{}
Expand Down Expand Up @@ -892,6 +921,78 @@ func (r LinuxVirtualMachineResource) diskOSStorageAccountTypeWithRestrictedLocat
return r.diskOSStorageAccountType(data, accountType)
}

func (r LinuxVirtualMachineResource) diskOSControllerTypeSCSI(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

resource "azurerm_linux_virtual_machine" "test" {
name = "acctestVM-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
size = "Standard_B1s"
admin_username = "adminuser"
disk_controller_type = "SCSI"

network_interface_ids = [
azurerm_network_interface.test.id,
]

admin_ssh_key {
username = "adminuser"
public_key = local.first_public_key
}

os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}

source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts-gen2"
version = "latest"
}
}
`, r.template(data), data.RandomInteger)
}

func (r LinuxVirtualMachineResource) diskOSControllerTypeNVMe(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

resource "azurerm_linux_virtual_machine" "test" {
name = "acctestVM-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
size = "Standard_E2bds_v5"
admin_username = "adminuser"
disk_controller_type = "NVMe"

network_interface_ids = [
azurerm_network_interface.test.id,
]

admin_ssh_key {
username = "adminuser"
public_key = local.first_public_key
}

os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}

source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts-gen2"
version = "latest"
}
}
`, r.template(data), data.RandomInteger)
}

func (r LinuxVirtualMachineResource) diskOSWriteAcceleratorEnabled(data acceptance.TestData, enabled bool) string {
return fmt.Sprintf(`
%s
Expand Down
Loading
Loading