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