Scaffold the Azure RM Virtual Machine resource
This commit is contained in:
parent
de1567c2e7
commit
cb109043f2
|
@ -46,35 +46,36 @@ func Provider() terraform.ResourceProvider {
|
||||||
},
|
},
|
||||||
|
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
"azurerm_resource_group": resourceArmResourceGroup(),
|
|
||||||
"azurerm_virtual_network": resourceArmVirtualNetwork(),
|
|
||||||
"azurerm_local_network_gateway": resourceArmLocalNetworkGateway(),
|
|
||||||
"azurerm_availability_set": resourceArmAvailabilitySet(),
|
"azurerm_availability_set": resourceArmAvailabilitySet(),
|
||||||
"azurerm_network_security_group": resourceArmNetworkSecurityGroup(),
|
|
||||||
"azurerm_network_security_rule": resourceArmNetworkSecurityRule(),
|
|
||||||
"azurerm_public_ip": resourceArmPublicIp(),
|
|
||||||
"azurerm_subnet": resourceArmSubnet(),
|
|
||||||
"azurerm_network_interface": resourceArmNetworkInterface(),
|
|
||||||
"azurerm_route_table": resourceArmRouteTable(),
|
|
||||||
"azurerm_route": resourceArmRoute(),
|
|
||||||
"azurerm_cdn_profile": resourceArmCdnProfile(),
|
|
||||||
"azurerm_cdn_endpoint": resourceArmCdnEndpoint(),
|
"azurerm_cdn_endpoint": resourceArmCdnEndpoint(),
|
||||||
"azurerm_storage_account": resourceArmStorageAccount(),
|
"azurerm_cdn_profile": resourceArmCdnProfile(),
|
||||||
"azurerm_storage_container": resourceArmStorageContainer(),
|
|
||||||
"azurerm_storage_blob": resourceArmStorageBlob(),
|
|
||||||
"azurerm_storage_queue": resourceArmStorageQueue(),
|
|
||||||
"azurerm_dns_zone": resourceArmDnsZone(),
|
|
||||||
"azurerm_dns_a_record": resourceArmDnsARecord(),
|
"azurerm_dns_a_record": resourceArmDnsARecord(),
|
||||||
"azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(),
|
"azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(),
|
||||||
"azurerm_dns_cname_record": resourceArmDnsCNameRecord(),
|
"azurerm_dns_cname_record": resourceArmDnsCNameRecord(),
|
||||||
"azurerm_dns_txt_record": resourceArmDnsTxtRecord(),
|
|
||||||
"azurerm_dns_ns_record": resourceArmDnsNsRecord(),
|
|
||||||
"azurerm_dns_mx_record": resourceArmDnsMxRecord(),
|
"azurerm_dns_mx_record": resourceArmDnsMxRecord(),
|
||||||
|
"azurerm_dns_ns_record": resourceArmDnsNsRecord(),
|
||||||
"azurerm_dns_srv_record": resourceArmDnsSrvRecord(),
|
"azurerm_dns_srv_record": resourceArmDnsSrvRecord(),
|
||||||
"azurerm_sql_server": resourceArmSqlServer(),
|
"azurerm_dns_txt_record": resourceArmDnsTxtRecord(),
|
||||||
|
"azurerm_dns_zone": resourceArmDnsZone(),
|
||||||
|
"azurerm_local_network_gateway": resourceArmLocalNetworkGateway(),
|
||||||
|
"azurerm_network_interface": resourceArmNetworkInterface(),
|
||||||
|
"azurerm_network_security_group": resourceArmNetworkSecurityGroup(),
|
||||||
|
"azurerm_network_security_rule": resourceArmNetworkSecurityRule(),
|
||||||
|
"azurerm_public_ip": resourceArmPublicIp(),
|
||||||
|
"azurerm_resource_group": resourceArmResourceGroup(),
|
||||||
|
"azurerm_route": resourceArmRoute(),
|
||||||
|
"azurerm_route_table": resourceArmRouteTable(),
|
||||||
|
"azurerm_search_service": resourceArmSearchService(),
|
||||||
"azurerm_sql_database": resourceArmSqlDatabase(),
|
"azurerm_sql_database": resourceArmSqlDatabase(),
|
||||||
"azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(),
|
"azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(),
|
||||||
"azurerm_search_service": resourceArmSearchService(),
|
"azurerm_sql_server": resourceArmSqlServer(),
|
||||||
|
"azurerm_storage_account": resourceArmStorageAccount(),
|
||||||
|
"azurerm_storage_blob": resourceArmStorageBlob(),
|
||||||
|
"azurerm_storage_container": resourceArmStorageContainer(),
|
||||||
|
"azurerm_storage_queue": resourceArmStorageQueue(),
|
||||||
|
"azurerm_subnet": resourceArmSubnet(),
|
||||||
|
"azurerm_virtual_machine": resourceArmVirtualMachine(),
|
||||||
|
"azurerm_virtual_network": resourceArmVirtualNetwork(),
|
||||||
},
|
},
|
||||||
ConfigureFunc: providerConfigure,
|
ConfigureFunc: providerConfigure,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,819 @@
|
||||||
|
package azurerm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/Azure/azure-sdk-for-go/arm/compute"
|
||||||
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceArmVirtualMachine() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceArmVirtualMachineCreate,
|
||||||
|
Read: resourceArmVirtualMachineRead,
|
||||||
|
Update: resourceArmVirtualMachineUpdate,
|
||||||
|
Delete: resourceArmVirtualMachineDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"location": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
StateFunc: azureRMNormalizeLocation,
|
||||||
|
},
|
||||||
|
|
||||||
|
"resource_group_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"plan": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"publisher": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"product": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Set: resourceArmVirtualMachinePlanHash,
|
||||||
|
},
|
||||||
|
|
||||||
|
"availability_set_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"license_type": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vm_size": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"storage_image_reference": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"publisher": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"offer": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"sku": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"version": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Set: resourceArmVirtualMachineStorageImageReferenceHash,
|
||||||
|
},
|
||||||
|
|
||||||
|
"storage_os_disk": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vhd_uri": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"caching": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"create_option": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Set: resourceArmVirtualMachineStorageOsDiskHash,
|
||||||
|
},
|
||||||
|
|
||||||
|
"storage_data_disk": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vhd_uri": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"create_option": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"disk_size_gb": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"lun": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Set: resourceArmVirtualMachineStorageDataDiskHash,
|
||||||
|
},
|
||||||
|
|
||||||
|
"os_profile": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"computer_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"admin_username": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"admin_password": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"custom_data": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Set: resourceArmVirtualMachineStorageOsProfileHash,
|
||||||
|
},
|
||||||
|
|
||||||
|
"os_profile_windows_config": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"provision_vm_agent": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"enable_automatic_upgrades": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"winrm": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"protocol": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"certificate_url": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"additional_unattend_config": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"pass": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"component": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"setting_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"content": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"os_profile_linux_config": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"disable_password_authentication": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"ssh_keys": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"path": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"key_data": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"os_profile_secrets": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"source_vault_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vault_certificates": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"certificate_url": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"certificate_store": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"network_interface_ids": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
Set: schema.HashString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*ArmClient)
|
||||||
|
vmClient := client.vmClient
|
||||||
|
|
||||||
|
log.Printf("[INFO] preparing arguments for Azure ARM Virtual Machine creation.")
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
location := d.Get("location").(string)
|
||||||
|
resGroup := d.Get("resource_group_name").(string)
|
||||||
|
|
||||||
|
osDisk, err := expandAzureRmVirtualMachineOsDisk(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
storageProfile := compute.StorageProfile{
|
||||||
|
OsDisk: osDisk,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := d.GetOk("storage_image_reference"); ok {
|
||||||
|
imageRef, err := expandAzureRmVirtualMachineImageReference(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
storageProfile.ImageReference = imageRef
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := d.GetOk("storage_data_disk"); ok {
|
||||||
|
dataDisks, err := expandAzureRmVirtualMachineDataDisk(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
storageProfile.DataDisks = &dataDisks
|
||||||
|
}
|
||||||
|
|
||||||
|
networkProfile := expandAzureRmVirtualMachineNetworkProfile(d)
|
||||||
|
vmSize := d.Get("vm_size").(string)
|
||||||
|
properties := compute.VirtualMachineProperties{
|
||||||
|
NetworkProfile: &networkProfile,
|
||||||
|
HardwareProfile: &compute.HardwareProfile{
|
||||||
|
VMSize: compute.VirtualMachineSizeTypes(vmSize),
|
||||||
|
},
|
||||||
|
StorageProfile: &storageProfile,
|
||||||
|
}
|
||||||
|
|
||||||
|
osProfile, err := expandAzureRmVirtualMachineOsProfile(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
properties.OsProfile = osProfile
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("availability_set_id"); ok {
|
||||||
|
availabilitySet := v.(string)
|
||||||
|
availSet := compute.SubResource{
|
||||||
|
ID: &availabilitySet,
|
||||||
|
}
|
||||||
|
|
||||||
|
properties.AvailabilitySet = &availSet
|
||||||
|
}
|
||||||
|
|
||||||
|
vm := compute.VirtualMachine{
|
||||||
|
Name: &name,
|
||||||
|
Location: &location,
|
||||||
|
Properties: &properties,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := d.GetOk("plan"); ok {
|
||||||
|
plan, err := expandAzureRmVirtualMachinePlan(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.Plan = plan
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = vmClient.CreateOrUpdate(resGroup, name, vm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceArmVirtualMachineRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
vmClient := meta.(*ArmClient).vmClient
|
||||||
|
|
||||||
|
id, err := parseAzureResourceID(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resGroup := id.ResourceGroup
|
||||||
|
name := id.Path["virtualMachines"]
|
||||||
|
|
||||||
|
resp, err := vmClient.Get(resGroup, name, "")
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error making Read request on Azure Virtual Machine %s: %s", name, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
return resourceArmVirtualMachineRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
vmClient := meta.(*ArmClient).vmClient
|
||||||
|
|
||||||
|
id, err := parseAzureResourceID(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resGroup := id.ResourceGroup
|
||||||
|
name := id.Path["virtualMachines"]
|
||||||
|
|
||||||
|
_, err = vmClient.Delete(resGroup, name)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachinePlanHash(v interface{}) int {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["publisher"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["product"].(string)))
|
||||||
|
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineStorageImageReferenceHash(v interface{}) int {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["publisher"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["offer"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["sku"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["version"].(string)))
|
||||||
|
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineStorageOsProfileHash(v interface{}) int {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["admin_username"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["admin_password"].(string)))
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineStorageDataDiskHash(v interface{}) int {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["vhd_uri"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["create_option"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%d-", m["disk_size_gb"].(int)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%d-", m["lun"].(int)))
|
||||||
|
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceArmVirtualMachineStorageOsDiskHash(v interface{}) int {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["vhd_uri"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["create_option"].(string)))
|
||||||
|
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachinePlan(d *schema.ResourceData) (*compute.Plan, error) {
|
||||||
|
planConfigs := d.Get("plan").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(planConfigs) != 1 {
|
||||||
|
return nil, fmt.Errorf("Cannot specify more than one plan.")
|
||||||
|
}
|
||||||
|
|
||||||
|
planConfig := planConfigs[0].(map[string]interface{})
|
||||||
|
|
||||||
|
publisher := planConfig["publisher"].(string)
|
||||||
|
name := planConfig["name"].(string)
|
||||||
|
product := planConfig["product"].(string)
|
||||||
|
|
||||||
|
return &compute.Plan{
|
||||||
|
Publisher: &publisher,
|
||||||
|
Name: &name,
|
||||||
|
Product: &product,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineOsProfile(d *schema.ResourceData) (*compute.OSProfile, error) {
|
||||||
|
osProfiles := d.Get("os_profile").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(osProfiles) != 1 {
|
||||||
|
return nil, fmt.Errorf("[ERROR] Only 1 OS Profile Can be specified for an Azure RM Virtual Machine")
|
||||||
|
}
|
||||||
|
|
||||||
|
osProfile := osProfiles[0].(map[string]interface{})
|
||||||
|
|
||||||
|
adminUsername := osProfile["admin_username"].(string)
|
||||||
|
adminPassword := osProfile["admin_password"].(string)
|
||||||
|
|
||||||
|
profile := &compute.OSProfile{
|
||||||
|
AdminUsername: &adminUsername,
|
||||||
|
AdminPassword: &adminPassword,
|
||||||
|
WindowsConfiguration: &compute.WindowsConfiguration{},
|
||||||
|
LinuxConfiguration: &compute.LinuxConfiguration{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := d.GetOk("os_profile_windows_config"); ok {
|
||||||
|
winConfig, err := expandAzureRmVirtualMachineOsProfileWindowsConfig(d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if winConfig != nil {
|
||||||
|
profile.WindowsConfiguration = winConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := d.GetOk("os_profile_linux_config"); ok {
|
||||||
|
linuxConfig, err := expandAzureRmVirtualMachineOsProfileLinuxConfig(d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if linuxConfig != nil {
|
||||||
|
profile.LinuxConfiguration = linuxConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := d.GetOk("os_profile_secrets"); ok {
|
||||||
|
secrets := expandAzureRmVirtualMachineOsProfileSecrets(d)
|
||||||
|
if secrets != nil {
|
||||||
|
profile.Secrets = secrets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v := osProfile["computer_name"].(string); v != "" {
|
||||||
|
profile.ComputerName = &v
|
||||||
|
}
|
||||||
|
if v := osProfile["custom_data"].(string); v != "" {
|
||||||
|
profile.CustomData = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineOsProfileSecrets(d *schema.ResourceData) *[]compute.VaultSecretGroup {
|
||||||
|
secretsConfig := d.Get("os_profile_secrets").(*schema.Set).List()
|
||||||
|
secrets := make([]compute.VaultSecretGroup, 0, len(secretsConfig))
|
||||||
|
|
||||||
|
for _, secretConfig := range secretsConfig {
|
||||||
|
config := secretConfig.(map[string]interface{})
|
||||||
|
sourceVaultId := config["source_vault_id"].(string)
|
||||||
|
|
||||||
|
vaultSecretGroup := compute.VaultSecretGroup{
|
||||||
|
SourceVault: &compute.SubResource{
|
||||||
|
ID: &sourceVaultId,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if v := config["vault_certificates"]; v != nil {
|
||||||
|
certsConfig := v.(*schema.Set).List()
|
||||||
|
certs := make([]compute.VaultCertificate, 0, len(certsConfig))
|
||||||
|
for _, certConfig := range certsConfig {
|
||||||
|
config := certConfig.(map[string]interface{})
|
||||||
|
|
||||||
|
certUrl := config["certificate_url"].(string)
|
||||||
|
cert := compute.VaultCertificate{
|
||||||
|
CertificateURL: &certUrl,
|
||||||
|
}
|
||||||
|
if v := config["certificate_store"].(string); v != "" {
|
||||||
|
cert.CertificateStore = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
certs = append(certs, cert)
|
||||||
|
}
|
||||||
|
vaultSecretGroup.VaultCertificates = &certs
|
||||||
|
}
|
||||||
|
|
||||||
|
secrets = append(secrets, vaultSecretGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &secrets
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineOsProfileLinuxConfig(d *schema.ResourceData) (*compute.LinuxConfiguration, error) {
|
||||||
|
osProfilesLinuxConfig := d.Get("os_profile_linux_config").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(osProfilesLinuxConfig) != 1 {
|
||||||
|
return nil, fmt.Errorf("[ERROR] Only 1 OS Profile Linux Config Can be specified for an Azure RM Virtual Machine")
|
||||||
|
}
|
||||||
|
|
||||||
|
linuxConfig := osProfilesLinuxConfig[0].(map[string]interface{})
|
||||||
|
disablePasswordAuth := linuxConfig["disable_password_authentication"].(bool)
|
||||||
|
|
||||||
|
config := &compute.LinuxConfiguration{
|
||||||
|
DisablePasswordAuthentication: &disablePasswordAuth,
|
||||||
|
}
|
||||||
|
|
||||||
|
linuxKeys := linuxConfig["ssh_keys"].(*schema.Set).List()
|
||||||
|
sshPublicKeys := make([]compute.SSHPublicKey, 0, len(linuxKeys))
|
||||||
|
for _, key := range linuxKeys {
|
||||||
|
sshKey := key.(map[string]interface{})
|
||||||
|
path := sshKey["path"].(string)
|
||||||
|
keyData := sshKey["key_data"].(string)
|
||||||
|
|
||||||
|
sshPublicKey := compute.SSHPublicKey{
|
||||||
|
Path: &path,
|
||||||
|
KeyData: &keyData,
|
||||||
|
}
|
||||||
|
|
||||||
|
sshPublicKeys = append(sshPublicKeys, sshPublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.SSH = &compute.SSHConfiguration{
|
||||||
|
PublicKeys: &sshPublicKeys,
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineOsProfileWindowsConfig(d *schema.ResourceData) (*compute.WindowsConfiguration, error) {
|
||||||
|
osProfilesWindowsConfig := d.Get("os_profile_windows_config").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(osProfilesWindowsConfig) != 1 {
|
||||||
|
return nil, fmt.Errorf("[ERROR] Only 1 OS Profile Windows Config Can be specified for an Azure RM Virtual Machine")
|
||||||
|
}
|
||||||
|
|
||||||
|
osProfileConfig := osProfilesWindowsConfig[0].(map[string]interface{})
|
||||||
|
config := &compute.WindowsConfiguration{}
|
||||||
|
|
||||||
|
if v := osProfileConfig["provision_vm_agent"]; v != nil {
|
||||||
|
provision := v.(bool)
|
||||||
|
config.ProvisionVMAgent = &provision
|
||||||
|
}
|
||||||
|
|
||||||
|
if v := osProfileConfig["enable_automatic_upgrades"]; v != nil {
|
||||||
|
update := v.(bool)
|
||||||
|
config.EnableAutomaticUpdates = &update
|
||||||
|
}
|
||||||
|
|
||||||
|
if v := osProfileConfig["winrm"]; v != nil {
|
||||||
|
winRm := v.(*schema.Set).List()
|
||||||
|
winRmListners := make([]compute.WinRMListener, 0, len(winRm))
|
||||||
|
for _, winRmConfig := range winRm {
|
||||||
|
config := winRmConfig.(map[string]interface{})
|
||||||
|
|
||||||
|
protocol := config["protocol"].(string)
|
||||||
|
winRmListner := compute.WinRMListener{
|
||||||
|
Protocol: compute.ProtocolTypes(protocol),
|
||||||
|
}
|
||||||
|
if v := config["certificate_url"].(string); v != "" {
|
||||||
|
winRmListner.CertificateURL = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
winRmListners = append(winRmListners, winRmListner)
|
||||||
|
}
|
||||||
|
config.WinRM = &compute.WinRMConfiguration{
|
||||||
|
Listeners: &winRmListners,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v := osProfileConfig["additional_unattend_config"]; v != nil {
|
||||||
|
additionalConfig := v.(*schema.Set).List()
|
||||||
|
additionalConfigContent := make([]compute.AdditionalUnattendContent, 0, len(additionalConfig))
|
||||||
|
for _, addConfig := range additionalConfig {
|
||||||
|
config := addConfig.(map[string]interface{})
|
||||||
|
pass := config["pass"].(string)
|
||||||
|
component := config["component"].(string)
|
||||||
|
settingName := config["setting_name"].(string)
|
||||||
|
content := config["content"].(string)
|
||||||
|
|
||||||
|
addContent := compute.AdditionalUnattendContent{
|
||||||
|
PassName: compute.PassNames(pass),
|
||||||
|
ComponentName: compute.ComponentNames(component),
|
||||||
|
SettingName: compute.SettingNames(settingName),
|
||||||
|
Content: &content,
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalConfigContent = append(additionalConfigContent, addContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.AdditionalUnattendContent = &additionalConfigContent
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineDataDisk(d *schema.ResourceData) ([]compute.DataDisk, error) {
|
||||||
|
disks := d.Get("storage_data_disk").([]interface{})
|
||||||
|
data_disks := make([]compute.DataDisk, 0, len(disks))
|
||||||
|
for _, disk_config := range disks {
|
||||||
|
config := disk_config.(map[string]interface{})
|
||||||
|
|
||||||
|
name := config["name"].(string)
|
||||||
|
vhd := config["vhd_uri"].(string)
|
||||||
|
createOption := config["create_option"].(string)
|
||||||
|
lun := config["lun"].(int)
|
||||||
|
disk_size := config["disk_size_gb"].(int)
|
||||||
|
|
||||||
|
data_disk := compute.DataDisk{
|
||||||
|
Name: &name,
|
||||||
|
Vhd: &compute.VirtualHardDisk{
|
||||||
|
URI: &vhd,
|
||||||
|
},
|
||||||
|
Lun: &lun,
|
||||||
|
DiskSizeGB: &disk_size,
|
||||||
|
CreateOption: compute.DiskCreateOptionTypes(createOption),
|
||||||
|
}
|
||||||
|
|
||||||
|
data_disks = append(data_disks, data_disk)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data_disks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineImageReference(d *schema.ResourceData) (*compute.ImageReference, error) {
|
||||||
|
storageImageRefs := d.Get("storage_image_reference").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(storageImageRefs) != 1 {
|
||||||
|
return nil, fmt.Errorf("Cannot specify more than one storage_image_reference.")
|
||||||
|
}
|
||||||
|
|
||||||
|
storageImageRef := storageImageRefs[0].(map[string]interface{})
|
||||||
|
|
||||||
|
publisher := storageImageRef["publisher"].(string)
|
||||||
|
offer := storageImageRef["offer"].(string)
|
||||||
|
sku := storageImageRef["sku"].(string)
|
||||||
|
version := storageImageRef["version"].(string)
|
||||||
|
|
||||||
|
return &compute.ImageReference{
|
||||||
|
Publisher: &publisher,
|
||||||
|
Offer: &offer,
|
||||||
|
Sku: &sku,
|
||||||
|
Version: &version,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineNetworkProfile(d *schema.ResourceData) compute.NetworkProfile {
|
||||||
|
nicIds := d.Get("network_interface_ids").(*schema.Set).List()
|
||||||
|
network_interfaces := make([]compute.NetworkInterfaceReference, 0, len(nicIds))
|
||||||
|
|
||||||
|
network_profile := compute.NetworkProfile{}
|
||||||
|
|
||||||
|
for _, nic := range nicIds {
|
||||||
|
id := nic.(string)
|
||||||
|
network_interface := compute.NetworkInterfaceReference{
|
||||||
|
ID: &id,
|
||||||
|
}
|
||||||
|
network_interfaces = append(network_interfaces, network_interface)
|
||||||
|
}
|
||||||
|
|
||||||
|
network_profile.NetworkInterfaces = &network_interfaces
|
||||||
|
|
||||||
|
return network_profile
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandAzureRmVirtualMachineOsDisk(d *schema.ResourceData) (*compute.OSDisk, error) {
|
||||||
|
disks := d.Get("storage_os_disk").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(disks) != 1 {
|
||||||
|
return nil, fmt.Errorf("[ERROR] Only 1 OS Disk Can be specified for an Azure RM Virtual Machine")
|
||||||
|
}
|
||||||
|
|
||||||
|
disk := disks[0].(map[string]interface{})
|
||||||
|
|
||||||
|
name := disk["name"].(string)
|
||||||
|
vhdURI := disk["vhd_uri"].(string)
|
||||||
|
createOption := disk["create_option"].(string)
|
||||||
|
|
||||||
|
osDisk := &compute.OSDisk{
|
||||||
|
Name: &name,
|
||||||
|
Vhd: &compute.VirtualHardDisk{
|
||||||
|
URI: &vhdURI,
|
||||||
|
},
|
||||||
|
CreateOption: compute.DiskCreateOptionTypes(createOption),
|
||||||
|
}
|
||||||
|
|
||||||
|
if v := disk["caching"].(string); v != "" {
|
||||||
|
osDisk.Caching = compute.CachingTypes(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return osDisk, nil
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
package azurerm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAzureRMVirtualMachine_basic(t *testing.T) {
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testCheckAzureRMVirtualMachineDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAzureRMVirtualMachine_basic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCheckAzureRMVirtualMachineExists(name string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
// Ensure we have enough information in state to look up in API
|
||||||
|
rs, ok := s.RootModule().Resources[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
vmName := rs.Primary.Attributes["name"]
|
||||||
|
resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
|
||||||
|
if !hasResourceGroup {
|
||||||
|
return fmt.Errorf("Bad: no resource group found in state for virtual machine: %s", vmName)
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*ArmClient).vmClient
|
||||||
|
|
||||||
|
resp, err := conn.Get(resourceGroup, vmName, "")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Bad: Get on vmClient: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
return fmt.Errorf("Bad: VirtualMachine %q (resource group: %q) does not exist", vmName, resourceGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCheckAzureRMVirtualMachineDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*ArmClient).vmClient
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "azurerm_virtual_machine" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
name := rs.Primary.Attributes["name"]
|
||||||
|
resourceGroup := rs.Primary.Attributes["resource_group_name"]
|
||||||
|
|
||||||
|
resp, err := conn.Get(resourceGroup, name, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusNotFound {
|
||||||
|
return fmt.Errorf("Virtual Machine still exists:\n%#v", resp.Properties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var testAccAzureRMVirtualMachine_basic = `
|
||||||
|
resource "azurerm_resource_group" "test" {
|
||||||
|
name = "acceptanceTestResourceGroup1"
|
||||||
|
location = "West US"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_virtual_network" "test" {
|
||||||
|
name = "acceptanceTestVirtualNetwork1"
|
||||||
|
address_space = ["10.0.0.0/16"]
|
||||||
|
location = "West US"
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_subnet" "test" {
|
||||||
|
name = "testsubnet"
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
virtual_network_name = "${azurerm_virtual_network.test.name}"
|
||||||
|
address_prefix = "10.0.2.0/24"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_network_interface" "test" {
|
||||||
|
name = "acceptanceTestNetworkInterface1"
|
||||||
|
location = "West US"
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
|
||||||
|
ip_configuration {
|
||||||
|
name = "testconfiguration1"
|
||||||
|
subnet_id = "${azurerm_subnet.test.id}"
|
||||||
|
private_ip_address_allocation = "dynamic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_virtual_machine" "test" {
|
||||||
|
name = "acceptanceTestVirtualMachine1"
|
||||||
|
location = "West US"
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
network_interface_ids = ["${azurerm_network_interface.test.id}"]
|
||||||
|
vm_size = "Standard_A0"
|
||||||
|
|
||||||
|
storage_os_disk {
|
||||||
|
name = "myosdisk1"
|
||||||
|
vhd_uri = "http://mystorage1.blob.core.windows.net/vhds/myosdisk1.vhd"
|
||||||
|
caching = "ReadWrite"
|
||||||
|
create_option = "FromImage"
|
||||||
|
}
|
||||||
|
|
||||||
|
os_profile {
|
||||||
|
computer_name = "my_computer"
|
||||||
|
admin_username = "testadmin"
|
||||||
|
admin_password = "Password1234!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
Loading…
Reference in New Issue