[MS] Adding support for VMSS Data Disks using Managed Disk feature (#14608)

* Added support for data disks with managed disks feature

* Updated docs with VMSS Data Disks changes
This commit is contained in:
Eugene Chuvyrov 2017-05-18 04:30:19 -07:00 committed by Paul Stack
parent 399af7710d
commit 5884d518e7
3 changed files with 266 additions and 0 deletions

View File

@ -343,6 +343,47 @@ func resourceArmVirtualMachineScaleSet() *schema.Resource {
Set: resourceArmVirtualMachineScaleSetStorageProfileOsDiskHash,
},
"storage_profile_data_disk": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"lun": {
Type: schema.TypeInt,
Required: true,
},
"create_option": {
Type: schema.TypeString,
Required: true,
},
"caching": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"disk_size_gb": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: validateDiskSizeGB,
},
"managed_disk_type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice([]string{
string(compute.PremiumLRS),
string(compute.StandardLRS),
}, true),
},
},
},
},
"storage_profile_image_reference": {
Type: schema.TypeSet,
Optional: true,
@ -450,6 +491,15 @@ func resourceArmVirtualMachineScaleSetCreate(d *schema.ResourceData, meta interf
return err
}
storageProfile.OsDisk = osDisk
if _, ok := d.GetOk("storage_profile_data_disk"); ok {
dataDisks, err := expandAzureRMVirtualMachineScaleSetsStorageProfileDataDisk(d)
if err != nil {
return err
}
storageProfile.DataDisks = &dataDisks
}
if _, ok := d.GetOk("storage_profile_image_reference"); ok {
imageRef, err := expandAzureRmVirtualMachineScaleSetStorageProfileImageReference(d)
if err != nil {
@ -586,6 +636,12 @@ func resourceArmVirtualMachineScaleSetRead(d *schema.ResourceData, meta interfac
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Storage Profile OS Disk error: %#v", err)
}
if resp.VirtualMachineProfile.StorageProfile.DataDisks != nil {
if err := d.Set("storage_profile_data_disk", flattenAzureRmVirtualMachineScaleSetStorageProfileDataDisk(properties.VirtualMachineProfile.StorageProfile.DataDisks)); err != nil {
return fmt.Errorf("[DEBUG] Error setting Virtual Machine Scale Set Storage Profile Data Disk error: %#v", err)
}
}
if properties.VirtualMachineProfile.ExtensionProfile != nil {
extension, err := flattenAzureRmVirtualMachineScaleSetExtensionProfile(properties.VirtualMachineProfile.ExtensionProfile)
if err != nil {
@ -802,6 +858,26 @@ func flattenAzureRmVirtualMachineScaleSetStorageProfileOSDisk(profile *compute.V
return []interface{}{result}
}
func flattenAzureRmVirtualMachineScaleSetStorageProfileDataDisk(disks *[]compute.VirtualMachineScaleSetDataDisk) interface{} {
result := make([]interface{}, len(*disks))
for i, disk := range *disks {
l := make(map[string]interface{})
if disk.ManagedDisk != nil {
l["managed_disk_type"] = string(disk.ManagedDisk.StorageAccountType)
}
l["create_option"] = disk.CreateOption
l["caching"] = string(disk.Caching)
if disk.DiskSizeGB != nil {
l["disk_size_gb"] = *disk.DiskSizeGB
}
l["lun"] = *disk.Lun
result[i] = l
}
return result
}
func flattenAzureRmVirtualMachineScaleSetStorageProfileImageReference(profile *compute.ImageReference) []interface{} {
result := make(map[string]interface{})
result["publisher"] = *profile.Publisher
@ -1149,6 +1225,46 @@ func expandAzureRMVirtualMachineScaleSetsStorageProfileOsDisk(d *schema.Resource
return osDisk, nil
}
func expandAzureRMVirtualMachineScaleSetsStorageProfileDataDisk(d *schema.ResourceData) ([]compute.VirtualMachineScaleSetDataDisk, error) {
disks := d.Get("storage_profile_data_disk").([]interface{})
dataDisks := make([]compute.VirtualMachineScaleSetDataDisk, 0, len(disks))
for _, diskConfig := range disks {
config := diskConfig.(map[string]interface{})
createOption := config["create_option"].(string)
managedDiskType := config["managed_disk_type"].(string)
lun := int32(config["lun"].(int))
dataDisk := compute.VirtualMachineScaleSetDataDisk{
Lun: &lun,
CreateOption: compute.DiskCreateOptionTypes(createOption),
}
managedDiskVMSS := &compute.VirtualMachineScaleSetManagedDiskParameters{}
if managedDiskType != "" {
managedDiskVMSS.StorageAccountType = compute.StorageAccountTypes(managedDiskType)
} else {
managedDiskVMSS.StorageAccountType = compute.StorageAccountTypes(compute.StandardLRS)
}
//assume that data disks in VMSS can only be Managed Disks
dataDisk.ManagedDisk = managedDiskVMSS
if v := config["caching"].(string); v != "" {
dataDisk.Caching = compute.CachingTypes(v)
}
if v := config["disk_size_gb"]; v != nil {
diskSize := int32(config["disk_size_gb"].(int))
dataDisk.DiskSizeGB = &diskSize
}
dataDisks = append(dataDisks, dataDisk)
}
return dataDisks, nil
}
func expandAzureRmVirtualMachineScaleSetStorageProfileImageReference(d *schema.ResourceData) (*compute.ImageReference, error) {
storageImageRefs := d.Get("storage_profile_image_reference").(*schema.Set).List()

View File

@ -136,6 +136,25 @@ func TestAccAzureRMVirtualMachineScaleSet_loadBalancer(t *testing.T) {
})
}
func TestAccAzureRMVirtualMachineScaleSet_loadBalancerManagedDataDisks(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMVirtualMachineScaleSetLoadbalancerTemplateManagedDataDisks, ri, ri, ri, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMVirtualMachineScaleSetDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMVirtualMachineScaleSetExists("azurerm_virtual_machine_scale_set.test"),
testCheckAzureRMVirtualMachineScaleSetHasDataDisks("azurerm_virtual_machine_scale_set.test"),
),
},
},
})
}
func TestAccAzureRMVirtualMachineScaleSet_overprovision(t *testing.T) {
ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMVirtualMachineScaleSetOverprovisionTemplate, ri, ri, ri, ri, ri, ri)
@ -369,6 +388,39 @@ func testCheckAzureRMVirtualMachineScaleSetExtension(name string) resource.TestC
}
}
func testCheckAzureRMVirtualMachineScaleSetHasDataDisks(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)
}
name := 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: scale set %s", name)
}
conn := testAccProvider.Meta().(*ArmClient).vmScaleSetClient
resp, err := conn.Get(resourceGroup, name)
if err != nil {
return fmt.Errorf("Bad: Get on vmScaleSetClient: %s", err)
}
if resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("Bad: VirtualMachineScaleSet %q (resource group: %q) does not exist", name, resourceGroup)
}
storageProfile := resp.VirtualMachineProfile.StorageProfile.DataDisks
if storageProfile == nil || len(*storageProfile) == 0 {
return fmt.Errorf("Bad: Could not get data disks configurations for scale set %v", name)
}
return nil
}
}
var testAccAzureRMVirtualMachineScaleSet_basic = `
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
@ -1286,3 +1338,84 @@ resource "azurerm_virtual_machine_scale_set" "test" {
}
}
`
var testAccAzureRMVirtualMachineScaleSetLoadbalancerTemplateManagedDataDisks = `
resource "azurerm_resource_group" "test" {
name = "acctestrg-%d"
location = "southcentralus"
}
resource "azurerm_virtual_network" "test" {
name = "acctvn-%d"
address_space = ["10.0.0.0/16"]
location = "southcentralus"
resource_group_name = "${azurerm_resource_group.test.name}"
}
resource "azurerm_subnet" "test" {
name = "acctsub-%d"
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_lb" "test" {
name = "acctestlb-%d"
location = "southcentralus"
resource_group_name = "${azurerm_resource_group.test.name}"
frontend_ip_configuration {
name = "default"
subnet_id = "${azurerm_subnet.test.id}"
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_lb_backend_address_pool" "test" {
name = "test"
resource_group_name = "${azurerm_resource_group.test.name}"
loadbalancer_id = "${azurerm_lb.test.id}"
}
resource "azurerm_virtual_machine_scale_set" "test" {
name = "acctvmss-%d"
location = "southcentralus"
resource_group_name = "${azurerm_resource_group.test.name}"
upgrade_policy_mode = "Manual"
sku {
name = "Standard_A0"
tier = "Standard"
capacity = 1
}
os_profile {
computer_name_prefix = "testvm-%d"
admin_username = "myadmin"
admin_password = "Passwword1234"
}
network_profile {
name = "TestNetworkProfile"
primary = true
ip_configuration {
name = "TestIPConfiguration"
subnet_id = "${azurerm_subnet.test.id}"
load_balancer_backend_address_pool_ids = [ "${azurerm_lb_backend_address_pool.test.id}" ]
}
}
storage_profile_os_disk {
name = ""
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
storage_profile_data_disk {
lun = 0
caching = "ReadWrite"
create_option = "Empty"
disk_size_gb = 10
managed_disk_type = "Standard_LRS"
}
storage_profile_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04.0-LTS"
version = "latest"
}
}
`

View File

@ -195,6 +195,13 @@ resource "azurerm_virtual_machine_scale_set" "test" {
managed_disk_type = "Standard_LRS"
}
storage_profile_data_disk {
lun = 0
caching = "ReadWrite"
create_option = "Empty"
disk_size_gb = 10
}
os_profile {
computer_name_prefix = "testvm"
admin_username = "myadmin"
@ -248,6 +255,7 @@ The following arguments are supported:
* `os_profile_linux_config` - (Required, when a linux machine) A Linux config block as documented below.
* `network_profile` - (Required) A collection of network profile block as documented below.
* `storage_profile_os_disk` - (Required) A storage profile os disk block as documented below
* `storage_profile_data_disk` - (Optional) A storage profile data disk block as documented below
* `storage_profile_image_reference` - (Optional) A storage profile image reference block as documented below.
* `extension` - (Optional) Can be specified multiple times to add extension profiles to the scale set. Each `extension` block supports the fields documented below.
* `tags` - (Optional) A mapping of tags to assign to the resource.
@ -329,6 +337,15 @@ The following arguments are supported:
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_data_disk` supports the following:
* `lun` - (Required) Specifies the Logical Unit Number of the disk in each virtual machine in the scale set.
`Premium_LRS`.
* `create_option` - (Optional) Specifies how the data disk should be created. The only possible options are `FromImage` and `Empty`.
* `caching` - (Optional) Specifies the caching requirements. Possible values include: `None` (default), `ReadOnly`, `ReadWrite`.
* `disk_size_gb` - (Optional) Specifies the size of the disk in GB. This element is required when creating an empty disk.
* `managed_disk_type` - (Optional) Specifies the type of managed disk to create. Value must be either `Standard_LRS` or
`storage_profile_image_reference` supports the following:
* `publisher` - (Required) Specifies the publisher of the image used to create the virtual machines