2016-01-15 23:07:25 +01:00
package azurerm
2016-06-02 02:51:57 +02:00
import (
"bytes"
"fmt"
"log"
"net/http"
2016-07-14 00:52:20 +02:00
"net/url"
2016-06-02 02:51:57 +02:00
"strings"
2017-03-02 02:10:27 +01:00
"github.com/Azure/azure-sdk-for-go/arm/compute"
2017-06-01 11:18:22 +02:00
"github.com/Azure/azure-sdk-for-go/storage"
2016-06-02 02:51:57 +02:00
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
2017-03-02 00:49:56 +01:00
"github.com/hashicorp/terraform/helper/validation"
2016-09-29 13:32:19 +02:00
riviera "github.com/jen20/riviera/azure"
2016-06-02 02:51:57 +02:00
)
func resourceArmVirtualMachine ( ) * schema . Resource {
return & schema . Resource {
Create : resourceArmVirtualMachineCreate ,
Read : resourceArmVirtualMachineRead ,
Update : resourceArmVirtualMachineCreate ,
Delete : resourceArmVirtualMachineDelete ,
2016-11-22 13:13:11 +01:00
Importer : & schema . ResourceImporter {
State : schema . ImportStatePassthrough ,
} ,
2016-06-02 02:51:57 +02:00
Schema : map [ string ] * schema . Schema {
"name" : {
Type : schema . TypeString ,
Required : true ,
ForceNew : true ,
} ,
2016-11-29 16:54:00 +01:00
"location" : locationSchema ( ) ,
2016-06-02 02:51:57 +02:00
"resource_group_name" : {
Type : schema . TypeString ,
Required : true ,
ForceNew : true ,
} ,
"plan" : {
Type : schema . TypeSet ,
Optional : true ,
2016-06-13 13:25:32 +02:00
MaxItems : 1 ,
2016-06-02 02:51:57 +02:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"name" : {
Type : schema . TypeString ,
Required : true ,
} ,
"publisher" : {
Type : schema . TypeString ,
Required : true ,
} ,
"product" : {
Type : schema . TypeString ,
Required : true ,
} ,
} ,
} ,
Set : resourceArmVirtualMachinePlanHash ,
} ,
"availability_set_id" : {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
2016-07-27 23:39:03 +02:00
ForceNew : true ,
2016-06-02 02:51:57 +02:00
StateFunc : func ( id interface { } ) string {
return strings . ToLower ( id . ( string ) )
} ,
} ,
"license_type" : {
2016-12-06 09:38:10 +01:00
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ValidateFunc : validateLicenseType ,
2016-06-02 02:51:57 +02:00
} ,
"vm_size" : {
Type : schema . TypeString ,
Required : true ,
} ,
"storage_image_reference" : {
Type : schema . TypeSet ,
Optional : true ,
Computed : true ,
2016-11-24 16:22:50 +01:00
ForceNew : true ,
2016-06-13 13:25:32 +02:00
MaxItems : 1 ,
2016-06-02 02:51:57 +02:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"publisher" : {
Type : schema . TypeString ,
Required : true ,
2016-11-24 16:22:50 +01:00
ForceNew : true ,
2016-06-02 02:51:57 +02:00
} ,
"offer" : {
Type : schema . TypeString ,
Required : true ,
2016-11-24 16:22:50 +01:00
ForceNew : true ,
2016-06-02 02:51:57 +02:00
} ,
"sku" : {
Type : schema . TypeString ,
Required : true ,
2016-11-24 16:22:50 +01:00
ForceNew : true ,
2016-06-02 02:51:57 +02:00
} ,
"version" : {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
2016-11-24 16:22:50 +01:00
ForceNew : true ,
2016-06-02 02:51:57 +02:00
} ,
} ,
} ,
Set : resourceArmVirtualMachineStorageImageReferenceHash ,
} ,
"storage_os_disk" : {
Type : schema . TypeSet ,
Required : true ,
2016-06-13 13:25:32 +02:00
MaxItems : 1 ,
2016-06-02 02:51:57 +02:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"os_type" : {
Type : schema . TypeString ,
Optional : true ,
} ,
"name" : {
Type : schema . TypeString ,
Required : true ,
} ,
"vhd_uri" : {
Type : schema . TypeString ,
2017-03-02 00:49:56 +01:00
Optional : true ,
2016-11-24 16:22:50 +01:00
ForceNew : true ,
2016-06-02 02:51:57 +02:00
} ,
2017-03-06 02:48:35 +01:00
"managed_disk_id" : {
2017-03-18 03:37:05 +01:00
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
Computed : true ,
ConflictsWith : [ ] string { "storage_os_disk.vhd_uri" } ,
2017-03-06 02:48:35 +01:00
} ,
"managed_disk_type" : {
2017-03-18 03:37:05 +01:00
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ConflictsWith : [ ] string { "storage_os_disk.vhd_uri" } ,
2017-03-06 02:48:35 +01:00
ValidateFunc : validation . StringInSlice ( [ ] string {
string ( compute . PremiumLRS ) ,
string ( compute . StandardLRS ) ,
} , true ) ,
2017-03-02 00:49:56 +01:00
} ,
2016-06-02 02:51:57 +02:00
"image_uri" : {
Type : schema . TypeString ,
Optional : true ,
} ,
"caching" : {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
} ,
"create_option" : {
2017-04-25 11:45:46 +02:00
Type : schema . TypeString ,
Required : true ,
DiffSuppressFunc : ignoreCaseDiffSuppressFunc ,
2016-06-02 02:51:57 +02:00
} ,
2016-10-25 18:54:55 +02:00
"disk_size_gb" : {
Type : schema . TypeInt ,
Optional : true ,
ValidateFunc : validateDiskSizeGB ,
} ,
2016-06-02 02:51:57 +02:00
} ,
} ,
Set : resourceArmVirtualMachineStorageOsDiskHash ,
} ,
2016-07-14 00:52:20 +02:00
"delete_os_disk_on_termination" : {
Type : schema . TypeBool ,
Optional : true ,
Default : false ,
} ,
2016-06-02 02:51:57 +02:00
"storage_data_disk" : {
Type : schema . TypeList ,
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"name" : {
Type : schema . TypeString ,
Required : true ,
} ,
"vhd_uri" : {
Type : schema . TypeString ,
2017-03-02 00:49:56 +01:00
Optional : true ,
} ,
2017-03-06 02:48:35 +01:00
"managed_disk_id" : {
2017-03-18 03:37:05 +01:00
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
Computed : true ,
ConflictsWith : [ ] string { "storage_data_disk.vhd_uri" } ,
2017-03-06 02:48:35 +01:00
} ,
"managed_disk_type" : {
2017-03-18 03:37:05 +01:00
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ConflictsWith : [ ] string { "storage_data_disk.vhd_uri" } ,
2017-03-06 02:48:35 +01:00
ValidateFunc : validation . StringInSlice ( [ ] string {
string ( compute . PremiumLRS ) ,
string ( compute . StandardLRS ) ,
} , true ) ,
2016-06-02 02:51:57 +02:00
} ,
"create_option" : {
2017-04-25 11:45:46 +02:00
Type : schema . TypeString ,
Required : true ,
DiffSuppressFunc : ignoreCaseDiffSuppressFunc ,
2016-06-02 02:51:57 +02:00
} ,
2017-01-12 14:52:40 +01:00
"caching" : {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
} ,
2016-06-02 02:51:57 +02:00
"disk_size_gb" : {
2017-03-03 23:32:16 +01:00
Type : schema . TypeInt ,
Optional : true ,
Computed : true ,
2017-03-03 21:12:00 +01:00
ValidateFunc : validateDiskSizeGB ,
2016-06-02 02:51:57 +02:00
} ,
"lun" : {
Type : schema . TypeInt ,
Required : true ,
} ,
} ,
} ,
} ,
2016-07-25 18:57:02 +02:00
"delete_data_disks_on_termination" : {
Type : schema . TypeBool ,
Optional : true ,
Default : false ,
} ,
2016-08-18 04:59:44 +02:00
"diagnostics_profile" : {
2016-09-29 13:32:19 +02:00
Type : schema . TypeSet ,
Optional : true ,
MaxItems : 1 ,
ConflictsWith : [ ] string { "boot_diagnostics" } ,
Deprecated : "Use field boot_diagnostics instead" ,
2016-08-18 04:59:44 +02:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"boot_diagnostics" : {
Type : schema . TypeSet ,
Required : true ,
MaxItems : 1 ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"enabled" : {
Type : schema . TypeBool ,
Required : true ,
} ,
"storage_uri" : {
Type : schema . TypeString ,
Required : true ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2016-09-29 13:32:19 +02:00
"boot_diagnostics" : {
Type : schema . TypeList ,
Optional : true ,
MaxItems : 1 ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"enabled" : {
Type : schema . TypeBool ,
Required : true ,
} ,
"storage_uri" : {
Type : schema . TypeString ,
Required : true ,
} ,
} ,
} ,
} ,
2016-06-02 02:51:57 +02:00
"os_profile" : {
Type : schema . TypeSet ,
2017-06-05 11:55:50 +02:00
Optional : true ,
2016-06-13 13:25:32 +02:00
MaxItems : 1 ,
2016-06-02 02:51:57 +02:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"computer_name" : {
Type : schema . TypeString ,
2016-07-14 16:48:41 +02:00
ForceNew : true ,
2016-07-20 21:03:54 +02:00
Required : true ,
2016-06-02 02:51:57 +02:00
} ,
"admin_username" : {
Type : schema . TypeString ,
Required : true ,
} ,
"admin_password" : {
Type : schema . TypeString ,
Required : true ,
} ,
"custom_data" : {
2017-03-08 22:57:51 +01:00
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
StateFunc : userDataStateFunc ,
2016-06-02 02:51:57 +02:00
} ,
} ,
} ,
Set : resourceArmVirtualMachineStorageOsProfileHash ,
} ,
"os_profile_windows_config" : {
Type : schema . TypeSet ,
Optional : true ,
2016-06-13 13:25:32 +02:00
MaxItems : 1 ,
2016-06-02 02:51:57 +02:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"provision_vm_agent" : {
Type : schema . TypeBool ,
Optional : true ,
} ,
"enable_automatic_upgrades" : {
Type : schema . TypeBool ,
Optional : true ,
} ,
"winrm" : {
2016-06-11 13:28:18 +02:00
Type : schema . TypeList ,
2016-06-02 02:51:57 +02:00
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"protocol" : {
Type : schema . TypeString ,
Required : true ,
} ,
"certificate_url" : {
Type : schema . TypeString ,
Optional : true ,
} ,
} ,
} ,
} ,
"additional_unattend_config" : {
2016-06-10 12:39:19 +02:00
Type : schema . TypeList ,
2016-06-02 02:51:57 +02:00
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"pass" : {
Type : schema . TypeString ,
Required : true ,
} ,
"component" : {
Type : schema . TypeString ,
Required : true ,
} ,
"setting_name" : {
Type : schema . TypeString ,
Required : true ,
} ,
"content" : {
Type : schema . TypeString ,
Required : true ,
} ,
} ,
} ,
} ,
} ,
} ,
Set : resourceArmVirtualMachineStorageOsProfileWindowsConfigHash ,
} ,
"os_profile_linux_config" : {
Type : schema . TypeSet ,
Optional : true ,
2016-06-13 13:25:32 +02:00
MaxItems : 1 ,
2016-06-02 02:51:57 +02:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"disable_password_authentication" : {
Type : schema . TypeBool ,
Required : true ,
} ,
"ssh_keys" : {
Type : schema . TypeList ,
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"path" : {
Type : schema . TypeString ,
Required : true ,
} ,
"key_data" : {
Type : schema . TypeString ,
Optional : true ,
} ,
} ,
} ,
} ,
} ,
} ,
Set : resourceArmVirtualMachineStorageOsProfileLinuxConfigHash ,
} ,
"os_profile_secrets" : {
Type : schema . TypeSet ,
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"source_vault_id" : {
Type : schema . TypeString ,
Required : true ,
} ,
"vault_certificates" : {
2016-07-18 11:20:18 +02:00
Type : schema . TypeList ,
2016-06-02 02:51:57 +02:00
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
"certificate_url" : {
Type : schema . TypeString ,
Required : true ,
} ,
"certificate_store" : {
Type : schema . TypeString ,
Optional : true ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
"network_interface_ids" : {
Type : schema . TypeSet ,
Required : true ,
Elem : & schema . Schema {
Type : schema . TypeString ,
} ,
Set : schema . HashString ,
} ,
2017-03-23 17:42:01 +01:00
"primary_network_interface_id" : {
Type : schema . TypeString ,
Optional : true ,
} ,
2016-06-02 02:51:57 +02:00
"tags" : tagsSchema ( ) ,
} ,
}
}
2016-12-06 09:38:10 +01:00
func validateLicenseType ( v interface { } , k string ) ( ws [ ] string , errors [ ] error ) {
value := v . ( string )
if value != "" && value != "Windows_Server" {
errors = append ( errors , fmt . Errorf (
"[ERROR] license_type must be 'Windows_Server' or empty" ) )
}
return
}
2016-06-02 02:51:57 +02:00
func resourceArmVirtualMachineCreate ( d * schema . ResourceData , meta interface { } ) error {
client := meta . ( * ArmClient )
vmClient := client . vmClient
log . Printf ( "[INFO] preparing arguments for Azure ARM Virtual Machine creation." )
name := d . Get ( "name" ) . ( string )
location := d . Get ( "location" ) . ( string )
resGroup := d . Get ( "resource_group_name" ) . ( string )
tags := d . Get ( "tags" ) . ( map [ string ] interface { } )
expandedTags := expandTags ( tags )
osDisk , err := expandAzureRmVirtualMachineOsDisk ( d )
if err != nil {
return err
}
storageProfile := compute . StorageProfile {
OsDisk : osDisk ,
}
if _ , ok := d . GetOk ( "storage_image_reference" ) ; ok {
imageRef , err := expandAzureRmVirtualMachineImageReference ( d )
if err != nil {
return err
}
storageProfile . ImageReference = imageRef
}
if _ , ok := d . GetOk ( "storage_data_disk" ) ; ok {
dataDisks , err := expandAzureRmVirtualMachineDataDisk ( d )
if err != nil {
return err
}
storageProfile . DataDisks = & dataDisks
}
networkProfile := expandAzureRmVirtualMachineNetworkProfile ( d )
vmSize := d . Get ( "vm_size" ) . ( string )
properties := compute . VirtualMachineProperties {
NetworkProfile : & networkProfile ,
HardwareProfile : & compute . HardwareProfile {
VMSize : compute . VirtualMachineSizeTypes ( vmSize ) ,
} ,
StorageProfile : & storageProfile ,
2016-12-07 00:43:18 +01:00
}
2016-12-07 11:22:39 +01:00
if v , ok := d . GetOk ( "license_type" ) ; ok {
2016-12-07 00:43:18 +01:00
license := v . ( string )
properties . LicenseType = & license
2016-06-02 02:51:57 +02:00
}
2016-09-29 13:32:19 +02:00
if _ , ok := d . GetOk ( "boot_diagnostics" ) ; ok {
2016-08-18 04:59:44 +02:00
diagnosticsProfile := expandAzureRmVirtualMachineDiagnosticsProfile ( d )
2016-09-29 13:32:19 +02:00
if diagnosticsProfile != nil {
properties . DiagnosticsProfile = diagnosticsProfile
}
2016-08-18 04:59:44 +02:00
}
2017-06-05 11:55:50 +02:00
if _ , ok := d . GetOk ( "os_profile" ) ; ok {
osProfile , err := expandAzureRmVirtualMachineOsProfile ( d )
if err != nil {
return err
}
properties . OsProfile = osProfile
2016-06-02 02:51:57 +02:00
}
if v , ok := d . GetOk ( "availability_set_id" ) ; ok {
availabilitySet := v . ( string )
availSet := compute . SubResource {
ID : & availabilitySet ,
}
properties . AvailabilitySet = & availSet
}
vm := compute . VirtualMachine {
2016-12-06 09:39:47 +01:00
Name : & name ,
Location : & location ,
VirtualMachineProperties : & properties ,
Tags : expandedTags ,
2016-06-02 02:51:57 +02:00
}
if _ , ok := d . GetOk ( "plan" ) ; ok {
plan , err := expandAzureRmVirtualMachinePlan ( d )
if err != nil {
return err
}
vm . Plan = plan
}
2017-06-01 11:18:22 +02:00
_ , vmError := vmClient . CreateOrUpdate ( resGroup , name , vm , make ( chan struct { } ) )
vmErr := <- vmError
2016-06-02 02:51:57 +02:00
if vmErr != nil {
return vmErr
}
read , err := vmClient . Get ( resGroup , name , "" )
if err != nil {
return err
}
if read . ID == nil {
return fmt . Errorf ( "Cannot read Virtual Machine %s (resource group %s) ID" , name , resGroup )
}
d . SetId ( * read . ID )
return resourceArmVirtualMachineRead ( d , meta )
}
func resourceArmVirtualMachineRead ( d * schema . ResourceData , meta interface { } ) error {
vmClient := meta . ( * ArmClient ) . vmClient
id , err := parseAzureResourceID ( d . Id ( ) )
if err != nil {
return err
}
resGroup := id . ResourceGroup
name := id . Path [ "virtualMachines" ]
resp , err := vmClient . Get ( resGroup , name , "" )
provider/azurerm: Reordering the checks after an Azure API Get
We are receiving suggestions of a panic as follows:
```
2016/09/01 07:21:55 [DEBUG] plugin: terraform: panic: runtime error: invalid memory address or nil pointer dereference
2016/09/01 07:21:55 [DEBUG] plugin: terraform: [signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0xa3170f]
2016/09/01 07:21:55 [DEBUG] plugin: terraform:
2016/09/01 07:21:55 [DEBUG] plugin: terraform: goroutine 114 [running]:
2016/09/01 07:21:55 [DEBUG] plugin: terraform: panic(0x27f4e60, 0xc4200100e0)
2016/09/01 07:21:55 [DEBUG] plugin: terraform: /opt/go/src/runtime/panic.go:500 +0x1a1
2016/09/01 07:21:55 [DEBUG] plugin: terraform: github.com/hashicorp/terraform/builtin/providers/azurerm.resourceArmVirtualMachineRead(0xc4206d8060, 0x2995620, 0xc4204d0000, 0x0, 0x17)
2016/09/01 07:21:55 [DEBUG] plugin: terraform: /opt/gopath/src/github.com/hashicorp/terraform/builtin/providers/azurerm/resource_arm_virtual_machine.go:488 +0x1ff
2016/09/01 07:21:55 [DEBUG] plugin: terraform: github.com/hashicorp/terraform/helper/schema.(*Resource).Refresh(0xc420017a40, 0xc42040c780, 0x2995620, 0xc4204d0000, 0xc42019c990, 0x1, 0x0)
```
This is because the code is as follows:
```
resp, err := client.Get(resGroup, vnetName, name)
if resp.StatusCode == http.StatusNotFound {
d.SetId("")
return nil
}
if err != nil {
return fmt.Errorf("Error making Read request on Azure virtual network peering %s: %s", name, err)
}
```
When a request throws an error, the response object isn't valid. Therefore, we need to flip that code to check the error first
```
resp, err := client.Get(resGroup, vnetName, name)
if err != nil {
return fmt.Errorf("Error making Read request on Azure virtual network peering %s: %s", name, err)
}
if resp.StatusCode == http.StatusNotFound {
d.SetId("")
return nil
}
```
2016-09-01 16:31:42 +02:00
if err != nil {
2016-09-30 18:57:59 +02:00
if resp . StatusCode == http . StatusNotFound {
d . SetId ( "" )
return nil
}
provider/azurerm: Reordering the checks after an Azure API Get
We are receiving suggestions of a panic as follows:
```
2016/09/01 07:21:55 [DEBUG] plugin: terraform: panic: runtime error: invalid memory address or nil pointer dereference
2016/09/01 07:21:55 [DEBUG] plugin: terraform: [signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0xa3170f]
2016/09/01 07:21:55 [DEBUG] plugin: terraform:
2016/09/01 07:21:55 [DEBUG] plugin: terraform: goroutine 114 [running]:
2016/09/01 07:21:55 [DEBUG] plugin: terraform: panic(0x27f4e60, 0xc4200100e0)
2016/09/01 07:21:55 [DEBUG] plugin: terraform: /opt/go/src/runtime/panic.go:500 +0x1a1
2016/09/01 07:21:55 [DEBUG] plugin: terraform: github.com/hashicorp/terraform/builtin/providers/azurerm.resourceArmVirtualMachineRead(0xc4206d8060, 0x2995620, 0xc4204d0000, 0x0, 0x17)
2016/09/01 07:21:55 [DEBUG] plugin: terraform: /opt/gopath/src/github.com/hashicorp/terraform/builtin/providers/azurerm/resource_arm_virtual_machine.go:488 +0x1ff
2016/09/01 07:21:55 [DEBUG] plugin: terraform: github.com/hashicorp/terraform/helper/schema.(*Resource).Refresh(0xc420017a40, 0xc42040c780, 0x2995620, 0xc4204d0000, 0xc42019c990, 0x1, 0x0)
```
This is because the code is as follows:
```
resp, err := client.Get(resGroup, vnetName, name)
if resp.StatusCode == http.StatusNotFound {
d.SetId("")
return nil
}
if err != nil {
return fmt.Errorf("Error making Read request on Azure virtual network peering %s: %s", name, err)
}
```
When a request throws an error, the response object isn't valid. Therefore, we need to flip that code to check the error first
```
resp, err := client.Get(resGroup, vnetName, name)
if err != nil {
return fmt.Errorf("Error making Read request on Azure virtual network peering %s: %s", name, err)
}
if resp.StatusCode == http.StatusNotFound {
d.SetId("")
return nil
}
```
2016-09-01 16:31:42 +02:00
return fmt . Errorf ( "Error making Read request on Azure Virtual Machine %s: %s" , name , err )
}
2016-06-02 02:51:57 +02:00
2016-11-22 13:13:11 +01:00
d . Set ( "name" , resp . Name )
d . Set ( "resource_group_name" , resGroup )
d . Set ( "location" , resp . Location )
2016-06-02 02:51:57 +02:00
if resp . Plan != nil {
2016-12-09 10:41:45 +01:00
if err := d . Set ( "plan" , schema . NewSet ( resourceArmVirtualMachinePlanHash , flattenAzureRmVirtualMachinePlan ( resp . Plan ) ) ) ; err != nil {
2016-06-02 02:51:57 +02:00
return fmt . Errorf ( "[DEBUG] Error setting Virtual Machine Plan error: %#v" , err )
}
}
2016-12-06 09:39:47 +01:00
if resp . VirtualMachineProperties . AvailabilitySet != nil {
d . Set ( "availability_set_id" , strings . ToLower ( * resp . VirtualMachineProperties . AvailabilitySet . ID ) )
2016-06-02 02:51:57 +02:00
}
2016-12-06 09:39:47 +01:00
d . Set ( "vm_size" , resp . VirtualMachineProperties . HardwareProfile . VMSize )
2016-06-02 02:51:57 +02:00
2016-12-06 09:39:47 +01:00
if resp . VirtualMachineProperties . StorageProfile . ImageReference != nil {
if err := d . Set ( "storage_image_reference" , schema . NewSet ( resourceArmVirtualMachineStorageImageReferenceHash , flattenAzureRmVirtualMachineImageReference ( resp . VirtualMachineProperties . StorageProfile . ImageReference ) ) ) ; err != nil {
2016-06-02 02:51:57 +02:00
return fmt . Errorf ( "[DEBUG] Error setting Virtual Machine Storage Image Reference error: %#v" , err )
}
}
2016-12-06 09:39:47 +01:00
if err := d . Set ( "storage_os_disk" , schema . NewSet ( resourceArmVirtualMachineStorageOsDiskHash , flattenAzureRmVirtualMachineOsDisk ( resp . VirtualMachineProperties . StorageProfile . OsDisk ) ) ) ; err != nil {
2016-06-02 02:51:57 +02:00
return fmt . Errorf ( "[DEBUG] Error setting Virtual Machine Storage OS Disk error: %#v" , err )
}
2016-12-06 09:39:47 +01:00
if resp . VirtualMachineProperties . StorageProfile . DataDisks != nil {
if err := d . Set ( "storage_data_disk" , flattenAzureRmVirtualMachineDataDisk ( resp . VirtualMachineProperties . StorageProfile . DataDisks ) ) ; err != nil {
2016-06-02 02:51:57 +02:00
return fmt . Errorf ( "[DEBUG] Error setting Virtual Machine Storage Data Disks error: %#v" , err )
}
}
2017-06-05 11:55:50 +02:00
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 )
}
2016-06-02 02:51:57 +02:00
2017-06-05 11:55:50 +02:00
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 )
}
2016-06-02 02:51:57 +02:00
}
2017-06-05 11:55:50 +02:00
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 )
}
2016-06-02 02:51:57 +02:00
}
2017-06-05 11:55:50 +02:00
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 )
}
2016-06-02 02:51:57 +02:00
}
}
2016-12-06 09:39:47 +01:00
if resp . VirtualMachineProperties . DiagnosticsProfile != nil && resp . VirtualMachineProperties . DiagnosticsProfile . BootDiagnostics != nil {
if err := d . Set ( "boot_diagnostics" , flattenAzureRmVirtualMachineDiagnosticsProfile ( resp . VirtualMachineProperties . DiagnosticsProfile . BootDiagnostics ) ) ; err != nil {
2016-08-18 04:59:44 +02:00
return fmt . Errorf ( "[DEBUG] Error setting Virtual Machine Diagnostics Profile: %#v" , err )
}
}
2016-12-06 09:39:47 +01:00
if resp . VirtualMachineProperties . NetworkProfile != nil {
if err := d . Set ( "network_interface_ids" , flattenAzureRmVirtualMachineNetworkInterfaces ( resp . VirtualMachineProperties . NetworkProfile ) ) ; err != nil {
2016-06-02 02:51:57 +02:00
return fmt . Errorf ( "[DEBUG] Error setting Virtual Machine Storage Network Interfaces: %#v" , err )
}
2017-03-23 17:42:01 +01:00
if resp . VirtualMachineProperties . NetworkProfile . NetworkInterfaces != nil {
for _ , nic := range * resp . VirtualMachineProperties . NetworkProfile . NetworkInterfaces {
if nic . NetworkInterfaceReferenceProperties != nil && * nic . NetworkInterfaceReferenceProperties . Primary {
d . Set ( "primary_network_interface_id" , nic . ID )
break
}
}
}
2016-06-02 02:51:57 +02:00
}
flattenAndSetTags ( d , resp . Tags )
return nil
}
func resourceArmVirtualMachineDelete ( d * schema . ResourceData , meta interface { } ) error {
vmClient := meta . ( * ArmClient ) . vmClient
id , err := parseAzureResourceID ( d . Id ( ) )
if err != nil {
return err
}
resGroup := id . ResourceGroup
name := id . Path [ "virtualMachines" ]
2017-06-01 11:18:22 +02:00
_ , error := vmClient . Delete ( resGroup , name , make ( chan struct { } ) )
err = <- error
if err != nil {
2016-07-14 00:52:20 +02:00
return err
}
2016-07-25 18:57:02 +02:00
// delete OS Disk if opted in
if deleteOsDisk := d . Get ( "delete_os_disk_on_termination" ) . ( bool ) ; deleteOsDisk {
2017-03-06 02:48:35 +01:00
log . Printf ( "[INFO] delete_os_disk_on_termination is enabled, deleting disk from %s" , name )
2016-07-25 18:57:02 +02:00
osDisk , err := expandAzureRmVirtualMachineOsDisk ( d )
if err != nil {
return fmt . Errorf ( "Error expanding OS Disk: %s" , err )
}
2017-03-06 02:48:35 +01:00
if osDisk . Vhd != nil {
if err = resourceArmVirtualMachineDeleteVhd ( * osDisk . Vhd . URI , meta ) ; err != nil {
return fmt . Errorf ( "Error deleting OS Disk VHD: %s" , err )
}
} else if osDisk . ManagedDisk != nil {
if err = resourceArmVirtualMachineDeleteManagedDisk ( * osDisk . ManagedDisk . ID , meta ) ; err != nil {
return fmt . Errorf ( "Error deleting OS Managed Disk: %s" , err )
}
} else {
return fmt . Errorf ( "Unable to locate OS managed disk properties from %s" , name )
2016-07-25 18:57:02 +02:00
}
2016-07-14 00:52:20 +02:00
}
2016-07-25 18:57:02 +02:00
// delete Data disks if opted in
if deleteDataDisks := d . Get ( "delete_data_disks_on_termination" ) . ( bool ) ; deleteDataDisks {
2017-03-06 02:48:35 +01:00
log . Printf ( "[INFO] delete_data_disks_on_termination is enabled, deleting each data disk from %s" , name )
2016-07-25 18:57:02 +02:00
disks , err := expandAzureRmVirtualMachineDataDisk ( d )
if err != nil {
return fmt . Errorf ( "Error expanding Data Disks: %s" , err )
}
for _ , disk := range disks {
2017-03-06 02:48:35 +01:00
if disk . Vhd != nil {
if err = resourceArmVirtualMachineDeleteVhd ( * disk . Vhd . URI , meta ) ; err != nil {
2017-03-14 20:07:02 +01:00
return fmt . Errorf ( "Error deleting Data Disk VHD: %s" , err )
2017-03-06 02:48:35 +01:00
}
} else if disk . ManagedDisk != nil {
if err = resourceArmVirtualMachineDeleteManagedDisk ( * disk . ManagedDisk . ID , meta ) ; err != nil {
return fmt . Errorf ( "Error deleting Data Managed Disk: %s" , err )
}
} else {
return fmt . Errorf ( "Unable to locate data managed disk properties from %s" , name )
2016-07-25 18:57:02 +02:00
}
}
2016-07-14 00:52:20 +02:00
}
2016-07-25 18:57:02 +02:00
return nil
}
2016-10-27 17:42:47 +02:00
func resourceArmVirtualMachineDeleteVhd ( uri string , meta interface { } ) error {
2016-07-25 18:57:02 +02:00
vhdURL , err := url . Parse ( uri )
2016-07-14 00:52:20 +02:00
if err != nil {
2016-07-25 18:57:02 +02:00
return fmt . Errorf ( "Cannot parse Disk VHD URI: %s" , err )
2016-07-14 00:52:20 +02:00
}
2016-06-02 02:51:57 +02:00
2016-07-14 00:52:20 +02:00
// VHD URI is in the form: https://storageAccountName.blob.core.windows.net/containerName/blobName
storageAccountName := strings . Split ( vhdURL . Host , "." ) [ 0 ]
path := strings . Split ( strings . TrimPrefix ( vhdURL . Path , "/" ) , "/" )
containerName := path [ 0 ]
blobName := path [ 1 ]
2016-10-27 17:42:47 +02:00
storageAccountResourceGroupName , err := findStorageAccountResourceGroup ( meta , storageAccountName )
if err != nil {
return fmt . Errorf ( "Error finding resource group for storage account %s: %s" , storageAccountName , err )
}
blobClient , saExists , err := meta . ( * ArmClient ) . getBlobStorageClientForStorageAccount ( storageAccountResourceGroupName , storageAccountName )
2016-07-14 00:52:20 +02:00
if err != nil {
2016-07-25 18:57:02 +02:00
return fmt . Errorf ( "Error creating blob store client for VHD deletion: %s" , err )
2016-07-14 00:52:20 +02:00
}
2016-07-25 18:57:02 +02:00
if ! saExists {
2016-10-27 17:42:47 +02:00
log . Printf ( "[INFO] Storage Account %q in resource group %q doesn't exist so the VHD blob won't exist" , storageAccountName , storageAccountResourceGroupName )
2016-07-14 00:52:20 +02:00
return nil
}
log . Printf ( "[INFO] Deleting VHD blob %s" , blobName )
2017-06-01 11:18:22 +02:00
container := blobClient . GetContainerReference ( containerName )
blob := container . GetBlobReference ( blobName )
options := & storage . DeleteBlobOptions { }
err = blob . Delete ( options )
2016-07-14 00:52:20 +02:00
if err != nil {
return fmt . Errorf ( "Error deleting VHD blob: %s" , err )
}
return nil
2016-06-02 02:51:57 +02:00
}
2017-03-06 02:48:35 +01:00
func resourceArmVirtualMachineDeleteManagedDisk ( managedDiskID string , meta interface { } ) error {
diskClient := meta . ( * ArmClient ) . diskClient
id , err := parseAzureResourceID ( managedDiskID )
if err != nil {
return err
}
resGroup := id . ResourceGroup
name := id . Path [ "disks" ]
2017-06-01 11:18:22 +02:00
_ , error := diskClient . Delete ( resGroup , name , make ( chan struct { } ) )
err = <- error
2017-03-06 02:48:35 +01:00
if err != nil {
return fmt . Errorf ( "Error deleting Managed Disk (%s %s) %s" , name , resGroup , err )
}
return nil
}
2016-06-02 02:51:57 +02:00
func resourceArmVirtualMachinePlanHash ( v interface { } ) int {
var buf bytes . Buffer
m := v . ( map [ string ] interface { } )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "name" ] . ( string ) ) )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "publisher" ] . ( string ) ) )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "product" ] . ( string ) ) )
return hashcode . String ( buf . String ( ) )
}
func resourceArmVirtualMachineStorageImageReferenceHash ( v interface { } ) int {
var buf bytes . Buffer
m := v . ( map [ string ] interface { } )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "publisher" ] . ( string ) ) )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "offer" ] . ( string ) ) )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "sku" ] . ( string ) ) )
return hashcode . String ( buf . String ( ) )
}
func resourceArmVirtualMachineStorageOsProfileHash ( v interface { } ) int {
var buf bytes . Buffer
m := v . ( map [ string ] interface { } )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "admin_username" ] . ( string ) ) )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "computer_name" ] . ( string ) ) )
return hashcode . String ( buf . String ( ) )
}
func resourceArmVirtualMachineStorageOsDiskHash ( v interface { } ) int {
var buf bytes . Buffer
m := v . ( map [ string ] interface { } )
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "name" ] . ( string ) ) )
2017-03-02 00:49:56 +01:00
if m [ "vhd_uri" ] != nil {
buf . WriteString ( fmt . Sprintf ( "%s-" , m [ "vhd_uri" ] . ( string ) ) )
}
2016-06-02 02:51:57 +02:00
return hashcode . String ( buf . String ( ) )
}
func resourceArmVirtualMachineStorageOsProfileLinuxConfigHash ( v interface { } ) int {
var buf bytes . Buffer
m := v . ( map [ string ] interface { } )
buf . WriteString ( fmt . Sprintf ( "%t-" , m [ "disable_password_authentication" ] . ( bool ) ) )
return hashcode . String ( buf . String ( ) )
}
func resourceArmVirtualMachineStorageOsProfileWindowsConfigHash ( v interface { } ) int {
var buf bytes . Buffer
m := v . ( map [ string ] interface { } )
if m [ "provision_vm_agent" ] != nil {
buf . WriteString ( fmt . Sprintf ( "%t-" , m [ "provision_vm_agent" ] . ( bool ) ) )
}
if m [ "enable_automatic_upgrades" ] != nil {
buf . WriteString ( fmt . Sprintf ( "%t-" , m [ "enable_automatic_upgrades" ] . ( bool ) ) )
}
return hashcode . String ( buf . String ( ) )
}
2016-12-09 10:41:45 +01:00
func flattenAzureRmVirtualMachinePlan ( plan * compute . Plan ) [ ] interface { } {
2016-06-02 02:51:57 +02:00
result := make ( map [ string ] interface { } )
result [ "name" ] = * plan . Name
result [ "publisher" ] = * plan . Publisher
result [ "product" ] = * plan . Product
2016-12-09 10:41:45 +01:00
return [ ] interface { } { result }
2016-06-02 02:51:57 +02:00
}
func flattenAzureRmVirtualMachineImageReference ( image * compute . ImageReference ) [ ] interface { } {
result := make ( map [ string ] interface { } )
result [ "offer" ] = * image . Offer
result [ "publisher" ] = * image . Publisher
result [ "sku" ] = * image . Sku
if image . Version != nil {
result [ "version" ] = * image . Version
}
return [ ] interface { } { result }
}
2016-09-29 13:32:19 +02:00
func flattenAzureRmVirtualMachineDiagnosticsProfile ( profile * compute . BootDiagnostics ) [ ] interface { } {
2016-08-18 04:59:44 +02:00
result := make ( map [ string ] interface { } )
2016-09-29 13:32:19 +02:00
result [ "enabled" ] = * profile . Enabled
2016-11-22 12:39:35 +01:00
if profile . StorageURI != nil {
result [ "storage_uri" ] = * profile . StorageURI
}
2016-09-29 13:32:19 +02:00
return [ ] interface { } { result }
2016-08-18 04:59:44 +02:00
}
2016-06-02 02:51:57 +02:00
func flattenAzureRmVirtualMachineNetworkInterfaces ( profile * compute . NetworkProfile ) [ ] string {
result := make ( [ ] string , 0 , len ( * profile . NetworkInterfaces ) )
for _ , nic := range * profile . NetworkInterfaces {
result = append ( result , * nic . ID )
}
return result
}
func flattenAzureRmVirtualMachineOsProfileSecrets ( secrets * [ ] compute . VaultSecretGroup ) [ ] map [ string ] interface { } {
result := make ( [ ] map [ string ] interface { } , 0 , len ( * secrets ) )
for _ , secret := range * secrets {
s := map [ string ] interface { } {
"source_vault_id" : * secret . SourceVault . ID ,
}
if secret . VaultCertificates != nil {
certs := make ( [ ] map [ string ] interface { } , 0 , len ( * secret . VaultCertificates ) )
for _ , cert := range * secret . VaultCertificates {
vaultCert := make ( map [ string ] interface { } )
vaultCert [ "certificate_url" ] = * cert . CertificateURL
if cert . CertificateStore != nil {
vaultCert [ "certificate_store" ] = * cert . CertificateStore
}
certs = append ( certs , vaultCert )
}
s [ "vault_certificates" ] = certs
}
result = append ( result , s )
}
return result
}
func flattenAzureRmVirtualMachineDataDisk ( disks * [ ] compute . DataDisk ) interface { } {
result := make ( [ ] interface { } , len ( * disks ) )
for i , disk := range * disks {
l := make ( map [ string ] interface { } )
l [ "name" ] = * disk . Name
2017-03-02 00:49:56 +01:00
if disk . Vhd != nil {
l [ "vhd_uri" ] = * disk . Vhd . URI
}
if disk . ManagedDisk != nil {
2017-03-06 02:48:35 +01:00
l [ "managed_disk_type" ] = string ( disk . ManagedDisk . StorageAccountType )
l [ "managed_disk_id" ] = * disk . ManagedDisk . ID
2017-03-02 00:49:56 +01:00
}
2016-06-02 02:51:57 +02:00
l [ "create_option" ] = disk . CreateOption
2017-01-12 14:52:40 +01:00
l [ "caching" ] = string ( disk . Caching )
2016-11-18 23:08:49 +01:00
if disk . DiskSizeGB != nil {
l [ "disk_size_gb" ] = * disk . DiskSizeGB
}
2016-06-02 02:51:57 +02:00
l [ "lun" ] = * disk . Lun
result [ i ] = l
}
return result
}
func flattenAzureRmVirtualMachineOsProfile ( osProfile * compute . OSProfile ) [ ] interface { } {
result := make ( map [ string ] interface { } )
result [ "computer_name" ] = * osProfile . ComputerName
result [ "admin_username" ] = * osProfile . AdminUsername
if osProfile . CustomData != nil {
2017-03-08 22:57:51 +01:00
result [ "custom_data" ] = * osProfile . CustomData
2016-06-02 02:51:57 +02:00
}
return [ ] interface { } { result }
}
func flattenAzureRmVirtualMachineOsProfileWindowsConfiguration ( config * compute . WindowsConfiguration ) [ ] interface { } {
result := make ( map [ string ] interface { } )
if config . ProvisionVMAgent != nil {
result [ "provision_vm_agent" ] = * config . ProvisionVMAgent
}
if config . EnableAutomaticUpdates != nil {
result [ "enable_automatic_upgrades" ] = * config . EnableAutomaticUpdates
}
if config . WinRM != nil {
listeners := make ( [ ] map [ string ] interface { } , 0 , len ( * config . WinRM . Listeners ) )
for _ , i := range * config . WinRM . Listeners {
listener := make ( map [ string ] interface { } )
listener [ "protocol" ] = i . Protocol
if i . CertificateURL != nil {
listener [ "certificate_url" ] = * i . CertificateURL
}
listeners = append ( listeners , listener )
}
result [ "winrm" ] = listeners
}
if config . AdditionalUnattendContent != nil {
content := make ( [ ] map [ string ] interface { } , 0 , len ( * config . AdditionalUnattendContent ) )
for _ , i := range * config . AdditionalUnattendContent {
c := make ( map [ string ] interface { } )
c [ "pass" ] = i . PassName
c [ "component" ] = i . ComponentName
c [ "setting_name" ] = i . SettingName
2016-07-03 12:31:35 +02:00
if i . Content != nil {
c [ "content" ] = * i . Content
}
2016-06-02 02:51:57 +02:00
content = append ( content , c )
}
result [ "additional_unattend_config" ] = content
}
return [ ] interface { } { result }
}
func flattenAzureRmVirtualMachineOsProfileLinuxConfiguration ( config * compute . LinuxConfiguration ) [ ] interface { } {
result := make ( map [ string ] interface { } )
result [ "disable_password_authentication" ] = * config . DisablePasswordAuthentication
if config . SSH != nil && len ( * config . SSH . PublicKeys ) > 0 {
2017-04-18 01:05:20 +02:00
ssh_keys := make ( [ ] map [ string ] interface { } , 0 , len ( * config . SSH . PublicKeys ) )
2016-06-02 02:51:57 +02:00
for _ , i := range * config . SSH . PublicKeys {
key := make ( map [ string ] interface { } )
key [ "path" ] = * i . Path
if i . KeyData != nil {
key [ "key_data" ] = * i . KeyData
}
ssh_keys = append ( ssh_keys , key )
}
result [ "ssh_keys" ] = ssh_keys
}
return [ ] interface { } { result }
}
func flattenAzureRmVirtualMachineOsDisk ( disk * compute . OSDisk ) [ ] interface { } {
result := make ( map [ string ] interface { } )
result [ "name" ] = * disk . Name
2017-03-02 00:49:56 +01:00
if disk . Vhd != nil {
result [ "vhd_uri" ] = * disk . Vhd . URI
}
if disk . ManagedDisk != nil {
2017-03-06 02:48:35 +01:00
result [ "managed_disk_type" ] = string ( disk . ManagedDisk . StorageAccountType )
result [ "managed_disk_id" ] = * disk . ManagedDisk . ID
2017-03-02 00:49:56 +01:00
}
2016-06-02 02:51:57 +02:00
result [ "create_option" ] = disk . CreateOption
result [ "caching" ] = disk . Caching
2016-10-25 18:54:55 +02:00
if disk . DiskSizeGB != nil {
result [ "disk_size_gb" ] = * disk . DiskSizeGB
}
2016-06-02 02:51:57 +02:00
return [ ] interface { } { result }
}
func expandAzureRmVirtualMachinePlan ( d * schema . ResourceData ) ( * compute . Plan , error ) {
planConfigs := d . Get ( "plan" ) . ( * schema . Set ) . List ( )
planConfig := planConfigs [ 0 ] . ( map [ string ] interface { } )
publisher := planConfig [ "publisher" ] . ( string )
name := planConfig [ "name" ] . ( string )
product := planConfig [ "product" ] . ( string )
return & compute . Plan {
Publisher : & publisher ,
Name : & name ,
Product : & product ,
} , nil
}
func expandAzureRmVirtualMachineOsProfile ( d * schema . ResourceData ) ( * compute . OSProfile , error ) {
osProfiles := d . Get ( "os_profile" ) . ( * schema . Set ) . List ( )
osProfile := osProfiles [ 0 ] . ( map [ string ] interface { } )
adminUsername := osProfile [ "admin_username" ] . ( string )
adminPassword := osProfile [ "admin_password" ] . ( string )
2016-07-20 21:03:54 +02:00
computerName := osProfile [ "computer_name" ] . ( string )
2016-06-02 02:51:57 +02:00
profile := & compute . OSProfile {
AdminUsername : & adminUsername ,
2016-07-20 21:03:54 +02:00
ComputerName : & computerName ,
2016-06-02 02:51:57 +02:00
}
if adminPassword != "" {
profile . AdminPassword = & adminPassword
}
if _ , ok := d . GetOk ( "os_profile_windows_config" ) ; ok {
winConfig , err := expandAzureRmVirtualMachineOsProfileWindowsConfig ( d )
if err != nil {
return nil , err
}
if winConfig != nil {
profile . WindowsConfiguration = winConfig
}
}
if _ , ok := d . GetOk ( "os_profile_linux_config" ) ; ok {
linuxConfig , err := expandAzureRmVirtualMachineOsProfileLinuxConfig ( d )
if err != nil {
return nil , err
}
if linuxConfig != nil {
profile . LinuxConfiguration = linuxConfig
}
}
if _ , ok := d . GetOk ( "os_profile_secrets" ) ; ok {
secrets := expandAzureRmVirtualMachineOsProfileSecrets ( d )
if secrets != nil {
profile . Secrets = secrets
}
}
if v := osProfile [ "custom_data" ] . ( string ) ; v != "" {
2017-03-08 22:57:51 +01:00
v = base64Encode ( v )
2016-06-02 02:51:57 +02:00
profile . CustomData = & v
}
return profile , nil
}
func expandAzureRmVirtualMachineOsProfileSecrets ( d * schema . ResourceData ) * [ ] compute . VaultSecretGroup {
secretsConfig := d . Get ( "os_profile_secrets" ) . ( * schema . Set ) . List ( )
secrets := make ( [ ] compute . VaultSecretGroup , 0 , len ( secretsConfig ) )
for _ , secretConfig := range secretsConfig {
config := secretConfig . ( map [ string ] interface { } )
sourceVaultId := config [ "source_vault_id" ] . ( string )
vaultSecretGroup := compute . VaultSecretGroup {
SourceVault : & compute . SubResource {
ID : & sourceVaultId ,
} ,
}
if v := config [ "vault_certificates" ] ; v != nil {
2016-07-18 11:20:18 +02:00
certsConfig := v . ( [ ] interface { } )
2016-06-02 02:51:57 +02:00
certs := make ( [ ] compute . VaultCertificate , 0 , len ( certsConfig ) )
for _ , certConfig := range certsConfig {
config := certConfig . ( map [ string ] interface { } )
certUrl := config [ "certificate_url" ] . ( string )
cert := compute . VaultCertificate {
CertificateURL : & certUrl ,
}
if v := config [ "certificate_store" ] . ( string ) ; v != "" {
cert . CertificateStore = & v
}
certs = append ( certs , cert )
}
vaultSecretGroup . VaultCertificates = & certs
}
secrets = append ( secrets , vaultSecretGroup )
}
return & secrets
}
func expandAzureRmVirtualMachineOsProfileLinuxConfig ( d * schema . ResourceData ) ( * compute . LinuxConfiguration , error ) {
osProfilesLinuxConfig := d . Get ( "os_profile_linux_config" ) . ( * schema . Set ) . List ( )
linuxConfig := osProfilesLinuxConfig [ 0 ] . ( map [ string ] interface { } )
disablePasswordAuth := linuxConfig [ "disable_password_authentication" ] . ( bool )
config := & compute . LinuxConfiguration {
DisablePasswordAuthentication : & disablePasswordAuth ,
}
linuxKeys := linuxConfig [ "ssh_keys" ] . ( [ ] interface { } )
sshPublicKeys := [ ] compute . SSHPublicKey { }
for _ , key := range linuxKeys {
sshKey , ok := key . ( map [ string ] interface { } )
if ! ok {
continue
}
path := sshKey [ "path" ] . ( string )
keyData := sshKey [ "key_data" ] . ( string )
sshPublicKey := compute . SSHPublicKey {
Path : & path ,
KeyData : & keyData ,
}
sshPublicKeys = append ( sshPublicKeys , sshPublicKey )
}
2017-02-10 12:52:33 +01:00
if len ( sshPublicKeys ) > 0 {
config . SSH = & compute . SSHConfiguration {
PublicKeys : & sshPublicKeys ,
}
2016-06-02 02:51:57 +02:00
}
return config , nil
}
func expandAzureRmVirtualMachineOsProfileWindowsConfig ( d * schema . ResourceData ) ( * compute . WindowsConfiguration , error ) {
osProfilesWindowsConfig := d . Get ( "os_profile_windows_config" ) . ( * schema . Set ) . List ( )
osProfileConfig := osProfilesWindowsConfig [ 0 ] . ( map [ string ] interface { } )
config := & compute . WindowsConfiguration { }
if v := osProfileConfig [ "provision_vm_agent" ] ; v != nil {
provision := v . ( bool )
config . ProvisionVMAgent = & provision
}
if v := osProfileConfig [ "enable_automatic_upgrades" ] ; v != nil {
update := v . ( bool )
config . EnableAutomaticUpdates = & update
}
if v := osProfileConfig [ "winrm" ] ; v != nil {
2016-06-11 13:28:18 +02:00
winRm := v . ( [ ] interface { } )
2016-06-02 02:51:57 +02:00
if len ( winRm ) > 0 {
2017-03-06 02:48:35 +01:00
winRmListeners := make ( [ ] compute . WinRMListener , 0 , len ( winRm ) )
2016-06-02 02:51:57 +02:00
for _ , winRmConfig := range winRm {
config := winRmConfig . ( map [ string ] interface { } )
protocol := config [ "protocol" ] . ( string )
2017-03-06 02:48:35 +01:00
winRmListener := compute . WinRMListener {
2016-06-02 02:51:57 +02:00
Protocol : compute . ProtocolTypes ( protocol ) ,
}
if v := config [ "certificate_url" ] . ( string ) ; v != "" {
2017-03-06 02:48:35 +01:00
winRmListener . CertificateURL = & v
2016-06-02 02:51:57 +02:00
}
2017-03-06 02:48:35 +01:00
winRmListeners = append ( winRmListeners , winRmListener )
2016-06-02 02:51:57 +02:00
}
config . WinRM = & compute . WinRMConfiguration {
2017-03-06 02:48:35 +01:00
Listeners : & winRmListeners ,
2016-06-02 02:51:57 +02:00
}
}
}
if v := osProfileConfig [ "additional_unattend_config" ] ; v != nil {
2016-06-10 12:39:19 +02:00
additionalConfig := v . ( [ ] interface { } )
2016-06-02 02:51:57 +02:00
if len ( additionalConfig ) > 0 {
additionalConfigContent := make ( [ ] compute . AdditionalUnattendContent , 0 , len ( additionalConfig ) )
for _ , addConfig := range additionalConfig {
config := addConfig . ( map [ string ] interface { } )
pass := config [ "pass" ] . ( string )
component := config [ "component" ] . ( string )
settingName := config [ "setting_name" ] . ( string )
content := config [ "content" ] . ( string )
addContent := compute . AdditionalUnattendContent {
PassName : compute . PassNames ( pass ) ,
ComponentName : compute . ComponentNames ( component ) ,
SettingName : compute . SettingNames ( settingName ) ,
Content : & content ,
}
additionalConfigContent = append ( additionalConfigContent , addContent )
}
config . AdditionalUnattendContent = & additionalConfigContent
}
}
return config , nil
}
func expandAzureRmVirtualMachineDataDisk ( d * schema . ResourceData ) ( [ ] compute . DataDisk , error ) {
disks := d . Get ( "storage_data_disk" ) . ( [ ] interface { } )
data_disks := make ( [ ] compute . DataDisk , 0 , len ( disks ) )
for _ , disk_config := range disks {
config := disk_config . ( map [ string ] interface { } )
name := config [ "name" ] . ( string )
createOption := config [ "create_option" ] . ( string )
2017-03-06 02:48:35 +01:00
vhdURI := config [ "vhd_uri" ] . ( string )
managedDiskType := config [ "managed_disk_type" ] . ( string )
managedDiskID := config [ "managed_disk_id" ] . ( string )
2016-06-02 02:51:57 +02:00
lun := int32 ( config [ "lun" ] . ( int ) )
data_disk := compute . DataDisk {
2017-03-02 00:49:56 +01:00
Name : & name ,
2016-06-02 02:51:57 +02:00
Lun : & lun ,
CreateOption : compute . DiskCreateOptionTypes ( createOption ) ,
}
2017-03-06 02:48:35 +01:00
if vhdURI != "" {
2017-03-02 00:49:56 +01:00
data_disk . Vhd = & compute . VirtualHardDisk {
2017-03-06 02:48:35 +01:00
URI : & vhdURI ,
2017-03-04 06:50:32 +01:00
}
2017-03-06 02:48:35 +01:00
}
managedDisk := & compute . ManagedDiskParameters { }
if managedDiskType != "" {
managedDisk . StorageAccountType = compute . StorageAccountTypes ( managedDiskType )
data_disk . ManagedDisk = managedDisk
}
if managedDiskID != "" {
managedDisk . ID = & managedDiskID
2017-03-04 06:50:32 +01:00
data_disk . ManagedDisk = managedDisk
2017-03-02 00:49:56 +01:00
}
2016-06-02 02:51:57 +02:00
2017-03-27 20:27:54 +02:00
//BEGIN: code to be removed after GH-13016 is merged
if vhdURI != "" && managedDiskID != "" {
return nil , fmt . Errorf ( "[ERROR] Conflict between `vhd_uri` and `managed_disk_id` (only one or the other can be used)" )
}
if vhdURI != "" && managedDiskType != "" {
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
2017-03-06 02:48:35 +01:00
if managedDiskID == "" && strings . EqualFold ( string ( data_disk . CreateOption ) , string ( compute . Attach ) ) {
return nil , fmt . Errorf ( "[ERROR] Must specify which disk to attach" )
}
2017-01-12 14:52:40 +01:00
if v := config [ "caching" ] . ( string ) ; v != "" {
data_disk . Caching = compute . CachingTypes ( v )
}
2016-12-05 16:05:21 +01:00
if v := config [ "disk_size_gb" ] ; v != nil {
diskSize := int32 ( config [ "disk_size_gb" ] . ( int ) )
data_disk . DiskSizeGB = & diskSize
}
2016-06-02 02:51:57 +02:00
data_disks = append ( data_disks , data_disk )
}
return data_disks , nil
}
2016-09-29 13:32:19 +02:00
func expandAzureRmVirtualMachineDiagnosticsProfile ( d * schema . ResourceData ) * compute . DiagnosticsProfile {
bootDiagnostics := d . Get ( "boot_diagnostics" ) . ( [ ] interface { } )
diagnosticsProfile := & compute . DiagnosticsProfile { }
if len ( bootDiagnostics ) > 0 {
bootDiagnostic := bootDiagnostics [ 0 ] . ( map [ string ] interface { } )
diagnostic := & compute . BootDiagnostics {
Enabled : riviera . Bool ( bootDiagnostic [ "enabled" ] . ( bool ) ) ,
StorageURI : riviera . String ( bootDiagnostic [ "storage_uri" ] . ( string ) ) ,
}
diagnosticsProfile . BootDiagnostics = diagnostic
return diagnosticsProfile
2016-08-18 04:59:44 +02:00
}
2016-09-29 13:32:19 +02:00
return nil
2016-08-18 04:59:44 +02:00
}
2016-06-02 02:51:57 +02:00
func expandAzureRmVirtualMachineImageReference ( d * schema . ResourceData ) ( * compute . ImageReference , error ) {
storageImageRefs := d . Get ( "storage_image_reference" ) . ( * schema . Set ) . List ( )
storageImageRef := storageImageRefs [ 0 ] . ( map [ string ] interface { } )
publisher := storageImageRef [ "publisher" ] . ( string )
offer := storageImageRef [ "offer" ] . ( string )
sku := storageImageRef [ "sku" ] . ( string )
version := storageImageRef [ "version" ] . ( string )
return & compute . ImageReference {
Publisher : & publisher ,
Offer : & offer ,
Sku : & sku ,
Version : & version ,
} , nil
}
func expandAzureRmVirtualMachineNetworkProfile ( d * schema . ResourceData ) compute . NetworkProfile {
nicIds := d . Get ( "network_interface_ids" ) . ( * schema . Set ) . List ( )
2017-03-23 17:42:01 +01:00
primaryNicId := d . Get ( "primary_network_interface_id" ) . ( string )
2016-06-02 02:51:57 +02:00
network_interfaces := make ( [ ] compute . NetworkInterfaceReference , 0 , len ( nicIds ) )
network_profile := compute . NetworkProfile { }
for _ , nic := range nicIds {
id := nic . ( string )
2017-03-23 17:42:01 +01:00
primary := id == primaryNicId
2016-06-02 02:51:57 +02:00
network_interface := compute . NetworkInterfaceReference {
ID : & id ,
2017-03-23 17:42:01 +01:00
NetworkInterfaceReferenceProperties : & compute . NetworkInterfaceReferenceProperties {
Primary : & primary ,
} ,
2016-06-02 02:51:57 +02:00
}
network_interfaces = append ( network_interfaces , network_interface )
}
network_profile . NetworkInterfaces = & network_interfaces
return network_profile
}
func expandAzureRmVirtualMachineOsDisk ( d * schema . ResourceData ) ( * compute . OSDisk , error ) {
disks := d . Get ( "storage_os_disk" ) . ( * schema . Set ) . List ( )
2017-03-06 02:48:35 +01:00
config := disks [ 0 ] . ( map [ string ] interface { } )
2016-06-02 02:51:57 +02:00
2017-03-06 02:48:35 +01:00
name := config [ "name" ] . ( string )
imageURI := config [ "image_uri" ] . ( string )
createOption := config [ "create_option" ] . ( string )
vhdURI := config [ "vhd_uri" ] . ( string )
managedDiskType := config [ "managed_disk_type" ] . ( string )
managedDiskID := config [ "managed_disk_id" ] . ( string )
2016-06-02 02:51:57 +02:00
osDisk := & compute . OSDisk {
2017-03-02 00:49:56 +01:00
Name : & name ,
2016-06-02 02:51:57 +02:00
CreateOption : compute . DiskCreateOptionTypes ( createOption ) ,
}
2017-03-06 02:48:35 +01:00
if vhdURI != "" {
2017-03-02 00:49:56 +01:00
osDisk . Vhd = & compute . VirtualHardDisk {
URI : & vhdURI ,
}
2017-03-06 02:48:35 +01:00
}
managedDisk := & compute . ManagedDiskParameters { }
if managedDiskType != "" {
managedDisk . StorageAccountType = compute . StorageAccountTypes ( managedDiskType )
osDisk . ManagedDisk = managedDisk
}
if managedDiskID != "" {
managedDisk . ID = & managedDiskID
2017-03-04 06:50:32 +01:00
osDisk . ManagedDisk = managedDisk
2017-03-02 00:49:56 +01:00
}
2017-03-27 20:27:54 +02:00
//BEGIN: code to be removed after GH-13016 is merged
if vhdURI != "" && managedDiskID != "" {
return nil , fmt . Errorf ( "[ERROR] Conflict between `vhd_uri` and `managed_disk_id` (only one or the other can be used)" )
}
if vhdURI != "" && managedDiskType != "" {
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
2017-06-05 11:55:50 +02:00
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" )
2017-03-06 02:48:35 +01:00
}
if v := config [ "image_uri" ] . ( string ) ; v != "" {
2016-06-02 02:51:57 +02:00
osDisk . Image = & compute . VirtualHardDisk {
URI : & imageURI ,
}
}
2017-03-06 02:48:35 +01:00
if v := config [ "os_type" ] . ( string ) ; v != "" {
2016-06-02 02:51:57 +02:00
if v == "linux" {
osDisk . OsType = compute . Linux
} else if v == "windows" {
osDisk . OsType = compute . Windows
} else {
return nil , fmt . Errorf ( "[ERROR] os_type must be 'linux' or 'windows'" )
}
}
2017-03-06 02:48:35 +01:00
if v := config [ "caching" ] . ( string ) ; v != "" {
2016-06-02 02:51:57 +02:00
osDisk . Caching = compute . CachingTypes ( v )
}
2017-03-06 02:48:35 +01:00
if v := config [ "disk_size_gb" ] . ( int ) ; v != 0 {
2016-10-25 18:54:55 +02:00
diskSize := int32 ( v )
osDisk . DiskSizeGB = & diskSize
}
2016-06-02 02:51:57 +02:00
return osDisk , nil
}
2016-10-27 17:42:47 +02:00
func findStorageAccountResourceGroup ( meta interface { } , storageAccountName string ) ( string , error ) {
client := meta . ( * ArmClient ) . resourceFindClient
filter := fmt . Sprintf ( "name eq '%s' and resourceType eq 'Microsoft.Storage/storageAccounts'" , storageAccountName )
expand := ""
var pager * int32
rf , err := client . List ( filter , expand , pager )
if err != nil {
return "" , fmt . Errorf ( "Error making resource request for query %s: %s" , filter , err )
}
results := * rf . Value
if len ( results ) != 1 {
2016-11-11 00:10:43 +01:00
return "" , fmt . Errorf ( "Wrong number of results making resource request for query %s: %d" , filter , len ( results ) )
2016-10-27 17:42:47 +02:00
}
id , err := parseAzureResourceID ( * results [ 0 ] . ID )
if err != nil {
return "" , err
}
return id . ResourceGroup , nil
}