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