Skip to content

Commit

Permalink
Update azurerm_linux|windows_virtual_machine - Support `extensions_…
Browse files Browse the repository at this point in the history
…time_budget` (#9257)
  • Loading branch information
ArcturusZhang authored Nov 17, 2020
1 parent 591277e commit 7a3b5bd
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
azValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse"
Expand Down Expand Up @@ -167,6 +168,13 @@ func resourceLinuxVirtualMachine() *schema.Resource {
}, false),
},

"extensions_time_budget": {
Type: schema.TypeString,
Optional: true,
Default: "PT1H30M",
ValidateFunc: azValidate.ISO8601DurationBetween("PT15M", "PT2H"),
},

"identity": virtualMachineIdentitySchema(),

"max_bid_price": {
Expand Down Expand Up @@ -388,6 +396,7 @@ func resourceLinuxVirtualMachineCreate(d *schema.ResourceData, meta interface{})
// Optional
AdditionalCapabilities: additionalCapabilities,
DiagnosticsProfile: bootDiagnostics,
ExtensionsTimeBudget: utils.String(d.Get("extensions_time_budget").(string)),
},
Tags: tags.Expand(t),
}
Expand Down Expand Up @@ -552,6 +561,12 @@ func resourceLinuxVirtualMachineRead(d *schema.ResourceData, meta interface{}) e
d.Set("size", string(profile.VMSize))
}

extensionsTimeBudget := "PT1H30M"
if props.ExtensionsTimeBudget != nil {
extensionsTimeBudget = *props.ExtensionsTimeBudget
}
d.Set("extensions_time_budget", extensionsTimeBudget)

// defaulted since BillingProfile isn't returned if it's unset
maxBidPrice := float64(-1.0)
if props.BillingProfile != nil && props.BillingProfile.MaxPrice != nil {
Expand Down Expand Up @@ -755,6 +770,11 @@ func resourceLinuxVirtualMachineUpdate(d *schema.ResourceData, meta interface{})
}
}

if d.HasChange("extensions_time_budget") {
shouldUpdate = true
update.ExtensionsTimeBudget = utils.String(d.Get("extensions_time_budget").(string))
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,62 @@ func TestAccLinuxVirtualMachine_otherAllowExtensionOperationsUpdatedWithoutVmAge
})
}

func TestAccLinuxVirtualMachine_otherExtensionsTimeBudget(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: checkLinuxVirtualMachineIsDestroyed,
Steps: []resource.TestStep{
{
Config: testLinuxVirtualMachine_otherExtensionsTimeBudget(data, "PT30M"),
Check: resource.ComposeTestCheckFunc(
checkLinuxVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT30M"),
),
},
data.ImportStep(),
},
})
}

func TestAccLinuxVirtualMachine_otherExtensionsTimeBudgetUpdate(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: checkLinuxVirtualMachineIsDestroyed,
Steps: []resource.TestStep{
{
Config: testLinuxVirtualMachine_otherExtensionsTimeBudget(data, "PT30M"),
Check: resource.ComposeTestCheckFunc(
checkLinuxVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT30M"),
),
},
data.ImportStep(),
{
Config: testLinuxVirtualMachine_otherExtensionsTimeBudget(data, "PT50M"),
Check: resource.ComposeTestCheckFunc(
checkLinuxVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT50M"),
),
},
data.ImportStep(),
{
Config: testLinuxVirtualMachine_otherExtensionsTimeBudget(data, "PT30M"),
Check: resource.ComposeTestCheckFunc(
checkLinuxVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT30M"),
),
},
data.ImportStep(),
},
})
}

func TestAccLinuxVirtualMachine_otherBootDiagnostics(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine", "test")

Expand Down Expand Up @@ -702,6 +758,43 @@ resource "azurerm_linux_virtual_machine" "test" {
`, template, data.RandomInteger)
}

func testLinuxVirtualMachine_otherExtensionsTimeBudget(data acceptance.TestData, duration string) string {
template := testLinuxVirtualMachine_template(data)
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"
}
extensions_time_budget = "%s"
}
`, template, data.RandomInteger, duration)
}

func testLinuxVirtualMachine_otherBootDiagnostics(data acceptance.TestData) string {
template := testLinuxVirtualMachine_otherBootDiagnosticsTemplate(data)
return fmt.Sprintf(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,70 @@ func TestAccWindowsVirtualMachine_otherAllowExtensionOperationsUpdatedWithoutVmA
})
}

func TestAccWindowsVirtualMachine_otherExtensionsTimeBudget(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: checkWindowsVirtualMachineIsDestroyed,
Steps: []resource.TestStep{
{
Config: testWindowsVirtualMachine_otherExtensionsTimeBudget(data, "PT30M"),
Check: resource.ComposeTestCheckFunc(
checkWindowsVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT30M"),
),
},
data.ImportStep(
"admin_password",
),
},
})
}

func TestAccWindowsVirtualMachine_otherExtensionsTimeBudgetUpdate(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: checkWindowsVirtualMachineIsDestroyed,
Steps: []resource.TestStep{
{
Config: testWindowsVirtualMachine_otherExtensionsTimeBudget(data, "PT30M"),
Check: resource.ComposeTestCheckFunc(
checkWindowsVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT30M"),
),
},
data.ImportStep(
"admin_password",
),
{
Config: testWindowsVirtualMachine_otherExtensionsTimeBudget(data, "PT50M"),
Check: resource.ComposeTestCheckFunc(
checkWindowsVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT50M"),
),
},
data.ImportStep(
"admin_password",
),
{
Config: testWindowsVirtualMachine_otherExtensionsTimeBudget(data, "PT30M"),
Check: resource.ComposeTestCheckFunc(
checkWindowsVirtualMachineExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "extensions_time_budget", "PT30M"),
),
},
data.ImportStep(
"admin_password",
),
},
})
}

func TestAccWindowsVirtualMachine_otherBootDiagnostics(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine", "test")

Expand Down Expand Up @@ -1225,6 +1289,39 @@ resource "azurerm_windows_virtual_machine" "test" {
`, template)
}

func testWindowsVirtualMachine_otherExtensionsTimeBudget(data acceptance.TestData, duration string) string {
template := testWindowsVirtualMachine_template(data)
return fmt.Sprintf(`
%s
resource "azurerm_windows_virtual_machine" "test" {
name = local.vm_name
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
size = "Standard_F2"
admin_username = "adminuser"
admin_password = "P@$$w0rd1234!"
network_interface_ids = [
azurerm_network_interface.test.id,
]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2016-Datacenter"
version = "latest"
}
extensions_time_budget = "%s"
}
`, template, duration)
}

func testWindowsVirtualMachine_otherBootDiagnostics(data acceptance.TestData) string {
template := testWindowsVirtualMachine_otherBootDiagnosticsTemplate(data)
return fmt.Sprintf(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
azValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse"
Expand Down Expand Up @@ -169,6 +170,13 @@ func resourceWindowsVirtualMachine() *schema.Resource {
}, false),
},

"extensions_time_budget": {
Type: schema.TypeString,
Optional: true,
Default: "PT1H30M",
ValidateFunc: azValidate.ISO8601DurationBetween("PT15M", "PT2H"),
},

"identity": virtualMachineIdentitySchema(),

"license_type": {
Expand Down Expand Up @@ -433,6 +441,7 @@ func resourceWindowsVirtualMachineCreate(d *schema.ResourceData, meta interface{
// Optional
AdditionalCapabilities: additionalCapabilities,
DiagnosticsProfile: bootDiagnostics,
ExtensionsTimeBudget: utils.String(d.Get("extensions_time_budget").(string)),
},
Tags: tags.Expand(t),
}
Expand Down Expand Up @@ -598,6 +607,12 @@ func resourceWindowsVirtualMachineRead(d *schema.ResourceData, meta interface{})
}
d.Set("license_type", props.LicenseType)

extensionsTimeBudget := "PT1H30M"
if props.ExtensionsTimeBudget != nil {
extensionsTimeBudget = *props.ExtensionsTimeBudget
}
d.Set("extensions_time_budget", extensionsTimeBudget)

// defaulted since BillingProfile isn't returned if it's unset
maxBidPrice := float64(-1.0)
if props.BillingProfile != nil && props.BillingProfile.MaxPrice != nil {
Expand Down Expand Up @@ -836,6 +851,11 @@ func resourceWindowsVirtualMachineUpdate(d *schema.ResourceData, meta interface{
}
}

if d.HasChange("extensions_time_budget") {
shouldUpdate = true
update.ExtensionsTimeBudget = utils.String(d.Get("extensions_time_budget").(string))
}

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

Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/linux_virtual_machine.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ The following arguments are supported:

-> **NOTE:** This can only be configured when `priority` is set to `Spot`.

* `extensions_time_budget` - (Optional) Specifies the duration allocated for all extensions to start. The time duration should be between 15 minutes and 120 minutes (inclusive) and should be specified in ISO 8601 format. Defaults to 90 minutes (`PT1H30M`).

* `identity` - (Optional) An `identity` block as defined below.

* `max_bid_price` - (Optional) The maximum price you're willing to pay for this Virtual Machine, in US Dollars; which must be greater than the current spot price. If this bid price falls below the current spot price the Virtual Machine will be evicted using the `eviction_policy`. Defaults to `-1`, which means that the Virtual Machine should not be evicted for price reasons.
Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/windows_virtual_machine.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ The following arguments are supported:

-> **NOTE:** This can only be configured when `priority` is set to `Spot`.

* `extensions_time_budget` - (Optional) Specifies the duration allocated for all extensions to start. The time duration should be between 15 minutes and 120 minutes (inclusive) and should be specified in ISO 8601 format. Defaults to 90 minutes (`PT1H30M`).

* `identity` - (Optional) An `identity` block as defined below.

* `license_type` - (Optional) Specifies the type of on-premise license (also known as [Azure Hybrid Use Benefit](https://docs.microsoft.com/azure/virtual-machines/virtual-machines-windows-hybrid-use-benefit-licensing)) which should be used for this Virtual Machine. Possible values are `None`, `Windows_Client` and `Windows_Server`.
Expand Down

0 comments on commit 7a3b5bd

Please sign in to comment.