diff --git a/docs/usage.md b/docs/usage.md index 67eee3e..bfc3b8a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -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 should be sent to. **NOTE** this variable was made mandatory in v2 of the module. | 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 | diff --git a/infrastructure/.terraform.lock.hcl b/infrastructure/.terraform.lock.hcl index aff7b5a..24555e4 100644 --- a/infrastructure/.terraform.lock.hcl +++ b/infrastructure/.terraform.lock.hcl @@ -2,21 +2,21 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/azurerm" { - version = "4.37.0" + version = "4.38.1" constraints = ">= 4.18.0, < 5.0.0" hashes = [ - "h1:MfFA2dyXwJlMi4p7PBjQzyRDLm0vcpnVeMPedvUT6BE=", - "zh:10acb818823a0319215beb796af1a7a97820be5d40ec1779deb8c2bdb1cac6d0", - "zh:31cac8c98e4b8e1f44e33394e6ed375552aea204ef9ce2e8612719c5ebb8ffae", - "zh:32048bf10eec89819f73de86a478aced0101be9d480badad8dec31f65b65590a", - "zh:38236dfd5e28c4ceaf27b3a719deb40802159ceed810c667be3a42ee8bc384d8", - "zh:438cff6ac72117016975d47fadfdbccb33218274c6c74fd4ff4f1eea2ec18b6a", - "zh:7763f4d97b3f67e65e730023755db6b567644c0fab9a65e966c9a34fb4690a97", - "zh:799eca3363eda85a6f6678d47bf01cb48dcb9296ecd6165814eb696a9d9e2c7d", - "zh:8508771cedbaa651156a3726cda04e1f28443a46e3a7c72b4a9a7abbf671aed9", - "zh:96b016af4ebe0db58ba51e40dd419465b5152f98842d366a5b5b8835f2c7be58", - "zh:eb7d0efaaaef225b6e867e5cbd0514f39f0bc4e12e6c3cdfdb666776c5948995", + "h1:YdwGzWX888zI/vp5nBTCks20+AxpBWPKEj2l/wRJHx8=", + "zh:2d4085678cad85782b0097d2f1d03d96862deb3684b14a1125bd46b36091fd30", + "zh:3fe8037a4e94bc694caca4a68c0e15436dedc91b70aa95a06e2770e3e8dde6df", + "zh:4178b3783fca42ebac4435db3531bd23069723caf1509b0e915c524a4dee25d3", + "zh:61c6d21e854696c1c6d3fadce9aa9ab433e9a8791340760f9e8fdd1327d1a391", + "zh:8ef26b97aed168b7b91b868c1e4493a79cdbdc4ecb987f0e2a4e402ab6cb2474", + "zh:b4b1edfb49a36a109c69d661bb26b961fcdf50058690deed9d906c09254e5c1a", + "zh:b5e07b1c160cf0cefc2e4bc8d2b4c0a382dd76513797dc70b0c2fd3bee7b8495", + "zh:b87029f89e7d445c85ee7a8940f4a2740a745124802c461d1e51cd8b11d7c106", + "zh:c21d488f12aa6750f4525fc120b1405dd1a37f0b59586960e78beeb0e4fffcca", + "zh:cd1402d0e004e23c2ee36744fa26d4daafa291a05d5410b7beca6dc8c30857ba", + "zh:e8a7eb3d937d27e779ae426ac9f4529bdc7053634f219df8c76b2b8180fbed71", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:ffa8d70d432894b7b023f50831490bd5db762c8f48d5f7607888aaa5d0da39e8", ] } diff --git a/infrastructure/backup_vault.tf b/infrastructure/backup_vault.tf index d599c25..538a5af 100644 --- a/infrastructure/backup_vault.tf +++ b/infrastructure/backup_vault.tf @@ -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 diff --git a/infrastructure/variables.tf b/infrastructure/variables.tf index 93a306f..78372a2 100644 --- a/infrastructure/variables.tf +++ b/infrastructure/variables.tf @@ -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" { diff --git a/tests/end-to-end-tests/basic_deployment_test.go b/tests/end-to-end-tests/basic_deployment_test.go index 0936d39..076fe15 100644 --- a/tests/end-to-end-tests/basic_deployment_test.go +++ b/tests/end-to-end-tests/basic_deployment_test.go @@ -2,15 +2,43 @@ 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/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" test_structure "github.com/gruntwork-io/terratest/modules/test-structure" "github.com/stretchr/testify/assert" ) +type TestBasicDeploymentExternalResources 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) *TestDiagnosticSettingsExternalResources { + externalResourceGroupName := fmt.Sprintf("%s-external", resourceGroupName) + resourceGroup := CreateResourceGroup(t, credential, subscriptionID, externalResourceGroupName, resourceGroupLocation) + + logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId)) + logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation) + + externalResources := &TestDiagnosticSettingsExternalResources{ + ResourceGroup: resourceGroup, + LogAnalyticsWorkspace: logAnalyticsWorkspace, + } + + return externalResources +} + /* * TestBasicDeployment tests the basic deployment of the infrastructure using Terraform. */ @@ -32,6 +60,8 @@ func TestBasicDeployment(t *testing.T) { "tagThree": "tagThreeValue", } + externalResources := setupExternalResourcesForBasicDeploymentTest(t, credential, environment.SubscriptionID, resourceGroupName, resourceGroupLocation, uniqueId) + // Teardown stage // ... @@ -49,11 +79,12 @@ func TestBasicDeployment(t *testing.T) { TerraformDir: environment.TerraformFolder, Vars: map[string]interface{}{ - "resource_group_name": resourceGroupName, - "resource_group_location": resourceGroupLocation, - "backup_vault_name": backupVaultName, - "backup_vault_redundancy": backupVaultRedundancy, - "tags": tags, + "resource_group_name": resourceGroupName, + "resource_group_location": resourceGroupLocation, + "backup_vault_name": backupVaultName, + "backup_vault_redundancy": backupVaultRedundancy, + "log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID, + "tags": tags, }, BackendConfig: map[string]interface{}{ diff --git a/tests/end-to-end-tests/blob_storage_backup_test.go b/tests/end-to-end-tests/blob_storage_backup_test.go index 899259a..c56d657 100644 --- a/tests/end-to-end-tests/blob_storage_backup_test.go +++ b/tests/end-to-end-tests/blob_storage_backup_test.go @@ -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" @@ -17,6 +18,7 @@ import ( type TestBlobStorageBackupExternalResources struct { ResourceGroup armresources.ResourceGroup + LogAnalyticsWorkspace armoperationalinsights.Workspace StorageAccountOne armstorage.Account StorageAccountOneContainer armstorage.BlobContainer StorageAccountTwo armstorage.Account @@ -31,6 +33,9 @@ func setupExternalResourcesForBlobStorageBackupTest(t *testing.T, credential *az externalResourceGroupName := fmt.Sprintf("%s-external", resourceGroupName) resourceGroup := CreateResourceGroup(t, credential, subscriptionID, externalResourceGroupName, resourceGroupLocation) + logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId)) + logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation) + storageAccountOneName := fmt.Sprintf("sa%sexternal1", strings.ToLower(uniqueId)) storageAccountOne := CreateStorageAccount(t, credential, subscriptionID, externalResourceGroupName, storageAccountOneName, resourceGroupLocation) storageAccountOneContainer := CreateStorageAccountContainer(t, credential, subscriptionID, externalResourceGroupName, storageAccountOneName, "test-container") @@ -41,6 +46,7 @@ func setupExternalResourcesForBlobStorageBackupTest(t *testing.T, credential *az externalResources := &TestBlobStorageBackupExternalResources{ ResourceGroup: resourceGroup, + LogAnalyticsWorkspace: logAnalyticsWorkspace, StorageAccountOne: storageAccountOne, StorageAccountOneContainer: storageAccountOneContainer, StorageAccountTwo: storageAccountTwo, @@ -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, + "log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID, + "blob_storage_backups": blobStorageBackups, }, BackendConfig: map[string]interface{}{ diff --git a/tests/end-to-end-tests/existing_resource_group_test.go b/tests/end-to-end-tests/existing_resource_group_test.go index e2feca0..97f7dc3 100644 --- a/tests/end-to-end-tests/existing_resource_group_test.go +++ b/tests/end-to-end-tests/existing_resource_group_test.go @@ -2,9 +2,11 @@ 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/resources/armresources" "github.com/gruntwork-io/terratest/modules/random" "github.com/gruntwork-io/terratest/modules/terraform" @@ -13,17 +15,22 @@ import ( ) 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", strings.ToLower(uniqueId)) + logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, resourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation) + externalResources := &TestExistingResourceGroupExternalResources{ - ResourceGroup: resourceGroup, + ResourceGroup: resourceGroup, + LogAnalyticsWorkspace: logAnalyticsWorkspace, } return externalResources @@ -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 // ... @@ -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{}{ diff --git a/tests/end-to-end-tests/managed_disk_backup_test.go b/tests/end-to-end-tests/managed_disk_backup_test.go index d628b8d..17bcf82 100644 --- a/tests/end-to-end-tests/managed_disk_backup_test.go +++ b/tests/end-to-end-tests/managed_disk_backup_test.go @@ -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" @@ -16,9 +17,10 @@ import ( ) type TestManagedDiskBackupExternalResources struct { - ResourceGroup armresources.ResourceGroup - ManagedDiskOne armcompute.Disk - ManagedDiskTwo armcompute.Disk + ResourceGroup armresources.ResourceGroup + LogAnalyticsWorkspace armoperationalinsights.Workspace + ManagedDiskOne armcompute.Disk + ManagedDiskTwo armcompute.Disk } /* @@ -29,6 +31,9 @@ func setupExternalResourcesForManagedDiskBackupTest(t *testing.T, credential *az externalResourceGroupName := fmt.Sprintf("%s-external", resourceGroupName) resourceGroup := CreateResourceGroup(t, credential, subscriptionID, externalResourceGroupName, resourceGroupLocation) + logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId)) + logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation) + managedDiskOneName := fmt.Sprintf("disk-%s-external-1", strings.ToLower(uniqueId)) managedDiskOne := CreateManagedDisk(t, credential, subscriptionID, externalResourceGroupName, managedDiskOneName, resourceGroupLocation, int32(1)) @@ -36,9 +41,10 @@ func setupExternalResourcesForManagedDiskBackupTest(t *testing.T, credential *az managedDiskTwo := CreateManagedDisk(t, credential, subscriptionID, externalResourceGroupName, managedDiskTwoName, resourceGroupLocation, int32(1)) externalResources := &TestManagedDiskBackupExternalResources{ - ResourceGroup: resourceGroup, - ManagedDiskOne: managedDiskOne, - ManagedDiskTwo: managedDiskTwo, + ResourceGroup: resourceGroup, + LogAnalyticsWorkspace: logAnalyticsWorkspace, + ManagedDiskOne: managedDiskOne, + ManagedDiskTwo: managedDiskTwo, } return externalResources @@ -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, + "log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID, + "managed_disk_backups": managedDiskBackups, }, BackendConfig: map[string]interface{}{ diff --git a/tests/end-to-end-tests/postgresql_flexible_server_backup_test.go b/tests/end-to-end-tests/postgresql_flexible_server_backup_test.go index 1168881..d57c1a8 100644 --- a/tests/end-to-end-tests/postgresql_flexible_server_backup_test.go +++ b/tests/end-to-end-tests/postgresql_flexible_server_backup_test.go @@ -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/postgresql/armpostgresqlflexibleservers" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" "github.com/gruntwork-io/terratest/modules/random" @@ -17,6 +18,7 @@ import ( type TestPostgresqlFlexibleServerBackupExternalResources struct { ResourceGroup armresources.ResourceGroup + LogAnalyticsWorkspace armoperationalinsights.Workspace PostgresqlFlexibleServerOne armpostgresqlflexibleservers.Server PostgresqlFlexibleServerTwo armpostgresqlflexibleservers.Server } @@ -29,6 +31,9 @@ func setupExternalResourcesForPostgresqlFlexibleServerBackupTest(t *testing.T, c externalResourceGroupName := fmt.Sprintf("%s-external", resourceGroupName) resourceGroup := CreateResourceGroup(t, credential, subscriptionID, externalResourceGroupName, resourceGroupLocation) + logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId)) + logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation) + PostgresqlFlexibleServerOneName := fmt.Sprintf("pgflexserver-%s-external-1", strings.ToLower(uniqueId)) PostgresqlFlexibleServerOne := CreatePostgresqlFlexibleServer(t, credential, subscriptionID, externalResourceGroupName, PostgresqlFlexibleServerOneName, resourceGroupLocation, int32(32)) @@ -37,6 +42,7 @@ func setupExternalResourcesForPostgresqlFlexibleServerBackupTest(t *testing.T, c externalResources := &TestPostgresqlFlexibleServerBackupExternalResources{ ResourceGroup: resourceGroup, + LogAnalyticsWorkspace: logAnalyticsWorkspace, PostgresqlFlexibleServerOne: PostgresqlFlexibleServerOne, PostgresqlFlexibleServerTwo: PostgresqlFlexibleServerTwo, } @@ -101,6 +107,7 @@ func TestPostgresqlFlexibleServerBackup(t *testing.T) { "resource_group_name": resourceGroupName, "resource_group_location": resourceGroupLocation, "backup_vault_name": backupVaultName, + "log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID, "postgresql_flexible_server_backups": PostgresqlFlexibleServerBackups, }, diff --git a/tests/end-to-end-tests/terraform_output_test.go b/tests/end-to-end-tests/terraform_output_test.go index 7577daf..83f4e03 100644 --- a/tests/end-to-end-tests/terraform_output_test.go +++ b/tests/end-to-end-tests/terraform_output_test.go @@ -2,14 +2,42 @@ 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/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 TestTerraformOutputsExternalResources 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 setupExternalResourcesForTerraformOutputTest(t *testing.T, credential *azidentity.ClientSecretCredential, subscriptionID string, resourceGroupName string, resourceGroupLocation string, uniqueId string) *TestDiagnosticSettingsExternalResources { + externalResourceGroupName := fmt.Sprintf("%s-external", resourceGroupName) + resourceGroup := CreateResourceGroup(t, credential, subscriptionID, externalResourceGroupName, resourceGroupLocation) + + logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId)) + logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation) + + externalResources := &TestDiagnosticSettingsExternalResources{ + ResourceGroup: resourceGroup, + LogAnalyticsWorkspace: logAnalyticsWorkspace, + } + + return externalResources +} + /* * TestTerraformOutput tests the output variables of the Terraform deployment. */ @@ -17,6 +45,7 @@ func TestTerraformOutput(t *testing.T) { t.Parallel() environment := GetEnvironmentConfiguration(t) + credential := GetAzureCredential(t, environment) uniqueId := random.UniqueId() resourceGroupName := fmt.Sprintf("rg-nhsbackup-%s", uniqueId) @@ -24,6 +53,8 @@ func TestTerraformOutput(t *testing.T) { backupVaultName := fmt.Sprintf("bvault-nhsbackup-%s", uniqueId) backupVaultRedundancy := "LocallyRedundant" + externalResources := setupExternalResourcesForTerraformOutputTest(t, credential, environment.SubscriptionID, resourceGroupName, resourceGroupLocation, uniqueId) + // Teardown stage // ... @@ -41,10 +72,11 @@ func TestTerraformOutput(t *testing.T) { TerraformDir: environment.TerraformFolder, Vars: map[string]interface{}{ - "resource_group_name": resourceGroupName, - "resource_group_location": resourceGroupLocation, - "backup_vault_name": backupVaultName, - "backup_vault_redundancy": backupVaultRedundancy, + "resource_group_name": resourceGroupName, + "resource_group_location": resourceGroupLocation, + "backup_vault_name": backupVaultName, + "backup_vault_redundancy": backupVaultRedundancy, + "log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID, }, BackendConfig: map[string]interface{}{ diff --git a/tests/end-to-end-tests/vault_immutability_test.go b/tests/end-to-end-tests/vault_immutability_test.go index 26810f7..5c59201 100644 --- a/tests/end-to-end-tests/vault_immutability_test.go +++ b/tests/end-to-end-tests/vault_immutability_test.go @@ -8,6 +8,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" @@ -18,6 +19,7 @@ import ( type TestVaultImmutabilityExternalResources struct { ResourceGroup armresources.ResourceGroup + LogAnalyticsWorkspace armoperationalinsights.Workspace StorageAccount armstorage.Account StorageAccountContainer armstorage.BlobContainer } @@ -30,12 +32,16 @@ func setupExternalResourcesForVaultImmutabilityTest(t *testing.T, credential *az externalResourceGroupName := fmt.Sprintf("%s-external", resourceGroupName) resourceGroup := CreateResourceGroup(t, credential, subscriptionID, externalResourceGroupName, resourceGroupLocation) + logAnalyticsWorkspaceName := fmt.Sprintf("law-%s-external", strings.ToLower(uniqueId)) + logAnalyticsWorkspace := CreateLogAnalyticsWorkspace(t, credential, subscriptionID, externalResourceGroupName, logAnalyticsWorkspaceName, resourceGroupLocation) + storageAccountName := fmt.Sprintf("sa%sexternal", strings.ToLower(uniqueId)) storageAccount := CreateStorageAccount(t, credential, subscriptionID, externalResourceGroupName, storageAccountName, resourceGroupLocation) storageAccountContainer := CreateStorageAccountContainer(t, credential, subscriptionID, externalResourceGroupName, storageAccountName, "test-container") externalResources := &TestVaultImmutabilityExternalResources{ ResourceGroup: resourceGroup, + LogAnalyticsWorkspace: logAnalyticsWorkspace, StorageAccount: storageAccount, StorageAccountContainer: storageAccountContainer, } @@ -91,11 +97,12 @@ func TestVaultImmutability(t *testing.T) { TerraformDir: environment.TerraformFolder, Vars: map[string]interface{}{ - "resource_group_name": resourceGroupName, - "resource_group_location": resourceGroupLocation, - "backup_vault_name": backupVaultName, - "backup_vault_immutability": backupVaultImmutability, - "blob_storage_backups": blobStorageBackups, + "resource_group_name": resourceGroupName, + "resource_group_location": resourceGroupLocation, + "backup_vault_name": backupVaultName, + "backup_vault_immutability": backupVaultImmutability, + "log_analytics_workspace_id": *externalResources.LogAnalyticsWorkspace.ID, + "blob_storage_backups": blobStorageBackups, }, BackendConfig: map[string]interface{}{ diff --git a/tests/integration-tests/.terraform.lock.hcl b/tests/integration-tests/.terraform.lock.hcl index eda0cbb..22832da 100644 --- a/tests/integration-tests/.terraform.lock.hcl +++ b/tests/integration-tests/.terraform.lock.hcl @@ -2,22 +2,22 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/azurerm" { - version = "4.37.0" + version = "4.38.1" constraints = ">= 4.18.0, < 5.0.0" hashes = [ - "h1:MfFA2dyXwJlMi4p7PBjQzyRDLm0vcpnVeMPedvUT6BE=", - "zh:10acb818823a0319215beb796af1a7a97820be5d40ec1779deb8c2bdb1cac6d0", - "zh:31cac8c98e4b8e1f44e33394e6ed375552aea204ef9ce2e8612719c5ebb8ffae", - "zh:32048bf10eec89819f73de86a478aced0101be9d480badad8dec31f65b65590a", - "zh:38236dfd5e28c4ceaf27b3a719deb40802159ceed810c667be3a42ee8bc384d8", - "zh:438cff6ac72117016975d47fadfdbccb33218274c6c74fd4ff4f1eea2ec18b6a", - "zh:7763f4d97b3f67e65e730023755db6b567644c0fab9a65e966c9a34fb4690a97", - "zh:799eca3363eda85a6f6678d47bf01cb48dcb9296ecd6165814eb696a9d9e2c7d", - "zh:8508771cedbaa651156a3726cda04e1f28443a46e3a7c72b4a9a7abbf671aed9", - "zh:96b016af4ebe0db58ba51e40dd419465b5152f98842d366a5b5b8835f2c7be58", - "zh:eb7d0efaaaef225b6e867e5cbd0514f39f0bc4e12e6c3cdfdb666776c5948995", + "h1:YdwGzWX888zI/vp5nBTCks20+AxpBWPKEj2l/wRJHx8=", + "zh:2d4085678cad85782b0097d2f1d03d96862deb3684b14a1125bd46b36091fd30", + "zh:3fe8037a4e94bc694caca4a68c0e15436dedc91b70aa95a06e2770e3e8dde6df", + "zh:4178b3783fca42ebac4435db3531bd23069723caf1509b0e915c524a4dee25d3", + "zh:61c6d21e854696c1c6d3fadce9aa9ab433e9a8791340760f9e8fdd1327d1a391", + "zh:8ef26b97aed168b7b91b868c1e4493a79cdbdc4ecb987f0e2a4e402ab6cb2474", + "zh:b4b1edfb49a36a109c69d661bb26b961fcdf50058690deed9d906c09254e5c1a", + "zh:b5e07b1c160cf0cefc2e4bc8d2b4c0a382dd76513797dc70b0c2fd3bee7b8495", + "zh:b87029f89e7d445c85ee7a8940f4a2740a745124802c461d1e51cd8b11d7c106", + "zh:c21d488f12aa6750f4525fc120b1405dd1a37f0b59586960e78beeb0e4fffcca", + "zh:cd1402d0e004e23c2ee36744fa26d4daafa291a05d5410b7beca6dc8c30857ba", + "zh:e8a7eb3d937d27e779ae426ac9f4529bdc7053634f219df8c76b2b8180fbed71", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:ffa8d70d432894b7b023f50831490bd5db762c8f48d5f7607888aaa5d0da39e8", ] } diff --git a/tests/integration-tests/backup_modules_blob_storage.tftest.hcl b/tests/integration-tests/backup_modules_blob_storage.tftest.hcl index 00d3b4a..0344149 100644 --- a/tests/integration-tests/backup_modules_blob_storage.tftest.hcl +++ b/tests/integration-tests/backup_modules_blob_storage.tftest.hcl @@ -16,10 +16,11 @@ run "create_blob_storage_backup" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags blob_storage_backups = { backup1 = { backup_name = "storage1" @@ -172,10 +173,11 @@ run "validate_retention_period" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags blob_storage_backups = { backup1 = { backup_name = "storage1" @@ -200,11 +202,12 @@ run "validate_retention_period_with_extended_retention" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags - use_extended_retention = true + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags + use_extended_retention = true blob_storage_backups = { backup1 = { backup_name = "storage1" @@ -230,10 +233,11 @@ run "validate_backup_intervals" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags blob_storage_backups = { backup1 = { backup_name = "storage1" @@ -258,10 +262,11 @@ run "validate_storage_account_containers" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags blob_storage_backups = { backup1 = { backup_name = "storage1" diff --git a/tests/integration-tests/backup_modules_managed_disk.tftest.hcl b/tests/integration-tests/backup_modules_managed_disk.tftest.hcl index 47bd360..e6cee41 100644 --- a/tests/integration-tests/backup_modules_managed_disk.tftest.hcl +++ b/tests/integration-tests/backup_modules_managed_disk.tftest.hcl @@ -16,10 +16,11 @@ run "create_managed_disk_backup" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags managed_disk_backups = { backup1 = { backup_name = "disk1" @@ -178,10 +179,11 @@ run "validate_retention_period" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags managed_disk_backups = { backup1 = { backup_name = "disk1" @@ -209,11 +211,12 @@ run "validate_retention_period_with_extended_retention" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags - use_extended_retention = true + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags + use_extended_retention = true managed_disk_backups = { backup1 = { backup_name = "disk1" @@ -242,10 +245,11 @@ run "validate_backup_intervals" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags managed_disk_backups = { backup1 = { backup_name = "disk1" @@ -263,4 +267,4 @@ run "validate_backup_intervals" { expect_failures = [ var.managed_disk_backups, ] -} \ No newline at end of file +} diff --git a/tests/integration-tests/backup_modules_postgresql_flexible_server.tftest.hcl b/tests/integration-tests/backup_modules_postgresql_flexible_server.tftest.hcl index bec91db..c33bd39 100644 --- a/tests/integration-tests/backup_modules_postgresql_flexible_server.tftest.hcl +++ b/tests/integration-tests/backup_modules_postgresql_flexible_server.tftest.hcl @@ -16,10 +16,11 @@ run "create_postgresql_flexible_server_backup" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags postgresql_flexible_server_backups = { backup1 = { backup_name = "server1" @@ -162,10 +163,11 @@ run "validate_retention_period" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags postgresql_flexible_server_backups = { backup1 = { backup_name = "server1" @@ -190,11 +192,12 @@ run "validate_retention_period_with_extended_retention" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags - use_extended_retention = true + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags + use_extended_retention = true postgresql_flexible_server_backups = { backup1 = { backup_name = "server1" @@ -220,10 +223,11 @@ run "validate_backup_intervals" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags postgresql_flexible_server_backups = { backup1 = { backup_name = "server1" diff --git a/tests/integration-tests/backup_vault.tftest.hcl b/tests/integration-tests/backup_vault.tftest.hcl index aaf4baa..c837cc5 100644 --- a/tests/integration-tests/backup_vault.tftest.hcl +++ b/tests/integration-tests/backup_vault.tftest.hcl @@ -16,12 +16,13 @@ run "create_backup_vault" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - backup_vault_redundancy = "LocallyRedundant" - backup_vault_immutability = "Unlocked" - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + backup_vault_redundancy = "LocallyRedundant" + backup_vault_immutability = "Unlocked" + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags } assert { @@ -78,7 +79,7 @@ run "create_backup_vault" { } } -run "configure_vault_diagnostics_when_enabled" { +run "configure_vault_diagnostics" { command = apply module { @@ -89,62 +90,37 @@ run "configure_vault_diagnostics_when_enabled" { resource_group_name = run.setup_tests.resource_group_name resource_group_location = "uksouth" backup_vault_name = run.setup_tests.backup_vault_name - log_analytics_workspace_id = "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.OperationalInsights/workspaces/workspace1" + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id tags = run.setup_tests.tags } assert { - condition = length(azurerm_monitor_diagnostic_setting.backup_vault) == 1 - error_message = "Backup vault diagnostic settings not as expected." - } - - assert { - condition = azurerm_monitor_diagnostic_setting.backup_vault[0].target_resource_id == azurerm_data_protection_backup_vault.backup_vault.id + condition = azurerm_monitor_diagnostic_setting.backup_vault.target_resource_id == azurerm_data_protection_backup_vault.backup_vault.id error_message = "Backup vault diagnostic setting target resource id not as expected." } assert { - condition = length(azurerm_monitor_diagnostic_setting.backup_vault[0].log_analytics_workspace_id) > 0 + condition = length(azurerm_monitor_diagnostic_setting.backup_vault.log_analytics_workspace_id) > 0 error_message = "Backup vault diagnostic setting log analytics workspace id not as expected." } assert { - condition = length(azurerm_monitor_diagnostic_setting.backup_vault[0].enabled_log) == length(local.backup_vault_diagnostics_log_categories) + condition = length(azurerm_monitor_diagnostic_setting.backup_vault.enabled_log) == length(local.backup_vault_diagnostics_log_categories) error_message = "Backup vault diagnostic setting enabled logs not as expected." } assert { - condition = alltrue([for enabled_log in azurerm_monitor_diagnostic_setting.backup_vault[0].enabled_log : contains(local.backup_vault_diagnostics_log_categories, enabled_log.category)]) + condition = alltrue([for enabled_log in azurerm_monitor_diagnostic_setting.backup_vault.enabled_log : contains(local.backup_vault_diagnostics_log_categories, enabled_log.category)]) error_message = "Backup vault diagnostic setting enabled logs not as expected." } assert { - condition = length(azurerm_monitor_diagnostic_setting.backup_vault[0].enabled_metric) == length(local.backup_vault_diagnostics_metric_categories) + condition = length(azurerm_monitor_diagnostic_setting.backup_vault.enabled_metric) == length(local.backup_vault_diagnostics_metric_categories) error_message = "Backup vault diagnostic setting metrics not as expected." } assert { - condition = alltrue([for metric in azurerm_monitor_diagnostic_setting.backup_vault[0].enabled_metric : contains(local.backup_vault_diagnostics_metric_categories, metric.category)]) + condition = alltrue([for metric in azurerm_monitor_diagnostic_setting.backup_vault.enabled_metric : contains(local.backup_vault_diagnostics_metric_categories, metric.category)]) error_message = "Backup vault diagnostic setting metrics not as expected." } } - -run "configure_vault_diagnostics_when_disabled" { - command = apply - - module { - source = "../../infrastructure" - } - - variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags - } - - assert { - condition = length(azurerm_monitor_diagnostic_setting.backup_vault) == 0 - error_message = "Backup vault diagnostic settings not as expected." - } -} diff --git a/tests/integration-tests/resource_group.tftest.hcl b/tests/integration-tests/resource_group.tftest.hcl index 143f4a1..fd782a1 100644 --- a/tests/integration-tests/resource_group.tftest.hcl +++ b/tests/integration-tests/resource_group.tftest.hcl @@ -16,10 +16,11 @@ run "create_resource_group" { } variables { - resource_group_name = run.setup_tests.resource_group_name - resource_group_location = "uksouth" - backup_vault_name = run.setup_tests.backup_vault_name - tags = run.setup_tests.tags + resource_group_name = run.setup_tests.resource_group_name + resource_group_location = "uksouth" + backup_vault_name = run.setup_tests.backup_vault_name + log_analytics_workspace_id = run.setup_tests.log_analytics_workspace_id + tags = run.setup_tests.tags } assert { diff --git a/tests/integration-tests/setup/main.tf b/tests/integration-tests/setup/main.tf index 3ece428..7986c06 100644 --- a/tests/integration-tests/setup/main.tf +++ b/tests/integration-tests/setup/main.tf @@ -19,6 +19,10 @@ output "backup_vault_name" { value = "bvault-${random_pet.backup_vault_name.id}" } +output "log_analytics_workspace_id" { + value = "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.OperationalInsights/workspaces/workspace1" +} + output "tags" { value = { tagOne = "tagOneValue"