github.com/IBM-Cloud/terraform@v0.6.4-0.20170726051544-8872b87621df/builtin/providers/azurerm/resource_arm_virtual_machine_scale_set.go (about)

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