Skip to content

Commit

Permalink
azurerm_backup_protected_vm: Support exclude_disk_luns and include_di…
Browse files Browse the repository at this point in the history
…sk_luns properties for backup protected VM resource (hashicorp#14097)

The purpose of this PR:

Supports exclude_disk_luns and include_disk_luns properties for backup protected VM resource.

Fixes: #issue 13570
  • Loading branch information
sinbai authored Nov 11, 2021
1 parent 931af70 commit 877e642
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 7 deletions.
79 changes: 73 additions & 6 deletions internal/services/recoveryservices/backup_protected_vm_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/internal/services/recoveryservices/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)
Expand Down Expand Up @@ -63,6 +64,26 @@ func resourceRecoveryServicesBackupProtectedVM() *pluginsdk.Resource {
ValidateFunc: azure.ValidateResourceID,
},

"exclude_disk_luns": {
Type: pluginsdk.TypeSet,
ConflictsWith: []string{"include_disk_luns"},
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeInt,
ValidateFunc: validation.IntAtLeast(0),
},
},

"include_disk_luns": {
Type: pluginsdk.TypeSet,
ConflictsWith: []string{"exclude_disk_luns"},
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeInt,
ValidateFunc: validation.IntAtLeast(0),
},
},

"tags": tags.Schema(),
},
}
Expand Down Expand Up @@ -107,12 +128,13 @@ func resourceRecoveryServicesBackupProtectedVMCreateUpdate(d *pluginsdk.Resource
item := backup.ProtectedItemResource{
Tags: tags.Expand(t),
Properties: &backup.AzureIaaSComputeVMProtectedItem{
PolicyID: &policyId,
ProtectedItemType: backup.ProtectedItemTypeMicrosoftClassicComputevirtualMachines,
WorkloadType: backup.DataSourceTypeVM,
SourceResourceID: utils.String(vmId),
FriendlyName: utils.String(parsedVmId.Name),
VirtualMachineID: utils.String(vmId),
PolicyID: &policyId,
ProtectedItemType: backup.ProtectedItemTypeMicrosoftClassicComputevirtualMachines,
WorkloadType: backup.DataSourceTypeVM,
SourceResourceID: utils.String(vmId),
FriendlyName: utils.String(parsedVmId.Name),
ExtendedProperties: expandDiskExclusion(d),
VirtualMachineID: utils.String(vmId),
},
}

Expand Down Expand Up @@ -163,6 +185,18 @@ func resourceRecoveryServicesBackupProtectedVMRead(d *pluginsdk.ResourceData, me
if v := vm.PolicyID; v != nil {
d.Set("backup_policy_id", strings.Replace(*v, "Subscriptions", "subscriptions", 1))
}

if v := vm.ExtendedProperties; v != nil && v.DiskExclusionProperties != nil {
if *v.DiskExclusionProperties.IsInclusionList {
if err := d.Set("include_disk_luns", utils.FlattenInt32Slice(v.DiskExclusionProperties.DiskLunList)); err != nil {
return fmt.Errorf("setting include_disk_luns: %+v", err)
}
} else {
if err := d.Set("exclude_disk_luns", utils.FlattenInt32Slice(v.DiskExclusionProperties.DiskLunList)); err != nil {
return fmt.Errorf("setting exclude_disk_luns: %+v", err)
}
}
}
}
}

Expand Down Expand Up @@ -268,3 +302,36 @@ func resourceRecoveryServicesBackupProtectedVMRefreshFunc(ctx context.Context, c
return resp, "Found", nil
}
}

func expandDiskExclusion(d *pluginsdk.ResourceData) *backup.ExtendedProperties {
if v, ok := d.GetOk("include_disk_luns"); ok {
var diskLun = expandDiskLunList(v.(*pluginsdk.Set).List())

return &backup.ExtendedProperties{
DiskExclusionProperties: &backup.DiskExclusionProperties{
DiskLunList: utils.ExpandInt32Slice(diskLun),
IsInclusionList: utils.Bool(true),
},
}
}

if v, ok := d.GetOk("exclude_disk_luns"); ok {
var diskLun = expandDiskLunList(v.(*pluginsdk.Set).List())

return &backup.ExtendedProperties{
DiskExclusionProperties: &backup.DiskExclusionProperties{
DiskLunList: utils.ExpandInt32Slice(diskLun),
IsInclusionList: utils.Bool(false),
},
}
}
return nil
}

func expandDiskLunList(input []interface{}) []interface{} {
result := make([]interface{}, 0, len(input))
for _, v := range input {
result = append(result, v.(int))
}
return result
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,38 @@ func TestAccBackupProtectedVm_updateBackupPolicyId(t *testing.T) {
})
}

func TestAccBackupProtectedVm_updateDiskExclusion(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_backup_protected_vm", "test")
r := BackupProtectedVmResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("resource_group_name").Exists(),
),
},
data.ImportStep(),
{
Config: r.updateDiskExclusion(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("resource_group_name").Exists(),
),
},
data.ImportStep(),
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("resource_group_name").Exists(),
),
},
data.ImportStep(),
})
}

func (t BackupProtectedVmResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := parse.ProtectedItemID(state.ID)
if err != nil {
Expand Down Expand Up @@ -200,7 +232,7 @@ resource "azurerm_virtual_machine" "test" {
name = "acctestvm"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
vm_size = "Standard_A0"
vm_size = "Standard_D1_v2"
network_interface_ids = [azurerm_network_interface.test.id]
storage_image_reference {
Expand All @@ -226,6 +258,14 @@ resource "azurerm_virtual_machine" "test" {
lun = 0
}
storage_data_disk {
name = "acctest-another-datadisk"
create_option = "Empty"
disk_size_gb = "1"
lun = 1
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "acctest"
admin_username = "vmadmin"
Expand Down Expand Up @@ -277,6 +317,23 @@ resource "azurerm_backup_protected_vm" "test" {
recovery_vault_name = azurerm_recovery_services_vault.test.name
source_vm_id = azurerm_virtual_machine.test.id
backup_policy_id = azurerm_backup_policy_vm.test.id
include_disk_luns = [0]
}
`, r.base(data))
}

func (r BackupProtectedVmResource) updateDiskExclusion(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_backup_protected_vm" "test" {
resource_group_name = azurerm_resource_group.test.name
recovery_vault_name = azurerm_recovery_services_vault.test.name
source_vm_id = azurerm_virtual_machine.test.id
backup_policy_id = azurerm_backup_policy_vm.test.id
exclude_disk_luns = [0, 1]
}
`, r.base(data))
}
Expand Down
4 changes: 4 additions & 0 deletions website/docs/r/backup_protected_vm.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ The following arguments are supported:

* `backup_policy_id` - (Required) Specifies the id of the backup policy to use.

* `exclude_disk_luns` - (Optional) A list of Disks' Logical Unit Numbers(LUN) to be excluded for VM Protection.

* `include_disk_luns` - (Optional) A list of Disks' Logical Unit Numbers(LUN) to be included for VM Protection.

* `tags` - (Optional) A mapping of tags to assign to the resource.

## Attributes Reference
Expand Down

0 comments on commit 877e642

Please sign in to comment.