[MS] provider/azurerm: Virtual Machine Scale Sets with managed disk support (#13717)

* added vmss with managed disk support

* Update vmss docs

* update vmss test

* added vmss managed disk import test

* update vmss tests

* remove unused test resources

* reverting breaking changes on storage_os_disk and storage_image_reference

* updated vmss tests and documentation

* updated vmss flatten osdisk

* updated vmss resource and import test

* update name in vmss osdisk

* update vmss test to include a blank name

* update vmss test to include a blank name
This commit is contained in:
Sertaç Özercan 2017-05-12 05:58:00 -07:00 committed by Paul Stack
parent 15a5a84cd1
commit e0cd380814
5 changed files with 715 additions and 352 deletions

View File

@ -31,6 +31,29 @@ func TestAccAzureRMVirtualMachineScaleSet_importBasic(t *testing.T) {
})
}
func TestAccAzureRMVirtualMachineScaleSet_importBasic_managedDisk(t *testing.T) {
resourceName := "azurerm_virtual_machine_scale_set.test"
ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMVirtualMachineScaleSet_basicLinux_managedDisk, ri, ri, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMVirtualMachineScaleSetDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccAzureRMVirtualMachineScaleSet_importLinux(t *testing.T) {
resourceName := "azurerm_virtual_machine_scale_set.test"

View File

@ -266,6 +266,14 @@ func resourceArmVirtualMachineScaleSet() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"load_balancer_inbound_nat_rules_ids": {
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
},
},
@ -297,9 +305,21 @@ func resourceArmVirtualMachineScaleSet() *schema.Resource {
Set: schema.HashString,
},
"managed_disk_type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"storage_profile_os_disk.vhd_containers"},
ValidateFunc: validation.StringInSlice([]string{
string(compute.PremiumLRS),
string(compute.StandardLRS),
}, true),
},
"caching": {
Type: schema.TypeString,
Required: true,
Optional: true,
Computed: true,
},
"os_type": {
@ -708,6 +728,14 @@ func flattenAzureRmVirtualMachineScaleSetNetworkProfile(profile *compute.Virtual
config["load_balancer_backend_address_pool_ids"] = schema.NewSet(schema.HashString, addressPools)
}
if properties.LoadBalancerInboundNatPools != nil {
inboundNatPools := make([]interface{}, 0, len(*properties.LoadBalancerInboundNatPools))
for _, rule := range *properties.LoadBalancerInboundNatPools {
inboundNatPools = append(inboundNatPools, *rule.ID)
}
config["load_balancer_inbound_nat_rules_ids"] = schema.NewSet(schema.HashString, inboundNatPools)
}
ipConfigs = append(ipConfigs, config)
}
@ -735,7 +763,11 @@ func flattenAzureRMVirtualMachineScaleSetOsProfile(profile *compute.VirtualMachi
func flattenAzureRmVirtualMachineScaleSetStorageProfileOSDisk(profile *compute.VirtualMachineScaleSetOSDisk) []interface{} {
result := make(map[string]interface{})
result["name"] = *profile.Name
if profile.Name != nil {
result["name"] = *profile.Name
}
if profile.Image != nil {
result["image"] = *profile.Image.URI
}
@ -748,6 +780,10 @@ func flattenAzureRmVirtualMachineScaleSetStorageProfileOSDisk(profile *compute.V
result["vhd_containers"] = schema.NewSet(schema.HashString, containers)
}
if profile.ManagedDisk != nil {
result["managed_disk_type"] = string(profile.ManagedDisk.StorageAccountType)
}
result["caching"] = profile.Caching
result["create_option"] = profile.CreateOption
result["os_type"] = profile.OsType
@ -838,8 +874,8 @@ func resourceArmVirtualMachineScaleSetStorageProfileOsDiskHash(v interface{}) in
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
if m["image"] != nil {
buf.WriteString(fmt.Sprintf("%s-", m["image"].(string)))
if m["vhd_containers"] != nil {
buf.WriteString(fmt.Sprintf("%s-", m["vhd_containers"].(*schema.Set).List()))
}
return hashcode.String(buf.String())
@ -961,6 +997,18 @@ func expandAzureRmVirtualMachineScaleSetNetworkProfile(d *schema.ResourceData) *
ipConfiguration.LoadBalancerBackendAddressPools = &resources
}
if v := ipconfig["load_balancer_inbound_nat_rules_ids"]; v != nil {
rules := v.(*schema.Set).List()
rulesResources := make([]compute.SubResource, 0, len(rules))
for _, m := range rules {
id := m.(string)
rulesResources = append(rulesResources, compute.SubResource{
ID: &id,
})
}
ipConfiguration.LoadBalancerInboundNatPools = &rulesResources
}
ipConfigurations = append(ipConfigurations, ipConfiguration)
}
@ -1037,9 +1085,11 @@ func expandAzureRMVirtualMachineScaleSetsStorageProfileOsDisk(d *schema.Resource
osDiskConfig := osDiskConfigs[0].(map[string]interface{})
name := osDiskConfig["name"].(string)
image := osDiskConfig["image"].(string)
vhd_containers := osDiskConfig["vhd_containers"].(*schema.Set).List()
caching := osDiskConfig["caching"].(string)
osType := osDiskConfig["os_type"].(string)
createOption := osDiskConfig["create_option"].(string)
managedDiskType := osDiskConfig["managed_disk_type"].(string)
osDisk := &compute.VirtualMachineScaleSetOSDisk{
Name: &name,
@ -1052,18 +1102,40 @@ func expandAzureRMVirtualMachineScaleSetsStorageProfileOsDisk(d *schema.Resource
osDisk.Image = &compute.VirtualHardDisk{
URI: &image,
}
} else {
}
if len(vhd_containers) > 0 {
var vhdContainers []string
containers := osDiskConfig["vhd_containers"].(*schema.Set).List()
for _, v := range containers {
for _, v := range vhd_containers {
str := v.(string)
vhdContainers = append(vhdContainers, str)
}
osDisk.VhdContainers = &vhdContainers
}
return osDisk, nil
managedDisk := &compute.VirtualMachineScaleSetManagedDiskParameters{}
if managedDiskType != "" {
if name == "" {
osDisk.Name = nil
managedDisk.StorageAccountType = compute.StorageAccountTypes(managedDiskType)
osDisk.ManagedDisk = managedDisk
} else {
return nil, fmt.Errorf("[ERROR] Conflict between `name` and `managed_disk_type` (please set name to blank)")
}
}
//BEGIN: code to be removed after GH-13016 is merged
if image != "" && managedDiskType != "" {
return nil, fmt.Errorf("[ERROR] Conflict between `image` and `managed_disk_type` (only one or the other can be used)")
}
if len(vhd_containers) > 0 && managedDiskType != "" {
return nil, fmt.Errorf("[ERROR] Conflict between `vhd_containers` and `managed_disk_type` (only one or the other can be used)")
}
//END: code to be removed after GH-13016 is merged
return osDisk, nil
}
func expandAzureRmVirtualMachineScaleSetStorageProfileImageReference(d *schema.ResourceData) (*compute.ImageReference, error) {
@ -1137,22 +1209,22 @@ func expandAzureRmVirtualMachineScaleSetOsProfileWindowsConfig(d *schema.Resourc
if v := osProfileConfig["winrm"]; v != nil {
winRm := v.(*schema.Set).List()
if len(winRm) > 0 {
winRmListners := make([]compute.WinRMListener, 0, len(winRm))
winRmListeners := make([]compute.WinRMListener, 0, len(winRm))
for _, winRmConfig := range winRm {
config := winRmConfig.(map[string]interface{})
protocol := config["protocol"].(string)
winRmListner := compute.WinRMListener{
winRmListener := compute.WinRMListener{
Protocol: compute.ProtocolTypes(protocol),
}
if v := config["certificate_url"].(string); v != "" {
winRmListner.CertificateURL = &v
winRmListener.CertificateURL = &v
}
winRmListners = append(winRmListners, winRmListner)
winRmListeners = append(winRmListeners, winRmListener)
}
config.WinRM = &compute.WinRMConfiguration{
Listeners: &winRmListners,
Listeners: &winRmListeners,
}
}
}

View File

@ -6,12 +6,13 @@ import (
"strings"
"testing"
"regexp"
"github.com/Azure/azure-sdk-for-go/arm/compute"
"github.com/Azure/azure-sdk-for-go/arm/disk"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"regexp"
)
func TestAccAzureRMVirtualMachine_basicLinuxMachine(t *testing.T) {

View File

@ -106,6 +106,128 @@ resource "azurerm_virtual_machine_scale_set" "test" {
}
```
## Example Usage with Managed Disks
```
resource "azurerm_resource_group" "test" {
name = "acctestrg"
location = "West US 2"
}
resource "azurerm_virtual_network" "test" {
name = "acctvn"
address_space = ["10.0.0.0/16"]
location = "West US 2"
resource_group_name = "${azurerm_resource_group.test.name}"
}
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"
}
resource "azurerm_public_ip" "test" {
name = "test"
location = "West US 2"
resource_group_name = "${azurerm_resource_group.test.name}"
public_ip_address_allocation = "static"
domain_name_label = "${azurerm_resource_group.test.name}"
tags {
environment = "staging"
}
}
resource "azurerm_lb" "test" {
name = "test"
location = "West US 2"
resource_group_name = "${azurerm_resource_group.test.name}"
frontend_ip_configuration {
name = "PublicIPAddress"
public_ip_address_id = "${azurerm_public_ip.test.id}"
}
}
resource "azurerm_lb_backend_address_pool" "bpepool" {
resource_group_name = "${azurerm_resource_group.test.name}"
loadbalancer_id = "${azurerm_lb.test.id}"
name = "BackEndAddressPool"
}
resource "azurerm_lb_nat_pool" "lbnatpool" {
count = 3
resource_group_name = "${azurerm_resource_group.test.name}"
name = "ssh"
loadbalancer_id = "${azurerm_lb.test.id}"
protocol = "Tcp"
frontend_port_start = 50000
frontend_port_end = 50119
backend_port = 22
frontend_ip_configuration_name = "PublicIPAddress"
}
resource "azurerm_virtual_machine_scale_set" "test" {
name = "mytestscaleset-1"
location = "West US 2"
resource_group_name = "${azurerm_resource_group.test.name}"
upgrade_policy_mode = "Manual"
sku {
name = "Standard_A0"
tier = "Standard"
capacity = 2
}
storage_profile_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "14.04.2-LTS"
version = "latest"
}
storage_profile_os_disk {
name = "myosdisk"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name_prefix = "testvm"
admin_username = "myadmin"
admin_password = "Passwword1234"
}
os_profile_linux_config {
disable_password_authentication = true
ssh_keys {
path = "/home/myadmin/.ssh/authorized_keys"
key_data = "${file("~/.ssh/demo_key.pub")}"
}
}
network_profile {
name = "terraformnetworkprofile"
primary = true
ip_configuration {
name = "TestIPConfiguration"
subnet_id = "${azurerm_subnet.test.id}"
load_balancer_backend_address_pool_ids = ["${azurerm_lb_backend_address_pool.bpepool.id}"]
load_balancer_inbound_nat_rules_ids = ["${element(azurerm_lb_nat_pool.lbnatpool.*.id, count.index)}"]
}
}
tags {
environment = "staging"
}
}
```
## Argument Reference
The following arguments are supported:
@ -191,16 +313,18 @@ The following arguments are supported:
* `name` - (Required) Specifies name of the IP configuration.
* `subnet_id` - (Required) Specifies the identifier of the subnet.
* `load_balancer_backend_address_pool_ids` - (Optional) Specifies an array of references to backend address pools of load balancers. A scale set can reference backend address pools of one public and one internal load balancer. Multiple scale sets cannot use the same load balancer.
* `load_balancer_inbound_nat_rules_ids` - (Optional) Specifies an array of references to inbound NAT rules for load balancers.
`storage_profile_os_disk` supports the following:
* `name` - (Required) Specifies the disk name.
* `vhd_containers` - (Optional) Specifies the vhd uri. This property is ignored if using a custom image.
* `vhd_containers` - (Optional) Specifies the vhd uri. Cannot be used when `image` or `managed_disk_type` is specified.
* `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_containers` or `image` is specified.
* `create_option` - (Required) Specifies how the virtual machine should be created. The only possible option is `FromImage`.
* `caching` - (Required) Specifies the caching requirements.
* `caching` - (Optional) Specifies the caching requirements. Possible values include: `None` (default), `ReadOnly`, `ReadWrite`.
* `image` - (Optional) Specifies the blob uri for user image. A virtual machine scale set creates an os disk in the same container as the user image.
Updating the osDisk image causes the existing disk to be deleted and a new one created with the new image. If the VM scale set is in Manual upgrade mode then the virtual machines are not updated until they have manualUpgrade applied to them.
If this property is set then vhd_containers is ignored.
When setting this field `os_type` needs to be specified. Cannot be used when `vhd_containers`, `managed_disk_type` or `storage_profile_image_reference ` are specified.
* `os_type` - (Optional) Specifies the operating system Type, valid values are windows, linux.
`storage_profile_image_reference` supports the following: