Deploy Azure Recovery Services Vault with LRS and GRS Using Terraform
Deploying Azure Recovery Services Vault with LRS and GRS Using Terraform
Introduction
Microsoft Azure Recovery Services Vault is a vital component for managing and safeguarding data in the cloud, offering robust, scalable, and secure solutions for backing up and restoring infrastructure. In this guide, we'll explore how to deploy an Azure Recovery Services Vault using Terraform, configure private endpoints, customize backup policies, and choose between Locally Redundant Storage (LRS) and Geo-Redundant Storage (GRS).
Why Choose Different SKUs, Private Endpoints, and Redundancy Options?
When deploying Azure Recovery Services Vault, selecting the right configuration is essential for data resilience and access control. Here’s a brief overview:
- Locally Redundant Storage (LRS): Stores data within a single data center or availability zone. It's the default, cost-effective option but provides minimal resilience during a data center outage.
- Geo Redundant Storage (GRS): Replicates data across geographically separated data centers, ensuring high availability and durability at a higher cost.
Private Endpoints: Establish a private connection between the vault and a subnet within a virtual network to secure traffic within the Azure backbone.
Prerequisites
Before proceeding, ensure the following:
- An active Azure subscription.
- Terraform installed on your local machine.
- Basic knowledge of Terraform and Azure.
Step 1: Set Up the Terraform Module Structure
Create a directory for the module and include these files:
- main.tf: Defines the resources.
- variables.tf: Holds input variables.
- outputs.tf: Manages output variables.
- data.tf: Retrieves existing networking resources (e.g., VNet and subnet).
Tip: A separate data.tf
file helps leverage existing networking infrastructure, simplifying the code and maintaining consistency across deployments.
Using Data Sources in Terraform: Utilizing azurerm_subnet
and azurerm_virtual_network
data sources in data.tf
ensures efficient use of existing VNets and subnets, streamlining deployments and maintaining compliance.
More details on using data sources in Terraform can be found here.
Step 2: Define Resources in main.tf
Here's a breakdown of what main.tf
should include:
-
Provider Configuration:
provider "azurerm" { features {} }
-
Resource Group and Recovery Services Vault:
resource "azurerm_resource_group" "example" { name = var.resource_group_name location = var.location } resource "azurerm_recovery_services_vault" "example" { name = "example-recovery-vault" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name sku = var.vault_sku storage_mode_type = var.storage_mode_type }
-
Custom Backup Policies:
locals { recovery_vault_name = azurerm_recovery_services_vault.example.name timezone = "AUS Eastern Standard Time" backup_policies = { daily_weekly_monthly_yearly1 = { frequency = "Daily" time = "23:00" retention_daily = 35 retention_weekly = 90 retention_monthly = 12 retention_yearly = 10 } daily_weekly_monthly_yearly2 = { frequency = "Daily" time = "23:00" retention_daily = 14 retention_weekly = 30 retention_monthly = 3 retention_yearly = 7 } daily_weekly_monthly_yearly3 = { frequency = "Daily" time = "22:00" retention_daily = 7 retention_weekly = 14 retention_monthly = 2 retention_yearly = 5 } } } resource "azurerm_backup_policy_file_share" "example" { for_each = local.backup_policies name = each.key resource_group_name = azurerm_resource_group.example.name recovery_vault_name = local.recovery_vault_name timezone = local.timezone backup { frequency = each.value.frequency time = each.value.time } retention_daily { count = each.value.retention_daily } retention_weekly { weekdays = ["Sunday"] count = each.value.retention_weekly } retention_monthly { weekdays = ["Sunday"] weeks = ["First"] count = each.value.retention_monthly } retention_yearly { count = each.value.retention_yearly weekdays = ["Sunday"] weeks = ["First"] months = toset(["January"]) } }
Important Note: The retention_yearly
block with months = ["January"]
ensures specific backups are retained for long-term retention, ideal for compliance with regulatory requirements.
4. Define the Private Endpoint:
resource "azurerm_private_endpoint" "example" {
name = "example-private-endpoint"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
subnet_id = data.azurerm_subnet.example.id
private_service_connection {
name = "example-private-connection"
is_manual_connection = false
private_connection_resource_id = azurerm_recovery_services_vault.example.id
subresource_names = ["AzureBackup"]
}
}
```
Step 3: Define Variables and Data Sources
variables.tf:
variable "vault_name" {
description = "The name of the Recovery Services Vault"
type = string
default = "myrsv-01"
}
variable "location" {
description = "The location of the Recovery Services Vault"
type = string
default = "Australia East"
}
variable "resource_group_name" {
description = "The name of the resource group"
type = string
default = "myTFResourceGroup1"
}
variable "vault_sku" {
description = "The SKU of the Recovery Services Vault. Possible values are Standard and Premium."
type = string
default = "Standard"
}
variable "storage_mode_type" {
description = "The storage type of the Recovery Services Vault."
type = string
default = "ZoneRedundant"
}
```
data.tf:
data "azurerm_virtual_network" "example" {
name = "example-vnet"
resource_group_name = "myTFResourceGroup"
}
data "azurerm_subnet" "example" {
name = "example-subnet"
virtual_network_name = data.azurerm_virtual_network.example.name
resource_group_name = "myTFResourceGroup"
}
```
Step 4: Define Outputs for Enhanced Visibility
outputs.tf:
output "recovery_services_vault_id" {
value = azurerm_recovery_services_vault.example.id
description = "The ID of the Recovery Services Vault"
}
output "private_endpoint_id" {
value = azurerm_private_endpoint.example.id
description = "The ID of the private endpoint"
}
output "private_endpoint_fqdn" {
value = azurerm_private_endpoint.example.private_service_connection[0].private_endpoint_fqdn
description = "The FQDN of the private endpoint"
}
output "private_endpoint_ip_address" {
value = azurerm_private_endpoint.example.private_service_connection[0].private_ip_address
description = "The private IP address of the private endpoint"
}
output "vault_soft_delete_enabled" {
value = azurerm_recovery_services_vault.example.soft_delete_enabled
description = "Indicates if soft delete is enabled for the Recovery Services Vault"
}
output "vault_enabled_features" {
value = azurerm_recovery_services_vault.example.enabled_features
description = "A list of enabled features for the Recovery Services Vault"
}
output "vault_minimum_tls_version" {
value = azurerm_recovery_services_vault.example.minimum_tls_version
description = "The minimum TLS version required for the Recovery Services Vault"
}
```
Conclusion
By following these steps, you have created a reusable Terraform module that deploys an Azure Recovery Services Vault with private endpoints and custom backup policies. The module supports LRS by default but allows switching to GRS when needed, ensuring data protection and business continuity.