Managing Azure Storage Account with Terraform
Learn how to set up and manage Azure Storage Account using Terraform, including blobs, files, queues, and tables
Managing Azure Storage Account with Terraform
Azure Storage Account is a foundational service that provides scalable and secure storage in the cloud. This guide demonstrates how to set up and manage Storage Account using Terraform.
Video Tutorial
Learn more about managing Azure Storage with Terraform in this comprehensive video tutorial:
Prerequisites
- Azure CLI configured with appropriate permissions
- Terraform installed (version 1.0.0 or later)
- Resource group created
- Understanding of storage concepts
Project Structure
terraform-azure-storage/
├── main.tf
├── variables.tf
├── outputs.tf
├── modules/
│ └── storage/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── policies/
└── lifecycle.json
Storage Account Configuration
Create modules/storage/main.tf
:
# Storage Account
resource "azurerm_storage_account" "main" {
name = "${var.project_name}storage"
resource_group_name = var.resource_group_name
location = var.location
account_tier = "Standard"
account_replication_type = "GRS"
account_kind = "StorageV2"
enable_https_traffic_only = true
min_tls_version = "TLS1_2"
allow_nested_items_to_be_public = false
network_rules {
default_action = "Deny"
ip_rules = var.allowed_ips
virtual_network_subnet_ids = [azurerm_subnet.storage.id]
bypass = ["AzureServices"]
}
blob_properties {
versioning_enabled = true
change_feed_enabled = true
last_access_time_enabled = true
container_delete_retention_policy {
days = 7
}
delete_retention_policy {
days = 30
}
}
queue_properties {
logging {
delete = true
read = true
write = true
version = "2.0"
retention_policy_days = 10
}
}
static_website {
index_document = "index.html"
error_404_document = "404.html"
}
identity {
type = "SystemAssigned"
}
customer_managed_key {
key_vault_key_id = azurerm_key_vault_key.storage.id
user_assigned_identity_id = azurerm_user_assigned_identity.storage.id
}
tags = var.tags
}
# Blob Container
resource "azurerm_storage_container" "data" {
name = "data"
storage_account_name = azurerm_storage_account.main.name
container_access_type = "private"
metadata = {
environment = var.environment
}
}
# File Share
resource "azurerm_storage_share" "documents" {
name = "documents"
storage_account_name = azurerm_storage_account.main.name
quota = 50
acl {
id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI"
access_policy {
permissions = "rwdl"
start = "2025-01-01T00:00:00.0000000Z"
expiry = "2025-12-31T00:00:00.0000000Z"
}
}
}
# Queue
resource "azurerm_storage_queue" "messages" {
name = "messages"
storage_account_name = azurerm_storage_account.main.name
metadata = {
environment = var.environment
}
}
# Table
resource "azurerm_storage_table" "configuration" {
name = "configuration"
storage_account_name = azurerm_storage_account.main.name
}
# Management Policy
resource "azurerm_storage_management_policy" "lifecycle" {
storage_account_id = azurerm_storage_account.main.id
rule {
name = "cleanupOldBlobs"
enabled = true
filters {
prefix_match = ["data/archive"]
blob_types = ["blockBlob"]
}
actions {
base_blob {
tier_to_cool_after_days_since_modification_greater_than = 90
tier_to_archive_after_days_since_modification_greater_than = 180
delete_after_days_since_modification_greater_than = 365
}
snapshot {
delete_after_days_since_creation_greater_than = 30
}
version {
delete_after_days_since_creation = 90
}
}
}
}
Network Configuration
- Virtual Network Integration
resource "azurerm_virtual_network" "main" {
name = "${var.project_name}-vnet"
location = var.location
resource_group_name = var.resource_group_name
address_space = ["10.0.0.0/16"]
subnet {
name = "storage-subnet"
address_prefix = "10.0.1.0/24"
service_endpoints = ["Microsoft.Storage"]
}
tags = var.tags
}
resource "azurerm_private_endpoint" "storage" {
name = "${var.project_name}-pe"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = azurerm_subnet.endpoints.id
private_service_connection {
name = "${var.project_name}-psc"
private_connection_resource_id = azurerm_storage_account.main.id
is_manual_connection = false
subresource_names = ["blob", "file", "queue", "table"]
}
private_dns_zone_group {
name = "default"
private_dns_zone_ids = [
azurerm_private_dns_zone.blob.id,
azurerm_private_dns_zone.file.id,
azurerm_private_dns_zone.queue.id,
azurerm_private_dns_zone.table.id
]
}
}
resource "azurerm_private_dns_zone" "blob" {
name = "privatelink.blob.core.windows.net"
resource_group_name = var.resource_group_name
}
resource "azurerm_private_dns_zone" "file" {
name = "privatelink.file.core.windows.net"
resource_group_name = var.resource_group_name
}
resource "azurerm_private_dns_zone" "queue" {
name = "privatelink.queue.core.windows.net"
resource_group_name = var.resource_group_name
}
resource "azurerm_private_dns_zone" "table" {
name = "privatelink.table.core.windows.net"
resource_group_name = var.resource_group_name
}
Security Configuration
- Role Assignments
resource "azurerm_role_assignment" "storage_blob_contributor" {
scope = "${azurerm_storage_account.main.id}/blobServices/default/containers/data"
role_definition_name = "Storage Blob Data Contributor"
principal_id = var.contributor_principal_id
}
resource "azurerm_role_assignment" "storage_queue_contributor" {
scope = "${azurerm_storage_account.main.id}/queueServices/default/queues/messages"
role_definition_name = "Storage Queue Data Contributor"
principal_id = var.contributor_principal_id
}
- Encryption Configuration
resource "azurerm_storage_account_customer_managed_key" "main" {
storage_account_id = azurerm_storage_account.main.id
key_vault_id = azurerm_key_vault.main.id
key_name = azurerm_key_vault_key.storage.name
}
resource "azurerm_key_vault_key" "storage" {
name = "${var.project_name}-key"
key_vault_id = azurerm_key_vault.main.id
key_type = "RSA"
key_size = 2048
key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
}
Monitoring Configuration
- Diagnostic Settings
resource "azurerm_monitor_diagnostic_setting" "storage" {
name = "${var.project_name}-diag"
target_resource_id = azurerm_storage_account.main.id
log_analytics_workspace_id = var.log_analytics_workspace_id
metric {
category = "Transaction"
enabled = true
retention_policy {
enabled = true
days = 30
}
}
metric {
category = "Capacity"
enabled = true
retention_policy {
enabled = true
days = 30
}
}
}
resource "azurerm_monitor_metric_alert" "storage" {
name = "${var.project_name}-capacity-alert"
resource_group_name = var.resource_group_name
scopes = [azurerm_storage_account.main.id]
description = "Alert when storage capacity is high"
criteria {
metric_namespace = "Microsoft.Storage/storageAccounts"
metric_name = "UsedCapacity"
aggregation = "Average"
operator = "GreaterThan"
threshold = 85
}
action {
action_group_id = var.action_group_id
}
}
Advanced Features
- Object Replication
resource "azurerm_storage_object_replication" "main" {
source_storage_account_id = azurerm_storage_account.source.id
destination_storage_account_id = azurerm_storage_account.destination.id
rules {
source_container_name = azurerm_storage_container.source.name
destination_container_name = azurerm_storage_container.destination.name
copy_blobs_created_after = "2025-01-01T00:00:00Z"
filters {
prefix_match = ["data/"]
blob_types = ["blockBlob"]
}
}
}
- CORS Configuration
resource "azurerm_storage_account" "cors" {
# ... other configuration ...
blob_properties {
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET", "POST"]
allowed_origins = ["https://example.com"]
exposed_headers = ["*"]
max_age_in_seconds = 3600
}
}
}
Best Practices
-
Performance
- Choose appropriate tier
- Enable CDN for static content
- Configure caching
- Use appropriate replication
-
Security
- Enable encryption
- Use private endpoints
- Implement RBAC
- Configure firewalls
-
Cost Optimization
- Use appropriate tier
- Implement lifecycle management
-
Data Protection
- Enable soft delete
- Configure backup
- Use versioning
- Implement replication
Conclusion
You’ve learned how to set up and manage Azure Storage Account using Terraform. This setup provides:
- Secure storage solution
- Multiple storage services
- Network isolation
- Data protection
Remember to:
- Monitor capacity usage
- Review security settings
- Manage lifecycle policies
- Update access controls