Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ module "my_backup" {
| `backup_vault_name` | The name of the backup vault. The value supplied will be automatically prefixed with `rg-nhsbackup-`. If more than one az-backup module is created, this value must be unique across them. | Yes | n/a |
| `backup_vault_redundancy` | The redundancy of the vault, e.g. `GeoRedundant`. [See the following link for the possible values.](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#redundancy) | No | `LocallyRedundant` |
| `backup_vault_immutability` | The immutability of the vault, e.g. `Locked`. [See the following link for the possible values.](https://learn.microsoft.com/en-us/azure/templates/microsoft.dataprotection/backupvaults?pivots=deployment-language-terraform#immutabilitysettings-2) | No | `Disabled` |
| `log_analytics_workspace_id` | The id of the log analytics workspace that backup telemetry and diagnostics should be sent to. When no value is provided then diagnostics will not be sent anywhere. | No | n/a |
| `log_analytics_workspace_id` | The id of the log analytics workspace that backup telemetry and diagnostics will be sent to. | Yes | n/a |
| `tags` | A map of tags which will be applied to the resource group and backup vault. When no tags are specified then no tags are added. NOTE when using an externally managed resource group the tags will not be applied to it (they will still be applied to the backup vault). | No | n/a |
| `use_extended_retention` | If set to true, then the backup retention periods can be set to anything, otherwise they are limited to 7 days. | No | `false` |
| `blob_storage_backups` | A map of blob storage backups that should be created. For each backup the following values should be provided: `storage_account_id`, `backup_name` and `retention_period`. When no value is provided then no backups are created. | No | n/a |
Expand Down
1 change: 0 additions & 1 deletion infrastructure/backup_vault.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ locals {
}

resource "azurerm_monitor_diagnostic_setting" "backup_vault" {
count = length(var.log_analytics_workspace_id) > 0 ? 1 : 0
name = "${var.backup_vault_name}-diagnostic-settings"
target_resource_id = azurerm_data_protection_backup_vault.backup_vault.id
log_analytics_workspace_id = var.log_analytics_workspace_id
Expand Down
1 change: 0 additions & 1 deletion infrastructure/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ variable "backup_vault_immutability" {
variable "log_analytics_workspace_id" {
description = "The id of the log analytics workspace to use for backup vault diagnostic settings"
type = string
default = ""
}

variable "tags" {
Expand Down
32 changes: 32 additions & 0 deletions tests/end-to-end-tests/basic_deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,40 @@ package e2e_tests

import (
"fmt"
"strings"
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dataprotection/armdataprotection/v3"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
)

type BasicDeploymentTestExternalResources struct {
ResourceGroup armresources.ResourceGroup
LogAnalyticsWorkspace armoperationalinsights.Workspace
}

/*
* Creates resources which are "external" to the az-backup module, and models
* what would be backed up in a real scenario.
*/
func setupExternalResourcesForBasicDeploymentTest(t *testing.T, credential *azidentity.ClientSecretCredential, subscriptionID string, resourceGroupName string, resourceGroupLocation string, uniqueId string) *BasicDeploymentTestExternalResources {

logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId))
logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, resourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation)

externalResources := &BasicDeploymentTestExternalResources{
LogAnalyticsWorkspace: logAnalyticsWorkspace,
}

return externalResources
}

/*
* TestBasicDeployment tests the basic deployment of the infrastructure using Terraform.
*/
Expand All @@ -26,6 +51,8 @@ func TestBasicDeployment(t *testing.T) {
backupVaultName := fmt.Sprintf("bvault-nhsbackup-%s", uniqueId)
backupVaultRedundancy := "LocallyRedundant"

externalResources := setupExternalResourcesForBasicDeploymentTest(t, credential, environment.SubscriptionID, resourceGroupName, resourceGroupLocation, uniqueId)

tags := map[string]string{
"tagOne": "tagOneValue",
"tagTwo": "tagTwoValue",
Expand Down Expand Up @@ -54,6 +81,7 @@ func TestBasicDeployment(t *testing.T) {
"backup_vault_name": backupVaultName,
"backup_vault_redundancy": backupVaultRedundancy,
"tags": tags,
"log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID,
},

BackendConfig: map[string]interface{}{
Expand Down Expand Up @@ -106,5 +134,9 @@ func TestBasicDeployment(t *testing.T) {
assert.True(t, exists, "Tag %s does not exist", key)
assert.Equal(t, expectedValue, *value, "Tag %s value does not match", key)
}

// Validate log analytics workspace
logAnalyticsWorkspace := GetLogAnalyticsWorkspace(t, credential, environment.SubscriptionID, resourceGroupName, *externalResources.LogAnalyticsWorkspace.Name)
assert.NotNil(t, logAnalyticsWorkspace, "Log Analytics Workspace does not exist")
})
}
19 changes: 15 additions & 4 deletions tests/end-to-end-tests/blob_storage_backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dataprotection/armdataprotection/v3"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
"github.com/gruntwork-io/terratest/modules/random"
Expand All @@ -21,6 +22,7 @@ type TestBlobStorageBackupExternalResources struct {
StorageAccountOneContainer armstorage.BlobContainer
StorageAccountTwo armstorage.Account
StorageAccountTwoContainer armstorage.BlobContainer
LogAnalyticsWorkspace armoperationalinsights.Workspace
}

/*
Expand All @@ -39,12 +41,16 @@ func setupExternalResourcesForBlobStorageBackupTest(t *testing.T, credential *az
storageAccountTwo := CreateStorageAccount(t, credential, subscriptionID, externalResourceGroupName, storageAccountTwoName, resourceGroupLocation)
storageAccountTwoContainer := CreateStorageAccountContainer(t, credential, subscriptionID, externalResourceGroupName, storageAccountTwoName, "test-container")

logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId))
logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation)

externalResources := &TestBlobStorageBackupExternalResources{
ResourceGroup: resourceGroup,
StorageAccountOne: storageAccountOne,
StorageAccountOneContainer: storageAccountOneContainer,
StorageAccountTwo: storageAccountTwo,
StorageAccountTwoContainer: storageAccountTwoContainer,
LogAnalyticsWorkspace: logAnalyticsWorkspace,
}

return externalResources
Expand Down Expand Up @@ -104,10 +110,11 @@ func TestBlobStorageBackup(t *testing.T) {
TerraformDir: environment.TerraformFolder,

Vars: map[string]interface{}{
"resource_group_name": resourceGroupName,
"resource_group_location": resourceGroupLocation,
"backup_vault_name": backupVaultName,
"blob_storage_backups": blobStorageBackups,
"resource_group_name": resourceGroupName,
"resource_group_location": resourceGroupLocation,
"backup_vault_name": backupVaultName,
"blob_storage_backups": blobStorageBackups,
"log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID,
},

BackendConfig: map[string]interface{}{
Expand All @@ -132,6 +139,10 @@ func TestBlobStorageBackup(t *testing.T) {
backupPolicies := GetBackupPolicies(t, credential, environment.SubscriptionID, resourceGroupName, backupVaultName)
backupInstances := GetBackupInstances(t, credential, environment.SubscriptionID, resourceGroupName, backupVaultName)

// Validate log analytics workspace
logAnalyticsWorkspace := GetLogAnalyticsWorkspace(t, credential, environment.SubscriptionID, resourceGroupName, *externalResources.LogAnalyticsWorkspace.Name)
assert.NotNil(t, logAnalyticsWorkspace, "Log Analytics Workspace does not exist")

assert.Equal(t, len(blobStorageBackups), len(backupPolicies), "Expected to find %2 backup policies in vault", len(blobStorageBackups))
assert.Equal(t, len(blobStorageBackups), len(backupInstances), "Expected to find %2 backup instances in vault", len(blobStorageBackups))

Expand Down
4 changes: 4 additions & 0 deletions tests/end-to-end-tests/diagnostic_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ func TestDiagnosticSettings(t *testing.T) {
backupVault := GetBackupVault(t, credential, environment.SubscriptionID, resourceGroupName, backupVaultName)
diagnosticSettings := GetDiagnosticSettings(t, credential, *backupVault.ID, *backupVault.Name)

// Validate log analytics workspace
logAnalyticsWorkspace := GetLogAnalyticsWorkspace(t, credential, environment.SubscriptionID, resourceGroupName, *externalResources.LogAnalyticsWorkspace.Name)
assert.NotNil(t, logAnalyticsWorkspace, "Log Analytics Workspace does not exist")

assert.Equal(t, len(diagnosticSettings.Properties.Logs), len(expectedLogCategories), "Expected to find %2 log categories in diagnostic settings", len(expectedLogCategories))
assert.Equal(t, len(diagnosticSettings.Properties.Metrics), len(expectedMetricCategories), "Expected to find %2 metric categories in diagnostic settings", len(expectedMetricCategories))

Expand Down
28 changes: 20 additions & 8 deletions tests/end-to-end-tests/existing_resource_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package e2e_tests

import (
"fmt"
"strings"
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
Expand All @@ -10,20 +11,26 @@ import (
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/assert"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights"
)

type TestExistingResourceGroupExternalResources struct {
ResourceGroup armresources.ResourceGroup
ResourceGroup armresources.ResourceGroup
LogAnalyticsWorkspace armoperationalinsights.Workspace
}

/*
* Creates resources which are "external" to the az-backup module.
*/
func setupExternalResourcesForExistingResourceGroupTest(t *testing.T, credential *azidentity.ClientSecretCredential, subscriptionID string, resourceGroupName string, resourceGroupLocation string) *TestExistingResourceGroupExternalResources {
func setupExternalResourcesForExistingResourceGroupTest(t *testing.T, credential *azidentity.ClientSecretCredential, subscriptionID string, resourceGroupName string, resourceGroupLocation string, uniqueId string) *TestExistingResourceGroupExternalResources {
resourceGroup := CreateResourceGroup(t, credential, subscriptionID, resourceGroupName, resourceGroupLocation)

logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId))
logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, resourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation)

externalResources := &TestExistingResourceGroupExternalResources{
ResourceGroup: resourceGroup,
ResourceGroup: resourceGroup,
LogAnalyticsWorkspace: logAnalyticsWorkspace,
}

return externalResources
Expand All @@ -43,7 +50,7 @@ func TestExistingResourceGroup(t *testing.T) {
resourceGroupLocation := "uksouth"
backupVaultName := fmt.Sprintf("bvault-nhsbackup-%s", uniqueId)

externalResources := setupExternalResourcesForExistingResourceGroupTest(t, credential, environment.SubscriptionID, resourceGroupName, resourceGroupLocation)
externalResources := setupExternalResourcesForExistingResourceGroupTest(t, credential, environment.SubscriptionID, resourceGroupName, resourceGroupLocation, uniqueId)

// Teardown stage
// ...
Expand All @@ -64,10 +71,11 @@ func TestExistingResourceGroup(t *testing.T) {
TerraformDir: environment.TerraformFolder,

Vars: map[string]interface{}{
"resource_group_name": resourceGroupName,
"resource_group_location": resourceGroupLocation,
"create_resource_group": false,
"backup_vault_name": backupVaultName,
"resource_group_name": resourceGroupName,
"resource_group_location": resourceGroupLocation,
"create_resource_group": false,
"backup_vault_name": backupVaultName,
"log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID,
},

BackendConfig: map[string]interface{}{
Expand All @@ -93,5 +101,9 @@ func TestExistingResourceGroup(t *testing.T) {
assert.NotNil(t, resourceGroup, "Resource group does not exist")
assert.Equal(t, resourceGroupName, *resourceGroup.Name, "Resource group name does not match")
assert.Equal(t, resourceGroupLocation, *resourceGroup.Location, "Resource group location does not match")

// Validate log analytics workspace
logAnalyticsWorkspace := GetLogAnalyticsWorkspace(t, credential, environment.SubscriptionID, resourceGroupName, *externalResources.LogAnalyticsWorkspace.Name)
assert.NotNil(t, logAnalyticsWorkspace, "Log Analytics Workspace does not exist")
})
}
2 changes: 1 addition & 1 deletion tests/end-to-end-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.1
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.2
github.com/gruntwork-io/go-commons v0.17.2
github.com/gruntwork-io/terratest v0.48.2
github.com/gruntwork-io/terratest v0.50.0
github.com/stretchr/testify v1.10.0
)

Expand Down
4 changes: 2 additions & 2 deletions tests/end-to-end-tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gruntwork-io/go-commons v0.17.2 h1:14dsCJ7M5Vv2X3BIPKeG9Kdy6vTMGhM8L4WZazxfTuY=
github.com/gruntwork-io/go-commons v0.17.2/go.mod h1:zs7Q2AbUKuTarBPy19CIxJVUX/rBamfW8IwuWKniWkE=
github.com/gruntwork-io/terratest v0.48.2 h1:+VwfODchq8jxZZWD+s8gBlhD1z6/C4bFLNrhpm9ONrs=
github.com/gruntwork-io/terratest v0.48.2/go.mod h1:Y5ETyD4ZQ2MZhasPno272fWuCpKwvTPYDi8Y0tIMqTE=
github.com/gruntwork-io/terratest v0.50.0 h1:AbBJ7IRCpLZ9H4HBrjeoWESITv8nLjN6/f1riMNcAsw=
github.com/gruntwork-io/terratest v0.50.0/go.mod h1:see0lbKvAqz6rvzvN2wyfuFQQG4PWcAb2yHulF6B2q4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down
15 changes: 15 additions & 0 deletions tests/end-to-end-tests/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,21 @@ func GetBackupInstanceForName(instances []*armdataprotection.BackupInstanceResou
return nil
}

/*
* Gets a Log Analytics Workspace for the provided name.
*/
func GetLogAnalyticsWorkspace(t *testing.T, credential *azidentity.ClientSecretCredential, subscriptionID string,
resourceGroupName string, workspaceName string) armoperationalinsights.Workspace {
client, err := armoperationalinsights.NewWorkspacesClient(subscriptionID, credential, nil)
assert.NoError(t, err, "Failed to create log analytics workspace client: %v", err)

// Get the log analytics workspace
resp, err := client.Get(context.Background(), resourceGroupName, workspaceName, nil)
assert.NoError(t, err, "Failed to get log analytics workspace: %v", err)

return resp.Workspace
}

/*
* Creates a resource group that can be used for testing purposes.
*/
Expand Down
21 changes: 14 additions & 7 deletions tests/end-to-end-tests/managed_disk_backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dataprotection/armdataprotection/v3"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/terraform"
Expand All @@ -19,6 +20,7 @@ type TestManagedDiskBackupExternalResources struct {
ResourceGroup armresources.ResourceGroup
ManagedDiskOne armcompute.Disk
ManagedDiskTwo armcompute.Disk
LogAnalyticsWorkspace armoperationalinsights.Workspace
}

/*
Expand All @@ -35,10 +37,14 @@ func setupExternalResourcesForManagedDiskBackupTest(t *testing.T, credential *az
managedDiskTwoName := fmt.Sprintf("disk-%s-external-2", strings.ToLower(uniqueId))
managedDiskTwo := CreateManagedDisk(t, credential, subscriptionID, externalResourceGroupName, managedDiskTwoName, resourceGroupLocation, int32(1))

logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId))
logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation)

externalResources := &TestManagedDiskBackupExternalResources{
ResourceGroup: resourceGroup,
ManagedDiskOne: managedDiskOne,
ManagedDiskTwo: managedDiskTwo,
ResourceGroup: resourceGroup,
ManagedDiskOne: managedDiskOne,
ManagedDiskTwo: managedDiskTwo,
LogAnalyticsWorkspace: logAnalyticsWorkspace,
}

return externalResources
Expand Down Expand Up @@ -104,10 +110,11 @@ func TestManagedDiskBackup(t *testing.T) {
TerraformDir: environment.TerraformFolder,

Vars: map[string]interface{}{
"resource_group_name": resourceGroupName,
"resource_group_location": resourceGroupLocation,
"backup_vault_name": backupVaultName,
"managed_disk_backups": managedDiskBackups,
"resource_group_name": resourceGroupName,
"resource_group_location": resourceGroupLocation,
"backup_vault_name": backupVaultName,
"managed_disk_backups": managedDiskBackups,
"log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID,
},

BackendConfig: map[string]interface{}{
Expand Down
Loading
Loading