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