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

Add timezone field to Virtual Machine (Windows Configuration) #1265

Merged
merged 14 commits into from
Jun 26, 2018
20 changes: 19 additions & 1 deletion azurerm/resource_arm_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ func resourceArmVirtualMachine() *schema.Resource {
State: schema.ImportStatePassthrough,
},

MigrateState: resourceAzureRMVirtualMachineMigrateState,
SchemaVersion: 1,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -374,6 +377,14 @@ func resourceArmVirtualMachine() *schema.Resource {
Optional: true,
Default: false,
},
"timezone": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: "UTC",
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
ValidateFunc: validateAzureVMTimeZone(),
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also needs a state migration to update the resourceArmVirtualMachineStorageOsProfileWindowsConfigHash function and a default value (UTC)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Is there any samples? I found one here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that'll do as an example, there's a few in the codebase - this value also needs to be added to the Hash function, otherwise this won't be detected as ForceNew for existing Virtual Machines (which is why the state migrations needed)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

"winrm": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -1019,6 +1030,10 @@ func flattenAzureRmVirtualMachineOsProfileWindowsConfiguration(config *compute.W
result["enable_automatic_upgrades"] = *config.EnableAutomaticUpdates
}

if config.TimeZone != nil {
result["timezone"] = *config.TimeZone
}

if config.WinRM != nil {
listeners := make([]map[string]interface{}, 0, len(*config.WinRM.Listeners))
for _, i := range *config.WinRM.Listeners {
Expand Down Expand Up @@ -1279,7 +1294,9 @@ func expandAzureRmVirtualMachineOsProfileWindowsConfig(d *schema.ResourceData) (
osProfilesWindowsConfig := d.Get("os_profile_windows_config").(*schema.Set).List()

osProfileConfig := osProfilesWindowsConfig[0].(map[string]interface{})
config := &compute.WindowsConfiguration{}
config := &compute.WindowsConfiguration{
TimeZone: utils.String(osProfileConfig["timezone"].(string)),
}

if v := osProfileConfig["provision_vm_agent"]; v != nil {
provision := v.(bool)
Expand Down Expand Up @@ -1595,6 +1612,7 @@ func resourceArmVirtualMachineStorageOsProfileWindowsConfigHash(v interface{}) i
if v, ok := m["enable_automatic_upgrades"]; ok {
buf.WriteString(fmt.Sprintf("%t-", v.(bool)))
}
buf.WriteString(fmt.Sprintf("%s-", m["timezone"].(string)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a crash where where this field doesn't exist - as such we need to nil-check this.

panic: interface conversion: interface {} is nil, not string
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm:
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: goroutine 32 [running]:
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/azurerm.resourceArmVirtualMachineStorageOsProfileWindowsConfigHash(0x25b6c00, 0xc4201a73e0, 0xc420530ab8)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/azurerm/resource_arm_virtual_machine.go:1615 +0x3d5
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema.(*Set).hash(0xc420530aa0, 0x25b6c00, 0xc4201a73e0, 0xc420530aa0, 0x0)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema/set.go:205 +0x3d
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema.(*Set).add(0xc420530aa0, 0x25b6c00, 0xc4201a73e0, 0x268dc00, 0x1, 0xc420530aa0)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema/set.go:192 +0x72
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema.(*Set).Add(0xc420530aa0, 0x25b6c00, 0xc4201a73e0)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema/set.go:69 +0x44
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema.NewSet(0x28650d8, 0xc4206f2d40, 0x1, 0x1, 0xc4205309e0)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema/set.go:56 +0x7a
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/azurerm.resourceArmVirtualMachineRead(0xc4206b1ea0, 0x27afe20, 0xc420360000, 0xc4206b1ea0, 0x0)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/azurerm/resource_arm_virtual_machine.go:712 +0x1166
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema.(*Resource).Refresh(0xc4202113b0, 0xc4203ac370, 0x27afe20, 0xc420360000, 0xc4203ea4a8, 0x10bc701, 0x24e1500)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema/resource.go:354 +0x167
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema.(*Provider).Refresh(0xc4202205b0, 0xc4203ac320, 0xc4203ac370, 0x1, 0x10623c3, 0x27f0001)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/helper/schema/provider.go:308 +0x9a
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/plugin.(*ResourceProviderServer).Refresh(0xc4205644c0, 0xc4205348e0, 0xc4205349e0, 0x0, 0x0)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/Users/tharvey/code/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/hashicorp/terraform/plugin/resource_provider.go:549 +0x4e
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: reflect.Value.call(0xc4200924e0, 0xc4201c2238, 0x13, 0x27ed6f9, 0x4, 0xc42069ef18, 0x3, 0x3, 0xc4200b3480, 0x0, ...)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/usr/local/Cellar/go/1.10.1/libexec/src/reflect/value.go:447 +0x969
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: reflect.Value.Call(0xc4200924e0, 0xc4201c2238, 0x13, 0xc420050718, 0x3, 0x3, 0x0, 0x0, 0x0)
2018-05-25T15:52:08.840+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/usr/local/Cellar/go/1.10.1/libexec/src/reflect/value.go:308 +0xa4
2018-05-25T15:52:08.841+0100 [DEBUG] plugin.terraform-provider-azurerm: net/rpc.(*service).call(0xc4203ae2c0, 0xc4206ea370, 0xc4200b0bf0, 0xc4200b0c00, 0xc4201be780, 0xc420564a60, 0x24e14c0, 0xc4205348e0, 0x16, 0x24e1500, ...)
2018-05-25T15:52:08.841+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/usr/local/Cellar/go/1.10.1/libexec/src/net/rpc/server.go:384 +0x14e
2018-05-25T15:52:08.841+0100 [DEBUG] plugin.terraform-provider-azurerm: created by net/rpc.(*Server).ServeCodec
2018-05-25T15:52:08.841+0100 [DEBUG] plugin.terraform-provider-azurerm: 	/usr/local/Cellar/go/1.10.1/libexec/src/net/rpc/server.go:480 +0x43a

Copy link
Author

@JunyiYi JunyiYi May 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it contains a default value. If the user didn't provide anything, will the default value be populated to the field?

What about the root field using d.Get()? How will Terraform handle the default value?

Copy link
Author

@JunyiYi JunyiYi May 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is caused by NewSet rather than any Get.

So what is the recommended way of handling default values in Read? Do we just leave it empty or set it to the field?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it contains a default value. If the user didn't provide anything, will the default value be populated to the field?

That's not true for existing values in the state (or, older VM's which didn't expose this field) which won't have this value (and thus will crash) - but we can work around that by nil-checking it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given this field is case insensitive in the schema you'll also want to make this value consistent by either upper/lower-casing it; otherwise you'll get spurious diff's here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}

return hashcode.String(buf.String())
Expand Down
85 changes: 85 additions & 0 deletions azurerm/resource_arm_virtual_machine_migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package azurerm

import (
"fmt"
"log"
"strconv"
"strings"

"github.com/hashicorp/terraform/terraform"
)

func resourceAzureRMVirtualMachineMigrateState(
v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
switch v {
case 0:
log.Println("[INFO] Found AzureRM Virtual Machine State v0; migrating to v1")
return migrateAzureRMVirtualMachineStateV0toV1(is)
default:
return is, fmt.Errorf("Unexpected schema version: %d", v)
}
}

func migrateAzureRMVirtualMachineStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) {
if is.Empty() {
log.Println("[DEBUG] Empty InstanceState; nothing to migrate.")
return is, nil
}

log.Printf("[DEBUG] ARM Virtual Machine Attributes before Migration: %#v", is.Attributes)

if is.Attributes["os_profile_windows_config.#"] == "1" {
hash, err := computeAzureRMVirtualMachineStateV1WinConfigHash(is, "UTC")
if err != nil {
return is, fmt.Errorf("Failed to calculate the new hash code for os_profile_windows_config field: %#v", err)
}
replaceAzureRMVirtualMachineStateV0WinConfigWithNewHash(is, hash)
tzKey := fmt.Sprintf("%s.%d.%s", "os_profile_windows_config", hash, "timezone")
is.Attributes[tzKey] = "UTC"
}

log.Printf("[DEBUG] ARM Virtual Machine Attributes after State Migration: %#v", is.Attributes)

return is, nil
}

func computeAzureRMVirtualMachineStateV1WinConfigHash(is *terraform.InstanceState, timezone string) (int, error) {
data := make(map[string]interface{})
for k, v := range is.Attributes {
if !strings.HasPrefix(k, "os_profile_windows_config.") {
continue
}
paths := strings.Split(k, ".")
if len(paths) == 3 && (paths[2] == "enable_automatic_upgrades" || paths[2] == "provision_vm_agent") {
b, err := strconv.ParseBool(v)
if err != nil {
return 0, err
}
data[paths[2]] = b
}
}
data["timezone"] = timezone
return resourceArmVirtualMachineStorageOsProfileWindowsConfigHash(data), nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The underlying data structures will diverge significantly in a future version of Terraform - as such direct manipulation of the state will cause hard to diagnose crashes later. Instead we need to use the schema parser (example) rather than assuming the format for keys, (as here)

This means we can simply assign the new value for the field, and allow Terraform Core to recompute the hash value; meaning the tests should stay the same, but all of this can disappear

Copy link
Author

@JunyiYi JunyiYi May 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice suggestion. I think this should be mentioned in the guideline as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(heads up that this needs to be resolved before we can merge this, which is why this is still "requested changes" 😄)

Just to add some additional context to testing this; you'll want to compare the state of a VM using the current provider release (currently v1.6.0) to the current development build you're working on; for instance:

provider "azurerm" {
  version = "=1.6.0"
}

resource "azurerm_resource_group" "test" {
  # ..
}

# ...
$ rm -rf .terraform/
$ terraform init
$ terraform apply

then un-pinning the provider version and re-initing/applying should show the state migration:

provider "azurerm" {
}

resource "azurerm_resource_group" "test" {
  # ..
}

# ...
$ rm -rf .terraform/
$ terraform init # to use the development version you've built via `make`
$ terraform plan|apply

In order to test this effectively unfortunately you'll want to destroy & recreate the VM for each iteration, which the taint command is quite helpful for:

$ terraform taint azurerm_virtual_machine.test
$ # switch back to "1.6.0"
$ terraform apply

Hope that helps :)

Copy link
Author

@JunyiYi JunyiYi Jun 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanations, and the test steps is really helpful here 👍 . So AFAIK, we can only do the manual test here for this kind of issues? Are there any unit-test infrastructure support it?

Copy link
Contributor

@tombuildsstuff tombuildsstuff Jun 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So AFAIK, we can only do the manual test here for this kind of issues? Are there any unit-test infrastructure support it?

The associated unit test is checking the logic from a given version - this is more exploratory testing / validation (so no, unfortunately not afaik)

}

func replaceAzureRMVirtualMachineStateV0WinConfigWithNewHash(is *terraform.InstanceState, hash int) {
toDel := make([]string, 0)
toAdd := make(map[string]string)
for k, v := range is.Attributes {
if !strings.HasPrefix(k, "os_profile_windows_config.") {
continue
}
paths := strings.Split(k, ".")
if len(paths) > 2 {
toDel = append(toDel, k)
paths[1] = fmt.Sprintf("%d", hash)
toAdd[strings.Join(paths, ".")] = v
}
}
for _, k := range toDel {
delete(is.Attributes, k)
}
for k, v := range toAdd {
is.Attributes[k] = v
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(which means this function can be removed)

95 changes: 95 additions & 0 deletions azurerm/resource_arm_virtual_machine_migration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package azurerm

import (
"testing"

"github.com/hashicorp/terraform/terraform"
)

func TestAzureRMVirtualMachineMigrateState(t *testing.T) {
cases := map[string]struct {
StateVersion int
ID string
InputAttributes map[string]string
ExpectedAttributes map[string]string
Meta interface{}
}{
"v0_1_simple": {
StateVersion: 0,
ID: "azurevm-dummy-id",
InputAttributes: map[string]string{
"os_profile_windows_config.#": "1",
"os_profile_windows_config.429474957.additional_unattend_config.#": "0",
"os_profile_windows_config.429474957.enable_automatic_upgrades": "false",
"os_profile_windows_config.429474957.provision_vm_agent": "false",
"os_profile_windows_config.429474957.winrm.#": "0",
},
ExpectedAttributes: map[string]string{
"os_profile_windows_config.#": "1",
"os_profile_windows_config.2229351482.additional_unattend_config.#": "0",
"os_profile_windows_config.2229351482.enable_automatic_upgrades": "false",
"os_profile_windows_config.2229351482.provision_vm_agent": "false",
"os_profile_windows_config.2229351482.timezone": "UTC",
"os_profile_windows_config.2229351482.winrm.#": "0",
},
},
"v0_1_full": {
StateVersion: 0,
ID: "azurevm-dummy-id",
InputAttributes: map[string]string{
"os_profile_windows_config.#": "1",
"os_profile_windows_config.2256145325.additional_unattend_config.#": "2",
"os_profile_windows_config.2256145325.additional_unattend_config.0.component": "shellsetup",
"os_profile_windows_config.2256145325.additional_unattend_config.0.content": "autologon content",
"os_profile_windows_config.2256145325.additional_unattend_config.0.pass": "mypass",
"os_profile_windows_config.2256145325.additional_unattend_config.1.component": "shellsetup2",
"os_profile_windows_config.2256145325.additional_unattend_config.0.setting_name": "AutoLogon",
"os_profile_windows_config.2256145325.additional_unattend_config.1.content": "first logon content",
"os_profile_windows_config.2256145325.additional_unattend_config.1.pass": "mypass2",
"os_profile_windows_config.2256145325.additional_unattend_config.1.setting_name": "FirstLogonCommands",
"os_profile_windows_config.2256145325.enable_automatic_upgrades": "true",
"os_profile_windows_config.2256145325.provision_vm_agent": "true",
"os_profile_windows_config.2256145325.winrm.#": "1",
"os_profile_windows_config.2256145325.winrm.0.certificate_url": "",
"os_profile_windows_config.2256145325.winrm.0.protocol": "http",
},
ExpectedAttributes: map[string]string{
"os_profile_windows_config.#": "1",
"os_profile_windows_config.1257668355.additional_unattend_config.#": "2",
"os_profile_windows_config.1257668355.additional_unattend_config.0.component": "shellsetup",
"os_profile_windows_config.1257668355.additional_unattend_config.0.content": "autologon content",
"os_profile_windows_config.1257668355.additional_unattend_config.0.pass": "mypass",
"os_profile_windows_config.1257668355.additional_unattend_config.0.setting_name": "AutoLogon",
"os_profile_windows_config.1257668355.additional_unattend_config.1.component": "shellsetup2",
"os_profile_windows_config.1257668355.additional_unattend_config.1.content": "first logon content",
"os_profile_windows_config.1257668355.additional_unattend_config.1.pass": "mypass2",
"os_profile_windows_config.1257668355.additional_unattend_config.1.setting_name": "FirstLogonCommands",
"os_profile_windows_config.1257668355.enable_automatic_upgrades": "true",
"os_profile_windows_config.1257668355.provision_vm_agent": "true",
"os_profile_windows_config.1257668355.timezone": "UTC",
"os_profile_windows_config.1257668355.winrm.#": "1",
"os_profile_windows_config.1257668355.winrm.0.certificate_url": "",
"os_profile_windows_config.1257668355.winrm.0.protocol": "http",
},
},
}

for tn, tc := range cases {
is := &terraform.InstanceState{
ID: tc.ID,
Attributes: tc.InputAttributes,
}
is, err := resourceAzureRMVirtualMachineMigrateState(tc.StateVersion, is, tc.Meta)

if err != nil {
t.Fatalf("bad: %s, err: %#v", tn, err)
}

for k, v := range tc.ExpectedAttributes {
actual := is.Attributes[k]
if actual != v {
t.Fatalf("Bad Virtual Machine Migrate for %q: %q\n\n expected: %q", k, actual, v)
}
}
}
}
109 changes: 109 additions & 0 deletions azurerm/resource_arm_virtual_machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package azurerm
import (
"fmt"
"net/http"
"testing"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2017-12-01/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
Expand Down Expand Up @@ -68,3 +70,110 @@ func testCheckAzureRMVirtualMachineDestroy(s *terraform.State) error {

return nil
}

func TestAccAzureRMVirtualMachine_winTimeZone(t *testing.T) {
resourceName := "azurerm_virtual_machine.test"
var vm compute.VirtualMachine
ri := acctest.RandInt()
config := testAccAzureRMVirtualMachine_winTimeZone(ri, testLocation())
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMVirtualMachineDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm),
resource.TestCheckResourceAttr(resourceName, "os_profile_windows_config.2277357006.timezone", "Pacific Standard Time"),
),
},
},
})
}

func testAccAzureRMVirtualMachine_winTimeZone(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_virtual_network" "test" {
name = "acctvn-%d"
address_space = ["10.0.0.0/16"]
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
}

resource "azurerm_subnet" "test" {
name = "acctsub-%d"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.0.2.0/24"
}

resource "azurerm_network_interface" "test" {
name = "acctni-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"

ip_configuration {
name = "testconfiguration1"
subnet_id = "${azurerm_subnet.test.id}"
private_ip_address_allocation = "dynamic"
}
}

resource "azurerm_storage_account" "test" {
name = "accsa%d"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
account_tier = "Standard"
account_replication_type = "LRS"

tags {
environment = "staging"
}
}

resource "azurerm_storage_container" "test" {
name = "vhds"
resource_group_name = "${azurerm_resource_group.test.name}"
storage_account_name = "${azurerm_storage_account.test.name}"
container_access_type = "private"
}

resource "azurerm_virtual_machine" "test" {
name = "acctvm-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
network_interface_ids = ["${azurerm_network_interface.test.id}"]
vm_size = "Standard_D1_v2"

storage_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2012-Datacenter"
version = "latest"
}

storage_os_disk {
name = "myosdisk1"
vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/myosdisk1.vhd"
caching = "ReadWrite"
create_option = "FromImage"
}

os_profile {
computer_name = "winhost01"
admin_username = "testadmin"
admin_password = "Password1234!"
}

os_profile_windows_config {
timezone = "Pacific Standard Time"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make the spacing consistent here? we use spaces for indentation for terraform configurations

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

`, rInt, location, rInt, rInt, rInt, rInt, rInt)
}
Loading