From 09dcb78b1190a907e732386dd2e7a0c9865fd95d Mon Sep 17 00:00:00 2001 From: Christian Pearce Date: Mon, 5 Jun 2017 05:55:50 -0400 Subject: [PATCH] Make os_profile optional #11147 (#14176) * Make os_profile optional #11147 * Test for optional os_profile and fix resourceArmVirtualMachineRead * Updating to match other optionally-required fields --- .../azurerm/resource_arm_virtual_machine.go | 48 +++--- .../resource_arm_virtual_machine_test.go | 159 ++++++++++++++++++ .../azurerm/r/virtual_machine.html.markdown | 3 +- 3 files changed, 187 insertions(+), 23 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_virtual_machine.go b/builtin/providers/azurerm/resource_arm_virtual_machine.go index fc2d14a48..8e0f56b24 100644 --- a/builtin/providers/azurerm/resource_arm_virtual_machine.go +++ b/builtin/providers/azurerm/resource_arm_virtual_machine.go @@ -317,7 +317,7 @@ func resourceArmVirtualMachine() *schema.Resource { "os_profile": { Type: schema.TypeSet, - Required: true, + Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -554,11 +554,13 @@ func resourceArmVirtualMachineCreate(d *schema.ResourceData, meta interface{}) e } } - osProfile, err := expandAzureRmVirtualMachineOsProfile(d) - if err != nil { - return err + if _, ok := d.GetOk("os_profile"); ok { + osProfile, err := expandAzureRmVirtualMachineOsProfile(d) + if err != nil { + return err + } + properties.OsProfile = osProfile } - properties.OsProfile = osProfile if v, ok := d.GetOk("availability_set_id"); ok { availabilitySet := v.(string) @@ -656,25 +658,27 @@ func resourceArmVirtualMachineRead(d *schema.ResourceData, meta interface{}) err } } - if err := d.Set("os_profile", schema.NewSet(resourceArmVirtualMachineStorageOsProfileHash, flattenAzureRmVirtualMachineOsProfile(resp.VirtualMachineProperties.OsProfile))); err != nil { - return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile: %#v", err) - } - - if resp.VirtualMachineProperties.OsProfile.WindowsConfiguration != nil { - if err := d.Set("os_profile_windows_config", flattenAzureRmVirtualMachineOsProfileWindowsConfiguration(resp.VirtualMachineProperties.OsProfile.WindowsConfiguration)); err != nil { - return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Windows Configuration: %#v", err) + if resp.VirtualMachineProperties.OsProfile != nil { + if err := d.Set("os_profile", schema.NewSet(resourceArmVirtualMachineStorageOsProfileHash, flattenAzureRmVirtualMachineOsProfile(resp.VirtualMachineProperties.OsProfile))); err != nil { + return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile: %#v", err) } - } - if resp.VirtualMachineProperties.OsProfile.LinuxConfiguration != nil { - if err := d.Set("os_profile_linux_config", flattenAzureRmVirtualMachineOsProfileLinuxConfiguration(resp.VirtualMachineProperties.OsProfile.LinuxConfiguration)); err != nil { - return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Linux Configuration: %#v", err) + if resp.VirtualMachineProperties.OsProfile.WindowsConfiguration != nil { + if err := d.Set("os_profile_windows_config", flattenAzureRmVirtualMachineOsProfileWindowsConfiguration(resp.VirtualMachineProperties.OsProfile.WindowsConfiguration)); err != nil { + return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Windows Configuration: %#v", err) + } } - } - if resp.VirtualMachineProperties.OsProfile.Secrets != nil { - if err := d.Set("os_profile_secrets", flattenAzureRmVirtualMachineOsProfileSecrets(resp.VirtualMachineProperties.OsProfile.Secrets)); err != nil { - return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Secrets: %#v", err) + if resp.VirtualMachineProperties.OsProfile.LinuxConfiguration != nil { + if err := d.Set("os_profile_linux_config", flattenAzureRmVirtualMachineOsProfileLinuxConfiguration(resp.VirtualMachineProperties.OsProfile.LinuxConfiguration)); err != nil { + return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Linux Configuration: %#v", err) + } + } + + if resp.VirtualMachineProperties.OsProfile.Secrets != nil { + if err := d.Set("os_profile_secrets", flattenAzureRmVirtualMachineOsProfileSecrets(resp.VirtualMachineProperties.OsProfile.Secrets)); err != nil { + return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Secrets: %#v", err) + } } } @@ -1461,8 +1465,8 @@ func expandAzureRmVirtualMachineOsDisk(d *schema.ResourceData) (*compute.OSDisk, return nil, fmt.Errorf("[ERROR] Conflict between `vhd_uri` and `managed_disk_type` (only one or the other can be used)") } //END: code to be removed after GH-13016 is merged - if managedDiskID == "" && strings.EqualFold(string(osDisk.CreateOption), string(compute.Attach)) { - return nil, fmt.Errorf("[ERROR] Must specify which disk to attach") + if managedDiskID == "" && vhdURI == "" && strings.EqualFold(string(osDisk.CreateOption), string(compute.Attach)) { + return nil, fmt.Errorf("[ERROR] Must specify `vhd_uri` or `managed_disk_id` to attach") } if v := config["image_uri"].(string); v != "" { diff --git a/builtin/providers/azurerm/resource_arm_virtual_machine_test.go b/builtin/providers/azurerm/resource_arm_virtual_machine_test.go index 33010eaf9..56291b3c8 100644 --- a/builtin/providers/azurerm/resource_arm_virtual_machine_test.go +++ b/builtin/providers/azurerm/resource_arm_virtual_machine_test.go @@ -819,6 +819,43 @@ func TestAccAzureRMVirtualMachine_primaryNetworkInterfaceId(t *testing.T) { }) } +func TestAccAzureRMVirtualMachine_optionalOSProfile(t *testing.T) { + var vm compute.VirtualMachine + + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine, ri, ri, ri, ri, ri, ri, ri) + prepConfig := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_destroy, ri, ri, ri, ri, ri) + config := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_attach_without_osProfile, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Destroy: false, + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + ), + }, + { + Destroy: false, + Config: prepConfig, + Check: func(s *terraform.State) error { + testCheckAzureRMVirtualMachineDestroy(s) + return nil + }, + }, + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + ), + }, + }, + }) +} + func testLookupAzureRMVirtualMachineManagedDiskID(vm *compute.VirtualMachine, diskName string, managedDiskID *string) resource.TestCheckFunc { return func(s *terraform.State) error { if osd := vm.StorageProfile.OsDisk; osd != nil { @@ -3567,3 +3604,125 @@ resource "azurerm_virtual_machine" "test" { } } ` +var testAccAzureRMVirtualMachine_basicLinuxMachine_destroy = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + 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 = "West US 2" + 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 = "West US 2" + account_type = "Standard_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" +} +` + +var testAccAzureRMVirtualMachine_basicLinuxMachine_attach_without_osProfile = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + 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 = "West US 2" + 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 = "West US 2" + account_type = "Standard_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 = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_F2" + + storage_os_disk { + name = "myosdisk1" + vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/myosdisk1.vhd" + os_type = "linux" + caching = "ReadWrite" + create_option = "Attach" + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` diff --git a/website/source/docs/providers/azurerm/r/virtual_machine.html.markdown b/website/source/docs/providers/azurerm/r/virtual_machine.html.markdown index 64609669e..db1d72683 100644 --- a/website/source/docs/providers/azurerm/r/virtual_machine.html.markdown +++ b/website/source/docs/providers/azurerm/r/virtual_machine.html.markdown @@ -310,7 +310,8 @@ The following arguments are supported: * `delete_os_disk_on_termination` - (Optional) Flag to enable deletion of the OS disk VHD blob or managed disk when the VM is deleted, defaults to `false` * `storage_data_disk` - (Optional) A list of Storage Data disk blocks as referenced below. * `delete_data_disks_on_termination` - (Optional) Flag to enable deletion of storage data disk VHD blobs or managed disks when the VM is deleted, defaults to `false` -* `os_profile` - (Required) An OS Profile block as documented below. +* `os_profile` - (Optional) An OS Profile block as documented below. Required when `create_option` in the `storage_os_disk` block is set to `FromImage`. + * `license_type` - (Optional, when a windows machine) Specifies the Windows OS license type. The only allowable value, if supplied, is `Windows_Server`. * `os_profile_windows_config` - (Required, when a windows machine) A Windows config block as documented below. * `os_profile_linux_config` - (Required, when a linux machine) A Linux config block as documented below.