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