Skip to content

Commit

Permalink
r\VirtualMachine: Add support for terminate_notification
Browse files Browse the repository at this point in the history
  • Loading branch information
myc2h6o committed Feb 23, 2022
1 parent 634f9d4 commit 3d73b67
Show file tree
Hide file tree
Showing 13 changed files with 535 additions and 3 deletions.
19 changes: 19 additions & 0 deletions internal/services/compute/linux_virtual_machine_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ func resourceLinuxVirtualMachine() *pluginsdk.Resource {

"tags": tags.Schema(),

"terminate_notification": virtualMachineTerminateNotificationSchema(),

"user_data": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -499,6 +501,10 @@ func resourceLinuxVirtualMachineCreate(d *pluginsdk.ResourceData, meta interface
params.VirtualMachineProperties.SecurityProfile.UefiSettings.SecureBootEnabled = utils.Bool(secureBootEnabled.(bool))
}

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

if vtpmEnabled, ok := d.GetOk("vtpm_enabled"); ok && vtpmEnabled.(bool) {
if params.VirtualMachineProperties.SecurityProfile == nil {
params.VirtualMachineProperties.SecurityProfile = &compute.SecurityProfile{}
Expand Down Expand Up @@ -783,6 +789,12 @@ func resourceLinuxVirtualMachineRead(d *pluginsdk.ResourceData, meta interface{}
}
}

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

encryptionAtHostEnabled := false
vtpmEnabled := false
secureBootEnabled := false
Expand Down Expand Up @@ -1092,6 +1104,13 @@ func resourceLinuxVirtualMachineUpdate(d *pluginsdk.ResourceData, meta interface
update.OsProfile.AllowExtensionOperations = utils.Bool(allowExtensionOperations)
}

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

notificationRaw := d.Get("terminate_notification").([]interface{})
update.ScheduledEventsProfile = expandVirtualMachineScheduledEventsProfile(notificationRaw)
}

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

Expand Down
137 changes: 137 additions & 0 deletions internal/services/compute/linux_virtual_machine_resource_other_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,66 @@ func TestAccLinuxVirtualMachine_otherTags(t *testing.T) {
})
}

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

data.ResourceTest(t, r, []acceptance.TestStep{
// turn terminate notification on
{
Config: r.otherTerminateNotification(data, true),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("terminate_notification.#").HasValue("1"),
check.That(data.ResourceName).Key("terminate_notification.0.enabled").HasValue("true"),
),
},
data.ImportStep("admin_password"),
// turn terminate notification off
{
Config: r.otherTerminateNotification(data, false),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("terminate_notification.#").HasValue("1"),
check.That(data.ResourceName).Key("terminate_notification.0.enabled").HasValue("false"),
),
},
data.ImportStep("admin_password"),
// turn terminate notification on again
{
Config: r.otherTerminateNotification(data, true),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("terminate_notification.#").HasValue("1"),
check.That(data.ResourceName).Key("terminate_notification.0.enabled").HasValue("true"),
),
},
data.ImportStep("admin_password"),
})
}

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

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.otherTerminateNotification(data, true),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password"),
{
Config: r.otherTerminateNotificationTimeout(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password"),
})
}

func TestAccLinuxVirtualMachine_otherUltraSsdDefault(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine", "test")
r := LinuxVirtualMachineResource{}
Expand Down Expand Up @@ -1772,6 +1832,83 @@ resource "azurerm_linux_virtual_machine" "test" {
`, r.template(data), data.RandomInteger)
}

func (r LinuxVirtualMachineResource) otherTerminateNotification(data acceptance.TestData, enabled bool) 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_F2"
admin_username = "adminuser"
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 = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
terminate_notification {
enabled = %t
}
}
`, r.template(data), data.RandomInteger, enabled)
}

func (r LinuxVirtualMachineResource) otherTerminateNotificationTimeout(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_F2"
admin_username = "adminuser"
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 = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
terminate_notification {
enabled = true
timeout = "PT15M"
}
}
`, r.template(data), data.RandomInteger)
}

func (r LinuxVirtualMachineResource) otherUltraSsd(data acceptance.TestData, ultraSsdEnabled bool) string {
return fmt.Sprintf(`
%s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,28 @@ func TestAccLinuxVirtualMachineScaleSet_otherTerminateNotification(t *testing.T)
})
}

func TestAccLinuxVirtualMachineScaleSet_otherTerminateNotificationTimeout(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test")
r := LinuxVirtualMachineScaleSetResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.otherTerminateNotification(data, true),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password"),
{
Config: r.otherTerminateNotificationTimeout(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password"),
})
}

func TestAccLinuxVirtualMachineScaleSet_otherAutomaticRepairsPolicy(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test")
r := LinuxVirtualMachineScaleSetResource{}
Expand Down Expand Up @@ -1893,6 +1915,53 @@ resource "azurerm_linux_virtual_machine_scale_set" "test" {
`, r.template(data), data.RandomInteger, enabled)
}

func (r LinuxVirtualMachineScaleSetResource) otherTerminateNotificationTimeout(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_linux_virtual_machine_scale_set" "test" {
name = "acctestvmss-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
sku = "Standard_F2"
instances = 1
admin_username = "adminuser"
admin_password = "P@ssword1234!"
disable_password_authentication = false
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
os_disk {
disk_size_gb = 30
storage_account_type = "Standard_LRS"
caching = "ReadWrite"
}
network_interface {
name = "example"
primary = true
ip_configuration {
name = "internal"
primary = true
subnet_id = azurerm_subnet.test.id
}
}
terminate_notification {
enabled = true
timeout = "PT15M"
}
}
`, r.template(data), data.RandomInteger)
}

func (r LinuxVirtualMachineScaleSetResource) otherAutomaticRepairsPolicy(data acceptance.TestData, enabled bool) string {
return fmt.Sprintf(`
%[1]s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ func OrchestratedVirtualMachineScaleSetTerminateNotificationSchema() *pluginsdk.
"timeout": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: azValidate.ISO8601Duration,
ValidateFunc: azValidate.ISO8601DurationBetween("PT5M", "PT15M"),
Default: "PT5M",
},
},
Expand Down
67 changes: 67 additions & 0 deletions internal/services/compute/virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-07-01/compute"
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity"
azValidate "github.com/hashicorp/terraform-provider-azurerm/helpers/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
Expand Down Expand Up @@ -349,3 +350,69 @@ func flattenVirtualMachineOSDisk(ctx context.Context, disksClient *compute.Disks
},
}, nil
}

func virtualMachineTerminateNotificationSchema() *pluginsdk.Schema {
return &pluginsdk.Schema{
Type: pluginsdk.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"enabled": {
Type: pluginsdk.TypeBool,
Required: true,
},
"timeout": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: azValidate.ISO8601DurationBetween("PT5M", "PT15M"),
Default: "PT5M",
},
},
},
}
}

func expandVirtualMachineScheduledEventsProfile(input []interface{}) *compute.ScheduledEventsProfile {
if len(input) == 0 {
return &compute.ScheduledEventsProfile{
TerminateNotificationProfile: &compute.TerminateNotificationProfile{
Enable: utils.Bool(false),
},
}
}

raw := input[0].(map[string]interface{})
enabled := raw["enabled"].(bool)
timeout := raw["timeout"].(string)

return &compute.ScheduledEventsProfile{
TerminateNotificationProfile: &compute.TerminateNotificationProfile{
Enable: &enabled,
NotBeforeTimeout: &timeout,
},
}
}

func flattenVirtualMachineScheduledEventsProfile(input *compute.ScheduledEventsProfile) []interface{} {
// if enabled is set to false, there will be no ScheduledEventsProfile in response, to avoid plan non empty when
// a user explicitly set enabled to false, we need to assign a default block to this field

enabled := false
if input != nil && input.TerminateNotificationProfile != nil && input.TerminateNotificationProfile.Enable != nil {
enabled = *input.TerminateNotificationProfile.Enable
}

timeout := "PT5M"
if input != nil && input.TerminateNotificationProfile != nil && input.TerminateNotificationProfile.NotBeforeTimeout != nil {
timeout = *input.TerminateNotificationProfile.NotBeforeTimeout
}

return []interface{}{
map[string]interface{}{
"enabled": enabled,
"timeout": timeout,
},
}
}
2 changes: 1 addition & 1 deletion internal/services/compute/virtual_machine_scale_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -1413,7 +1413,7 @@ func VirtualMachineScaleSetTerminateNotificationSchema() *pluginsdk.Schema {
"timeout": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: azValidate.ISO8601Duration,
ValidateFunc: azValidate.ISO8601DurationBetween("PT5M", "PT15M"),
Default: "PT5M",
},
},
Expand Down
Loading

0 comments on commit 3d73b67

Please sign in to comment.