github.com/dougneal/terraform@v0.6.15-0.20170330092735-b6a3840768a4/builtin/providers/azurerm/resource_arm_virtual_machine.go (about)

     1  package azurerm
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"net/http"
     8  	"net/url"
     9  	"strings"
    10  
    11  	"github.com/Azure/azure-sdk-for-go/arm/compute"
    12  	"github.com/hashicorp/terraform/helper/hashcode"
    13  	"github.com/hashicorp/terraform/helper/schema"
    14  	riviera "github.com/jen20/riviera/azure"
    15  )
    16  
    17  func resourceArmVirtualMachine() *schema.Resource {
    18  	return &schema.Resource{
    19  		Create: resourceArmVirtualMachineCreate,
    20  		Read:   resourceArmVirtualMachineRead,
    21  		Update: resourceArmVirtualMachineCreate,
    22  		Delete: resourceArmVirtualMachineDelete,
    23  		Importer: &schema.ResourceImporter{
    24  			State: schema.ImportStatePassthrough,
    25  		},
    26  
    27  		Schema: map[string]*schema.Schema{
    28  			"name": {
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  
    34  			"location": locationSchema(),
    35  
    36  			"resource_group_name": {
    37  				Type:     schema.TypeString,
    38  				Required: true,
    39  				ForceNew: true,
    40  			},
    41  
    42  			"plan": {
    43  				Type:     schema.TypeSet,
    44  				Optional: true,
    45  				MaxItems: 1,
    46  				Elem: &schema.Resource{
    47  					Schema: map[string]*schema.Schema{
    48  						"name": {
    49  							Type:     schema.TypeString,
    50  							Required: true,
    51  						},
    52  
    53  						"publisher": {
    54  							Type:     schema.TypeString,
    55  							Required: true,
    56  						},
    57  
    58  						"product": {
    59  							Type:     schema.TypeString,
    60  							Required: true,
    61  						},
    62  					},
    63  				},
    64  				Set: resourceArmVirtualMachinePlanHash,
    65  			},
    66  
    67  			"availability_set_id": {
    68  				Type:     schema.TypeString,
    69  				Optional: true,
    70  				Computed: true,
    71  				ForceNew: true,
    72  				StateFunc: func(id interface{}) string {
    73  					return strings.ToLower(id.(string))
    74  				},
    75  			},
    76  
    77  			"license_type": {
    78  				Type:         schema.TypeString,
    79  				Optional:     true,
    80  				Computed:     true,
    81  				ValidateFunc: validateLicenseType,
    82  			},
    83  
    84  			"vm_size": {
    85  				Type:     schema.TypeString,
    86  				Required: true,
    87  			},
    88  
    89  			"storage_image_reference": {
    90  				Type:     schema.TypeSet,
    91  				Optional: true,
    92  				Computed: true,
    93  				ForceNew: true,
    94  				MaxItems: 1,
    95  				Elem: &schema.Resource{
    96  					Schema: map[string]*schema.Schema{
    97  						"publisher": {
    98  							Type:     schema.TypeString,
    99  							Required: true,
   100  							ForceNew: true,
   101  						},
   102  
   103  						"offer": {
   104  							Type:     schema.TypeString,
   105  							Required: true,
   106  							ForceNew: true,
   107  						},
   108  
   109  						"sku": {
   110  							Type:     schema.TypeString,
   111  							Required: true,
   112  							ForceNew: true,
   113  						},
   114  
   115  						"version": {
   116  							Type:     schema.TypeString,
   117  							Optional: true,
   118  							Computed: true,
   119  							ForceNew: true,
   120  						},
   121  					},
   122  				},
   123  				Set: resourceArmVirtualMachineStorageImageReferenceHash,
   124  			},
   125  
   126  			"storage_os_disk": {
   127  				Type:     schema.TypeSet,
   128  				Required: true,
   129  				MaxItems: 1,
   130  				Elem: &schema.Resource{
   131  					Schema: map[string]*schema.Schema{
   132  						"os_type": {
   133  							Type:     schema.TypeString,
   134  							Optional: true,
   135  						},
   136  
   137  						"name": {
   138  							Type:     schema.TypeString,
   139  							Required: true,
   140  						},
   141  
   142  						"vhd_uri": {
   143  							Type:     schema.TypeString,
   144  							Required: true,
   145  							ForceNew: true,
   146  						},
   147  
   148  						"image_uri": {
   149  							Type:     schema.TypeString,
   150  							Optional: true,
   151  						},
   152  
   153  						"caching": {
   154  							Type:     schema.TypeString,
   155  							Optional: true,
   156  							Computed: true,
   157  						},
   158  
   159  						"create_option": {
   160  							Type:     schema.TypeString,
   161  							Required: true,
   162  						},
   163  
   164  						"disk_size_gb": {
   165  							Type:         schema.TypeInt,
   166  							Optional:     true,
   167  							ValidateFunc: validateDiskSizeGB,
   168  						},
   169  					},
   170  				},
   171  				Set: resourceArmVirtualMachineStorageOsDiskHash,
   172  			},
   173  
   174  			"delete_os_disk_on_termination": {
   175  				Type:     schema.TypeBool,
   176  				Optional: true,
   177  				Default:  false,
   178  			},
   179  
   180  			"storage_data_disk": {
   181  				Type:     schema.TypeList,
   182  				Optional: true,
   183  				Elem: &schema.Resource{
   184  					Schema: map[string]*schema.Schema{
   185  						"name": {
   186  							Type:     schema.TypeString,
   187  							Required: true,
   188  						},
   189  
   190  						"vhd_uri": {
   191  							Type:     schema.TypeString,
   192  							Required: true,
   193  						},
   194  
   195  						"create_option": {
   196  							Type:     schema.TypeString,
   197  							Required: true,
   198  						},
   199  
   200  						"caching": {
   201  							Type:     schema.TypeString,
   202  							Optional: true,
   203  							Computed: true,
   204  						},
   205  
   206  						"disk_size_gb": {
   207  							Type:     schema.TypeInt,
   208  							Optional: true,
   209  							Computed: true,
   210  						},
   211  
   212  						"lun": {
   213  							Type:     schema.TypeInt,
   214  							Required: true,
   215  						},
   216  					},
   217  				},
   218  			},
   219  
   220  			"delete_data_disks_on_termination": {
   221  				Type:     schema.TypeBool,
   222  				Optional: true,
   223  				Default:  false,
   224  			},
   225  
   226  			"diagnostics_profile": {
   227  				Type:          schema.TypeSet,
   228  				Optional:      true,
   229  				MaxItems:      1,
   230  				ConflictsWith: []string{"boot_diagnostics"},
   231  				Deprecated:    "Use field boot_diagnostics instead",
   232  				Elem: &schema.Resource{
   233  					Schema: map[string]*schema.Schema{
   234  						"boot_diagnostics": {
   235  							Type:     schema.TypeSet,
   236  							Required: true,
   237  							MaxItems: 1,
   238  							Elem: &schema.Resource{
   239  								Schema: map[string]*schema.Schema{
   240  									"enabled": {
   241  										Type:     schema.TypeBool,
   242  										Required: true,
   243  									},
   244  
   245  									"storage_uri": {
   246  										Type:     schema.TypeString,
   247  										Required: true,
   248  									},
   249  								},
   250  							},
   251  						},
   252  					},
   253  				},
   254  			},
   255  
   256  			"boot_diagnostics": {
   257  				Type:     schema.TypeList,
   258  				Optional: true,
   259  				MaxItems: 1,
   260  				Elem: &schema.Resource{
   261  					Schema: map[string]*schema.Schema{
   262  						"enabled": {
   263  							Type:     schema.TypeBool,
   264  							Required: true,
   265  						},
   266  
   267  						"storage_uri": {
   268  							Type:     schema.TypeString,
   269  							Required: true,
   270  						},
   271  					},
   272  				},
   273  			},
   274  
   275  			"os_profile": {
   276  				Type:     schema.TypeSet,
   277  				Required: true,
   278  				MaxItems: 1,
   279  				Elem: &schema.Resource{
   280  					Schema: map[string]*schema.Schema{
   281  						"computer_name": {
   282  							Type:     schema.TypeString,
   283  							ForceNew: true,
   284  							Required: true,
   285  						},
   286  
   287  						"admin_username": {
   288  							Type:     schema.TypeString,
   289  							Required: true,
   290  						},
   291  
   292  						"admin_password": {
   293  							Type:     schema.TypeString,
   294  							Required: true,
   295  						},
   296  
   297  						"custom_data": {
   298  							Type:      schema.TypeString,
   299  							Optional:  true,
   300  							Computed:  true,
   301  							StateFunc: userDataStateFunc,
   302  						},
   303  					},
   304  				},
   305  				Set: resourceArmVirtualMachineStorageOsProfileHash,
   306  			},
   307  
   308  			"os_profile_windows_config": {
   309  				Type:     schema.TypeSet,
   310  				Optional: true,
   311  				MaxItems: 1,
   312  				Elem: &schema.Resource{
   313  					Schema: map[string]*schema.Schema{
   314  						"provision_vm_agent": {
   315  							Type:     schema.TypeBool,
   316  							Optional: true,
   317  						},
   318  						"enable_automatic_upgrades": {
   319  							Type:     schema.TypeBool,
   320  							Optional: true,
   321  						},
   322  						"winrm": {
   323  							Type:     schema.TypeList,
   324  							Optional: true,
   325  							Elem: &schema.Resource{
   326  								Schema: map[string]*schema.Schema{
   327  									"protocol": {
   328  										Type:     schema.TypeString,
   329  										Required: true,
   330  									},
   331  									"certificate_url": {
   332  										Type:     schema.TypeString,
   333  										Optional: true,
   334  									},
   335  								},
   336  							},
   337  						},
   338  						"additional_unattend_config": {
   339  							Type:     schema.TypeList,
   340  							Optional: true,
   341  							Elem: &schema.Resource{
   342  								Schema: map[string]*schema.Schema{
   343  									"pass": {
   344  										Type:     schema.TypeString,
   345  										Required: true,
   346  									},
   347  									"component": {
   348  										Type:     schema.TypeString,
   349  										Required: true,
   350  									},
   351  									"setting_name": {
   352  										Type:     schema.TypeString,
   353  										Required: true,
   354  									},
   355  									"content": {
   356  										Type:     schema.TypeString,
   357  										Required: true,
   358  									},
   359  								},
   360  							},
   361  						},
   362  					},
   363  				},
   364  				Set: resourceArmVirtualMachineStorageOsProfileWindowsConfigHash,
   365  			},
   366  
   367  			"os_profile_linux_config": {
   368  				Type:     schema.TypeSet,
   369  				Optional: true,
   370  				MaxItems: 1,
   371  				Elem: &schema.Resource{
   372  					Schema: map[string]*schema.Schema{
   373  						"disable_password_authentication": {
   374  							Type:     schema.TypeBool,
   375  							Required: true,
   376  						},
   377  						"ssh_keys": {
   378  							Type:     schema.TypeList,
   379  							Optional: true,
   380  							Elem: &schema.Resource{
   381  								Schema: map[string]*schema.Schema{
   382  									"path": {
   383  										Type:     schema.TypeString,
   384  										Required: true,
   385  									},
   386  									"key_data": {
   387  										Type:     schema.TypeString,
   388  										Optional: true,
   389  									},
   390  								},
   391  							},
   392  						},
   393  					},
   394  				},
   395  				Set: resourceArmVirtualMachineStorageOsProfileLinuxConfigHash,
   396  			},
   397  
   398  			"os_profile_secrets": {
   399  				Type:     schema.TypeSet,
   400  				Optional: true,
   401  				Elem: &schema.Resource{
   402  					Schema: map[string]*schema.Schema{
   403  						"source_vault_id": {
   404  							Type:     schema.TypeString,
   405  							Required: true,
   406  						},
   407  
   408  						"vault_certificates": {
   409  							Type:     schema.TypeList,
   410  							Optional: true,
   411  							Elem: &schema.Resource{
   412  								Schema: map[string]*schema.Schema{
   413  									"certificate_url": {
   414  										Type:     schema.TypeString,
   415  										Required: true,
   416  									},
   417  									"certificate_store": {
   418  										Type:     schema.TypeString,
   419  										Optional: true,
   420  									},
   421  								},
   422  							},
   423  						},
   424  					},
   425  				},
   426  			},
   427  
   428  			"network_interface_ids": {
   429  				Type:     schema.TypeSet,
   430  				Required: true,
   431  				Elem: &schema.Schema{
   432  					Type: schema.TypeString,
   433  				},
   434  				Set: schema.HashString,
   435  			},
   436  
   437  			"primary_network_interface_id": {
   438  				Type:     schema.TypeString,
   439  				Optional: true,
   440  			},
   441  
   442  			"tags": tagsSchema(),
   443  		},
   444  	}
   445  }
   446  
   447  func validateLicenseType(v interface{}, k string) (ws []string, errors []error) {
   448  	value := v.(string)
   449  	if value != "" && value != "Windows_Server" {
   450  		errors = append(errors, fmt.Errorf(
   451  			"[ERROR] license_type must be 'Windows_Server' or empty"))
   452  	}
   453  	return
   454  }
   455  
   456  func validateDiskSizeGB(v interface{}, k string) (ws []string, errors []error) {
   457  	value := v.(int)
   458  	if value < 1 || value > 1023 {
   459  		errors = append(errors, fmt.Errorf(
   460  			"The `disk_size_gb` can only be between 1 and 1023"))
   461  	}
   462  	return
   463  }
   464  
   465  func resourceArmVirtualMachineCreate(d *schema.ResourceData, meta interface{}) error {
   466  	client := meta.(*ArmClient)
   467  	vmClient := client.vmClient
   468  
   469  	log.Printf("[INFO] preparing arguments for Azure ARM Virtual Machine creation.")
   470  
   471  	name := d.Get("name").(string)
   472  	location := d.Get("location").(string)
   473  	resGroup := d.Get("resource_group_name").(string)
   474  	tags := d.Get("tags").(map[string]interface{})
   475  	expandedTags := expandTags(tags)
   476  
   477  	osDisk, err := expandAzureRmVirtualMachineOsDisk(d)
   478  	if err != nil {
   479  		return err
   480  	}
   481  	storageProfile := compute.StorageProfile{
   482  		OsDisk: osDisk,
   483  	}
   484  
   485  	if _, ok := d.GetOk("storage_image_reference"); ok {
   486  		imageRef, err := expandAzureRmVirtualMachineImageReference(d)
   487  		if err != nil {
   488  			return err
   489  		}
   490  		storageProfile.ImageReference = imageRef
   491  	}
   492  
   493  	if _, ok := d.GetOk("storage_data_disk"); ok {
   494  		dataDisks, err := expandAzureRmVirtualMachineDataDisk(d)
   495  		if err != nil {
   496  			return err
   497  		}
   498  		storageProfile.DataDisks = &dataDisks
   499  	}
   500  
   501  	networkProfile := expandAzureRmVirtualMachineNetworkProfile(d)
   502  	vmSize := d.Get("vm_size").(string)
   503  	properties := compute.VirtualMachineProperties{
   504  		NetworkProfile: &networkProfile,
   505  		HardwareProfile: &compute.HardwareProfile{
   506  			VMSize: compute.VirtualMachineSizeTypes(vmSize),
   507  		},
   508  		StorageProfile: &storageProfile,
   509  	}
   510  
   511  	if v, ok := d.GetOk("license_type"); ok {
   512  		license := v.(string)
   513  		properties.LicenseType = &license
   514  	}
   515  
   516  	if _, ok := d.GetOk("boot_diagnostics"); ok {
   517  		diagnosticsProfile := expandAzureRmVirtualMachineDiagnosticsProfile(d)
   518  		if diagnosticsProfile != nil {
   519  			properties.DiagnosticsProfile = diagnosticsProfile
   520  		}
   521  	}
   522  
   523  	osProfile, err := expandAzureRmVirtualMachineOsProfile(d)
   524  	if err != nil {
   525  		return err
   526  	}
   527  	properties.OsProfile = osProfile
   528  
   529  	if v, ok := d.GetOk("availability_set_id"); ok {
   530  		availabilitySet := v.(string)
   531  		availSet := compute.SubResource{
   532  			ID: &availabilitySet,
   533  		}
   534  
   535  		properties.AvailabilitySet = &availSet
   536  	}
   537  
   538  	vm := compute.VirtualMachine{
   539  		Name:                     &name,
   540  		Location:                 &location,
   541  		VirtualMachineProperties: &properties,
   542  		Tags: expandedTags,
   543  	}
   544  
   545  	if _, ok := d.GetOk("plan"); ok {
   546  		plan, err := expandAzureRmVirtualMachinePlan(d)
   547  		if err != nil {
   548  			return err
   549  		}
   550  
   551  		vm.Plan = plan
   552  	}
   553  
   554  	_, vmErr := vmClient.CreateOrUpdate(resGroup, name, vm, make(chan struct{}))
   555  	if vmErr != nil {
   556  		return vmErr
   557  	}
   558  
   559  	read, err := vmClient.Get(resGroup, name, "")
   560  	if err != nil {
   561  		return err
   562  	}
   563  	if read.ID == nil {
   564  		return fmt.Errorf("Cannot read Virtual Machine %s (resource group %s) ID", name, resGroup)
   565  	}
   566  
   567  	d.SetId(*read.ID)
   568  
   569  	return resourceArmVirtualMachineRead(d, meta)
   570  }
   571  
   572  func resourceArmVirtualMachineRead(d *schema.ResourceData, meta interface{}) error {
   573  	vmClient := meta.(*ArmClient).vmClient
   574  
   575  	id, err := parseAzureResourceID(d.Id())
   576  	if err != nil {
   577  		return err
   578  	}
   579  	resGroup := id.ResourceGroup
   580  	name := id.Path["virtualMachines"]
   581  
   582  	resp, err := vmClient.Get(resGroup, name, "")
   583  
   584  	if err != nil {
   585  		if resp.StatusCode == http.StatusNotFound {
   586  			d.SetId("")
   587  			return nil
   588  		}
   589  		return fmt.Errorf("Error making Read request on Azure Virtual Machine %s: %s", name, err)
   590  	}
   591  
   592  	d.Set("name", resp.Name)
   593  	d.Set("resource_group_name", resGroup)
   594  	d.Set("location", resp.Location)
   595  
   596  	if resp.Plan != nil {
   597  		if err := d.Set("plan", schema.NewSet(resourceArmVirtualMachinePlanHash, flattenAzureRmVirtualMachinePlan(resp.Plan))); err != nil {
   598  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Plan error: %#v", err)
   599  		}
   600  	}
   601  
   602  	if resp.VirtualMachineProperties.AvailabilitySet != nil {
   603  		d.Set("availability_set_id", strings.ToLower(*resp.VirtualMachineProperties.AvailabilitySet.ID))
   604  	}
   605  
   606  	d.Set("vm_size", resp.VirtualMachineProperties.HardwareProfile.VMSize)
   607  
   608  	if resp.VirtualMachineProperties.StorageProfile.ImageReference != nil {
   609  		if err := d.Set("storage_image_reference", schema.NewSet(resourceArmVirtualMachineStorageImageReferenceHash, flattenAzureRmVirtualMachineImageReference(resp.VirtualMachineProperties.StorageProfile.ImageReference))); err != nil {
   610  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage Image Reference error: %#v", err)
   611  		}
   612  	}
   613  
   614  	if err := d.Set("storage_os_disk", schema.NewSet(resourceArmVirtualMachineStorageOsDiskHash, flattenAzureRmVirtualMachineOsDisk(resp.VirtualMachineProperties.StorageProfile.OsDisk))); err != nil {
   615  		return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Disk error: %#v", err)
   616  	}
   617  
   618  	if resp.VirtualMachineProperties.StorageProfile.DataDisks != nil {
   619  		if err := d.Set("storage_data_disk", flattenAzureRmVirtualMachineDataDisk(resp.VirtualMachineProperties.StorageProfile.DataDisks)); err != nil {
   620  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage Data Disks error: %#v", err)
   621  		}
   622  	}
   623  
   624  	if err := d.Set("os_profile", schema.NewSet(resourceArmVirtualMachineStorageOsProfileHash, flattenAzureRmVirtualMachineOsProfile(resp.VirtualMachineProperties.OsProfile))); err != nil {
   625  		return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile: %#v", err)
   626  	}
   627  
   628  	if resp.VirtualMachineProperties.OsProfile.WindowsConfiguration != nil {
   629  		if err := d.Set("os_profile_windows_config", flattenAzureRmVirtualMachineOsProfileWindowsConfiguration(resp.VirtualMachineProperties.OsProfile.WindowsConfiguration)); err != nil {
   630  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Windows Configuration: %#v", err)
   631  		}
   632  	}
   633  
   634  	if resp.VirtualMachineProperties.OsProfile.LinuxConfiguration != nil {
   635  		if err := d.Set("os_profile_linux_config", flattenAzureRmVirtualMachineOsProfileLinuxConfiguration(resp.VirtualMachineProperties.OsProfile.LinuxConfiguration)); err != nil {
   636  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Linux Configuration: %#v", err)
   637  		}
   638  	}
   639  
   640  	if resp.VirtualMachineProperties.OsProfile.Secrets != nil {
   641  		if err := d.Set("os_profile_secrets", flattenAzureRmVirtualMachineOsProfileSecrets(resp.VirtualMachineProperties.OsProfile.Secrets)); err != nil {
   642  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage OS Profile Secrets: %#v", err)
   643  		}
   644  	}
   645  
   646  	if resp.VirtualMachineProperties.DiagnosticsProfile != nil && resp.VirtualMachineProperties.DiagnosticsProfile.BootDiagnostics != nil {
   647  		if err := d.Set("boot_diagnostics", flattenAzureRmVirtualMachineDiagnosticsProfile(resp.VirtualMachineProperties.DiagnosticsProfile.BootDiagnostics)); err != nil {
   648  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Diagnostics Profile: %#v", err)
   649  		}
   650  	}
   651  
   652  	if resp.VirtualMachineProperties.NetworkProfile != nil {
   653  		if err := d.Set("network_interface_ids", flattenAzureRmVirtualMachineNetworkInterfaces(resp.VirtualMachineProperties.NetworkProfile)); err != nil {
   654  			return fmt.Errorf("[DEBUG] Error setting Virtual Machine Storage Network Interfaces: %#v", err)
   655  		}
   656  
   657  		if resp.VirtualMachineProperties.NetworkProfile.NetworkInterfaces != nil {
   658  			for _, nic := range *resp.VirtualMachineProperties.NetworkProfile.NetworkInterfaces {
   659  				if nic.NetworkInterfaceReferenceProperties != nil && *nic.NetworkInterfaceReferenceProperties.Primary {
   660  					d.Set("primary_network_interface_id", nic.ID)
   661  					break
   662  				}
   663  			}
   664  		}
   665  	}
   666  
   667  	flattenAndSetTags(d, resp.Tags)
   668  
   669  	return nil
   670  }
   671  
   672  func resourceArmVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error {
   673  	vmClient := meta.(*ArmClient).vmClient
   674  
   675  	id, err := parseAzureResourceID(d.Id())
   676  	if err != nil {
   677  		return err
   678  	}
   679  	resGroup := id.ResourceGroup
   680  	name := id.Path["virtualMachines"]
   681  
   682  	if _, err = vmClient.Delete(resGroup, name, make(chan struct{})); err != nil {
   683  		return err
   684  	}
   685  
   686  	// delete OS Disk if opted in
   687  	if deleteOsDisk := d.Get("delete_os_disk_on_termination").(bool); deleteOsDisk {
   688  		log.Printf("[INFO] delete_os_disk_on_termination is enabled, deleting")
   689  
   690  		osDisk, err := expandAzureRmVirtualMachineOsDisk(d)
   691  		if err != nil {
   692  			return fmt.Errorf("Error expanding OS Disk: %s", err)
   693  		}
   694  
   695  		if err = resourceArmVirtualMachineDeleteVhd(*osDisk.Vhd.URI, meta); err != nil {
   696  			return fmt.Errorf("Error deleting OS Disk VHD: %s", err)
   697  		}
   698  	}
   699  
   700  	// delete Data disks if opted in
   701  	if deleteDataDisks := d.Get("delete_data_disks_on_termination").(bool); deleteDataDisks {
   702  		log.Printf("[INFO] delete_data_disks_on_termination is enabled, deleting each data disk")
   703  
   704  		disks, err := expandAzureRmVirtualMachineDataDisk(d)
   705  		if err != nil {
   706  			return fmt.Errorf("Error expanding Data Disks: %s", err)
   707  		}
   708  
   709  		for _, disk := range disks {
   710  			if err = resourceArmVirtualMachineDeleteVhd(*disk.Vhd.URI, meta); err != nil {
   711  				return fmt.Errorf("Error deleting Data Disk VHD: %s", err)
   712  			}
   713  		}
   714  	}
   715  
   716  	return nil
   717  }
   718  
   719  func resourceArmVirtualMachineDeleteVhd(uri string, meta interface{}) error {
   720  	vhdURL, err := url.Parse(uri)
   721  	if err != nil {
   722  		return fmt.Errorf("Cannot parse Disk VHD URI: %s", err)
   723  	}
   724  
   725  	// VHD URI is in the form: https://storageAccountName.blob.core.windows.net/containerName/blobName
   726  	storageAccountName := strings.Split(vhdURL.Host, ".")[0]
   727  	path := strings.Split(strings.TrimPrefix(vhdURL.Path, "/"), "/")
   728  	containerName := path[0]
   729  	blobName := path[1]
   730  
   731  	storageAccountResourceGroupName, err := findStorageAccountResourceGroup(meta, storageAccountName)
   732  	if err != nil {
   733  		return fmt.Errorf("Error finding resource group for storage account %s: %s", storageAccountName, err)
   734  	}
   735  
   736  	blobClient, saExists, err := meta.(*ArmClient).getBlobStorageClientForStorageAccount(storageAccountResourceGroupName, storageAccountName)
   737  	if err != nil {
   738  		return fmt.Errorf("Error creating blob store client for VHD deletion: %s", err)
   739  	}
   740  
   741  	if !saExists {
   742  		log.Printf("[INFO] Storage Account %q in resource group %q doesn't exist so the VHD blob won't exist", storageAccountName, storageAccountResourceGroupName)
   743  		return nil
   744  	}
   745  
   746  	log.Printf("[INFO] Deleting VHD blob %s", blobName)
   747  	_, err = blobClient.DeleteBlobIfExists(containerName, blobName, nil)
   748  	if err != nil {
   749  		return fmt.Errorf("Error deleting VHD blob: %s", err)
   750  	}
   751  
   752  	return nil
   753  }
   754  
   755  func resourceArmVirtualMachinePlanHash(v interface{}) int {
   756  	var buf bytes.Buffer
   757  	m := v.(map[string]interface{})
   758  	buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
   759  	buf.WriteString(fmt.Sprintf("%s-", m["publisher"].(string)))
   760  	buf.WriteString(fmt.Sprintf("%s-", m["product"].(string)))
   761  
   762  	return hashcode.String(buf.String())
   763  }
   764  
   765  func resourceArmVirtualMachineStorageImageReferenceHash(v interface{}) int {
   766  	var buf bytes.Buffer
   767  	m := v.(map[string]interface{})
   768  	buf.WriteString(fmt.Sprintf("%s-", m["publisher"].(string)))
   769  	buf.WriteString(fmt.Sprintf("%s-", m["offer"].(string)))
   770  	buf.WriteString(fmt.Sprintf("%s-", m["sku"].(string)))
   771  
   772  	return hashcode.String(buf.String())
   773  }
   774  
   775  func resourceArmVirtualMachineStorageOsProfileHash(v interface{}) int {
   776  	var buf bytes.Buffer
   777  	m := v.(map[string]interface{})
   778  	buf.WriteString(fmt.Sprintf("%s-", m["admin_username"].(string)))
   779  	buf.WriteString(fmt.Sprintf("%s-", m["computer_name"].(string)))
   780  	return hashcode.String(buf.String())
   781  }
   782  
   783  func resourceArmVirtualMachineStorageOsDiskHash(v interface{}) int {
   784  	var buf bytes.Buffer
   785  	m := v.(map[string]interface{})
   786  	buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
   787  	buf.WriteString(fmt.Sprintf("%s-", m["vhd_uri"].(string)))
   788  
   789  	return hashcode.String(buf.String())
   790  }
   791  
   792  func resourceArmVirtualMachineStorageOsProfileLinuxConfigHash(v interface{}) int {
   793  	var buf bytes.Buffer
   794  	m := v.(map[string]interface{})
   795  	buf.WriteString(fmt.Sprintf("%t-", m["disable_password_authentication"].(bool)))
   796  
   797  	return hashcode.String(buf.String())
   798  }
   799  
   800  func resourceArmVirtualMachineStorageOsProfileWindowsConfigHash(v interface{}) int {
   801  	var buf bytes.Buffer
   802  	m := v.(map[string]interface{})
   803  	if m["provision_vm_agent"] != nil {
   804  		buf.WriteString(fmt.Sprintf("%t-", m["provision_vm_agent"].(bool)))
   805  	}
   806  	if m["enable_automatic_upgrades"] != nil {
   807  		buf.WriteString(fmt.Sprintf("%t-", m["enable_automatic_upgrades"].(bool)))
   808  	}
   809  	return hashcode.String(buf.String())
   810  }
   811  
   812  func flattenAzureRmVirtualMachinePlan(plan *compute.Plan) []interface{} {
   813  	result := make(map[string]interface{})
   814  	result["name"] = *plan.Name
   815  	result["publisher"] = *plan.Publisher
   816  	result["product"] = *plan.Product
   817  
   818  	return []interface{}{result}
   819  }
   820  
   821  func flattenAzureRmVirtualMachineImageReference(image *compute.ImageReference) []interface{} {
   822  	result := make(map[string]interface{})
   823  	result["offer"] = *image.Offer
   824  	result["publisher"] = *image.Publisher
   825  	result["sku"] = *image.Sku
   826  
   827  	if image.Version != nil {
   828  		result["version"] = *image.Version
   829  	}
   830  
   831  	return []interface{}{result}
   832  }
   833  
   834  func flattenAzureRmVirtualMachineDiagnosticsProfile(profile *compute.BootDiagnostics) []interface{} {
   835  	result := make(map[string]interface{})
   836  
   837  	result["enabled"] = *profile.Enabled
   838  	if profile.StorageURI != nil {
   839  		result["storage_uri"] = *profile.StorageURI
   840  	}
   841  
   842  	return []interface{}{result}
   843  }
   844  
   845  func flattenAzureRmVirtualMachineNetworkInterfaces(profile *compute.NetworkProfile) []string {
   846  	result := make([]string, 0, len(*profile.NetworkInterfaces))
   847  	for _, nic := range *profile.NetworkInterfaces {
   848  		result = append(result, *nic.ID)
   849  	}
   850  	return result
   851  }
   852  
   853  func flattenAzureRmVirtualMachineOsProfileSecrets(secrets *[]compute.VaultSecretGroup) []map[string]interface{} {
   854  	result := make([]map[string]interface{}, 0, len(*secrets))
   855  	for _, secret := range *secrets {
   856  		s := map[string]interface{}{
   857  			"source_vault_id": *secret.SourceVault.ID,
   858  		}
   859  
   860  		if secret.VaultCertificates != nil {
   861  			certs := make([]map[string]interface{}, 0, len(*secret.VaultCertificates))
   862  			for _, cert := range *secret.VaultCertificates {
   863  				vaultCert := make(map[string]interface{})
   864  				vaultCert["certificate_url"] = *cert.CertificateURL
   865  
   866  				if cert.CertificateStore != nil {
   867  					vaultCert["certificate_store"] = *cert.CertificateStore
   868  				}
   869  
   870  				certs = append(certs, vaultCert)
   871  			}
   872  
   873  			s["vault_certificates"] = certs
   874  		}
   875  
   876  		result = append(result, s)
   877  	}
   878  	return result
   879  }
   880  
   881  func flattenAzureRmVirtualMachineDataDisk(disks *[]compute.DataDisk) interface{} {
   882  	result := make([]interface{}, len(*disks))
   883  	for i, disk := range *disks {
   884  		l := make(map[string]interface{})
   885  		l["name"] = *disk.Name
   886  		l["vhd_uri"] = *disk.Vhd.URI
   887  		l["create_option"] = disk.CreateOption
   888  		l["caching"] = string(disk.Caching)
   889  		if disk.DiskSizeGB != nil {
   890  			l["disk_size_gb"] = *disk.DiskSizeGB
   891  		}
   892  		l["lun"] = *disk.Lun
   893  
   894  		result[i] = l
   895  	}
   896  	return result
   897  }
   898  
   899  func flattenAzureRmVirtualMachineOsProfile(osProfile *compute.OSProfile) []interface{} {
   900  	result := make(map[string]interface{})
   901  	result["computer_name"] = *osProfile.ComputerName
   902  	result["admin_username"] = *osProfile.AdminUsername
   903  	if osProfile.CustomData != nil {
   904  		result["custom_data"] = *osProfile.CustomData
   905  	}
   906  
   907  	return []interface{}{result}
   908  }
   909  
   910  func flattenAzureRmVirtualMachineOsProfileWindowsConfiguration(config *compute.WindowsConfiguration) []interface{} {
   911  	result := make(map[string]interface{})
   912  
   913  	if config.ProvisionVMAgent != nil {
   914  		result["provision_vm_agent"] = *config.ProvisionVMAgent
   915  	}
   916  
   917  	if config.EnableAutomaticUpdates != nil {
   918  		result["enable_automatic_upgrades"] = *config.EnableAutomaticUpdates
   919  	}
   920  
   921  	if config.WinRM != nil {
   922  		listeners := make([]map[string]interface{}, 0, len(*config.WinRM.Listeners))
   923  		for _, i := range *config.WinRM.Listeners {
   924  			listener := make(map[string]interface{})
   925  			listener["protocol"] = i.Protocol
   926  
   927  			if i.CertificateURL != nil {
   928  				listener["certificate_url"] = *i.CertificateURL
   929  			}
   930  
   931  			listeners = append(listeners, listener)
   932  		}
   933  
   934  		result["winrm"] = listeners
   935  	}
   936  
   937  	if config.AdditionalUnattendContent != nil {
   938  		content := make([]map[string]interface{}, 0, len(*config.AdditionalUnattendContent))
   939  		for _, i := range *config.AdditionalUnattendContent {
   940  			c := make(map[string]interface{})
   941  			c["pass"] = i.PassName
   942  			c["component"] = i.ComponentName
   943  			c["setting_name"] = i.SettingName
   944  
   945  			if i.Content != nil {
   946  				c["content"] = *i.Content
   947  			}
   948  
   949  			content = append(content, c)
   950  		}
   951  
   952  		result["additional_unattend_config"] = content
   953  	}
   954  
   955  	return []interface{}{result}
   956  }
   957  
   958  func flattenAzureRmVirtualMachineOsProfileLinuxConfiguration(config *compute.LinuxConfiguration) []interface{} {
   959  
   960  	result := make(map[string]interface{})
   961  	result["disable_password_authentication"] = *config.DisablePasswordAuthentication
   962  
   963  	if config.SSH != nil && len(*config.SSH.PublicKeys) > 0 {
   964  		ssh_keys := make([]map[string]interface{}, len(*config.SSH.PublicKeys))
   965  		for _, i := range *config.SSH.PublicKeys {
   966  			key := make(map[string]interface{})
   967  			key["path"] = *i.Path
   968  
   969  			if i.KeyData != nil {
   970  				key["key_data"] = *i.KeyData
   971  			}
   972  
   973  			ssh_keys = append(ssh_keys, key)
   974  		}
   975  
   976  		result["ssh_keys"] = ssh_keys
   977  	}
   978  
   979  	return []interface{}{result}
   980  }
   981  
   982  func flattenAzureRmVirtualMachineOsDisk(disk *compute.OSDisk) []interface{} {
   983  	result := make(map[string]interface{})
   984  	result["name"] = *disk.Name
   985  	result["vhd_uri"] = *disk.Vhd.URI
   986  	result["create_option"] = disk.CreateOption
   987  	result["caching"] = disk.Caching
   988  	if disk.DiskSizeGB != nil {
   989  		result["disk_size_gb"] = *disk.DiskSizeGB
   990  	}
   991  
   992  	return []interface{}{result}
   993  }
   994  
   995  func expandAzureRmVirtualMachinePlan(d *schema.ResourceData) (*compute.Plan, error) {
   996  	planConfigs := d.Get("plan").(*schema.Set).List()
   997  
   998  	planConfig := planConfigs[0].(map[string]interface{})
   999  
  1000  	publisher := planConfig["publisher"].(string)
  1001  	name := planConfig["name"].(string)
  1002  	product := planConfig["product"].(string)
  1003  
  1004  	return &compute.Plan{
  1005  		Publisher: &publisher,
  1006  		Name:      &name,
  1007  		Product:   &product,
  1008  	}, nil
  1009  }
  1010  
  1011  func expandAzureRmVirtualMachineOsProfile(d *schema.ResourceData) (*compute.OSProfile, error) {
  1012  	osProfiles := d.Get("os_profile").(*schema.Set).List()
  1013  
  1014  	osProfile := osProfiles[0].(map[string]interface{})
  1015  
  1016  	adminUsername := osProfile["admin_username"].(string)
  1017  	adminPassword := osProfile["admin_password"].(string)
  1018  	computerName := osProfile["computer_name"].(string)
  1019  
  1020  	profile := &compute.OSProfile{
  1021  		AdminUsername: &adminUsername,
  1022  		ComputerName:  &computerName,
  1023  	}
  1024  
  1025  	if adminPassword != "" {
  1026  		profile.AdminPassword = &adminPassword
  1027  	}
  1028  
  1029  	if _, ok := d.GetOk("os_profile_windows_config"); ok {
  1030  		winConfig, err := expandAzureRmVirtualMachineOsProfileWindowsConfig(d)
  1031  		if err != nil {
  1032  			return nil, err
  1033  		}
  1034  		if winConfig != nil {
  1035  			profile.WindowsConfiguration = winConfig
  1036  		}
  1037  	}
  1038  
  1039  	if _, ok := d.GetOk("os_profile_linux_config"); ok {
  1040  		linuxConfig, err := expandAzureRmVirtualMachineOsProfileLinuxConfig(d)
  1041  		if err != nil {
  1042  			return nil, err
  1043  		}
  1044  		if linuxConfig != nil {
  1045  			profile.LinuxConfiguration = linuxConfig
  1046  		}
  1047  	}
  1048  
  1049  	if _, ok := d.GetOk("os_profile_secrets"); ok {
  1050  		secrets := expandAzureRmVirtualMachineOsProfileSecrets(d)
  1051  		if secrets != nil {
  1052  			profile.Secrets = secrets
  1053  		}
  1054  	}
  1055  
  1056  	if v := osProfile["custom_data"].(string); v != "" {
  1057  		v = base64Encode(v)
  1058  		profile.CustomData = &v
  1059  	}
  1060  
  1061  	return profile, nil
  1062  }
  1063  
  1064  func expandAzureRmVirtualMachineOsProfileSecrets(d *schema.ResourceData) *[]compute.VaultSecretGroup {
  1065  	secretsConfig := d.Get("os_profile_secrets").(*schema.Set).List()
  1066  	secrets := make([]compute.VaultSecretGroup, 0, len(secretsConfig))
  1067  
  1068  	for _, secretConfig := range secretsConfig {
  1069  		config := secretConfig.(map[string]interface{})
  1070  		sourceVaultId := config["source_vault_id"].(string)
  1071  
  1072  		vaultSecretGroup := compute.VaultSecretGroup{
  1073  			SourceVault: &compute.SubResource{
  1074  				ID: &sourceVaultId,
  1075  			},
  1076  		}
  1077  
  1078  		if v := config["vault_certificates"]; v != nil {
  1079  			certsConfig := v.([]interface{})
  1080  			certs := make([]compute.VaultCertificate, 0, len(certsConfig))
  1081  			for _, certConfig := range certsConfig {
  1082  				config := certConfig.(map[string]interface{})
  1083  
  1084  				certUrl := config["certificate_url"].(string)
  1085  				cert := compute.VaultCertificate{
  1086  					CertificateURL: &certUrl,
  1087  				}
  1088  				if v := config["certificate_store"].(string); v != "" {
  1089  					cert.CertificateStore = &v
  1090  				}
  1091  
  1092  				certs = append(certs, cert)
  1093  			}
  1094  			vaultSecretGroup.VaultCertificates = &certs
  1095  		}
  1096  
  1097  		secrets = append(secrets, vaultSecretGroup)
  1098  	}
  1099  
  1100  	return &secrets
  1101  }
  1102  
  1103  func expandAzureRmVirtualMachineOsProfileLinuxConfig(d *schema.ResourceData) (*compute.LinuxConfiguration, error) {
  1104  	osProfilesLinuxConfig := d.Get("os_profile_linux_config").(*schema.Set).List()
  1105  
  1106  	linuxConfig := osProfilesLinuxConfig[0].(map[string]interface{})
  1107  	disablePasswordAuth := linuxConfig["disable_password_authentication"].(bool)
  1108  
  1109  	config := &compute.LinuxConfiguration{
  1110  		DisablePasswordAuthentication: &disablePasswordAuth,
  1111  	}
  1112  
  1113  	linuxKeys := linuxConfig["ssh_keys"].([]interface{})
  1114  	sshPublicKeys := []compute.SSHPublicKey{}
  1115  	for _, key := range linuxKeys {
  1116  
  1117  		sshKey, ok := key.(map[string]interface{})
  1118  		if !ok {
  1119  			continue
  1120  		}
  1121  		path := sshKey["path"].(string)
  1122  		keyData := sshKey["key_data"].(string)
  1123  
  1124  		sshPublicKey := compute.SSHPublicKey{
  1125  			Path:    &path,
  1126  			KeyData: &keyData,
  1127  		}
  1128  
  1129  		sshPublicKeys = append(sshPublicKeys, sshPublicKey)
  1130  	}
  1131  
  1132  	if len(sshPublicKeys) > 0 {
  1133  		config.SSH = &compute.SSHConfiguration{
  1134  			PublicKeys: &sshPublicKeys,
  1135  		}
  1136  	}
  1137  
  1138  	return config, nil
  1139  }
  1140  
  1141  func expandAzureRmVirtualMachineOsProfileWindowsConfig(d *schema.ResourceData) (*compute.WindowsConfiguration, error) {
  1142  	osProfilesWindowsConfig := d.Get("os_profile_windows_config").(*schema.Set).List()
  1143  
  1144  	osProfileConfig := osProfilesWindowsConfig[0].(map[string]interface{})
  1145  	config := &compute.WindowsConfiguration{}
  1146  
  1147  	if v := osProfileConfig["provision_vm_agent"]; v != nil {
  1148  		provision := v.(bool)
  1149  		config.ProvisionVMAgent = &provision
  1150  	}
  1151  
  1152  	if v := osProfileConfig["enable_automatic_upgrades"]; v != nil {
  1153  		update := v.(bool)
  1154  		config.EnableAutomaticUpdates = &update
  1155  	}
  1156  
  1157  	if v := osProfileConfig["winrm"]; v != nil {
  1158  		winRm := v.([]interface{})
  1159  		if len(winRm) > 0 {
  1160  			winRmListners := make([]compute.WinRMListener, 0, len(winRm))
  1161  			for _, winRmConfig := range winRm {
  1162  				config := winRmConfig.(map[string]interface{})
  1163  
  1164  				protocol := config["protocol"].(string)
  1165  				winRmListner := compute.WinRMListener{
  1166  					Protocol: compute.ProtocolTypes(protocol),
  1167  				}
  1168  				if v := config["certificate_url"].(string); v != "" {
  1169  					winRmListner.CertificateURL = &v
  1170  				}
  1171  
  1172  				winRmListners = append(winRmListners, winRmListner)
  1173  			}
  1174  			config.WinRM = &compute.WinRMConfiguration{
  1175  				Listeners: &winRmListners,
  1176  			}
  1177  		}
  1178  	}
  1179  	if v := osProfileConfig["additional_unattend_config"]; v != nil {
  1180  		additionalConfig := v.([]interface{})
  1181  		if len(additionalConfig) > 0 {
  1182  			additionalConfigContent := make([]compute.AdditionalUnattendContent, 0, len(additionalConfig))
  1183  			for _, addConfig := range additionalConfig {
  1184  				config := addConfig.(map[string]interface{})
  1185  				pass := config["pass"].(string)
  1186  				component := config["component"].(string)
  1187  				settingName := config["setting_name"].(string)
  1188  				content := config["content"].(string)
  1189  
  1190  				addContent := compute.AdditionalUnattendContent{
  1191  					PassName:      compute.PassNames(pass),
  1192  					ComponentName: compute.ComponentNames(component),
  1193  					SettingName:   compute.SettingNames(settingName),
  1194  					Content:       &content,
  1195  				}
  1196  
  1197  				additionalConfigContent = append(additionalConfigContent, addContent)
  1198  			}
  1199  			config.AdditionalUnattendContent = &additionalConfigContent
  1200  		}
  1201  	}
  1202  	return config, nil
  1203  }
  1204  
  1205  func expandAzureRmVirtualMachineDataDisk(d *schema.ResourceData) ([]compute.DataDisk, error) {
  1206  	disks := d.Get("storage_data_disk").([]interface{})
  1207  	data_disks := make([]compute.DataDisk, 0, len(disks))
  1208  	for _, disk_config := range disks {
  1209  		config := disk_config.(map[string]interface{})
  1210  
  1211  		name := config["name"].(string)
  1212  		vhd := config["vhd_uri"].(string)
  1213  		createOption := config["create_option"].(string)
  1214  		lun := int32(config["lun"].(int))
  1215  
  1216  		data_disk := compute.DataDisk{
  1217  			Name: &name,
  1218  			Vhd: &compute.VirtualHardDisk{
  1219  				URI: &vhd,
  1220  			},
  1221  			Lun:          &lun,
  1222  			CreateOption: compute.DiskCreateOptionTypes(createOption),
  1223  		}
  1224  
  1225  		if v := config["caching"].(string); v != "" {
  1226  			data_disk.Caching = compute.CachingTypes(v)
  1227  		}
  1228  
  1229  		if v := config["disk_size_gb"]; v != nil {
  1230  			diskSize := int32(config["disk_size_gb"].(int))
  1231  			data_disk.DiskSizeGB = &diskSize
  1232  		}
  1233  
  1234  		data_disks = append(data_disks, data_disk)
  1235  	}
  1236  
  1237  	return data_disks, nil
  1238  }
  1239  
  1240  func expandAzureRmVirtualMachineDiagnosticsProfile(d *schema.ResourceData) *compute.DiagnosticsProfile {
  1241  	bootDiagnostics := d.Get("boot_diagnostics").([]interface{})
  1242  
  1243  	diagnosticsProfile := &compute.DiagnosticsProfile{}
  1244  	if len(bootDiagnostics) > 0 {
  1245  		bootDiagnostic := bootDiagnostics[0].(map[string]interface{})
  1246  
  1247  		diagnostic := &compute.BootDiagnostics{
  1248  			Enabled:    riviera.Bool(bootDiagnostic["enabled"].(bool)),
  1249  			StorageURI: riviera.String(bootDiagnostic["storage_uri"].(string)),
  1250  		}
  1251  
  1252  		diagnosticsProfile.BootDiagnostics = diagnostic
  1253  
  1254  		return diagnosticsProfile
  1255  	}
  1256  
  1257  	return nil
  1258  }
  1259  
  1260  func expandAzureRmVirtualMachineImageReference(d *schema.ResourceData) (*compute.ImageReference, error) {
  1261  	storageImageRefs := d.Get("storage_image_reference").(*schema.Set).List()
  1262  
  1263  	storageImageRef := storageImageRefs[0].(map[string]interface{})
  1264  
  1265  	publisher := storageImageRef["publisher"].(string)
  1266  	offer := storageImageRef["offer"].(string)
  1267  	sku := storageImageRef["sku"].(string)
  1268  	version := storageImageRef["version"].(string)
  1269  
  1270  	return &compute.ImageReference{
  1271  		Publisher: &publisher,
  1272  		Offer:     &offer,
  1273  		Sku:       &sku,
  1274  		Version:   &version,
  1275  	}, nil
  1276  }
  1277  
  1278  func expandAzureRmVirtualMachineNetworkProfile(d *schema.ResourceData) compute.NetworkProfile {
  1279  	nicIds := d.Get("network_interface_ids").(*schema.Set).List()
  1280  	primaryNicId := d.Get("primary_network_interface_id").(string)
  1281  	network_interfaces := make([]compute.NetworkInterfaceReference, 0, len(nicIds))
  1282  
  1283  	network_profile := compute.NetworkProfile{}
  1284  
  1285  	for _, nic := range nicIds {
  1286  		id := nic.(string)
  1287  		primary := id == primaryNicId
  1288  
  1289  		network_interface := compute.NetworkInterfaceReference{
  1290  			ID: &id,
  1291  			NetworkInterfaceReferenceProperties: &compute.NetworkInterfaceReferenceProperties{
  1292  				Primary: &primary,
  1293  			},
  1294  		}
  1295  		network_interfaces = append(network_interfaces, network_interface)
  1296  	}
  1297  
  1298  	network_profile.NetworkInterfaces = &network_interfaces
  1299  
  1300  	return network_profile
  1301  }
  1302  
  1303  func expandAzureRmVirtualMachineOsDisk(d *schema.ResourceData) (*compute.OSDisk, error) {
  1304  	disks := d.Get("storage_os_disk").(*schema.Set).List()
  1305  
  1306  	disk := disks[0].(map[string]interface{})
  1307  
  1308  	name := disk["name"].(string)
  1309  	vhdURI := disk["vhd_uri"].(string)
  1310  	imageURI := disk["image_uri"].(string)
  1311  	createOption := disk["create_option"].(string)
  1312  
  1313  	osDisk := &compute.OSDisk{
  1314  		Name: &name,
  1315  		Vhd: &compute.VirtualHardDisk{
  1316  			URI: &vhdURI,
  1317  		},
  1318  		CreateOption: compute.DiskCreateOptionTypes(createOption),
  1319  	}
  1320  
  1321  	if v := disk["image_uri"].(string); v != "" {
  1322  		osDisk.Image = &compute.VirtualHardDisk{
  1323  			URI: &imageURI,
  1324  		}
  1325  	}
  1326  
  1327  	if v := disk["os_type"].(string); v != "" {
  1328  		if v == "linux" {
  1329  			osDisk.OsType = compute.Linux
  1330  		} else if v == "windows" {
  1331  			osDisk.OsType = compute.Windows
  1332  		} else {
  1333  			return nil, fmt.Errorf("[ERROR] os_type must be 'linux' or 'windows'")
  1334  		}
  1335  	}
  1336  
  1337  	if v := disk["caching"].(string); v != "" {
  1338  		osDisk.Caching = compute.CachingTypes(v)
  1339  	}
  1340  
  1341  	if v := disk["disk_size_gb"].(int); v != 0 {
  1342  		diskSize := int32(v)
  1343  		osDisk.DiskSizeGB = &diskSize
  1344  	}
  1345  
  1346  	return osDisk, nil
  1347  }
  1348  
  1349  func findStorageAccountResourceGroup(meta interface{}, storageAccountName string) (string, error) {
  1350  	client := meta.(*ArmClient).resourceFindClient
  1351  	filter := fmt.Sprintf("name eq '%s' and resourceType eq 'Microsoft.Storage/storageAccounts'", storageAccountName)
  1352  	expand := ""
  1353  	var pager *int32
  1354  
  1355  	rf, err := client.List(filter, expand, pager)
  1356  	if err != nil {
  1357  		return "", fmt.Errorf("Error making resource request for query %s: %s", filter, err)
  1358  	}
  1359  
  1360  	results := *rf.Value
  1361  	if len(results) != 1 {
  1362  		return "", fmt.Errorf("Wrong number of results making resource request for query %s: %d", filter, len(results))
  1363  	}
  1364  
  1365  	id, err := parseAzureResourceID(*results[0].ID)
  1366  	if err != nil {
  1367  		return "", err
  1368  	}
  1369  
  1370  	return id.ResourceGroup, nil
  1371  }