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