diff --git a/azurerm/resource_arm_virtual_machine.go b/azurerm/resource_arm_virtual_machine.go
index 1eb3a49999da..5dee7b87b5fa 100644
--- a/azurerm/resource_arm_virtual_machine.go
+++ b/azurerm/resource_arm_virtual_machine.go
@@ -412,6 +412,11 @@ func resourceArmVirtualMachine() *schema.Resource {
"protocol": {
Type: schema.TypeString,
Required: true,
+ ValidateFunc: validation.StringInSlice([]string{
+ "HTTP",
+ "HTTPS",
+ }, true),
+ DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
},
"certificate_url": {
Type: schema.TypeString,
@@ -425,17 +430,28 @@ func resourceArmVirtualMachine() *schema.Resource {
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
+ // TODO: should we make `pass` and `component` Optional + Defaulted?
"pass": {
Type: schema.TypeString,
Required: true,
+ ValidateFunc: validation.StringInSlice([]string{
+ "oobeSystem",
+ }, false),
},
"component": {
Type: schema.TypeString,
Required: true,
+ ValidateFunc: validation.StringInSlice([]string{
+ "Microsoft-Windows-Shell-Setup",
+ }, false),
},
"setting_name": {
Type: schema.TypeString,
Required: true,
+ ValidateFunc: validation.StringInSlice([]string{
+ "AutoLogon",
+ "FirstLogonCommands",
+ }, false),
},
"content": {
Type: schema.TypeString,
@@ -472,7 +488,7 @@ func resourceArmVirtualMachine() *schema.Resource {
},
"key_data": {
Type: schema.TypeString,
- Optional: true,
+ Required: true,
},
},
},
diff --git a/examples/virtual-machines/managed-disks/attaching-external-disks/1-dependencies.tf b/examples/virtual-machines/managed-disks/attaching-external-disks/1-dependencies.tf
new file mode 100644
index 000000000000..7d9d5da5ef5c
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/attaching-external-disks/1-dependencies.tf
@@ -0,0 +1,33 @@
+resource "azurerm_resource_group" "main" {
+ name = "${var.prefix}-resources"
+ location = "${var.location}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_virtual_network" "main" {
+ name = "${var.prefix}-network"
+ address_space = ["10.0.0.0/16"]
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_subnet" "internal" {
+ name = "internal"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ virtual_network_name = "${azurerm_virtual_network.main.name}"
+ address_prefix = "10.0.2.0/24"
+}
+
+resource "azurerm_network_interface" "main" {
+ name = "${var.prefix}-nic"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+
+ ip_configuration {
+ name = "testconfiguration1"
+ subnet_id = "${azurerm_subnet.internal.id}"
+ private_ip_address_allocation = "dynamic"
+ }
+}
diff --git a/examples/virtual-machines/managed-disks/attaching-external-disks/2-virtual-machine.tf b/examples/virtual-machines/managed-disks/attaching-external-disks/2-virtual-machine.tf
new file mode 100644
index 000000000000..460d041c2a0d
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/attaching-external-disks/2-virtual-machine.tf
@@ -0,0 +1,41 @@
+resource "azurerm_virtual_machine" "main" {
+ name = "${var.prefix}-vm"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ network_interface_ids = ["${azurerm_network_interface.main.id}"]
+ vm_size = "Standard_F2"
+
+ # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_os_disk_on_termination = true
+
+ # This means the Data Disk Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ publisher = "Canonical"
+ offer = "UbuntuServer"
+ sku = "16.04-LTS"
+ version = "latest"
+ }
+
+ storage_os_disk {
+ name = "myosdisk1"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ managed_disk_type = "Standard_LRS"
+ }
+
+ os_profile {
+ computer_name = "hostname"
+ admin_username = "testadmin"
+ admin_password = "Password1234!"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+
+ tags = "${var.tags}"
+}
diff --git a/examples/virtual-machines/managed-disks/attaching-external-disks/3-external-disks.tf b/examples/virtual-machines/managed-disks/attaching-external-disks/3-external-disks.tf
new file mode 100644
index 000000000000..1c89d2c37f69
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/attaching-external-disks/3-external-disks.tf
@@ -0,0 +1,17 @@
+resource "azurerm_managed_disk" "external" {
+ count = "${var.number_of_disks}"
+ name = "${var.prefix}-disk${count.index+1}"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ storage_account_type = "Standard_LRS"
+ create_option = "Empty"
+ disk_size_gb = "10"
+}
+
+resource "azurerm_virtual_machine_data_disk_attachment" "external" {
+ count = "${var.number_of_disks}"
+ managed_disk_id = "${azurerm_managed_disk.external.*.id[count.index]}"
+ virtual_machine_id = "${azurerm_virtual_machine.main.id}"
+ lun = "${10+count.index}"
+ caching = "ReadWrite"
+}
diff --git a/examples/virtual-machines/managed-disks/attaching-external-disks/README.md b/examples/virtual-machines/managed-disks/attaching-external-disks/README.md
new file mode 100644
index 000000000000..120cdc02a798
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/attaching-external-disks/README.md
@@ -0,0 +1,14 @@
+## Example: Virtual Machine with Data Disks
+
+This example provisions a Virtual Machine with 2 Data Disks and an OS Disk all of which are Managed Disks.
+
+Notes:
+
+- The files involved in this example are split out to make it easier to read, however all of the resources could be combined into a single file if needed.
+
+### Variables
+
+* `prefix` - (Required) The Prefix used for all resources in this example.
+* `location` - (Required) The Azure Region in which the resources in this example should exist.
+* `tags` - (Optional) Any tags which should be assigned to the resources in this example.
+* `number_of_disks` - (Optional) The number of Data Disks which should be attached, defaults to `2`.
diff --git a/examples/virtual-machines/managed-disks/attaching-external-disks/variables.tf b/examples/virtual-machines/managed-disks/attaching-external-disks/variables.tf
new file mode 100644
index 000000000000..98d5a62c3f03
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/attaching-external-disks/variables.tf
@@ -0,0 +1,18 @@
+variable "prefix" {
+ description = "The Prefix used for all resources in this example"
+}
+
+variable "location" {
+ description = "The Azure Region in which the resources in this example should exist"
+}
+
+variable "tags" {
+ type = "map"
+ default = {}
+ description = "Any tags which should be assigned to the resources in this example"
+}
+
+variable "number_of_disks" {
+ description = "The number of Data Disks which should be attached"
+ default = 2
+}
diff --git a/examples/virtual-machines/managed-disks/basic-osdisk/1-dependencies.tf b/examples/virtual-machines/managed-disks/basic-osdisk/1-dependencies.tf
new file mode 100644
index 000000000000..7d9d5da5ef5c
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/basic-osdisk/1-dependencies.tf
@@ -0,0 +1,33 @@
+resource "azurerm_resource_group" "main" {
+ name = "${var.prefix}-resources"
+ location = "${var.location}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_virtual_network" "main" {
+ name = "${var.prefix}-network"
+ address_space = ["10.0.0.0/16"]
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_subnet" "internal" {
+ name = "internal"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ virtual_network_name = "${azurerm_virtual_network.main.name}"
+ address_prefix = "10.0.2.0/24"
+}
+
+resource "azurerm_network_interface" "main" {
+ name = "${var.prefix}-nic"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+
+ ip_configuration {
+ name = "testconfiguration1"
+ subnet_id = "${azurerm_subnet.internal.id}"
+ private_ip_address_allocation = "dynamic"
+ }
+}
diff --git a/examples/virtual-machines/managed-disks/basic-osdisk/2-virtual-machine.tf b/examples/virtual-machines/managed-disks/basic-osdisk/2-virtual-machine.tf
new file mode 100644
index 000000000000..62932ed9a14f
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/basic-osdisk/2-virtual-machine.tf
@@ -0,0 +1,41 @@
+resource "azurerm_virtual_machine" "test" {
+ name = "${var.prefix}-vm"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ network_interface_ids = ["${azurerm_network_interface.main.id}"]
+ vm_size = "Standard_F2"
+
+ # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_os_disk_on_termination = true
+
+ # This means the Data Disk Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ publisher = "Canonical"
+ offer = "UbuntuServer"
+ sku = "16.04-LTS"
+ version = "latest"
+ }
+
+ storage_os_disk {
+ name = "myosdisk1"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ managed_disk_type = "Standard_LRS"
+ }
+
+ os_profile {
+ computer_name = "hostname"
+ admin_username = "testadmin"
+ admin_password = "Password1234!"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+
+ tags = "${var.tags}"
+}
diff --git a/examples/virtual-machines/managed-disks/basic-osdisk/README.md b/examples/virtual-machines/managed-disks/basic-osdisk/README.md
new file mode 100644
index 000000000000..8ae13ecd1c56
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/basic-osdisk/README.md
@@ -0,0 +1,13 @@
+## Example: Basic Virtual Machine using a Managed Disk
+
+This example provisions a Virtual Machine with no Data Disks with a Managed Disk as the main OS Disk.
+
+Notes:
+
+- The files involved in this example are split out to make it easier to read, however all of the resources could be combined into a single file if needed.
+
+### Variables
+
+* `prefix` - (Required) The Prefix used for all resources in this example.
+* `location` - (Required) The Azure Region in which the resources in this example should exist.
+* `tags` - (Optional) Any tags which should be assigned to the resources in this example.
diff --git a/examples/virtual-machines/managed-disks/basic-osdisk/variables.tf b/examples/virtual-machines/managed-disks/basic-osdisk/variables.tf
new file mode 100644
index 000000000000..1bd6bc2dbce3
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/basic-osdisk/variables.tf
@@ -0,0 +1,13 @@
+variable "prefix" {
+ description = "The Prefix used for all resources in this example"
+}
+
+variable "location" {
+ description = "The Azure Region in which the resources in this example should exist"
+}
+
+variable "tags" {
+ type = "map"
+ default = {}
+ description = "Any tags which should be assigned to the resources in this example"
+}
diff --git a/examples/virtual-machines/managed-disks/from-custom-image/1-dependencies.tf b/examples/virtual-machines/managed-disks/from-custom-image/1-dependencies.tf
new file mode 100644
index 000000000000..7d9d5da5ef5c
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/from-custom-image/1-dependencies.tf
@@ -0,0 +1,33 @@
+resource "azurerm_resource_group" "main" {
+ name = "${var.prefix}-resources"
+ location = "${var.location}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_virtual_network" "main" {
+ name = "${var.prefix}-network"
+ address_space = ["10.0.0.0/16"]
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_subnet" "internal" {
+ name = "internal"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ virtual_network_name = "${azurerm_virtual_network.main.name}"
+ address_prefix = "10.0.2.0/24"
+}
+
+resource "azurerm_network_interface" "main" {
+ name = "${var.prefix}-nic"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+
+ ip_configuration {
+ name = "testconfiguration1"
+ subnet_id = "${azurerm_subnet.internal.id}"
+ private_ip_address_allocation = "dynamic"
+ }
+}
diff --git a/examples/virtual-machines/managed-disks/from-custom-image/2-virtual-machine.tf b/examples/virtual-machines/managed-disks/from-custom-image/2-virtual-machine.tf
new file mode 100644
index 000000000000..953ec859ca8e
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/from-custom-image/2-virtual-machine.tf
@@ -0,0 +1,44 @@
+# we assume that this Custom Image already exists
+data "azurerm_image" "custom" {
+ name = "${var.custom_image_name}"
+ resource_group_name = "${var.custom_image_resource_group_name}"
+}
+
+resource "azurerm_virtual_machine" "test" {
+ name = "${var.prefix}-vm"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ network_interface_ids = ["${azurerm_network_interface.main.id}"]
+ vm_size = "Standard_F2"
+
+ # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_os_disk_on_termination = true
+
+ # This means the Data Disk Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ id = "${data.azurerm_image.custom.id}"
+ }
+
+ storage_os_disk {
+ name = "osdisk"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ managed_disk_type = "Standard_LRS"
+ }
+
+ os_profile {
+ computer_name = "hostname"
+ admin_username = "testadmin"
+ admin_password = "Password1234!"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+
+ tags = "${var.tags}"
+}
diff --git a/examples/virtual-machines/managed-disks/from-custom-image/README.md b/examples/virtual-machines/managed-disks/from-custom-image/README.md
new file mode 100644
index 000000000000..8a85af6abdae
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/from-custom-image/README.md
@@ -0,0 +1,17 @@
+## Example: Virtual Machine with Managed Disks from a Custom Image
+
+This example provisions a Virtual Machine with Managed Disks from a Custom Image that already exists.
+
+Notes:
+
+- The files involved in this example are split out to make it easier to read, however all of the resources could be combined into a single file if needed.
+- This example assumes the Custom Image specified exists - if it doesn't this example will fail.
+
+### Variables
+
+* `prefix` - (Required) The Prefix used for all resources in this example.
+* `location` - (Required) The Azure Region in which the resources in this example should exist.
+* `tags` - (Optional) Any tags which should be assigned to the resources in this example.
+
+* `custom_image_resource_group_name` - (Required) The name of the Resource Group in which the Custom Image exists.
+* `custom_image_name` - (Required) The name of the Custom Image to provision this Virtual Machine from.
diff --git a/examples/virtual-machines/managed-disks/from-custom-image/variables.tf b/examples/virtual-machines/managed-disks/from-custom-image/variables.tf
new file mode 100644
index 000000000000..b4ade98af701
--- /dev/null
+++ b/examples/virtual-machines/managed-disks/from-custom-image/variables.tf
@@ -0,0 +1,21 @@
+variable "prefix" {
+ description = "The Prefix used for all resources in this example"
+}
+
+variable "location" {
+ description = "The Azure Region in which the resources in this example should exist"
+}
+
+variable "tags" {
+ type = "map"
+ default = {}
+ description = "Any tags which should be assigned to the resources in this example"
+}
+
+variable "custom_image_resource_group_name" {
+ description = "The name of the Resource Group in which the Custom Image exists."
+}
+
+variable "custom_image_name" {
+ description = "The name of the Custom Image to provision this Virtual Machine from."
+}
diff --git a/examples/virtual-machines/provisioners/linux/1-dependencies.tf b/examples/virtual-machines/provisioners/linux/1-dependencies.tf
new file mode 100644
index 000000000000..9e50341b7747
--- /dev/null
+++ b/examples/virtual-machines/provisioners/linux/1-dependencies.tf
@@ -0,0 +1,47 @@
+locals {
+ virtual_machine_name = "${var.prefix}-vm"
+ admin_username = "testadmin"
+ admin_password = "Password1234!"
+}
+
+resource "azurerm_resource_group" "main" {
+ name = "${var.prefix}-resources"
+ location = "${var.location}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_virtual_network" "main" {
+ name = "${var.prefix}-network"
+ address_space = ["10.0.0.0/16"]
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_subnet" "internal" {
+ name = "internal"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ virtual_network_name = "${azurerm_virtual_network.main.name}"
+ address_prefix = "10.0.2.0/24"
+}
+
+resource "azurerm_public_ip" "main" {
+ name = "${var.prefix}-publicip"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ location = "${azurerm_resource_group.main.location}"
+ public_ip_address_allocation = "static"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_network_interface" "main" {
+ name = "${var.prefix}-nic"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+
+ ip_configuration {
+ name = "configuration"
+ subnet_id = "${azurerm_subnet.internal.id}"
+ private_ip_address_allocation = "dynamic"
+ public_ip_address_id = "${azurerm_public_ip.main.id}"
+ }
+}
diff --git a/examples/virtual-machines/provisioners/linux/2-virtual-machine.tf b/examples/virtual-machines/provisioners/linux/2-virtual-machine.tf
new file mode 100644
index 000000000000..3507de92b4c7
--- /dev/null
+++ b/examples/virtual-machines/provisioners/linux/2-virtual-machine.tf
@@ -0,0 +1,52 @@
+resource "azurerm_virtual_machine" "example" {
+ name = "${local.virtual_machine_name}"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ network_interface_ids = ["${azurerm_network_interface.main.id}"]
+ vm_size = "Standard_F2"
+
+ # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_os_disk_on_termination = true
+
+ # This means the Data Disk Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ publisher = "Canonical"
+ offer = "UbuntuServer"
+ sku = "16.04-LTS"
+ version = "latest"
+ }
+
+ storage_os_disk {
+ name = "${var.prefix}-osdisk"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ managed_disk_type = "Standard_LRS"
+ }
+
+ os_profile {
+ computer_name = "${local.virtual_machine_name}"
+ admin_username = "${local.admin_username}"
+ admin_password = "${local.admin_password}"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+
+ provisioner "remote-exec" {
+ connection {
+ user = "${local.admin_username}"
+ password = "${local.admin_password}"
+ }
+
+ inline = [
+ "ls -la",
+ ]
+ }
+
+ tags = "${var.tags}"
+}
diff --git a/examples/virtual-machines/provisioners/linux/README.md b/examples/virtual-machines/provisioners/linux/README.md
new file mode 100644
index 000000000000..9d9b03d3073c
--- /dev/null
+++ b/examples/virtual-machines/provisioners/linux/README.md
@@ -0,0 +1,11 @@
+## Example: using Provisioner over SSH to a Linux Virtual Machine
+
+This example provisions a Virtual Machine running Ubuntu 16.04-LTS with a Public IP Address and [runs a `remote-exec` provisioner](https://www.terraform.io/docs/provisioners/remote-exec.html) over SSH.
+
+The files involved in this example are split out to make it easier to read, however all of the resources could be combined into a single file if needed.
+
+### Variables
+
+* `prefix` - (Required) The Prefix used for all resources in this example.
+* `location` - (Required) The Azure Region in which the resources in this example should exist.
+* `tags` - (Optional) Any tags which should be assigned to the resources in this example.
diff --git a/examples/virtual-machines/provisioners/linux/variables.tf b/examples/virtual-machines/provisioners/linux/variables.tf
new file mode 100644
index 000000000000..1bd6bc2dbce3
--- /dev/null
+++ b/examples/virtual-machines/provisioners/linux/variables.tf
@@ -0,0 +1,13 @@
+variable "prefix" {
+ description = "The Prefix used for all resources in this example"
+}
+
+variable "location" {
+ description = "The Azure Region in which the resources in this example should exist"
+}
+
+variable "tags" {
+ type = "map"
+ default = {}
+ description = "Any tags which should be assigned to the resources in this example"
+}
diff --git a/examples/virtual-machines/provisioners/windows/1-dependencies.tf b/examples/virtual-machines/provisioners/windows/1-dependencies.tf
new file mode 100644
index 000000000000..9e50341b7747
--- /dev/null
+++ b/examples/virtual-machines/provisioners/windows/1-dependencies.tf
@@ -0,0 +1,47 @@
+locals {
+ virtual_machine_name = "${var.prefix}-vm"
+ admin_username = "testadmin"
+ admin_password = "Password1234!"
+}
+
+resource "azurerm_resource_group" "main" {
+ name = "${var.prefix}-resources"
+ location = "${var.location}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_virtual_network" "main" {
+ name = "${var.prefix}-network"
+ address_space = ["10.0.0.0/16"]
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_subnet" "internal" {
+ name = "internal"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ virtual_network_name = "${azurerm_virtual_network.main.name}"
+ address_prefix = "10.0.2.0/24"
+}
+
+resource "azurerm_public_ip" "main" {
+ name = "${var.prefix}-publicip"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ location = "${azurerm_resource_group.main.location}"
+ public_ip_address_allocation = "static"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_network_interface" "main" {
+ name = "${var.prefix}-nic"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+
+ ip_configuration {
+ name = "configuration"
+ subnet_id = "${azurerm_subnet.internal.id}"
+ private_ip_address_allocation = "dynamic"
+ public_ip_address_id = "${azurerm_public_ip.main.id}"
+ }
+}
diff --git a/examples/virtual-machines/provisioners/windows/2-certificates.tf b/examples/virtual-machines/provisioners/windows/2-certificates.tf
new file mode 100644
index 000000000000..29a09d75cad8
--- /dev/null
+++ b/examples/virtual-machines/provisioners/windows/2-certificates.tf
@@ -0,0 +1,78 @@
+data "azurerm_client_config" "current" {}
+
+resource "azurerm_key_vault" "main" {
+ name = "${var.prefix}keyvault"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tenant_id = "${data.azurerm_client_config.current.tenant_id}"
+
+ enabled_for_deployment = true
+ enabled_for_template_deployment = true
+
+ sku {
+ name = "standard"
+ }
+
+ access_policy {
+ tenant_id = "${data.azurerm_client_config.current.tenant_id}"
+ object_id = "${data.azurerm_client_config.current.service_principal_object_id}"
+
+ certificate_permissions = [
+ "create",
+ "delete",
+ "get",
+ "update",
+ ]
+
+ key_permissions = []
+ secret_permissions = []
+ }
+
+ tags = "${var.tags}"
+}
+
+resource "azurerm_key_vault_certificate" "main" {
+ name = "${local.virtual_machine_name}-cert"
+ vault_uri = "${azurerm_key_vault.main.vault_uri}"
+
+ certificate_policy {
+ issuer_parameters {
+ name = "Self"
+ }
+
+ key_properties {
+ exportable = true
+ key_size = 2048
+ key_type = "RSA"
+ reuse_key = true
+ }
+
+ lifetime_action {
+ action {
+ action_type = "AutoRenew"
+ }
+
+ trigger {
+ days_before_expiry = 30
+ }
+ }
+
+ secret_properties {
+ content_type = "application/x-pkcs12"
+ }
+
+ x509_certificate_properties {
+ key_usage = [
+ "cRLSign",
+ "dataEncipherment",
+ "digitalSignature",
+ "keyAgreement",
+ "keyCertSign",
+ "keyEncipherment",
+ ]
+
+ subject = "CN=${local.virtual_machine_name}"
+ validity_in_months = 12
+ }
+ }
+}
diff --git a/examples/virtual-machines/provisioners/windows/3-virtual-machine.tf b/examples/virtual-machines/provisioners/windows/3-virtual-machine.tf
new file mode 100644
index 000000000000..8bb6691078f3
--- /dev/null
+++ b/examples/virtual-machines/provisioners/windows/3-virtual-machine.tf
@@ -0,0 +1,91 @@
+locals {
+ custom_data_params = "Param($ComputerName = \"${local.virtual_machine_name}\")"
+ custom_data_content = "${local.custom_data_params} ${file("./files/winrm.ps1")}"
+}
+
+resource "azurerm_virtual_machine" "example" {
+ name = "${local.virtual_machine_name}"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ network_interface_ids = ["${azurerm_network_interface.main.id}"]
+ vm_size = "Standard_F2"
+
+ # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_os_disk_on_termination = true
+
+ # This means the Data Disk Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ publisher = "MicrosoftWindowsServer"
+ offer = "WindowsServer"
+ sku = "2016-Datacenter"
+ version = "latest"
+ }
+
+ storage_os_disk {
+ name = "${var.prefix}-osdisk"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ managed_disk_type = "Standard_LRS"
+ }
+
+ os_profile {
+ computer_name = "${local.virtual_machine_name}"
+ admin_username = "${local.admin_username}"
+ admin_password = "${local.admin_password}"
+ custom_data = "${local.custom_data_content}"
+ }
+
+ os_profile_secrets {
+ source_vault_id = "${azurerm_key_vault.main.id}"
+
+ vault_certificates {
+ certificate_url = "${azurerm_key_vault_certificate.main.secret_id}"
+ certificate_store = "My"
+ }
+ }
+
+ os_profile_windows_config {
+ provision_vm_agent = true
+ enable_automatic_upgrades = true
+
+ # Auto-Login's required to configure WinRM
+ additional_unattend_config {
+ pass = "oobeSystem"
+ component = "Microsoft-Windows-Shell-Setup"
+ setting_name = "AutoLogon"
+ content = "${local.admin_password}true1${local.admin_username}"
+ }
+
+ # Unattend config is to enable basic auth in WinRM, required for the provisioner stage.
+ additional_unattend_config {
+ pass = "oobeSystem"
+ component = "Microsoft-Windows-Shell-Setup"
+ setting_name = "FirstLogonCommands"
+ content = "${file("./files/FirstLogonCommands.xml")}"
+ }
+ }
+
+ provisioner "remote-exec" {
+ connection {
+ user = "${local.admin_username}"
+ password = "${local.admin_password}"
+ port = 5986
+ https = true
+ timeout = "10m"
+
+ # NOTE: if you're using a real certificate, rather than a self-signed one, you'll want this set to `false`/to remove this.
+ insecure = true
+ }
+
+ inline = [
+ "cd C:\\Windows",
+ "dir",
+ ]
+ }
+
+ tags = "${var.tags}"
+}
diff --git a/examples/virtual-machines/provisioners/windows/README.md b/examples/virtual-machines/provisioners/windows/README.md
new file mode 100644
index 000000000000..3041a495a92d
--- /dev/null
+++ b/examples/virtual-machines/provisioners/windows/README.md
@@ -0,0 +1,14 @@
+## Example: Running commands via WinRM on a Windows Virtual Machine
+
+This example provisions a Virtual Machine running Windows Server 2016 with a Public IP Address and [runs a `remote-exec` provisioner](https://www.terraform.io/docs/provisioners/remote-exec.html) via WinRM.
+
+Notes:
+
+- The files involved in this example are split out to make it easier to read, however all of the resources could be combined into a single file if needed.
+- The certificate used for WinRM is generated by Azure KeyVault and then installed on the VM; as such the certificate in this example is self-signed, which may not be desirable in a real-world environment.
+
+### Variables
+
+* `prefix` - (Required) The Prefix used for all resources in this example.
+* `location` - (Required) The Azure Region in which the resources in this example should exist.
+* `tags` - (Optional) Any tags which should be assigned to the resources in this example.
diff --git a/examples/virtual-machines/provisioners/windows/files/FirstLogonCommands.xml b/examples/virtual-machines/provisioners/windows/files/FirstLogonCommands.xml
new file mode 100644
index 000000000000..fead3000350c
--- /dev/null
+++ b/examples/virtual-machines/provisioners/windows/files/FirstLogonCommands.xml
@@ -0,0 +1,17 @@
+
+
+ cmd /c "mkdir C:\terraform"
+ Create the Terraform working directory
+ 11
+
+
+ cmd /c "copy C:\AzureData\CustomData.bin C:\terraform\winrm.ps1"
+ Move the CustomData file to the working directory
+ 12
+
+
+ powershell.exe -sta -ExecutionPolicy Unrestricted -file C:\terraform\winrm.ps1
+ Execute the WinRM enabling script
+ 13
+
+
diff --git a/examples/virtual-machines/provisioners/windows/files/winrm.ps1 b/examples/virtual-machines/provisioners/windows/files/winrm.ps1
new file mode 100644
index 000000000000..f1e189cdbf99
--- /dev/null
+++ b/examples/virtual-machines/provisioners/windows/files/winrm.ps1
@@ -0,0 +1,11 @@
+Write-Host "Obtaining the Thumbprint of the Certificate from KeyVault"
+$Thumbprint = (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "$ComputerName"}).Thumbprint
+
+Write-Host "Enable HTTPS in WinRM.."
+winrm create winrm/config/Listener?Address=*+Transport=HTTPS "@{Hostname=`"$ComputerName`"; CertificateThumbprint=`"$Thumbprint`"}"
+
+Write-Host "Enabling Basic Authentication.."
+winrm set winrm/config/service/Auth "@{Basic=`"true`"}"
+
+Write-Host "Open Firewall Ports"
+netsh advfirewall firewall add rule name="Windows Remote Management (HTTPS-In)" dir=in action=allow protocol=TCP localport=5986
diff --git a/examples/virtual-machines/provisioners/windows/variables.tf b/examples/virtual-machines/provisioners/windows/variables.tf
new file mode 100644
index 000000000000..1bd6bc2dbce3
--- /dev/null
+++ b/examples/virtual-machines/provisioners/windows/variables.tf
@@ -0,0 +1,13 @@
+variable "prefix" {
+ description = "The Prefix used for all resources in this example"
+}
+
+variable "location" {
+ description = "The Azure Region in which the resources in this example should exist"
+}
+
+variable "tags" {
+ type = "map"
+ default = {}
+ description = "Any tags which should be assigned to the resources in this example"
+}
diff --git a/examples/virtual-machines/unmanaged-disks/1-dependencies.tf b/examples/virtual-machines/unmanaged-disks/1-dependencies.tf
new file mode 100644
index 000000000000..28813415ea5e
--- /dev/null
+++ b/examples/virtual-machines/unmanaged-disks/1-dependencies.tf
@@ -0,0 +1,5 @@
+resource "azurerm_resource_group" "main" {
+ name = "${var.prefix}-resources"
+ location = "${var.location}"
+ tags = "${var.tags}"
+}
diff --git a/examples/virtual-machines/unmanaged-disks/2-network.tf b/examples/virtual-machines/unmanaged-disks/2-network.tf
new file mode 100644
index 000000000000..2876cf658987
--- /dev/null
+++ b/examples/virtual-machines/unmanaged-disks/2-network.tf
@@ -0,0 +1,27 @@
+resource "azurerm_virtual_network" "main" {
+ name = "${var.prefix}-network"
+ address_space = ["10.0.0.0/16"]
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_subnet" "internal" {
+ name = "internal"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ virtual_network_name = "${azurerm_virtual_network.main.name}"
+ address_prefix = "10.0.2.0/24"
+}
+
+resource "azurerm_network_interface" "main" {
+ name = "${var.prefix}-nic"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ tags = "${var.tags}"
+
+ ip_configuration {
+ name = "testconfiguration1"
+ subnet_id = "${azurerm_subnet.internal.id}"
+ private_ip_address_allocation = "dynamic"
+ }
+}
diff --git a/examples/virtual-machines/unmanaged-disks/3-storage-account.tf b/examples/virtual-machines/unmanaged-disks/3-storage-account.tf
new file mode 100644
index 000000000000..d87baef1ba1c
--- /dev/null
+++ b/examples/virtual-machines/unmanaged-disks/3-storage-account.tf
@@ -0,0 +1,15 @@
+resource "azurerm_storage_account" "main" {
+ name = "${var.prefix}stor"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ location = "${azurerm_resource_group.main.location}"
+ account_tier = "Standard"
+ account_replication_type = "LRS"
+ tags = "${var.tags}"
+}
+
+resource "azurerm_storage_container" "disks" {
+ name = "vhds"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ storage_account_name = "${azurerm_storage_account.main.name}"
+ container_access_type = "private"
+}
diff --git a/examples/virtual-machines/unmanaged-disks/3-virtual-machine.tf b/examples/virtual-machines/unmanaged-disks/3-virtual-machine.tf
new file mode 100644
index 000000000000..3ca475aaff53
--- /dev/null
+++ b/examples/virtual-machines/unmanaged-disks/3-virtual-machine.tf
@@ -0,0 +1,53 @@
+locals {
+ storage_account_base_uri = "${azurerm_storage_account.main.primary_blob_endpoint}${azurerm_storage_container.disks.name}"
+}
+
+resource "azurerm_virtual_machine" "example" {
+ name = "${var.prefix}-vm"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ network_interface_ids = ["${azurerm_network_interface.main.id}"]
+ vm_size = "Standard_F2"
+ tags = "${var.tags}"
+
+ # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_os_disk_on_termination = true
+
+ # This means the Data Disk Disk will be deleted when Terraform destroys the Virtual Machine
+ # NOTE: This may not be optimal in all cases.
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ publisher = "Canonical"
+ offer = "UbuntuServer"
+ sku = "16.04-LTS"
+ version = "latest"
+ }
+
+ storage_os_disk {
+ name = "osdisk"
+ vhd_uri = "${local.storage_account_base_uri}/osdisk.vhd"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ }
+
+ # Optional data disks
+ storage_data_disk {
+ name = "datadisk1"
+ vhd_uri = "${local.storage_account_base_uri}/datadisk1.vhd"
+ disk_size_gb = "1023"
+ create_option = "Empty"
+ lun = 0
+ }
+
+ os_profile {
+ computer_name = "hostname"
+ admin_username = "testadmin"
+ admin_password = "Password1234!"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+}
diff --git a/examples/virtual-machines/unmanaged-disks/README.md b/examples/virtual-machines/unmanaged-disks/README.md
new file mode 100644
index 000000000000..755b23f64925
--- /dev/null
+++ b/examples/virtual-machines/unmanaged-disks/README.md
@@ -0,0 +1,13 @@
+## Example: Virtual Machine with Unmanaged Disks
+
+This example provisions a Virtual Machine with Unmanaged Disks, with one OS Disk and one Data Disk.
+
+Notes:
+
+- The files involved in this example are split out to make it easier to read, however all of the resources could be combined into a single file if needed.
+
+### Variables
+
+* `prefix` - (Required) The Prefix used for all resources in this example.
+* `location` - (Required) The Azure Region in which the resources in this example should exist.
+* `tags` - (Optional) Any tags which should be assigned to the resources in this example.
diff --git a/examples/virtual-machines/unmanaged-disks/variables.tf b/examples/virtual-machines/unmanaged-disks/variables.tf
new file mode 100644
index 000000000000..1bd6bc2dbce3
--- /dev/null
+++ b/examples/virtual-machines/unmanaged-disks/variables.tf
@@ -0,0 +1,13 @@
+variable "prefix" {
+ description = "The Prefix used for all resources in this example"
+}
+
+variable "location" {
+ description = "The Azure Region in which the resources in this example should exist"
+}
+
+variable "tags" {
+ type = "map"
+ default = {}
+ description = "Any tags which should be assigned to the resources in this example"
+}
diff --git a/website/docs/r/virtual_machine.html.markdown b/website/docs/r/virtual_machine.html.markdown
index 8614fc85adc7..838843edf1b3 100644
--- a/website/docs/r/virtual_machine.html.markdown
+++ b/website/docs/r/virtual_machine.html.markdown
@@ -3,63 +3,60 @@ layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_virtual_machine"
sidebar_current: "docs-azurerm-resource-compute-virtual-machine-x"
description: |-
- Create a Virtual Machine.
+ Manages a Virtual Machine.
---
# azurerm_virtual_machine
-Create a virtual machine.
+Manages a Virtual Machine.
~> **NOTE:** Data Disks can be attached either directly on the `azurerm_virtual_machine` resource, or using the `azurerm_virtual_machine_data_disk_attachment` resource - but the two cannot be used together. If both are used against the same Virtual Machine, spurious changes will occur.
-## Example Usage with Managed Disks and Azure Platform Images (Recommended)
+## Example Usage (from an Azure Platform Image)
+
+This example provisions a Virtual Machine with Managed Disks. Other examples of the `azurerm_virtual_machine` resource can be found in [the `./examples/virtual-machines` directory within the Github Repository](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/virtual-machines)
```hcl
-resource "azurerm_resource_group" "test" {
- name = "acctestRG"
+variable "prefix" {
+ default = "tfvmex"
+}
+
+resource "azurerm_resource_group" "main" {
+ name = "${var.prefix}-resources"
location = "West US 2"
}
-resource "azurerm_virtual_network" "test" {
- name = "acctvn"
+resource "azurerm_virtual_network" "main" {
+ name = "${var.prefix}-network"
address_space = ["10.0.0.0/16"]
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
}
-resource "azurerm_subnet" "test" {
- name = "acctsub"
- resource_group_name = "${azurerm_resource_group.test.name}"
- virtual_network_name = "${azurerm_virtual_network.test.name}"
+resource "azurerm_subnet" "internal" {
+ name = "internal"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ virtual_network_name = "${azurerm_virtual_network.main.name}"
address_prefix = "10.0.2.0/24"
}
-resource "azurerm_network_interface" "test" {
- name = "acctni"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
+resource "azurerm_network_interface" "main" {
+ name = "${var.prefix}-nic"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
ip_configuration {
name = "testconfiguration1"
- subnet_id = "${azurerm_subnet.test.id}"
+ subnet_id = "${azurerm_subnet.internal.id}"
private_ip_address_allocation = "dynamic"
}
}
-resource "azurerm_managed_disk" "test" {
- name = "datadisk_existing"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
- storage_account_type = "Standard_LRS"
- create_option = "Empty"
- disk_size_gb = "1023"
-}
-
-resource "azurerm_virtual_machine" "test" {
- name = "acctvm"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
- network_interface_ids = ["${azurerm_network_interface.test.id}"]
+resource "azurerm_virtual_machine" "main" {
+ name = "${var.prefix}-vm"
+ location = "${azurerm_resource_group.main.location}"
+ resource_group_name = "${azurerm_resource_group.main.name}"
+ network_interface_ids = ["${azurerm_network_interface.main.id}"]
vm_size = "Standard_DS1_v2"
# Uncomment this line to delete the OS disk automatically when deleting the VM
@@ -82,23 +79,6 @@ resource "azurerm_virtual_machine" "test" {
managed_disk_type = "Standard_LRS"
}
- # Optional data disks
- storage_data_disk {
- name = "datadisk_new"
- managed_disk_type = "Standard_LRS"
- create_option = "Empty"
- lun = 0
- disk_size_gb = "1023"
- }
-
- storage_data_disk {
- name = "${azurerm_managed_disk.test.name}"
- managed_disk_id = "${azurerm_managed_disk.test.id}"
- create_option = "Attach"
- lun = 1
- disk_size_gb = "${azurerm_managed_disk.test.disk_size_gb}"
- }
-
os_profile {
computer_name = "hostname"
admin_username = "testadmin"
@@ -115,409 +95,254 @@ resource "azurerm_virtual_machine" "test" {
}
```
-## Example Usage with Managed Disks and Custom Images (Recommended)
+## Argument Reference
-```hcl
-#Assume that custom image has been already created in the 'customimage' resource group
-data "azurerm_resource_group" "image" {
- name = "customimage"
-}
+The following arguments are supported:
-data "azurerm_image" "image" {
- name = "myCustomImage"
- resource_group_name = "${data.azurerm_resource_group.image.name}"
-}
+* `name` - (Required) Specifies the name of the Virtual Machine. Changing this forces a new resource to be created.
-resource "azurerm_resource_group" "test" {
- name = "acctestRG"
- location = "West US 2"
-}
+* `resource_group_name` - (Required) Specifies the name of the Resource Group in which the Virtual Machine should exist. Changing this forces a new resource to be created.
-resource "azurerm_virtual_network" "test" {
- name = "acctvn"
- address_space = ["10.0.0.0/16"]
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
-}
+* `location` - (Required) Specifies the Azure Region where the Virtual Machine exists. Changing this forces a new resource to be created.
-resource "azurerm_subnet" "test" {
- name = "acctsub"
- resource_group_name = "${azurerm_resource_group.test.name}"
- virtual_network_name = "${azurerm_virtual_network.test.name}"
- address_prefix = "10.0.2.0/24"
-}
+* `network_interface_ids` - (Required) A list of Network Interface ID's which should be associated with the Virtual Machine.
-resource "azurerm_network_interface" "test" {
- name = "acctni"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
+* `os_profile_linux_config` - (Required, when a Linux machine) A `os_profile_linux_config` block.
- ip_configuration {
- name = "testconfiguration1"
- subnet_id = "${azurerm_subnet.test.id}"
- private_ip_address_allocation = "dynamic"
- }
-}
+* `os_profile_windows_config` - (Required, when a Windows machine) A `os_profile_windows_config` block.
-resource "azurerm_managed_disk" "test" {
- name = "datadisk_existing"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
- storage_account_type = "Standard_LRS"
- create_option = "Empty"
- disk_size_gb = "1023"
-}
+* `vm_size` - (Required) Specifies the [size of the Virtual Machine](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-size-specs/).
-resource "azurerm_virtual_machine" "test" {
- name = "acctvm"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
- network_interface_ids = ["${azurerm_network_interface.test.id}"]
- vm_size = "Standard_DS1_v2"
+---
- # Uncomment this line to delete the OS disk automatically when deleting the VM
- # delete_os_disk_on_termination = true
+* `availability_set_id` - (Optional) The ID of the Availability Set in which the Virtual Machine should exist. Changing this forces a new resource to be created.
- # Uncomment this line to delete the data disks automatically when deleting the VM
- # delete_data_disks_on_termination = true
+* `boot_diagnostics` - (Optional) A `boot_diagnostics` block.
- storage_image_reference {
- id="${data.azurerm_image.image.id}"
- }
+* `delete_os_disk_on_termination` - (Optional) Should the OS Disk (either the Managed Disk / VHD Blob) be deleted when the Virtual Machine is destroyed? Defaults to `false`.
- storage_os_disk {
- name = "myosdisk1"
- caching = "ReadWrite"
- create_option = "FromImage"
- managed_disk_type = "Standard_LRS"
- }
+* `delete_data_disks_on_termination` - (Optional) Should the Data Disks (either the Managed Disks / VHD Blobs) be deleted when the Virtual Machine is destroyed? Defaults to `false`.
- # Optional data disks
- storage_data_disk {
- name = "datadisk_new"
- managed_disk_type = "Standard_LRS"
- create_option = "Empty"
- lun = 0
- disk_size_gb = "1023"
- }
+* `identity` - (Optional) A `identity` block.
- storage_data_disk {
- name = "${azurerm_managed_disk.test.name}"
- managed_disk_id = "${azurerm_managed_disk.test.id}"
- create_option = "Attach"
- lun = 1
- disk_size_gb = "${azurerm_managed_disk.test.disk_size_gb}"
- }
+* `license_type` - (Optional) Specifies the BYOL Type for this Virtual Machine. This is only applicable to Windows Virtual Machines. Possible values are `Windows_Client` and `Windows_Server`.
- os_profile {
- computer_name = "hostname"
- admin_username = "testadmin"
- admin_password = "Password1234!"
- }
+* `os_profile` - (Optional) An `os_profile` block. Required when `create_option` in the `storage_os_disk` block is set to `FromImage`.
- os_profile_linux_config {
- disable_password_authentication = false
- }
+* `os_profile_secrets` - (Optional) One or more `os_profile_secrets` blocks.
- tags {
- environment = "staging"
- }
-}
-```
+* `plan` - (Optional) A `plan` block.
-## Example Usage with Unmanaged Disks
+* `primary_network_interface_id` - (Optional) The ID of the Network Interface (which must be attached to the Virtual Machine) which should be the Primary Network Interface for this Virtual Machine.
-```hcl
-resource "azurerm_resource_group" "test" {
- name = "acctestRG"
- location = "West US"
-}
+* `storage_data_disk` - (Optional) One or more `storage_data_disk` blocks.
-resource "azurerm_virtual_network" "test" {
- name = "acctvn"
- address_space = ["10.0.0.0/16"]
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
-}
+~> **Please Note:** Data Disks can also be attached either using this block or [the `azurerm_virtual_machine_data_disk_attachment` resource](virtual_machine_data_disk_attachment.html) - but not both.
-resource "azurerm_subnet" "test" {
- name = "acctsub"
- resource_group_name = "${azurerm_resource_group.test.name}"
- virtual_network_name = "${azurerm_virtual_network.test.name}"
- address_prefix = "10.0.2.0/24"
-}
+* `storage_image_reference` - (Optional) A `storage_image_reference` block.
-resource "azurerm_network_interface" "test" {
- name = "acctni"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
+* `storage_os_disk` - (Required) A `storage_os_disk` block.
- ip_configuration {
- name = "testconfiguration1"
- subnet_id = "${azurerm_subnet.test.id}"
- private_ip_address_allocation = "dynamic"
- }
-}
+* `tags` - (Optional) A mapping of tags to assign to the Virtual Machine.
-resource "azurerm_storage_account" "test" {
- name = "accsa"
- resource_group_name = "${azurerm_resource_group.test.name}"
- location = "${azurerm_resource_group.test.location}"
- account_tier = "Standard"
- account_replication_type = "LRS"
+* `zones` - (Optional) A list of a single item of the Availability Zone which the Virtual Machine should be allocated in.
- tags {
- environment = "staging"
- }
-}
+-> **Please Note**: Availability Zones are [in Preview and only supported in several regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview) - as such you must be opted into the Preview to use this functionality. You can [opt into the Availability Zones Preview in the Azure Portal](http://aka.ms/azenroll).
-resource "azurerm_storage_container" "test" {
- name = "vhds"
- resource_group_name = "${azurerm_resource_group.test.name}"
- storage_account_name = "${azurerm_storage_account.test.name}"
- container_access_type = "private"
-}
+For more information on the different example configurations, please check out the [Azure documentation](https://docs.microsoft.com/en-gb/rest/api/compute/virtualmachines/createorupdate#examples)
-resource "azurerm_virtual_machine" "test" {
- name = "acctvm"
- location = "${azurerm_resource_group.test.location}"
- resource_group_name = "${azurerm_resource_group.test.name}"
- network_interface_ids = ["${azurerm_network_interface.test.id}"]
- vm_size = "Standard_F2"
+---
- # Uncomment this line to delete the OS disk automatically when deleting the VM
- # delete_os_disk_on_termination = true
+A `additional_unattend_config` block supports the following:
- # Uncomment this line to delete the data disks automatically when deleting the VM
- # delete_data_disks_on_termination = true
+* `pass` - (Required) Specifies the name of the pass that the content applies to. The only allowable value is `oobeSystem`.
- storage_image_reference {
- publisher = "Canonical"
- offer = "UbuntuServer"
- sku = "16.04-LTS"
- version = "latest"
- }
+* `component` - (Required) Specifies the name of the component to configure with the added content. The only allowable value is `Microsoft-Windows-Shell-Setup`.
- storage_os_disk {
- name = "myosdisk1"
- vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/myosdisk1.vhd"
- caching = "ReadWrite"
- create_option = "FromImage"
- }
+* `setting_name` - (Required) Specifies the name of the setting to which the content applies. Possible values are: `FirstLogonCommands` and `AutoLogon`.
- # Optional data disks
- storage_data_disk {
- name = "datadisk0"
- vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/datadisk0.vhd"
- disk_size_gb = "1023"
- create_option = "Empty"
- lun = 0
- }
+* `content` - (Optional) Specifies the base-64 encoded XML formatted content that is added to the unattend.xml file for the specified path and component.
- os_profile {
- computer_name = "hostname"
- admin_username = "testadmin"
- admin_password = "Password1234!"
- }
+---
- os_profile_linux_config {
- disable_password_authentication = false
- }
+A `boot_diagnostics` block supports the following:
- tags {
- environment = "staging"
- }
-}
-```
+* `enabled` - (Required) Should Boot Diagnostics be enabled for this Virtual Machine?
-## Argument Reference
+* `storage_uri` - (Required) The Storage Account's Blob Endpoint which should hold the virtual machine's diagnostic files.
-The following arguments are supported:
+~> **NOTE:** This needs to be the root of a Storage Account and not a Storage Container.
-* `name` - (Required) Specifies the name of the virtual machine resource. Changing this forces a
- new resource to be created.
-* `resource_group_name` - (Required) The name of the resource group in which to
- create the virtual machine.
-* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created.
-* `plan` - (Optional) A plan block as documented below.
-* `availability_set_id` - (Optional) The Id of the Availability Set in which to create the virtual machine
-* `boot_diagnostics` - (Optional) A boot diagnostics profile block as referenced below.
-* `vm_size` - (Required) Specifies the [size of the virtual machine](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-size-specs/).
-* `storage_image_reference` - (Optional) A Storage Image Reference block as documented below.
-* `storage_os_disk` - (Required) A Storage OS Disk block as referenced below.
-* `delete_os_disk_on_termination` - (Optional) Flag to enable deletion of the OS disk VHD blob or managed disk when the VM is deleted, defaults to `false`
-* `storage_data_disk` - (Optional) A list of Storage Data disk blocks as referenced below.
+---
-~> **Please Note:** Data Disks can also be attached either using this block or [the `azurerm_virtual_machine_data_disk_attachment` resource](virtual_machine_data_disk_attachment.html) - but not both.
+A `identity` block supports the following:
-* `delete_data_disks_on_termination` - (Optional) Flag to enable deletion of storage data disk VHD blobs or managed disks when the VM is deleted, defaults to `false`
-* `os_profile` - (Optional) An OS Profile block as documented below. Required when `create_option` in the `storage_os_disk` block is set to `FromImage`.
-* `identity` - (Optional) An identity block as documented below.
+* `type` - (Required) The Managed Service Identity Type of this Virtual Machine. Possible values are `SystemAssigned` (where Azure will generate a Service Principal for you) and `UserAssigned` (where you can specify the Service Principal ID's) to be used by this Virtual Machine using the `identity_ids` field.
-* `license_type` - (Optional, when a Windows machine) Specifies the Windows OS license type. If supplied, the only allowed values are `Windows_Client` and `Windows_Server`.
-* `os_profile_windows_config` - (Required, when a Windows machine) A Windows config block as documented below.
-* `os_profile_linux_config` - (Required, when a Linux machine) A Linux config block as documented below.
-* `os_profile_secrets` - (Optional) A collection of Secret blocks as documented below.
-* `network_interface_ids` - (Required) Specifies the list of resource IDs for the network interfaces associated with the virtual machine.
-* `primary_network_interface_id` - (Optional) Specifies the resource ID for the primary network interface associated with the virtual machine.
-* `tags` - (Optional) A mapping of tags to assign to the resource.
-* `zones` - (Optional) A collection containing the availability zone to allocate the Virtual Machine in.
+-> **NOTE:** Managed Service Identity previously required the installation of a VM Extension, but this information [is now available via the Azure Instance Metadata Service](https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview#how-does-it-work).
--> **Please Note**: Availability Zones are [in Preview and only supported in several regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview) - as such you must be opted into the Preview to use this functionality. You can [opt into the Availability Zones Preview in the Azure Portal](http://aka.ms/azenroll).
+~> **NOTE:** When `type` is set to `SystemAssigned`, identity the Principal ID can be retrieved after the virtual machine has been created. See [documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview) for more information.
+
+* `identity_ids` - (Optional) Specifies a list of user managed identity ids to be assigned to the VM. Required if `type` is `UserAssigned`.
+
+---
+
+A `os_profile` block supports the following:
+
+* `computer_name` - (Required) Specifies the name of the Virtual Machine.
+
+* `admin_username` - (Required) Specifies the name of the local administrator account.
-For more information on the different example configurations, please check out the [azure documentation](https://msdn.microsoft.com/en-us/library/mt163591.aspx#Anchor_2)
+* `admin_password` - (Required for Windows, Optional for Linux) The password associated with the local administrator account.
-`Plan` supports the following:
+-> **NOTE:** If using Linux, it may be preferable to use SSH Key authentication (available in the `os_profile_linux_config` block) instead of password authentication.
+
+~> **NOTE:** `admin_password` must be between 6-72 characters long and must satisfy at least 3 of password complexity requirements from the following:
+1. Contains an uppercase character
+2. Contains a lowercase character
+3. Contains a numeric digit
+4. Contains a special character
+
+* `custom_data` - (Optional) Specifies custom data to supply to the machine. On Linux-based systems, this can be used as a cloud-init script. On other systems, this will be copied as a file on disk. Internally, Terraform will base64 encode this value before sending it to the API. The maximum length of the binary array is 65535 bytes.
+
+---
+
+A `os_profile_linux_config` block supports the following:
+
+* `disable_password_authentication` - (Required) Specifies whether password authentication should be disabled. If set to `false`, an `admin_password` must be specified.
+
+* `ssh_keys` - (Optional) One or more `ssh_keys` blocks. This field is required if `disable_password_authentication` is set to `true`.
+
+---
+
+A `os_profile_secrets` block supports the following:
+
+* `source_vault_id` - (Required) Specifies the ID of the Key Vault to use.
+
+* `vault_certificates` - (Required) One or more `vault_certificates` blocks.
+
+---
+
+A `os_profile_windows_config` block supports the following:
+
+* `provision_vm_agent` - (Optional) Should the Azure Virtual Machine Guest Agent be installed on this Virtual Machine? Defaults to `false`.
+
+-> **NOTE:** This is different from the Default value used for this field within Azure.
+
+* `enable_automatic_upgrades` - (Optional) Are automatic updates enabled on this Virtual Machine? Defaults to `false.`
+
+* `timezone` - (Optional) Specifies the time zone of the virtual machine, [the possible values are defined here](http://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/).
+
+* `winrm` - (Optional) One or more `winrm` block.
+
+* `additional_unattend_config` - (Optional) A `additional_unattend_config` block.
+
+---
+
+A `plan` block supports the following:
* `name` - (Required) Specifies the name of the image from the marketplace.
+
* `publisher` - (Required) Specifies the publisher of the image.
+
* `product` - (Required) Specifies the product of the image from the marketplace.
-`boot_diagnostics` supports the following:
+---
-* `enabled`: (Required) Whether to enable boot diagnostics for the virtual machine.
-* `storage_uri`: (Required) Blob endpoint for the storage account to hold the virtual machine's diagnostic files. This must be the root of a storage account, and not a storage container.
+A `ssh_keys` block supports the following:
-`storage_image_reference` supports the following:
+* `key_data` - (Required) The Public SSH Key which should be written to the `path` defined above.
-* `id` - (Optional) Specifies the ID of the (custom) image to use to create the virtual
-machine, for example:
+-> **NOTE:** Rather than defining this in-line you can source this from a local file using [the `file` interpolation function](https://www.terraform.io/docs/configuration/interpolation.html#file_path_) - for example `key_data = "${file("~/.ssh/id_rsa.pub")}"`.
-```hcl
+* `path` - (Required) The path of the destination file on the virtual machine
+
+-> **NOTE:** Due to a limitation in the Azure VM Agent the only allowed `path` is `/home/{username}/.ssh/authorized_keys`.
-resource "azurerm_image" "test" {
- name = "test"
- ...
-}
-resource "azurerm_virtual_machine" "test" {
- name = "test"
- ...
+---
- storage_image_reference {
- id = "${azurerm_image.test.id}"
- }
+A `storage_image_reference` block supports the following:
-...
-```
+This block provisions the Virtual Machine from one of two sources: an Azure Platform Image (e.g. Ubuntu/Windows Server) or a Custom Image.
+
+To provision from an Azure Platform Image, the following fields are applicable:
+
+* `publisher` - (Required) Specifies the publisher of the image used to create the virtual machine. Changing this forces a new resource to be created.
+
+* `offer` - (Required) Specifies the offer of the image used to create the virtual machine. Changing this forces a new resource to be created.
+
+* `sku` - (Required) Specifies the SKU of the image used to create the virtual machine. Changing this forces a new resource to be created.
-* `publisher` - (Required, when not using image resource) Specifies the publisher of the image used to create the virtual machine. Changing this forces a new resource to be created.
-* `offer` - (Required, when not using image resource) Specifies the offer of the image used to create the virtual machine. Changing this forces a new resource to be created.
-* `sku` - (Required, when not using image resource) Specifies the SKU of the image used to create the virtual machine. Changing this forces a new resource to be created.
* `version` - (Optional) Specifies the version of the image used to create the virtual machine. Changing this forces a new resource to be created.
-`storage_os_disk` supports the following:
-
-* `name` - (Required) Specifies the disk name.
-* `vhd_uri` - (Optional) Specifies the vhd uri. Changing this forces a new resource to be created. Cannot be used with managed disks.
-* `managed_disk_type` - (Optional) Specifies the type of managed disk to create. Value you must be either `Standard_LRS` or `Premium_LRS`. Cannot be used when `vhd_uri` is specified.
-* `managed_disk_id` - (Optional) Specifies an existing managed disk to use by id. Can only be used when `create_option` is `Attach`. Cannot be used when `vhd_uri` is specified.
-* `create_option` - (Required) Specifies how the virtual machine should be created. Possible values are `Attach` (managed disks only) and `FromImage`.
-* `caching` - (Optional) Specifies the caching requirements.
-* `image_uri` - (Optional) Specifies the image_uri in the form publisherName:offer:skus:version. `image_uri` can also specify the [VHD uri](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-cli-deploy-templates/#create-a-custom-vm-image) of a custom VM image to clone. When cloning a custom disk image the `os_type` documented below becomes required.
-* `os_type` - (Optional) Specifies the operating system Type, valid values are windows, linux.
-* `disk_size_gb` - (Optional) Specifies the size of the os disk in gigabytes.
-* `write_accelerator_enabled` - (Optional) Specifies if Write Accelerator is enabled on the disk. This can only be enabled on `Premium_LRS` managed disks with no caching and [M-Series VMs](https://docs.microsoft.com/en-us/azure/virtual-machines/workloads/sap/how-to-enable-write-accelerator). Defaults to `false`.
+To provision a Custom Image, the following fields are applicable:
+
+* `id` - (Required) Specifies the ID of the Custom Image which the Virtual Machine should be created from. Changing this forces a new resource to be created.
+
+-> **NOTE:** An example of how to use this is available within [the `./examples/virtual-machines/managed-disks/from-custom-image` directory within the Github Repository](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/virtual-machines/managed-disks/from-custom-image)
+
+---
-`storage_data_disk` supports the following:
+A `storage_data_disk` block supports the following:
+
+~> **NOTE:** Data Disks can also be attached either using this block or [the `azurerm_virtual_machine_data_disk_attachment` resource](virtual_machine_data_disk_attachment.html) - but not both.
+
+* `name` - (Required) The name of the Data Disk.
+
+* `caching` - (Optional) Specifies the caching requirements for the Data Disk. Possible values include `None`, `ReadOnly` and `ReadWrite`.
-* `name` - (Required) Specifies the name of the data disk.
-* `vhd_uri` - (Optional) Specifies the uri of the location in storage where the vhd for the virtual machine should be placed. Cannot be used with managed disks.
-* `managed_disk_type` - (Optional) Specifies the type of managed disk to create. Value you must be either `Standard_LRS` or `Premium_LRS`. Cannot be used when `vhd_uri` is specified.
-* `managed_disk_id` - (Optional) Specifies an existing managed disk to use by id. Can only be used when `create_option` is `Attach`. Cannot be used when `vhd_uri` is specified.
* `create_option` - (Required) Specifies how the data disk should be created. Possible values are `Attach`, `FromImage` and `Empty`.
+
* `disk_size_gb` - (Required) Specifies the size of the data disk in gigabytes.
-* `caching` - (Optional) Specifies the caching requirements.
-* `lun` - (Required) Specifies the logical unit number of the data disk.
+
+* `lun` - (Required) Specifies the logical unit number of the data disk. This needs to be unique within all the Data Disks on the Virtual Machine.
+
* `write_accelerator_enabled` - (Optional) Specifies if Write Accelerator is enabled on the disk. This can only be enabled on `Premium_LRS` managed disks with no caching and [M-Series VMs](https://docs.microsoft.com/en-us/azure/virtual-machines/workloads/sap/how-to-enable-write-accelerator). Defaults to `false`.
-`os_profile` supports the following:
+The following properties apply when using Managed Disks:
-* `computer_name` - (Required) Specifies the name of the virtual machine.
-* `admin_username` - (Required) Specifies the name of the administrator account.
-* `admin_password` - (Required for Windows, Optional for Linux) Specifies the password of the administrator account.
-* `custom_data` - (Optional) Specifies custom data to supply to the machine. On linux-based systems, this can be used as a cloud-init script. On other systems, this will be copied as a file on disk. Internally, Terraform will base64 encode this value before sending it to the API. The maximum length of the binary array is 65535 bytes.
+* `managed_disk_type` - (Optional) Specifies the type of managed disk to create. Possible values are either `Standard_LRS` or `Premium_LRS`.
-~> **NOTE:** `admin_password` must be between 6-72 characters long and must satisfy at least 3 of password complexity requirements from the following:
-1. Contains an uppercase character
-2. Contains a lowercase character
-3. Contains a numeric digit
-4. Contains a special character
+* `managed_disk_id` - (Optional) Specifies the ID of an Existing Managed Disk which should be attached to this Virtual Machine. When this field is set `create_option` must be set to `Attach`.
-`identity` supports the following:
+The following properties apply when using Unmanaged Disks:
-* `type` - (Required) Specifies the identity type of the virtual machine. Allowable values are `SystemAssigned` and `UserAssigned`. To enable Managed Service Identity the virtual machine extension "ManagedIdentityExtensionForWindows" or "ManagedIdentityExtensionForLinux" must also be added to the virtual machine. For the `SystemAssigned` identity the Principal ID can be retrieved after the virtual machine has been created. See [documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview) for more information.
+* `vhd_uri` - (Optional) Specifies the URI of the VHD file backing this Unmanaged Data Disk. Changing this forces a new resource to be created.
-* `identity_ids` - (Optional) Specifies a list of user managed identity ids to be assigned to the VM. Required if `type` is `UserAssigned`.
+---
-```hcl
-resource "azurerm_virtual_machine" "test" {
- name = "test"
+A `storage_os_disk` block supports the following:
- identity = {
- type = "SystemAssigned"
- }
-}
-resource "azurerm_virtual_machine_extension" "test" {
- name = "test"
- resource_group_name = "${azurerm_resource_group.test.name}"
- location = "${azurerm_resource_group.test.location}"
- virtual_machine_name = "${azurerm_virtual_machine.test.name}"
- publisher = "Microsoft.ManagedIdentity"
- type = "ManagedIdentityExtensionForWindows"
- type_handler_version = "1.0"
-
- settings = <` needs to be replaced with the actual username):
-```hcl
- ssh_keys {
- key_data = "${file("/home//.ssh/authorized_keys")}"
- path = "/home//.ssh/authorized_keys"
- }
-```
-~> **Note:** Please note that the only allowed `path` is `/home//.ssh/authorized_keys` due to a limitation of Azure.
+* `managed_disk_id` - (Optional) Specifies the ID of an existing Managed Disk which should be attached as the OS Disk of this Virtual Machine. If this is set then the `create_option` must be set to `Attach`.
+
+* `managed_disk_type` - (Optional) Specifies the type of Managed Disk which should be created. Possible values are `Standard_LRS` or `Premium_LRS`.
-`os_profile_secrets` supports the following:
+The following properties apply when using Unmanaged Disks:
-* `source_vault_id` - (Required) Specifies the key vault to use.
-* `vault_certificates` - (Required) A collection of Vault Certificates as documented below
+* `vhd_uri` - (Optional) Specifies the URI of the VHD file backing this Unmanaged OS Disk. Changing this forces a new resource to be created.
-`vault_certificates` support the following:
+---
+
+A `vault_certificates` block supports the following:
-* `certificate_url` - (Required) Specifies the URI of the key vault secrets in the format of `https:///secrets//`. Stored secret is the Base64 encoding of a JSON Object that which is encoded in UTF-8 of which the contents need to be
+* `certificate_url` - (Required) The ID of the Key Vault Secret. Stored secret is the Base64 encoding of a JSON Object that which is encoded in UTF-8 of which the contents need to be:
```json
{
@@ -527,13 +352,25 @@ output "principal_id" {
}
```
-* `certificate_store` - (Required, on windows machines) Specifies the certificate store on the Virtual Machine where the certificate should be added to.
+-> **NOTE:** If your certificate is stored in Azure Key Vault - this can be sourced from the `secret_id` property on the `azurerm_key_vault_certificate` resource.
+
+* `certificate_store` - (Required, on windows machines) Specifies the certificate store on the Virtual Machine where the certificate should be added to, such as `My`.
+
+---
+
+A `winrm` block supports the following:
+
+* `protocol` - (Required) Specifies the protocol of listener. Possible values are `HTTP` or `HTTPS`.
+
+* `certificate_url` - (Optional) The ID of the Key Vault Secret which contains the encrypted Certificate which should be installed on the Virtual Machine. This certificate must also be specified in the `vault_certificates` block within the `os_profile_secrets` block.
+
+-> **NOTE:** This can be sourced from the `secret_id` field on the `azurerm_key_vault_certificate` resource.
## Attributes Reference
The following attributes are exported:
-* `id` - The virtual machine ID.
+* `id` - The ID of the Virtual Machine.
## Import