github.com/bradfeehan/terraform@v0.7.0-rc3.0.20170529055808-34b45c5ad841/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_data_disk": { 347 Type: schema.TypeList, 348 Optional: true, 349 Elem: &schema.Resource{ 350 Schema: map[string]*schema.Schema{ 351 "lun": { 352 Type: schema.TypeInt, 353 Required: true, 354 }, 355 356 "create_option": { 357 Type: schema.TypeString, 358 Required: true, 359 }, 360 361 "caching": { 362 Type: schema.TypeString, 363 Optional: true, 364 Computed: true, 365 }, 366 367 "disk_size_gb": { 368 Type: schema.TypeInt, 369 Optional: true, 370 Computed: true, 371 ValidateFunc: validateDiskSizeGB, 372 }, 373 374 "managed_disk_type": { 375 Type: schema.TypeString, 376 Optional: true, 377 Computed: true, 378 ValidateFunc: validation.StringInSlice([]string{ 379 string(compute.PremiumLRS), 380 string(compute.StandardLRS), 381 }, true), 382 }, 383 }, 384 }, 385 }, 386 387 "storage_profile_image_reference": { 388 Type: schema.TypeSet, 389 Optional: true, 390 Computed: true, 391 MaxItems: 1, 392 Elem: &schema.Resource{ 393 Schema: map[string]*schema.Schema{ 394 "publisher": { 395 Type: schema.TypeString, 396 Required: true, 397 }, 398 399 "offer": { 400 Type: schema.TypeString, 401 Required: true, 402 }, 403 404 "sku": { 405 Type: schema.TypeString, 406 Required: true, 407 }, 408 409 "version": { 410 Type: schema.TypeString, 411 Required: true, 412 }, 413 }, 414 }, 415 Set: resourceArmVirtualMachineScaleSetStorageProfileImageReferenceHash, 416 }, 417 418 "extension": { 419 Type: schema.TypeSet, 420 Optional: true, 421 Elem: &schema.Resource{ 422 Schema: map[string]*schema.Schema{ 423 "name": { 424 Type: schema.TypeString, 425 Required: true, 426 }, 427 428 "publisher": { 429 Type: schema.TypeString, 430 Required: true, 431 }, 432 433 "type": { 434 Type: schema.TypeString, 435 Required: true, 436 }, 437 438 "type_handler_version": { 439 Type: schema.TypeString, 440 Required: true, 441 }, 442 443 "auto_upgrade_minor_version": { 444 Type: schema.TypeBool, 445 Optional: true, 446 }, 447 448 "settings": { 449 Type: schema.TypeString, 450 Optional: true, 451 ValidateFunc: validation.ValidateJsonString, 452 DiffSuppressFunc: structure.SuppressJsonDiff, 453 }, 454 455 "protected_settings": { 456 Type: schema.TypeString, 457 Optional: true, 458 Sensitive: true, 459 ValidateFunc: validation.ValidateJsonString, 460 DiffSuppressFunc: structure.SuppressJsonDiff, 461 }, 462 }, 463 }, 464 Set: resourceArmVirtualMachineScaleSetExtensionHash, 465 }, 466 467 "tags": tagsSchema(), 468 }, 469 } 470 } 471 472 func resourceArmVirtualMachineScaleSetCreate(d *schema.ResourceData, meta interface{}) error { 473 client := meta.(*ArmClient) 474 vmScaleSetClient := client.vmScaleSetClient 475 476 log.Printf("[INFO] preparing arguments for Azure ARM Virtual Machine Scale Set creation.") 477 478 name := d.Get("name").(string) 479 location := d.Get("location").(string) 480 resGroup := d.Get("resource_group_name").(string) 481 tags := d.Get("tags").(map[string]interface{}) 482 483 sku, err := expandVirtualMachineScaleSetSku(d) 484 if err != nil { 485 return err 486 } 487 488 storageProfile := compute.VirtualMachineScaleSetStorageProfile{} 489 osDisk, err := expandAzureRMVirtualMachineScaleSetsStorageProfileOsDisk(d) 490 if err != nil { 491 return err 492 } 493 storageProfile.OsDisk = osDisk 494 495 if _, ok := d.GetOk("storage_profile_data_disk"); ok { 496 dataDisks, err := expandAzureRMVirtualMachineScaleSetsStorageProfileDataDisk(d) 497 if err != nil { 498 return err 499 } 500 storageProfile.DataDisks = &dataDisks 501 } 502 503 if _, ok := d.GetOk("storage_profile_image_reference"); ok { 504 imageRef, err := expandAzureRmVirtualMachineScaleSetStorageProfileImageReference(d) 505 if err != nil { 506 return err 507 } 508 storageProfile.ImageReference = imageRef 509 } 510 511 osProfile, err := expandAzureRMVirtualMachineScaleSetsOsProfile(d) 512 if err != nil { 513 return err 514 } 515 516 extensions, err := expandAzureRMVirtualMachineScaleSetExtensions(d) 517 if err != nil { 518 return err 519 } 520 521 updatePolicy := d.Get("upgrade_policy_mode").(string) 522 overprovision := d.Get("overprovision").(bool) 523 singlePlacementGroup := d.Get("single_placement_group").(bool) 524 525 scaleSetProps := compute.VirtualMachineScaleSetProperties{ 526 UpgradePolicy: &compute.UpgradePolicy{ 527 Mode: compute.UpgradeMode(updatePolicy), 528 }, 529 VirtualMachineProfile: &compute.VirtualMachineScaleSetVMProfile{ 530 NetworkProfile: expandAzureRmVirtualMachineScaleSetNetworkProfile(d), 531 StorageProfile: &storageProfile, 532 OsProfile: osProfile, 533 ExtensionProfile: extensions, 534 }, 535 Overprovision: &overprovision, 536 SinglePlacementGroup: &singlePlacementGroup, 537 } 538 539 scaleSetParams := compute.VirtualMachineScaleSet{ 540 Name: &name, 541 Location: &location, 542 Tags: expandTags(tags), 543 Sku: sku, 544 VirtualMachineScaleSetProperties: &scaleSetProps, 545 } 546 _, vmErr := vmScaleSetClient.CreateOrUpdate(resGroup, name, scaleSetParams, make(chan struct{})) 547 if vmErr != nil { 548 return vmErr 549 } 550 551 read, err := vmScaleSetClient.Get(resGroup, name) 552 if err != nil { 553 return err 554 } 555 if read.ID == nil { 556 return fmt.Errorf("Cannot read Virtual Machine Scale Set %s (resource group %s) ID", name, resGroup) 557 } 558 559 d.SetId(*read.ID) 560 561 return resourceArmVirtualMachineScaleSetRead(d, meta) 562 } 563 564 func resourceArmVirtualMachineScaleSetRead(d *schema.ResourceData, meta interface{}) error { 565 vmScaleSetClient := meta.(*ArmClient).vmScaleSetClient 566 567 id, err := parseAzureResourceID(d.Id()) 568 if err != nil { 569 return err 570 } 571 resGroup := id.ResourceGroup 572 name := id.Path["virtualMachineScaleSets"] 573 574 resp, err := vmScaleSetClient.Get(resGroup, name) 575 if err != nil { 576 if resp.StatusCode == http.StatusNotFound { 577 log.Printf("[INFO] AzureRM Virtual Machine Scale Set (%s) Not Found. Removing from State", name) 578 d.SetId("") 579 return nil 580 } 581 return fmt.Errorf("Error making Read request on Azure Virtual Machine Scale Set %s: %s", name, err) 582 } 583 584 d.Set("name", resp.Name) 585 d.Set("resource_group_name", resGroup) 586 d.Set("location", azureRMNormalizeLocation(*resp.Location)) 587 588 if err := d.Set("sku", flattenAzureRmVirtualMachineScaleSetSku(resp.Sku)); err != nil { 589 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Sku error: %#v", err) 590 } 591 592 properties := resp.VirtualMachineScaleSetProperties 593 594 d.Set("upgrade_policy_mode", properties.UpgradePolicy.Mode) 595 d.Set("overprovision", properties.Overprovision) 596 d.Set("single_placement_group", properties.SinglePlacementGroup) 597 598 osProfile, err := flattenAzureRMVirtualMachineScaleSetOsProfile(properties.VirtualMachineProfile.OsProfile) 599 if err != nil { 600 return fmt.Errorf("[DEBUG] Error flattening Virtual Machine Scale Set OS Profile. Error: %#v", err) 601 } 602 603 if err := d.Set("os_profile", osProfile); err != nil { 604 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile error: %#v", err) 605 } 606 607 if properties.VirtualMachineProfile.OsProfile.Secrets != nil { 608 if err := d.Set("os_profile_secrets", flattenAzureRmVirtualMachineScaleSetOsProfileSecrets(properties.VirtualMachineProfile.OsProfile.Secrets)); err != nil { 609 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile Secrets error: %#v", err) 610 } 611 } 612 613 if properties.VirtualMachineProfile.OsProfile.WindowsConfiguration != nil { 614 if err := d.Set("os_profile_windows_config", flattenAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(properties.VirtualMachineProfile.OsProfile.WindowsConfiguration)); err != nil { 615 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile Windows config error: %#v", err) 616 } 617 } 618 619 if properties.VirtualMachineProfile.OsProfile.LinuxConfiguration != nil { 620 if err := d.Set("os_profile_linux_config", flattenAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(properties.VirtualMachineProfile.OsProfile.LinuxConfiguration)); err != nil { 621 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set OS Profile Windows config error: %#v", err) 622 } 623 } 624 625 if err := d.Set("network_profile", flattenAzureRmVirtualMachineScaleSetNetworkProfile(properties.VirtualMachineProfile.NetworkProfile)); err != nil { 626 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Network Profile error: %#v", err) 627 } 628 629 if properties.VirtualMachineProfile.StorageProfile.ImageReference != nil { 630 if err := d.Set("storage_profile_image_reference", flattenAzureRmVirtualMachineScaleSetStorageProfileImageReference(properties.VirtualMachineProfile.StorageProfile.ImageReference)); err != nil { 631 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Storage Profile Image Reference error: %#v", err) 632 } 633 } 634 635 if err := d.Set("storage_profile_os_disk", flattenAzureRmVirtualMachineScaleSetStorageProfileOSDisk(properties.VirtualMachineProfile.StorageProfile.OsDisk)); err != nil { 636 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Storage Profile OS Disk error: %#v", err) 637 } 638 639 if resp.VirtualMachineProfile.StorageProfile.DataDisks != nil { 640 if err := d.Set("storage_profile_data_disk", flattenAzureRmVirtualMachineScaleSetStorageProfileDataDisk(properties.VirtualMachineProfile.StorageProfile.DataDisks)); err != nil { 641 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Storage Profile Data Disk error: %#v", err) 642 } 643 } 644 645 if properties.VirtualMachineProfile.ExtensionProfile != nil { 646 extension, err := flattenAzureRmVirtualMachineScaleSetExtensionProfile(properties.VirtualMachineProfile.ExtensionProfile) 647 if err != nil { 648 return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Extension Profile error: %#v", err) 649 } 650 d.Set("extension", extension) 651 } 652 653 flattenAndSetTags(d, resp.Tags) 654 655 return nil 656 } 657 658 func resourceArmVirtualMachineScaleSetDelete(d *schema.ResourceData, meta interface{}) error { 659 vmScaleSetClient := meta.(*ArmClient).vmScaleSetClient 660 661 id, err := parseAzureResourceID(d.Id()) 662 if err != nil { 663 return err 664 } 665 resGroup := id.ResourceGroup 666 name := id.Path["virtualMachineScaleSets"] 667 668 _, err = vmScaleSetClient.Delete(resGroup, name, make(chan struct{})) 669 670 return err 671 } 672 673 func flattenAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(config *compute.LinuxConfiguration) []interface{} { 674 result := make(map[string]interface{}) 675 result["disable_password_authentication"] = *config.DisablePasswordAuthentication 676 677 if config.SSH != nil && len(*config.SSH.PublicKeys) > 0 { 678 ssh_keys := make([]map[string]interface{}, 0, len(*config.SSH.PublicKeys)) 679 for _, i := range *config.SSH.PublicKeys { 680 key := make(map[string]interface{}) 681 key["path"] = *i.Path 682 683 if i.KeyData != nil { 684 key["key_data"] = *i.KeyData 685 } 686 687 ssh_keys = append(ssh_keys, key) 688 } 689 690 result["ssh_keys"] = ssh_keys 691 } 692 693 return []interface{}{result} 694 } 695 696 func flattenAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(config *compute.WindowsConfiguration) []interface{} { 697 result := make(map[string]interface{}) 698 699 if config.ProvisionVMAgent != nil { 700 result["provision_vm_agent"] = *config.ProvisionVMAgent 701 } 702 703 if config.EnableAutomaticUpdates != nil { 704 result["enable_automatic_upgrades"] = *config.EnableAutomaticUpdates 705 } 706 707 if config.WinRM != nil { 708 listeners := make([]map[string]interface{}, 0, len(*config.WinRM.Listeners)) 709 for _, i := range *config.WinRM.Listeners { 710 listener := make(map[string]interface{}) 711 listener["protocol"] = i.Protocol 712 713 if i.CertificateURL != nil { 714 listener["certificate_url"] = *i.CertificateURL 715 } 716 717 listeners = append(listeners, listener) 718 } 719 720 result["winrm"] = listeners 721 } 722 723 if config.AdditionalUnattendContent != nil { 724 content := make([]map[string]interface{}, 0, len(*config.AdditionalUnattendContent)) 725 for _, i := range *config.AdditionalUnattendContent { 726 c := make(map[string]interface{}) 727 c["pass"] = i.PassName 728 c["component"] = i.ComponentName 729 c["setting_name"] = i.SettingName 730 c["content"] = *i.Content 731 732 content = append(content, c) 733 } 734 735 result["additional_unattend_config"] = content 736 } 737 738 return []interface{}{result} 739 } 740 741 func flattenAzureRmVirtualMachineScaleSetOsProfileSecrets(secrets *[]compute.VaultSecretGroup) []map[string]interface{} { 742 result := make([]map[string]interface{}, 0, len(*secrets)) 743 for _, secret := range *secrets { 744 s := map[string]interface{}{ 745 "source_vault_id": *secret.SourceVault.ID, 746 } 747 748 if secret.VaultCertificates != nil { 749 certs := make([]map[string]interface{}, 0, len(*secret.VaultCertificates)) 750 for _, cert := range *secret.VaultCertificates { 751 vaultCert := make(map[string]interface{}) 752 vaultCert["certificate_url"] = *cert.CertificateURL 753 754 if cert.CertificateStore != nil { 755 vaultCert["certificate_store"] = *cert.CertificateStore 756 } 757 758 certs = append(certs, vaultCert) 759 } 760 761 s["vault_certificates"] = certs 762 } 763 764 result = append(result, s) 765 } 766 return result 767 } 768 769 func flattenAzureRmVirtualMachineScaleSetNetworkProfile(profile *compute.VirtualMachineScaleSetNetworkProfile) []map[string]interface{} { 770 networkConfigurations := profile.NetworkInterfaceConfigurations 771 result := make([]map[string]interface{}, 0, len(*networkConfigurations)) 772 for _, netConfig := range *networkConfigurations { 773 s := map[string]interface{}{ 774 "name": *netConfig.Name, 775 "primary": *netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.Primary, 776 } 777 778 if netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.IPConfigurations != nil { 779 ipConfigs := make([]map[string]interface{}, 0, len(*netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.IPConfigurations)) 780 for _, ipConfig := range *netConfig.VirtualMachineScaleSetNetworkConfigurationProperties.IPConfigurations { 781 config := make(map[string]interface{}) 782 config["name"] = *ipConfig.Name 783 784 properties := ipConfig.VirtualMachineScaleSetIPConfigurationProperties 785 786 if ipConfig.VirtualMachineScaleSetIPConfigurationProperties.Subnet != nil { 787 config["subnet_id"] = *properties.Subnet.ID 788 } 789 790 if properties.LoadBalancerBackendAddressPools != nil { 791 addressPools := make([]interface{}, 0, len(*properties.LoadBalancerBackendAddressPools)) 792 for _, pool := range *properties.LoadBalancerBackendAddressPools { 793 addressPools = append(addressPools, *pool.ID) 794 } 795 config["load_balancer_backend_address_pool_ids"] = schema.NewSet(schema.HashString, addressPools) 796 } 797 798 if properties.LoadBalancerInboundNatPools != nil { 799 inboundNatPools := make([]interface{}, 0, len(*properties.LoadBalancerInboundNatPools)) 800 for _, rule := range *properties.LoadBalancerInboundNatPools { 801 inboundNatPools = append(inboundNatPools, *rule.ID) 802 } 803 config["load_balancer_inbound_nat_rules_ids"] = schema.NewSet(schema.HashString, inboundNatPools) 804 } 805 806 ipConfigs = append(ipConfigs, config) 807 } 808 809 s["ip_configuration"] = ipConfigs 810 } 811 812 result = append(result, s) 813 } 814 815 return result 816 } 817 818 func flattenAzureRMVirtualMachineScaleSetOsProfile(profile *compute.VirtualMachineScaleSetOSProfile) ([]interface{}, error) { 819 result := make(map[string]interface{}) 820 821 result["computer_name_prefix"] = *profile.ComputerNamePrefix 822 result["admin_username"] = *profile.AdminUsername 823 824 if profile.CustomData != nil { 825 result["custom_data"] = *profile.CustomData 826 } 827 828 return []interface{}{result}, nil 829 } 830 831 func flattenAzureRmVirtualMachineScaleSetStorageProfileOSDisk(profile *compute.VirtualMachineScaleSetOSDisk) []interface{} { 832 result := make(map[string]interface{}) 833 834 if profile.Name != nil { 835 result["name"] = *profile.Name 836 } 837 838 if profile.Image != nil { 839 result["image"] = *profile.Image.URI 840 } 841 842 if profile.VhdContainers != nil { 843 containers := make([]interface{}, 0, len(*profile.VhdContainers)) 844 for _, container := range *profile.VhdContainers { 845 containers = append(containers, container) 846 } 847 result["vhd_containers"] = schema.NewSet(schema.HashString, containers) 848 } 849 850 if profile.ManagedDisk != nil { 851 result["managed_disk_type"] = string(profile.ManagedDisk.StorageAccountType) 852 } 853 854 result["caching"] = profile.Caching 855 result["create_option"] = profile.CreateOption 856 result["os_type"] = profile.OsType 857 858 return []interface{}{result} 859 } 860 861 func flattenAzureRmVirtualMachineScaleSetStorageProfileDataDisk(disks *[]compute.VirtualMachineScaleSetDataDisk) interface{} { 862 result := make([]interface{}, len(*disks)) 863 for i, disk := range *disks { 864 l := make(map[string]interface{}) 865 if disk.ManagedDisk != nil { 866 l["managed_disk_type"] = string(disk.ManagedDisk.StorageAccountType) 867 } 868 869 l["create_option"] = disk.CreateOption 870 l["caching"] = string(disk.Caching) 871 if disk.DiskSizeGB != nil { 872 l["disk_size_gb"] = *disk.DiskSizeGB 873 } 874 l["lun"] = *disk.Lun 875 876 result[i] = l 877 } 878 return result 879 } 880 881 func flattenAzureRmVirtualMachineScaleSetStorageProfileImageReference(profile *compute.ImageReference) []interface{} { 882 result := make(map[string]interface{}) 883 result["publisher"] = *profile.Publisher 884 result["offer"] = *profile.Offer 885 result["sku"] = *profile.Sku 886 result["version"] = *profile.Version 887 888 return []interface{}{result} 889 } 890 891 func flattenAzureRmVirtualMachineScaleSetSku(sku *compute.Sku) []interface{} { 892 result := make(map[string]interface{}) 893 result["name"] = *sku.Name 894 result["capacity"] = *sku.Capacity 895 896 if *sku.Tier != "" { 897 result["tier"] = *sku.Tier 898 } 899 900 return []interface{}{result} 901 } 902 903 func flattenAzureRmVirtualMachineScaleSetExtensionProfile(profile *compute.VirtualMachineScaleSetExtensionProfile) ([]map[string]interface{}, error) { 904 if profile.Extensions == nil { 905 return nil, nil 906 } 907 908 result := make([]map[string]interface{}, 0, len(*profile.Extensions)) 909 for _, extension := range *profile.Extensions { 910 e := make(map[string]interface{}) 911 e["name"] = *extension.Name 912 properties := extension.VirtualMachineScaleSetExtensionProperties 913 if properties != nil { 914 e["publisher"] = *properties.Publisher 915 e["type"] = *properties.Type 916 e["type_handler_version"] = *properties.TypeHandlerVersion 917 if properties.AutoUpgradeMinorVersion != nil { 918 e["auto_upgrade_minor_version"] = *properties.AutoUpgradeMinorVersion 919 } 920 921 if properties.Settings != nil { 922 settings, err := structure.FlattenJsonToString(*properties.Settings) 923 if err != nil { 924 return nil, err 925 } 926 e["settings"] = settings 927 } 928 } 929 930 result = append(result, e) 931 } 932 933 return result, nil 934 } 935 936 func resourceArmVirtualMachineScaleSetStorageProfileImageReferenceHash(v interface{}) int { 937 var buf bytes.Buffer 938 m := v.(map[string]interface{}) 939 buf.WriteString(fmt.Sprintf("%s-", m["publisher"].(string))) 940 buf.WriteString(fmt.Sprintf("%s-", m["offer"].(string))) 941 buf.WriteString(fmt.Sprintf("%s-", m["sku"].(string))) 942 buf.WriteString(fmt.Sprintf("%s-", m["version"].(string))) 943 944 return hashcode.String(buf.String()) 945 } 946 947 func resourceArmVirtualMachineScaleSetSkuHash(v interface{}) int { 948 var buf bytes.Buffer 949 m := v.(map[string]interface{}) 950 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 951 if m["tier"] != nil { 952 buf.WriteString(fmt.Sprintf("%s-", m["tier"].(string))) 953 } 954 buf.WriteString(fmt.Sprintf("%d-", m["capacity"].(int))) 955 956 return hashcode.String(buf.String()) 957 } 958 959 func resourceArmVirtualMachineScaleSetStorageProfileOsDiskHash(v interface{}) int { 960 var buf bytes.Buffer 961 m := v.(map[string]interface{}) 962 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 963 964 if m["vhd_containers"] != nil { 965 buf.WriteString(fmt.Sprintf("%s-", m["vhd_containers"].(*schema.Set).List())) 966 } 967 968 return hashcode.String(buf.String()) 969 } 970 971 func resourceArmVirtualMachineScaleSetNetworkConfigurationHash(v interface{}) int { 972 var buf bytes.Buffer 973 m := v.(map[string]interface{}) 974 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 975 buf.WriteString(fmt.Sprintf("%t-", m["primary"].(bool))) 976 return hashcode.String(buf.String()) 977 } 978 979 func resourceArmVirtualMachineScaleSetsOsProfileHash(v interface{}) int { 980 var buf bytes.Buffer 981 m := v.(map[string]interface{}) 982 buf.WriteString(fmt.Sprintf("%s-", m["computer_name_prefix"].(string))) 983 buf.WriteString(fmt.Sprintf("%s-", m["admin_username"].(string))) 984 if m["custom_data"] != nil { 985 customData := m["custom_data"].(string) 986 if !isBase64Encoded(customData) { 987 customData = base64Encode(customData) 988 } 989 buf.WriteString(fmt.Sprintf("%s-", customData)) 990 } 991 return hashcode.String(buf.String()) 992 } 993 994 func resourceArmVirtualMachineScaleSetOsProfileLinuxConfigHash(v interface{}) int { 995 var buf bytes.Buffer 996 m := v.(map[string]interface{}) 997 buf.WriteString(fmt.Sprintf("%t-", m["disable_password_authentication"].(bool))) 998 999 return hashcode.String(buf.String()) 1000 } 1001 1002 func resourceArmVirtualMachineScaleSetOsProfileLWindowsConfigHash(v interface{}) int { 1003 var buf bytes.Buffer 1004 m := v.(map[string]interface{}) 1005 if m["provision_vm_agent"] != nil { 1006 buf.WriteString(fmt.Sprintf("%t-", m["provision_vm_agent"].(bool))) 1007 } 1008 if m["enable_automatic_upgrades"] != nil { 1009 buf.WriteString(fmt.Sprintf("%t-", m["enable_automatic_upgrades"].(bool))) 1010 } 1011 return hashcode.String(buf.String()) 1012 } 1013 1014 func resourceArmVirtualMachineScaleSetExtensionHash(v interface{}) int { 1015 var buf bytes.Buffer 1016 m := v.(map[string]interface{}) 1017 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 1018 buf.WriteString(fmt.Sprintf("%s-", m["publisher"].(string))) 1019 buf.WriteString(fmt.Sprintf("%s-", m["type"].(string))) 1020 buf.WriteString(fmt.Sprintf("%s-", m["type_handler_version"].(string))) 1021 if m["auto_upgrade_minor_version"] != nil { 1022 buf.WriteString(fmt.Sprintf("%t-", m["auto_upgrade_minor_version"].(bool))) 1023 } 1024 1025 return hashcode.String(buf.String()) 1026 } 1027 1028 func expandVirtualMachineScaleSetSku(d *schema.ResourceData) (*compute.Sku, error) { 1029 skuConfig := d.Get("sku").(*schema.Set).List() 1030 1031 config := skuConfig[0].(map[string]interface{}) 1032 1033 name := config["name"].(string) 1034 tier := config["tier"].(string) 1035 capacity := int64(config["capacity"].(int)) 1036 1037 sku := &compute.Sku{ 1038 Name: &name, 1039 Capacity: &capacity, 1040 } 1041 1042 if tier != "" { 1043 sku.Tier = &tier 1044 } 1045 1046 return sku, nil 1047 } 1048 1049 func expandAzureRmVirtualMachineScaleSetNetworkProfile(d *schema.ResourceData) *compute.VirtualMachineScaleSetNetworkProfile { 1050 scaleSetNetworkProfileConfigs := d.Get("network_profile").(*schema.Set).List() 1051 networkProfileConfig := make([]compute.VirtualMachineScaleSetNetworkConfiguration, 0, len(scaleSetNetworkProfileConfigs)) 1052 1053 for _, npProfileConfig := range scaleSetNetworkProfileConfigs { 1054 config := npProfileConfig.(map[string]interface{}) 1055 1056 name := config["name"].(string) 1057 primary := config["primary"].(bool) 1058 1059 ipConfigurationConfigs := config["ip_configuration"].([]interface{}) 1060 ipConfigurations := make([]compute.VirtualMachineScaleSetIPConfiguration, 0, len(ipConfigurationConfigs)) 1061 for _, ipConfigConfig := range ipConfigurationConfigs { 1062 ipconfig := ipConfigConfig.(map[string]interface{}) 1063 name := ipconfig["name"].(string) 1064 subnetId := ipconfig["subnet_id"].(string) 1065 1066 ipConfiguration := compute.VirtualMachineScaleSetIPConfiguration{ 1067 Name: &name, 1068 VirtualMachineScaleSetIPConfigurationProperties: &compute.VirtualMachineScaleSetIPConfigurationProperties{ 1069 Subnet: &compute.APIEntityReference{ 1070 ID: &subnetId, 1071 }, 1072 }, 1073 } 1074 1075 if v := ipconfig["load_balancer_backend_address_pool_ids"]; v != nil { 1076 pools := v.(*schema.Set).List() 1077 resources := make([]compute.SubResource, 0, len(pools)) 1078 for _, p := range pools { 1079 id := p.(string) 1080 resources = append(resources, compute.SubResource{ 1081 ID: &id, 1082 }) 1083 } 1084 ipConfiguration.LoadBalancerBackendAddressPools = &resources 1085 } 1086 1087 if v := ipconfig["load_balancer_inbound_nat_rules_ids"]; v != nil { 1088 rules := v.(*schema.Set).List() 1089 rulesResources := make([]compute.SubResource, 0, len(rules)) 1090 for _, m := range rules { 1091 id := m.(string) 1092 rulesResources = append(rulesResources, compute.SubResource{ 1093 ID: &id, 1094 }) 1095 } 1096 ipConfiguration.LoadBalancerInboundNatPools = &rulesResources 1097 } 1098 1099 ipConfigurations = append(ipConfigurations, ipConfiguration) 1100 } 1101 1102 nProfile := compute.VirtualMachineScaleSetNetworkConfiguration{ 1103 Name: &name, 1104 VirtualMachineScaleSetNetworkConfigurationProperties: &compute.VirtualMachineScaleSetNetworkConfigurationProperties{ 1105 Primary: &primary, 1106 IPConfigurations: &ipConfigurations, 1107 }, 1108 } 1109 1110 networkProfileConfig = append(networkProfileConfig, nProfile) 1111 } 1112 1113 return &compute.VirtualMachineScaleSetNetworkProfile{ 1114 NetworkInterfaceConfigurations: &networkProfileConfig, 1115 } 1116 } 1117 1118 func expandAzureRMVirtualMachineScaleSetsOsProfile(d *schema.ResourceData) (*compute.VirtualMachineScaleSetOSProfile, error) { 1119 osProfileConfigs := d.Get("os_profile").(*schema.Set).List() 1120 1121 osProfileConfig := osProfileConfigs[0].(map[string]interface{}) 1122 namePrefix := osProfileConfig["computer_name_prefix"].(string) 1123 username := osProfileConfig["admin_username"].(string) 1124 password := osProfileConfig["admin_password"].(string) 1125 customData := osProfileConfig["custom_data"].(string) 1126 1127 osProfile := &compute.VirtualMachineScaleSetOSProfile{ 1128 ComputerNamePrefix: &namePrefix, 1129 AdminUsername: &username, 1130 } 1131 1132 if password != "" { 1133 osProfile.AdminPassword = &password 1134 } 1135 1136 if customData != "" { 1137 customData = base64Encode(customData) 1138 osProfile.CustomData = &customData 1139 } 1140 1141 if _, ok := d.GetOk("os_profile_secrets"); ok { 1142 secrets := expandAzureRmVirtualMachineScaleSetOsProfileSecrets(d) 1143 if secrets != nil { 1144 osProfile.Secrets = secrets 1145 } 1146 } 1147 1148 if _, ok := d.GetOk("os_profile_linux_config"); ok { 1149 linuxConfig, err := expandAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(d) 1150 if err != nil { 1151 return nil, err 1152 } 1153 osProfile.LinuxConfiguration = linuxConfig 1154 } 1155 1156 if _, ok := d.GetOk("os_profile_windows_config"); ok { 1157 winConfig, err := expandAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(d) 1158 if err != nil { 1159 return nil, err 1160 } 1161 if winConfig != nil { 1162 osProfile.WindowsConfiguration = winConfig 1163 } 1164 } 1165 1166 return osProfile, nil 1167 } 1168 1169 func expandAzureRMVirtualMachineScaleSetsStorageProfileOsDisk(d *schema.ResourceData) (*compute.VirtualMachineScaleSetOSDisk, error) { 1170 osDiskConfigs := d.Get("storage_profile_os_disk").(*schema.Set).List() 1171 1172 osDiskConfig := osDiskConfigs[0].(map[string]interface{}) 1173 name := osDiskConfig["name"].(string) 1174 image := osDiskConfig["image"].(string) 1175 vhd_containers := osDiskConfig["vhd_containers"].(*schema.Set).List() 1176 caching := osDiskConfig["caching"].(string) 1177 osType := osDiskConfig["os_type"].(string) 1178 createOption := osDiskConfig["create_option"].(string) 1179 managedDiskType := osDiskConfig["managed_disk_type"].(string) 1180 1181 osDisk := &compute.VirtualMachineScaleSetOSDisk{ 1182 Name: &name, 1183 Caching: compute.CachingTypes(caching), 1184 OsType: compute.OperatingSystemTypes(osType), 1185 CreateOption: compute.DiskCreateOptionTypes(createOption), 1186 } 1187 1188 if image != "" { 1189 osDisk.Image = &compute.VirtualHardDisk{ 1190 URI: &image, 1191 } 1192 } 1193 1194 if len(vhd_containers) > 0 { 1195 var vhdContainers []string 1196 for _, v := range vhd_containers { 1197 str := v.(string) 1198 vhdContainers = append(vhdContainers, str) 1199 } 1200 osDisk.VhdContainers = &vhdContainers 1201 } 1202 1203 managedDisk := &compute.VirtualMachineScaleSetManagedDiskParameters{} 1204 1205 if managedDiskType != "" { 1206 if name == "" { 1207 osDisk.Name = nil 1208 managedDisk.StorageAccountType = compute.StorageAccountTypes(managedDiskType) 1209 osDisk.ManagedDisk = managedDisk 1210 } else { 1211 return nil, fmt.Errorf("[ERROR] Conflict between `name` and `managed_disk_type` on `storage_profile_os_disk` (please set name to blank)") 1212 } 1213 } 1214 1215 //BEGIN: code to be removed after GH-13016 is merged 1216 if image != "" && managedDiskType != "" { 1217 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)") 1218 } 1219 1220 if len(vhd_containers) > 0 && managedDiskType != "" { 1221 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)") 1222 } 1223 //END: code to be removed after GH-13016 is merged 1224 1225 return osDisk, nil 1226 } 1227 1228 func expandAzureRMVirtualMachineScaleSetsStorageProfileDataDisk(d *schema.ResourceData) ([]compute.VirtualMachineScaleSetDataDisk, error) { 1229 disks := d.Get("storage_profile_data_disk").([]interface{}) 1230 dataDisks := make([]compute.VirtualMachineScaleSetDataDisk, 0, len(disks)) 1231 for _, diskConfig := range disks { 1232 config := diskConfig.(map[string]interface{}) 1233 1234 createOption := config["create_option"].(string) 1235 managedDiskType := config["managed_disk_type"].(string) 1236 lun := int32(config["lun"].(int)) 1237 1238 dataDisk := compute.VirtualMachineScaleSetDataDisk{ 1239 Lun: &lun, 1240 CreateOption: compute.DiskCreateOptionTypes(createOption), 1241 } 1242 1243 managedDiskVMSS := &compute.VirtualMachineScaleSetManagedDiskParameters{} 1244 1245 if managedDiskType != "" { 1246 managedDiskVMSS.StorageAccountType = compute.StorageAccountTypes(managedDiskType) 1247 } else { 1248 managedDiskVMSS.StorageAccountType = compute.StorageAccountTypes(compute.StandardLRS) 1249 } 1250 1251 //assume that data disks in VMSS can only be Managed Disks 1252 dataDisk.ManagedDisk = managedDiskVMSS 1253 if v := config["caching"].(string); v != "" { 1254 dataDisk.Caching = compute.CachingTypes(v) 1255 } 1256 1257 if v := config["disk_size_gb"]; v != nil { 1258 diskSize := int32(config["disk_size_gb"].(int)) 1259 dataDisk.DiskSizeGB = &diskSize 1260 } 1261 1262 dataDisks = append(dataDisks, dataDisk) 1263 } 1264 1265 return dataDisks, nil 1266 } 1267 1268 func expandAzureRmVirtualMachineScaleSetStorageProfileImageReference(d *schema.ResourceData) (*compute.ImageReference, error) { 1269 storageImageRefs := d.Get("storage_profile_image_reference").(*schema.Set).List() 1270 1271 storageImageRef := storageImageRefs[0].(map[string]interface{}) 1272 1273 publisher := storageImageRef["publisher"].(string) 1274 offer := storageImageRef["offer"].(string) 1275 sku := storageImageRef["sku"].(string) 1276 version := storageImageRef["version"].(string) 1277 1278 return &compute.ImageReference{ 1279 Publisher: &publisher, 1280 Offer: &offer, 1281 Sku: &sku, 1282 Version: &version, 1283 }, nil 1284 } 1285 1286 func expandAzureRmVirtualMachineScaleSetOsProfileLinuxConfig(d *schema.ResourceData) (*compute.LinuxConfiguration, error) { 1287 osProfilesLinuxConfig := d.Get("os_profile_linux_config").(*schema.Set).List() 1288 1289 linuxConfig := osProfilesLinuxConfig[0].(map[string]interface{}) 1290 disablePasswordAuth := linuxConfig["disable_password_authentication"].(bool) 1291 1292 linuxKeys := linuxConfig["ssh_keys"].([]interface{}) 1293 sshPublicKeys := make([]compute.SSHPublicKey, 0, len(linuxKeys)) 1294 for _, key := range linuxKeys { 1295 if key == nil { 1296 continue 1297 } 1298 sshKey := key.(map[string]interface{}) 1299 path := sshKey["path"].(string) 1300 keyData := sshKey["key_data"].(string) 1301 1302 sshPublicKey := compute.SSHPublicKey{ 1303 Path: &path, 1304 KeyData: &keyData, 1305 } 1306 1307 sshPublicKeys = append(sshPublicKeys, sshPublicKey) 1308 } 1309 1310 config := &compute.LinuxConfiguration{ 1311 DisablePasswordAuthentication: &disablePasswordAuth, 1312 SSH: &compute.SSHConfiguration{ 1313 PublicKeys: &sshPublicKeys, 1314 }, 1315 } 1316 1317 return config, nil 1318 } 1319 1320 func expandAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(d *schema.ResourceData) (*compute.WindowsConfiguration, error) { 1321 osProfilesWindowsConfig := d.Get("os_profile_windows_config").(*schema.Set).List() 1322 1323 osProfileConfig := osProfilesWindowsConfig[0].(map[string]interface{}) 1324 config := &compute.WindowsConfiguration{} 1325 1326 if v := osProfileConfig["provision_vm_agent"]; v != nil { 1327 provision := v.(bool) 1328 config.ProvisionVMAgent = &provision 1329 } 1330 1331 if v := osProfileConfig["enable_automatic_upgrades"]; v != nil { 1332 update := v.(bool) 1333 config.EnableAutomaticUpdates = &update 1334 } 1335 1336 if v := osProfileConfig["winrm"]; v != nil { 1337 winRm := v.(*schema.Set).List() 1338 if len(winRm) > 0 { 1339 winRmListeners := make([]compute.WinRMListener, 0, len(winRm)) 1340 for _, winRmConfig := range winRm { 1341 config := winRmConfig.(map[string]interface{}) 1342 1343 protocol := config["protocol"].(string) 1344 winRmListener := compute.WinRMListener{ 1345 Protocol: compute.ProtocolTypes(protocol), 1346 } 1347 if v := config["certificate_url"].(string); v != "" { 1348 winRmListener.CertificateURL = &v 1349 } 1350 1351 winRmListeners = append(winRmListeners, winRmListener) 1352 } 1353 config.WinRM = &compute.WinRMConfiguration{ 1354 Listeners: &winRmListeners, 1355 } 1356 } 1357 } 1358 if v := osProfileConfig["additional_unattend_config"]; v != nil { 1359 additionalConfig := v.(*schema.Set).List() 1360 if len(additionalConfig) > 0 { 1361 additionalConfigContent := make([]compute.AdditionalUnattendContent, 0, len(additionalConfig)) 1362 for _, addConfig := range additionalConfig { 1363 config := addConfig.(map[string]interface{}) 1364 pass := config["pass"].(string) 1365 component := config["component"].(string) 1366 settingName := config["setting_name"].(string) 1367 content := config["content"].(string) 1368 1369 addContent := compute.AdditionalUnattendContent{ 1370 PassName: compute.PassNames(pass), 1371 ComponentName: compute.ComponentNames(component), 1372 SettingName: compute.SettingNames(settingName), 1373 Content: &content, 1374 } 1375 1376 additionalConfigContent = append(additionalConfigContent, addContent) 1377 } 1378 config.AdditionalUnattendContent = &additionalConfigContent 1379 } 1380 } 1381 return config, nil 1382 } 1383 1384 func expandAzureRmVirtualMachineScaleSetOsProfileSecrets(d *schema.ResourceData) *[]compute.VaultSecretGroup { 1385 secretsConfig := d.Get("os_profile_secrets").(*schema.Set).List() 1386 secrets := make([]compute.VaultSecretGroup, 0, len(secretsConfig)) 1387 1388 for _, secretConfig := range secretsConfig { 1389 config := secretConfig.(map[string]interface{}) 1390 sourceVaultId := config["source_vault_id"].(string) 1391 1392 vaultSecretGroup := compute.VaultSecretGroup{ 1393 SourceVault: &compute.SubResource{ 1394 ID: &sourceVaultId, 1395 }, 1396 } 1397 1398 if v := config["vault_certificates"]; v != nil { 1399 certsConfig := v.([]interface{}) 1400 certs := make([]compute.VaultCertificate, 0, len(certsConfig)) 1401 for _, certConfig := range certsConfig { 1402 config := certConfig.(map[string]interface{}) 1403 1404 certUrl := config["certificate_url"].(string) 1405 cert := compute.VaultCertificate{ 1406 CertificateURL: &certUrl, 1407 } 1408 if v := config["certificate_store"].(string); v != "" { 1409 cert.CertificateStore = &v 1410 } 1411 1412 certs = append(certs, cert) 1413 } 1414 vaultSecretGroup.VaultCertificates = &certs 1415 } 1416 1417 secrets = append(secrets, vaultSecretGroup) 1418 } 1419 1420 return &secrets 1421 } 1422 1423 func expandAzureRMVirtualMachineScaleSetExtensions(d *schema.ResourceData) (*compute.VirtualMachineScaleSetExtensionProfile, error) { 1424 extensions := d.Get("extension").(*schema.Set).List() 1425 resources := make([]compute.VirtualMachineScaleSetExtension, 0, len(extensions)) 1426 for _, e := range extensions { 1427 config := e.(map[string]interface{}) 1428 name := config["name"].(string) 1429 publisher := config["publisher"].(string) 1430 t := config["type"].(string) 1431 version := config["type_handler_version"].(string) 1432 1433 extension := compute.VirtualMachineScaleSetExtension{ 1434 Name: &name, 1435 VirtualMachineScaleSetExtensionProperties: &compute.VirtualMachineScaleSetExtensionProperties{ 1436 Publisher: &publisher, 1437 Type: &t, 1438 TypeHandlerVersion: &version, 1439 }, 1440 } 1441 1442 if u := config["auto_upgrade_minor_version"]; u != nil { 1443 upgrade := u.(bool) 1444 extension.VirtualMachineScaleSetExtensionProperties.AutoUpgradeMinorVersion = &upgrade 1445 } 1446 1447 if s := config["settings"].(string); s != "" { 1448 settings, err := structure.ExpandJsonFromString(s) 1449 if err != nil { 1450 return nil, fmt.Errorf("unable to parse settings: %s", err) 1451 } 1452 extension.VirtualMachineScaleSetExtensionProperties.Settings = &settings 1453 } 1454 1455 if s := config["protected_settings"].(string); s != "" { 1456 protectedSettings, err := structure.ExpandJsonFromString(s) 1457 if err != nil { 1458 return nil, fmt.Errorf("unable to parse protected_settings: %s", err) 1459 } 1460 extension.VirtualMachineScaleSetExtensionProperties.ProtectedSettings = &protectedSettings 1461 } 1462 1463 resources = append(resources, extension) 1464 } 1465 1466 return &compute.VirtualMachineScaleSetExtensionProfile{ 1467 Extensions: &resources, 1468 }, nil 1469 }