2016-06-11 00:37:14 +02:00
|
|
|
package azurerm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/Azure/azure-sdk-for-go/arm/compute"
|
|
|
|
"github.com/hashicorp/terraform/helper/hashcode"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
)
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSet() *schema.Resource {
|
|
|
|
return &schema.Resource{
|
|
|
|
Create: resourceArmVirtualMachineScaleSetCreate,
|
|
|
|
Read: resourceArmVirtualMachineScaleSetRead,
|
|
|
|
Update: resourceArmVirtualMachineScaleSetCreate,
|
|
|
|
Delete: resourceArmVirtualMachineScaleSetDelete,
|
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"name": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
2016-11-29 16:54:00 +01:00
|
|
|
"location": locationSchema(),
|
2016-06-11 00:37:14 +02:00
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"resource_group_name": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"sku": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Required: true,
|
|
|
|
MaxItems: 1,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"name": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"tier": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"capacity": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeInt,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetSkuHash,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"upgrade_policy_mode": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"overprovision": {
|
2017-01-31 13:57:11 +01:00
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"os_profile": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Required: true,
|
|
|
|
MaxItems: 1,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"computer_name_prefix": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"admin_username": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"admin_password": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
Sensitive: true,
|
2016-06-11 00:37:14 +02:00
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"custom_data": {
|
2017-03-08 22:57:51 +01:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
StateFunc: userDataStateFunc,
|
2016-06-11 00:37:14 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetsOsProfileHash,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"os_profile_secrets": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"source_vault_id": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"vault_certificates": {
|
2016-07-18 11:20:18 +02:00
|
|
|
Type: schema.TypeList,
|
2016-06-11 00:37:14 +02:00
|
|
|
Optional: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"certificate_url": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"certificate_store": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"os_profile_windows_config": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
MaxItems: 1,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"provision_vm_agent": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"enable_automatic_upgrades": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"winrm": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"protocol": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"certificate_url": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"additional_unattend_config": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"pass": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"component": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"setting_name": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"content": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetOsProfileLWindowsConfigHash,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"os_profile_linux_config": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
MaxItems: 1,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"disable_password_authentication": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
Default: false,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"ssh_keys": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeList,
|
|
|
|
Optional: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"path": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
2017-02-16 00:03:55 +01:00
|
|
|
"key_data": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetOsProfileLinuxConfigHash,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"network_profile": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Required: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"name": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"primary": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeBool,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"ip_configuration": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeList,
|
|
|
|
Required: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"name": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"subnet_id": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"load_balancer_backend_address_pool_ids": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
|
|
Set: schema.HashString,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetNetworkConfigurationHash,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"storage_profile_os_disk": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Required: true,
|
|
|
|
MaxItems: 1,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"name": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"image": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"vhd_containers": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
2017-01-31 13:57:11 +01:00
|
|
|
Optional: true,
|
2016-06-11 00:37:14 +02:00
|
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
|
|
Set: schema.HashString,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"caching": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"os_type": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"create_option": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetStorageProfileOsDiskHash,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"storage_profile_image_reference": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
MaxItems: 1,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
2017-02-16 00:03:55 +01:00
|
|
|
"publisher": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"offer": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"sku": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
2017-02-16 00:03:55 +01:00
|
|
|
"version": {
|
2016-06-11 00:37:14 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetStorageProfileImageReferenceHash,
|
|
|
|
},
|
|
|
|
|
2017-03-12 15:13:38 +01:00
|
|
|
"extension": {
|
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"name": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"publisher": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"type": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"type_handler_version": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"auto_upgrade_minor_version": {
|
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"settings": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
ValidateFunc: validateJsonString,
|
|
|
|
DiffSuppressFunc: suppressDiffVirtualMachineExtensionSettings,
|
|
|
|
},
|
|
|
|
|
|
|
|
"protected_settings": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Sensitive: true,
|
|
|
|
ValidateFunc: validateJsonString,
|
|
|
|
DiffSuppressFunc: suppressDiffVirtualMachineExtensionSettings,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Set: resourceArmVirtualMachineScaleSetExtensionHash,
|
|
|
|
},
|
|
|
|
|
2016-06-11 00:37:14 +02:00
|
|
|
"tags": tagsSchema(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetCreate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
client := meta.(*ArmClient)
|
|
|
|
vmScaleSetClient := client.vmScaleSetClient
|
|
|
|
|
|
|
|
log.Printf("[INFO] preparing arguments for Azure ARM Virtual Machine Scale Set 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{})
|
|
|
|
|
|
|
|
sku, err := expandVirtualMachineScaleSetSku(d)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
storageProfile := compute.VirtualMachineScaleSetStorageProfile{}
|
|
|
|
osDisk, err := expandAzureRMVirtualMachineScaleSetsStorageProfileOsDisk(d)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
storageProfile.OsDisk = osDisk
|
|
|
|
if _, ok := d.GetOk("storage_profile_image_reference"); ok {
|
|
|
|
imageRef, err := expandAzureRmVirtualMachineScaleSetStorageProfileImageReference(d)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
storageProfile.ImageReference = imageRef
|
|
|
|
}
|
|
|
|
|
|
|
|
osProfile, err := expandAzureRMVirtualMachineScaleSetsOsProfile(d)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-03-12 15:13:38 +01:00
|
|
|
extensions, err := expandAzureRMVirtualMachineScaleSetExtensions(d)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-06-11 00:37:14 +02:00
|
|
|
updatePolicy := d.Get("upgrade_policy_mode").(string)
|
2017-01-31 13:57:11 +01:00
|
|
|
overprovision := d.Get("overprovision").(bool)
|
2016-06-11 00:37:14 +02:00
|
|
|
scaleSetProps := compute.VirtualMachineScaleSetProperties{
|
|
|
|
UpgradePolicy: &compute.UpgradePolicy{
|
|
|
|
Mode: compute.UpgradeMode(updatePolicy),
|
|
|
|
},
|
|
|
|
VirtualMachineProfile: &compute.VirtualMachineScaleSetVMProfile{
|
2017-03-12 15:13:38 +01:00
|
|
|
NetworkProfile: expandAzureRmVirtualMachineScaleSetNetworkProfile(d),
|
|
|
|
StorageProfile: &storageProfile,
|
|
|
|
OsProfile: osProfile,
|
|
|
|
ExtensionProfile: extensions,
|
2016-06-11 00:37:14 +02:00
|
|
|
},
|
2017-01-31 13:57:11 +01:00
|
|
|
Overprovision: &overprovision,
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
scaleSetParams := compute.VirtualMachineScaleSet{
|
2016-12-06 09:39:47 +01:00
|
|
|
Name: &name,
|
|
|
|
Location: &location,
|
|
|
|
Tags: expandTags(tags),
|
|
|
|
Sku: sku,
|
|
|
|
VirtualMachineScaleSetProperties: &scaleSetProps,
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
_, vmErr := vmScaleSetClient.CreateOrUpdate(resGroup, name, scaleSetParams, make(chan struct{}))
|
|
|
|
if vmErr != nil {
|
|
|
|
return vmErr
|
|
|
|
}
|
|
|
|
|
|
|
|
read, err := vmScaleSetClient.Get(resGroup, name)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if read.ID == nil {
|
|
|
|
return fmt.Errorf("Cannot read Virtual Machine Scale Set %s (resource group %s) ID", name, resGroup)
|
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId(*read.ID)
|
|
|
|
|
|
|
|
return resourceArmVirtualMachineScaleSetRead(d, meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetRead(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
vmScaleSetClient := meta.(*ArmClient).vmScaleSetClient
|
|
|
|
|
|
|
|
id, err := parseAzureResourceID(d.Id())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
resGroup := id.ResourceGroup
|
|
|
|
name := id.Path["virtualMachineScaleSets"]
|
|
|
|
|
|
|
|
resp, err := vmScaleSetClient.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 {
|
|
|
|
log.Printf("[INFO] AzureRM Virtual Machine Scale Set (%s) Not Found. Removing from State", name)
|
|
|
|
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 Scale Set %s: %s", name, err)
|
|
|
|
}
|
2016-06-11 00:37:14 +02:00
|
|
|
|
|
|
|
d.Set("location", resp.Location)
|
|
|
|
d.Set("name", resp.Name)
|
|
|
|
|
|
|
|
if err := d.Set("sku", flattenAzureRmVirtualMachineScaleSetSku(resp.Sku)); err != nil {
|
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Sku error: %#v", err)
|
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
properties := resp.VirtualMachineScaleSetProperties
|
|
|
|
|
|
|
|
d.Set("upgrade_policy_mode", properties.UpgradePolicy.Mode)
|
2017-01-31 13:57:11 +01:00
|
|
|
d.Set("overprovision", properties.Overprovision)
|
2016-06-11 00:37:14 +02:00
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if err := d.Set("os_profile", flattenAzureRMVirtualMachineScaleSetOsProfile(properties.VirtualMachineProfile.OsProfile)); err != nil {
|
2016-06-11 00:37:14 +02:00
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile error: %#v", err)
|
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if properties.VirtualMachineProfile.OsProfile.Secrets != nil {
|
|
|
|
if err := d.Set("os_profile_secrets", flattenAzureRmVirtualMachineScaleSetOsProfileSecrets(properties.VirtualMachineProfile.OsProfile.Secrets)); err != nil {
|
2016-06-11 00:37:14 +02:00
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile Secrets error: %#v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if properties.VirtualMachineProfile.OsProfile.WindowsConfiguration != nil {
|
|
|
|
if err := d.Set("os_profile_windows_config", flattenAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(properties.VirtualMachineProfile.OsProfile.WindowsConfiguration)); err != nil {
|
2016-06-11 00:37:14 +02:00
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile Windows config error: %#v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if properties.VirtualMachineProfile.OsProfile.LinuxConfiguration != nil {
|
|
|
|
if err := d.Set("os_profile_linux_config", flattenAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(properties.VirtualMachineProfile.OsProfile.LinuxConfiguration)); err != nil {
|
2016-06-11 00:37:14 +02:00
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile Windows config error: %#v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if err := d.Set("network_profile", flattenAzureRmVirtualMachineScaleSetNetworkProfile(properties.VirtualMachineProfile.NetworkProfile)); err != nil {
|
2016-06-11 00:37:14 +02:00
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Network Profile error: %#v", err)
|
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if properties.VirtualMachineProfile.StorageProfile.ImageReference != nil {
|
|
|
|
if err := d.Set("storage_profile_image_reference", flattenAzureRmVirtualMachineScaleSetStorageProfileImageReference(properties.VirtualMachineProfile.StorageProfile.ImageReference)); err != nil {
|
2016-06-11 00:37:14 +02:00
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Storage Profile Image Reference error: %#v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if err := d.Set("storage_profile_os_disk", flattenAzureRmVirtualMachineScaleSetStorageProfileOSDisk(properties.VirtualMachineProfile.StorageProfile.OsDisk)); err != nil {
|
2016-06-11 00:37:14 +02:00
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Storage Profile OS Disk error: %#v", err)
|
|
|
|
}
|
|
|
|
|
2017-03-12 15:13:38 +01:00
|
|
|
if properties.VirtualMachineProfile.ExtensionProfile != nil {
|
|
|
|
extension, err := flattenAzureRmVirtualMachineScaleSetExtensionProfile(properties.VirtualMachineProfile.ExtensionProfile)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Extension Profile error: %#v", err)
|
|
|
|
}
|
|
|
|
d.Set("extension", extension)
|
|
|
|
}
|
|
|
|
|
2016-06-11 00:37:14 +02:00
|
|
|
flattenAndSetTags(d, resp.Tags)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetDelete(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
vmScaleSetClient := meta.(*ArmClient).vmScaleSetClient
|
|
|
|
|
|
|
|
id, err := parseAzureResourceID(d.Id())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
resGroup := id.ResourceGroup
|
|
|
|
name := id.Path["virtualMachineScaleSets"]
|
|
|
|
|
|
|
|
_, err = vmScaleSetClient.Delete(resGroup, name, make(chan struct{}))
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(config *compute.LinuxConfiguration) []interface{} {
|
|
|
|
result := make(map[string]interface{})
|
|
|
|
result["disable_password_authentication"] = *config.DisablePasswordAuthentication
|
|
|
|
|
|
|
|
if config.SSH != nil && len(*config.SSH.PublicKeys) > 0 {
|
|
|
|
ssh_keys := make([]map[string]interface{}, len(*config.SSH.PublicKeys))
|
|
|
|
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 flattenAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(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
|
|
|
|
c["content"] = *i.Content
|
|
|
|
|
|
|
|
content = append(content, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
result["additional_unattend_config"] = content
|
|
|
|
}
|
|
|
|
|
|
|
|
return []interface{}{result}
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenAzureRmVirtualMachineScaleSetOsProfileSecrets(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 flattenAzureRmVirtualMachineScaleSetNetworkProfile(profile *compute.VirtualMachineScaleSetNetworkProfile) []map[string]interface{} {
|
|
|
|
networkConfigurations := profile.NetworkInterfaceConfigurations
|
|
|
|
result := make([]map[string]interface{}, 0, len(*networkConfigurations))
|
|
|
|
for _, netConfig := range *networkConfigurations {
|
|
|
|
s := map[string]interface{}{
|
|
|
|
"name": *netConfig.Name,
|
2016-12-06 09:39:47 +01:00
|
|
|
"primary": *netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.Primary,
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.IPConfigurations != nil {
|
|
|
|
ipConfigs := make([]map[string]interface{}, 0, len(*netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.IPConfigurations))
|
|
|
|
for _, ipConfig := range *netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.IPConfigurations {
|
2016-06-11 00:37:14 +02:00
|
|
|
config := make(map[string]interface{})
|
|
|
|
config["name"] = *ipConfig.Name
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
properties := ipConfig.VirtualMachineScaleSetIPConfigurationProperties
|
|
|
|
|
|
|
|
if ipConfig.VirtualMachineScaleSetIPConfigurationProperties.Subnet != nil {
|
|
|
|
config["subnet_id"] = *properties.Subnet.ID
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
2016-12-06 09:39:47 +01:00
|
|
|
if properties.LoadBalancerBackendAddressPools != nil {
|
2017-01-31 13:57:11 +01:00
|
|
|
addressPools := make([]interface{}, 0, len(*properties.LoadBalancerBackendAddressPools))
|
2016-12-06 09:39:47 +01:00
|
|
|
for _, pool := range *properties.LoadBalancerBackendAddressPools {
|
2016-06-11 00:37:14 +02:00
|
|
|
addressPools = append(addressPools, *pool.ID)
|
|
|
|
}
|
2017-01-31 13:57:11 +01:00
|
|
|
config["load_balancer_backend_address_pool_ids"] = schema.NewSet(schema.HashString, addressPools)
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
2017-01-31 13:57:11 +01:00
|
|
|
|
|
|
|
ipConfigs = append(ipConfigs, config)
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
s["ip_configuration"] = ipConfigs
|
|
|
|
}
|
|
|
|
|
|
|
|
result = append(result, s)
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenAzureRMVirtualMachineScaleSetOsProfile(profile *compute.VirtualMachineScaleSetOSProfile) []interface{} {
|
|
|
|
result := make(map[string]interface{})
|
|
|
|
|
|
|
|
result["computer_name_prefix"] = *profile.ComputerNamePrefix
|
|
|
|
result["admin_username"] = *profile.AdminUsername
|
|
|
|
|
|
|
|
if profile.CustomData != nil {
|
2017-03-08 22:57:51 +01:00
|
|
|
result["custom_data"] = *profile.CustomData
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return []interface{}{result}
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenAzureRmVirtualMachineScaleSetStorageProfileOSDisk(profile *compute.VirtualMachineScaleSetOSDisk) []interface{} {
|
|
|
|
result := make(map[string]interface{})
|
|
|
|
result["name"] = *profile.Name
|
|
|
|
if profile.Image != nil {
|
|
|
|
result["image"] = *profile.Image.URI
|
|
|
|
}
|
|
|
|
|
2017-01-31 13:57:11 +01:00
|
|
|
if profile.VhdContainers != nil {
|
|
|
|
containers := make([]interface{}, 0, len(*profile.VhdContainers))
|
|
|
|
for _, container := range *profile.VhdContainers {
|
|
|
|
containers = append(containers, container)
|
|
|
|
}
|
|
|
|
result["vhd_containers"] = schema.NewSet(schema.HashString, containers)
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
result["caching"] = profile.Caching
|
|
|
|
result["create_option"] = profile.CreateOption
|
2017-01-31 13:57:11 +01:00
|
|
|
result["os_type"] = profile.OsType
|
2016-06-11 00:37:14 +02:00
|
|
|
|
|
|
|
return []interface{}{result}
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenAzureRmVirtualMachineScaleSetStorageProfileImageReference(profile *compute.ImageReference) []interface{} {
|
|
|
|
result := make(map[string]interface{})
|
|
|
|
result["publisher"] = *profile.Publisher
|
|
|
|
result["offer"] = *profile.Offer
|
|
|
|
result["sku"] = *profile.Sku
|
|
|
|
result["version"] = *profile.Version
|
|
|
|
|
|
|
|
return []interface{}{result}
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenAzureRmVirtualMachineScaleSetSku(sku *compute.Sku) []interface{} {
|
|
|
|
result := make(map[string]interface{})
|
|
|
|
result["name"] = *sku.Name
|
|
|
|
result["capacity"] = *sku.Capacity
|
|
|
|
|
|
|
|
if *sku.Tier != "" {
|
|
|
|
result["tier"] = *sku.Tier
|
|
|
|
}
|
|
|
|
|
|
|
|
return []interface{}{result}
|
|
|
|
}
|
|
|
|
|
2017-03-12 15:13:38 +01:00
|
|
|
func flattenAzureRmVirtualMachineScaleSetExtensionProfile(profile *compute.VirtualMachineScaleSetExtensionProfile) ([]map[string]interface{}, error) {
|
|
|
|
if profile.Extensions == nil {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
result := make([]map[string]interface{}, 0, len(*profile.Extensions))
|
|
|
|
for _, extension := range *profile.Extensions {
|
|
|
|
e := make(map[string]interface{})
|
|
|
|
e["name"] = *extension.Name
|
|
|
|
properties := extension.VirtualMachineScaleSetExtensionProperties
|
|
|
|
if properties != nil {
|
|
|
|
e["publisher"] = *properties.Publisher
|
|
|
|
e["type"] = *properties.Type
|
|
|
|
e["type_handler_version"] = *properties.TypeHandlerVersion
|
|
|
|
if properties.AutoUpgradeMinorVersion != nil {
|
|
|
|
e["auto_upgrade_minor_version"] = *properties.AutoUpgradeMinorVersion
|
|
|
|
}
|
|
|
|
|
|
|
|
if properties.Settings != nil {
|
|
|
|
settings, err := flattenArmVirtualMachineExtensionSettings(*properties.Settings)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
e["settings"] = settings
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result = append(result, e)
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
2016-06-11 00:37:14 +02:00
|
|
|
func resourceArmVirtualMachineScaleSetStorageProfileImageReferenceHash(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)))
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["version"].(string)))
|
|
|
|
|
|
|
|
return hashcode.String(buf.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetSkuHash(v interface{}) int {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
m := v.(map[string]interface{})
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
|
|
|
|
if m["tier"] != nil {
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["tier"].(string)))
|
|
|
|
}
|
|
|
|
buf.WriteString(fmt.Sprintf("%d-", m["capacity"].(int)))
|
|
|
|
|
|
|
|
return hashcode.String(buf.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetStorageProfileOsDiskHash(v interface{}) int {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
m := v.(map[string]interface{})
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
|
|
|
|
|
|
|
|
if m["image"] != nil {
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["image"].(string)))
|
|
|
|
}
|
|
|
|
|
|
|
|
return hashcode.String(buf.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetNetworkConfigurationHash(v interface{}) int {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
m := v.(map[string]interface{})
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
|
|
|
|
buf.WriteString(fmt.Sprintf("%t-", m["primary"].(bool)))
|
|
|
|
return hashcode.String(buf.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetsOsProfileHash(v interface{}) int {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
m := v.(map[string]interface{})
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["computer_name_prefix"].(string)))
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["admin_username"].(string)))
|
|
|
|
if m["custom_data"] != nil {
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["custom_data"].(string)))
|
|
|
|
}
|
|
|
|
return hashcode.String(buf.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmVirtualMachineScaleSetOsProfileLinuxConfigHash(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 resourceArmVirtualMachineScaleSetOsProfileLWindowsConfigHash(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())
|
|
|
|
}
|
|
|
|
|
2017-03-12 15:13:38 +01:00
|
|
|
func resourceArmVirtualMachineScaleSetExtensionHash(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["type"].(string)))
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-", m["type_handler_version"].(string)))
|
|
|
|
if m["auto_upgrade_minor_version"] != nil {
|
|
|
|
buf.WriteString(fmt.Sprintf("%t-", m["auto_upgrade_minor_version"].(bool)))
|
|
|
|
}
|
|
|
|
|
|
|
|
return hashcode.String(buf.String())
|
|
|
|
}
|
|
|
|
|
2016-06-11 00:37:14 +02:00
|
|
|
func expandVirtualMachineScaleSetSku(d *schema.ResourceData) (*compute.Sku, error) {
|
|
|
|
skuConfig := d.Get("sku").(*schema.Set).List()
|
|
|
|
|
|
|
|
config := skuConfig[0].(map[string]interface{})
|
|
|
|
|
|
|
|
name := config["name"].(string)
|
|
|
|
tier := config["tier"].(string)
|
|
|
|
capacity := int64(config["capacity"].(int))
|
|
|
|
|
|
|
|
sku := &compute.Sku{
|
|
|
|
Name: &name,
|
|
|
|
Capacity: &capacity,
|
|
|
|
}
|
|
|
|
|
|
|
|
if tier != "" {
|
|
|
|
sku.Tier = &tier
|
|
|
|
}
|
|
|
|
|
|
|
|
return sku, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func expandAzureRmVirtualMachineScaleSetNetworkProfile(d *schema.ResourceData) *compute.VirtualMachineScaleSetNetworkProfile {
|
|
|
|
scaleSetNetworkProfileConfigs := d.Get("network_profile").(*schema.Set).List()
|
|
|
|
networkProfileConfig := make([]compute.VirtualMachineScaleSetNetworkConfiguration, 0, len(scaleSetNetworkProfileConfigs))
|
|
|
|
|
|
|
|
for _, npProfileConfig := range scaleSetNetworkProfileConfigs {
|
|
|
|
config := npProfileConfig.(map[string]interface{})
|
|
|
|
|
|
|
|
name := config["name"].(string)
|
|
|
|
primary := config["primary"].(bool)
|
|
|
|
|
|
|
|
ipConfigurationConfigs := config["ip_configuration"].([]interface{})
|
|
|
|
ipConfigurations := make([]compute.VirtualMachineScaleSetIPConfiguration, 0, len(ipConfigurationConfigs))
|
|
|
|
for _, ipConfigConfig := range ipConfigurationConfigs {
|
|
|
|
ipconfig := ipConfigConfig.(map[string]interface{})
|
|
|
|
name := ipconfig["name"].(string)
|
|
|
|
subnetId := ipconfig["subnet_id"].(string)
|
|
|
|
|
|
|
|
ipConfiguration := compute.VirtualMachineScaleSetIPConfiguration{
|
|
|
|
Name: &name,
|
2016-12-06 09:39:47 +01:00
|
|
|
VirtualMachineScaleSetIPConfigurationProperties: &compute.VirtualMachineScaleSetIPConfigurationProperties{
|
2016-06-11 00:37:14 +02:00
|
|
|
Subnet: &compute.APIEntityReference{
|
|
|
|
ID: &subnetId,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2017-01-31 13:57:11 +01:00
|
|
|
|
|
|
|
if v := ipconfig["load_balancer_backend_address_pool_ids"]; v != nil {
|
|
|
|
pools := v.(*schema.Set).List()
|
|
|
|
resources := make([]compute.SubResource, 0, len(pools))
|
|
|
|
for _, p := range pools {
|
|
|
|
id := p.(string)
|
|
|
|
resources = append(resources, compute.SubResource{
|
|
|
|
ID: &id,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
ipConfiguration.LoadBalancerBackendAddressPools = &resources
|
|
|
|
}
|
2016-06-11 00:37:14 +02:00
|
|
|
|
|
|
|
ipConfigurations = append(ipConfigurations, ipConfiguration)
|
|
|
|
}
|
|
|
|
|
|
|
|
nProfile := compute.VirtualMachineScaleSetNetworkConfiguration{
|
|
|
|
Name: &name,
|
2016-12-06 09:39:47 +01:00
|
|
|
VirtualMachineScaleSetNetworkConfigurationProperties: &compute.VirtualMachineScaleSetNetworkConfigurationProperties{
|
2016-06-11 00:37:14 +02:00
|
|
|
Primary: &primary,
|
|
|
|
IPConfigurations: &ipConfigurations,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
networkProfileConfig = append(networkProfileConfig, nProfile)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &compute.VirtualMachineScaleSetNetworkProfile{
|
|
|
|
NetworkInterfaceConfigurations: &networkProfileConfig,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func expandAzureRMVirtualMachineScaleSetsOsProfile(d *schema.ResourceData) (*compute.VirtualMachineScaleSetOSProfile, error) {
|
|
|
|
osProfileConfigs := d.Get("os_profile").(*schema.Set).List()
|
|
|
|
|
|
|
|
osProfileConfig := osProfileConfigs[0].(map[string]interface{})
|
|
|
|
namePrefix := osProfileConfig["computer_name_prefix"].(string)
|
|
|
|
username := osProfileConfig["admin_username"].(string)
|
|
|
|
password := osProfileConfig["admin_password"].(string)
|
|
|
|
customData := osProfileConfig["custom_data"].(string)
|
|
|
|
|
|
|
|
osProfile := &compute.VirtualMachineScaleSetOSProfile{
|
|
|
|
ComputerNamePrefix: &namePrefix,
|
|
|
|
AdminUsername: &username,
|
|
|
|
}
|
|
|
|
|
|
|
|
if password != "" {
|
|
|
|
osProfile.AdminPassword = &password
|
|
|
|
}
|
|
|
|
|
|
|
|
if customData != "" {
|
2017-03-08 22:57:51 +01:00
|
|
|
customData = base64Encode(customData)
|
2016-06-11 00:37:14 +02:00
|
|
|
osProfile.CustomData = &customData
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := d.GetOk("os_profile_secrets"); ok {
|
|
|
|
secrets := expandAzureRmVirtualMachineScaleSetOsProfileSecrets(d)
|
|
|
|
if secrets != nil {
|
|
|
|
osProfile.Secrets = secrets
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := d.GetOk("os_profile_linux_config"); ok {
|
|
|
|
linuxConfig, err := expandAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(d)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
osProfile.LinuxConfiguration = linuxConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := d.GetOk("os_profile_windows_config"); ok {
|
|
|
|
winConfig, err := expandAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(d)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if winConfig != nil {
|
|
|
|
osProfile.WindowsConfiguration = winConfig
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return osProfile, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func expandAzureRMVirtualMachineScaleSetsStorageProfileOsDisk(d *schema.ResourceData) (*compute.VirtualMachineScaleSetOSDisk, error) {
|
|
|
|
osDiskConfigs := d.Get("storage_profile_os_disk").(*schema.Set).List()
|
|
|
|
|
|
|
|
osDiskConfig := osDiskConfigs[0].(map[string]interface{})
|
|
|
|
name := osDiskConfig["name"].(string)
|
|
|
|
image := osDiskConfig["image"].(string)
|
|
|
|
caching := osDiskConfig["caching"].(string)
|
|
|
|
osType := osDiskConfig["os_type"].(string)
|
|
|
|
createOption := osDiskConfig["create_option"].(string)
|
|
|
|
|
|
|
|
osDisk := &compute.VirtualMachineScaleSetOSDisk{
|
2017-01-31 13:57:11 +01:00
|
|
|
Name: &name,
|
|
|
|
Caching: compute.CachingTypes(caching),
|
|
|
|
OsType: compute.OperatingSystemTypes(osType),
|
|
|
|
CreateOption: compute.DiskCreateOptionTypes(createOption),
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if image != "" {
|
|
|
|
osDisk.Image = &compute.VirtualHardDisk{
|
|
|
|
URI: &image,
|
|
|
|
}
|
2017-01-31 13:57:11 +01:00
|
|
|
} else {
|
|
|
|
var vhdContainers []string
|
|
|
|
containers := osDiskConfig["vhd_containers"].(*schema.Set).List()
|
|
|
|
for _, v := range containers {
|
|
|
|
str := v.(string)
|
|
|
|
vhdContainers = append(vhdContainers, str)
|
|
|
|
}
|
|
|
|
osDisk.VhdContainers = &vhdContainers
|
2016-06-11 00:37:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return osDisk, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func expandAzureRmVirtualMachineScaleSetStorageProfileImageReference(d *schema.ResourceData) (*compute.ImageReference, error) {
|
|
|
|
storageImageRefs := d.Get("storage_profile_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 expandAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(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 := make([]compute.SSHPublicKey, 0, len(linuxKeys))
|
|
|
|
for _, key := range linuxKeys {
|
|
|
|
sshKey := key.(map[string]interface{})
|
|
|
|
path := sshKey["path"].(string)
|
|
|
|
keyData := sshKey["key_data"].(string)
|
|
|
|
|
|
|
|
sshPublicKey := compute.SSHPublicKey{
|
|
|
|
Path: &path,
|
|
|
|
KeyData: &keyData,
|
|
|
|
}
|
|
|
|
|
|
|
|
sshPublicKeys = append(sshPublicKeys, sshPublicKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
config.SSH = &compute.SSHConfiguration{
|
|
|
|
PublicKeys: &sshPublicKeys,
|
|
|
|
}
|
|
|
|
|
|
|
|
return config, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func expandAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(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 {
|
|
|
|
winRm := v.(*schema.Set).List()
|
|
|
|
if len(winRm) > 0 {
|
|
|
|
winRmListners := make([]compute.WinRMListener, 0, len(winRm))
|
|
|
|
for _, winRmConfig := range winRm {
|
|
|
|
config := winRmConfig.(map[string]interface{})
|
|
|
|
|
|
|
|
protocol := config["protocol"].(string)
|
|
|
|
winRmListner := compute.WinRMListener{
|
|
|
|
Protocol: compute.ProtocolTypes(protocol),
|
|
|
|
}
|
|
|
|
if v := config["certificate_url"].(string); v != "" {
|
|
|
|
winRmListner.CertificateURL = &v
|
|
|
|
}
|
|
|
|
|
|
|
|
winRmListners = append(winRmListners, winRmListner)
|
|
|
|
}
|
|
|
|
config.WinRM = &compute.WinRMConfiguration{
|
|
|
|
Listeners: &winRmListners,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if v := osProfileConfig["additional_unattend_config"]; v != nil {
|
|
|
|
additionalConfig := v.(*schema.Set).List()
|
|
|
|
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 expandAzureRmVirtualMachineScaleSetOsProfileSecrets(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-11 00:37:14 +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
|
|
|
|
}
|
2017-03-12 15:13:38 +01:00
|
|
|
|
|
|
|
func expandAzureRMVirtualMachineScaleSetExtensions(d *schema.ResourceData) (*compute.VirtualMachineScaleSetExtensionProfile, error) {
|
|
|
|
extensions := d.Get("extension").(*schema.Set).List()
|
|
|
|
resources := make([]compute.VirtualMachineScaleSetExtension, 0, len(extensions))
|
|
|
|
for _, e := range extensions {
|
|
|
|
config := e.(map[string]interface{})
|
|
|
|
name := config["name"].(string)
|
|
|
|
publisher := config["publisher"].(string)
|
|
|
|
t := config["type"].(string)
|
|
|
|
version := config["type_handler_version"].(string)
|
|
|
|
|
|
|
|
extension := compute.VirtualMachineScaleSetExtension{
|
|
|
|
Name: &name,
|
|
|
|
VirtualMachineScaleSetExtensionProperties: &compute.VirtualMachineScaleSetExtensionProperties{
|
|
|
|
Publisher: &publisher,
|
|
|
|
Type: &t,
|
|
|
|
TypeHandlerVersion: &version,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if u := config["auto_upgrade_minor_version"]; u != nil {
|
|
|
|
upgrade := u.(bool)
|
|
|
|
extension.VirtualMachineScaleSetExtensionProperties.AutoUpgradeMinorVersion = &upgrade
|
|
|
|
}
|
|
|
|
|
|
|
|
if s := config["settings"].(string); s != "" {
|
|
|
|
settings, err := expandArmVirtualMachineExtensionSettings(s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to parse settings: %s", err)
|
|
|
|
}
|
|
|
|
extension.VirtualMachineScaleSetExtensionProperties.Settings = &settings
|
|
|
|
}
|
|
|
|
|
|
|
|
if s := config["protected_settings"].(string); s != "" {
|
|
|
|
protectedSettings, err := expandArmVirtualMachineExtensionSettings(s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to parse protected_settings: %s", err)
|
|
|
|
}
|
|
|
|
extension.VirtualMachineScaleSetExtensionProperties.ProtectedSettings = &protectedSettings
|
|
|
|
}
|
|
|
|
|
|
|
|
resources = append(resources, extension)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &compute.VirtualMachineScaleSetExtensionProfile{
|
|
|
|
Extensions: &resources,
|
|
|
|
}, nil
|
|
|
|
}
|