Skip to content

Terraform module overlay to create SCCA compliant Azure Storage to use with Azure NoOps.

License

Notifications You must be signed in to change notification settings

azurenoops/terraform-azurerm-overlays-storage-account

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Storage Account Overlay

Changelog Notice MIT License TF Registry

This Overlay terraform module can create a Storage Account with a set of containers (and access level), set of file shares (and quota), tables, queues, Network policies and Blob lifecycle management and manage related parameters (Threat protection, Network Rules, Private Endpoints, etc.) to be used in a SCCA compliant Network.

To defines the kind of account, set the argument to account_kind = "StorageV2". Account kind defaults to StorageV2. If you want to change this value to other storage accounts kind, then this module automatically computes the appropriate values for account_tier, account_replication_type. The valid options are BlobStorage, BlockBlobStorage, FileStorage, Storage and StorageV2. static_website can only be set when the account_kind is set to StorageV2.

SCCA Compliance

This module can be SCCA compliant and can be used in a SCCA compliant Network. Enable private endpoints and SCCA compliant network rules to make it SCCA compliant.

For more information, please read the SCCA documentation.

Resources Supported

Module Usage

# Azurerm provider configuration
provider "azurerm" {
  features {}
}

Resource Group

By default, this module will not create a resource group and the name of an existing resource group to be given in an argument existing_resource_group_name. If you want to create a new resource group, set the argument create_resource_group = true.

Note

If you are using an existing resource group, then this module uses the same resource group location to create all resources in this module.

Azure File Share Authentication

If you need to enable Active Directory or AAD DS authentication for Azure File on this Storage Account, please read the Microsoft documentation and set the required values in the file_share_authentication variable.

BlockBlobStorage accounts

A BlockBlobStorage account is a specialized storage account in the premium performance tier for storing unstructured object data as block blobs or append blobs. Compared with general-purpose v2 and BlobStorage accounts, BlockBlobStorage accounts provide low, consistent latency and higher transaction rates.

BlockBlobStorage accounts don't currently support tiering to hot, cool, or archive access tiers. This type of storage account does not support page blobs, tables, or queues.

To create BlockBlobStorage accounts, set the argument to account_kind = "BlockBlobStorage".

FileStorage accounts

A FileStorage account is a specialized storage account used to store and create premium file shares. This storage account kind supports files but not block blobs, append blobs, page blobs, tables, or queues.

FileStorage accounts offer unique performance dedicated characteristics such as IOPS bursting. For more information on these characteristics, see the File share storage tiers section of the Files planning guide.

To create BlockBlobStorage accounts, set the argument to account_kind = "FileStorage".

Containers

A container organizes a set of blobs, similar to a directory in a file system. A storage account can include an unlimited number of containers, and a container can store an unlimited number of blobs. The container name must be lowercase.

This module creates the containers based on your input within an Azure Storage Account. Configure the access_type for this Container as per your preference. Possible values are blob, container or private. Preferred Defaults to private.

SMB File Shares

Azure Files offers fully managed file shares in the cloud that are accessible via the industry standard Server Message Block (SMB) protocol. Azure file shares can be mounted concurrently by cloud or on-premises deployments of Windows, Linux, and macOS.

This module creates the SMB file shares based on your input within an Azure Storage Account. Configure the quota for this file share as per your preference. The maximum size of the share, in gigabytes. For Standard storage accounts, this must be greater than 0 and less than 5120 GB (5 TB). For Premium FileStorage storage accounts, this must be greater than 100 GB and less than 102400 GB (100 TB).

Soft delete for Blobs or Containers

Soft delete protects blob data from being accidentally or erroneously modified or deleted. When soft delete is enabled for a storage account, containers, blobs, blob versions, and snapshots in that storage account may be recovered after they are deleted, within a retention period that you specify.

This module allows you to specify the number of days that the blob or container should be retained period using blob_soft_delete_retention_days and container_soft_delete_retention_days arguments between 1 and 365 days. Default is 7 days.

Warning

Container soft delete can restore only whole containers and their contents at the time of deletion. You cannot restore a deleted blob within a container by using container soft delete. Microsoft recommends also enabling blob soft delete and blob versioning to protect individual blobs in a container.

When you restore a container, you must restore it to its original name. If the original name has been used to create a new container, then you will not be able to restore the soft-deleted container.

Configure Azure Storage firewalls and virtual networks

The Azure storage firewall provides access control access for the public endpoints of the storage account. Use network policies to block all access through the public endpoint when using private endpoints. The storage firewall configuration also enables select trusted Azure platform services to access the storage account securely.

The default action set to Allow when no network rules matched. A subnet_ids or ip_rules can be added to network_rules block to allow a request that is not Azure Services.

module "storage" {
  source  = "azurenoops/overlays-storage-account/azurerm"
  version = "x.x.x"

  # .... omitted

  # If specifying network_rules, one of either `ip_rules` or `subnet_ids` must be specified
  network_rules = {
    bypass     = ["AzureServices"]
    # One or more IP Addresses, or CIDR Blocks to access this Key Vault.
    ip_rules   = ["123.201.18.148"]
    # One or more Subnet ID's to access this Key Vault.
    subnet_ids = []
  }

  # .... omitted
  }

Manage the Azure Blob storage lifecycle

Azure Blob storage lifecycle management offers a rich, rule-based policy for General Purpose v2 (GPv2) accounts, Blob storage accounts, and Premium Block Blob storage accounts. Use the policy to transition your data to the appropriate access tiers or expire at the end of the data's lifecycle.

The lifecycle management policy lets you:

  • Transition blobs to a cooler storage tier (hot to cool, hot to archive, or cool to archive) to optimize for performance and cost
  • Delete blobs at the end of their lifecycles
  • Define rules to be run once per day at the storage account level
  • Apply rules to containers or a subset of blobs*

This module supports the implementation of storage lifecycle management. If specifying network_rules, one of either ip_rules or subnet_ids must be specified and default_action must be set to Deny.

module "storage" {
  source  = "azurenoops/overlays-storage-account/azurerm"
  version = "x.x.x"

  # .... omitted

  # Lifecycle management for storage account.
  # Must specify the value to each argument and default is `0`
  lifecycles = [
    {
      prefix_match               = ["mystore250/folder_path"]
      tier_to_cool_after_days    = 0
      tier_to_archive_after_days = 50
      delete_after_days          = 100
      snapshot_delete_after_days = 30
    },
    {
      prefix_match               = ["blobstore251/another_path"]
      tier_to_cool_after_days    = 0
      tier_to_archive_after_days = 30
      delete_after_days          = 75
      snapshot_delete_after_days = 30
    }
  ]

  # .... omitted
  }

Identity - Configure managed identities to access Azure Storage

Managed identities for Azure resources provides Azure services with an automatically managed identity in Azure Active Directory. You can use this identity to authenticate to any service that supports Azure AD authentication, without having credentials in your code.

There are two types of managed identities:

  • System-assigned: When enabled a system-assigned managed identity an identity is created in Azure AD that is tied to the lifecycle of that service instance. when the resource is deleted, Azure automatically deletes the identity. By design, only that Azure resource can use this identity to request tokens from Azure AD.
  • User-assigned: A managed identity as a standalone Azure resource. For User-assigned managed identities, the identity is managed separately from the resources that use it.

Regardless of the type of identity chosen a managed identity is a service principal of a special type that may only be used with Azure resources. When the managed identity is deleted, the corresponding service principal is automatically removed.

resource "azurerm_user_assigned_identity" "example" {
  for_each            = toset(["user-identity1", "user-identity2"])
  resource_group_name = "rg-shared-westeurope-01"
  location            = "westeurope"
  name                = each.key
}

module "storage" {
  source  = "azurenoops/overlays-storage-account/azurerm"
  version = "x.x.x"

  # .... omitted

  # Configure managed identities to access Azure Storage (Optional)
  # Possible types are `SystemAssigned`, `UserAssigned` and `SystemAssigned, UserAssigned`.
  managed_identity_type = "UserAssigned"
  managed_identity_ids  = [for k in azurerm_user_assigned_identity.example : k.id]

# .... omitted for bravity

}

Recommended naming and tagging conventions

Applying tags to your Azure resources, resource groups, and subscriptions to logically organize them into a taxonomy. Each tag consists of a name and a value pair. For example, you can apply the name Environment and the value Production to all the resources in production. For recommendations on how to implement a tagging strategy, see Resource naming and tagging decision guide.

Important

Tag names are case-insensitive for operations. A tag with a tag name, regardless of the casing, is updated or retrieved. However, the resource provider might keep the casing you provide for the tag name. You'll see that casing in cost reports. Tag values are case-sensitive.

An effective naming convention assembles resource names by using important resource information as parts of a resource's name. For example, using these recommended naming conventions, a public IP resource for a production SharePoint workload is named like this: pip-sharepoint-prod-westus-001.

Optional Features

Storage Account Overlay has optional features that can be enabled by setting parameters on the deployment.

Create resource group

By default, this module will create a resource group and the name of the resource group to be given in an argument resource_group_name located in variables.naming.tf. If you want to use an existing resource group, specify the existing resource group name, and set the argument to create_resource_group = false.

Note: If you are using an existing resource group, then this module uses the same resource group location to create all resources in this module.

Requirements

Name Version
terraform >= 1.3
azurenoopsutils ~> 1.0.4
azurerm ~> 3.22

Providers

Name Version
azurenoopsutils ~> 1.0.4
azurerm ~> 3.22

Modules

Name Source Version
mod_azure_region_lookup azurenoops/overlays-azregions-lookup/azurerm ~> 1.0

Resources

Name Type
azurerm_advanced_threat_protection.example resource
azurerm_management_lock.resource_group_level_lock resource
azurerm_private_dns_a_record.a_record resource
azurerm_private_dns_zone.dns_zone resource
azurerm_private_dns_zone_virtual_network_link.vnet_link resource
azurerm_private_endpoint.pep resource
azurerm_resource_group.rg resource
azurerm_storage_account.storage resource
azurerm_storage_account_network_rules.network_rules resource
azurerm_storage_container.container resource
azurerm_storage_management_policy.lcpolicy resource
azurerm_storage_queue.queue resource
azurerm_storage_share.share resource
azurerm_storage_table.table resource
azurenoopsutils_resource_name.sa data source
azurerm_private_endpoint_connection.pip data source
azurerm_virtual_network.vnet data source

Inputs

Name Description Type Default Required
access_tier Defines the access tier for BlobStorage, FileStorage and StorageV2 accounts. Valid options are Hot and Cool, defaults to Hot. string "Hot" no
account_kind Defines the Kind of account. Valid options are BlobStorage, BlockBlobStorage, FileStorage, Storage and StorageV2. Changing this forces a new resource to be created. Defaults to StorageV2. string "StorageV2" no
account_replication_type Defines the type of replication to use for this Storage Account. Valid options are LRS, GRS, RAGRS, ZRS, GZRS and RAGZRS. string "ZRS" no
account_tier Defines the Tier to use for this Storage Account. Valid options are Standard and Premium. For BlockBlobStorage and FileStorage accounts only Premium is valid. Changing this forces a new resource to be created. string "Standard" no
add_tags Map of custom tags. map(string) {} no
advanced_threat_protection_enabled Boolean flag which controls if advanced threat protection is enabled, see documentation for more information. bool false no
allowed_cidrs List of CIDR to allow access to that Storage Account. list(string) [] no
containers List of objects to create some Blob containers in this Storage Account.
list(object({
name = string
container_access_type = optional(string)
metadata = optional(map(string))
}))
[] no
create_storage_account_resource_group Should the storage account be created in a separate resource group? bool false no
custom_domain_name The Custom Domain Name to use for the Storage Account, which will be validated by Azure. string null no
default_firewall_action Which default firewalling policy to apply. Valid values are Allow or Deny. string "Deny" no
default_tags_enabled Option to enable or disable default tags. bool true no
deploy_environment Name of the workload's environnement string n/a yes
enable_advanced_threat_protection Threat detection policy configuration, known in the API as Server Security Alerts Policy. Currently available only for the SQL API. bool false no
enable_blob_private_endpoint Manages a Private Endpoint to Azure Storage Account for Blob bool false no
enable_resource_locks (Optional) Enable resource locks bool false no
enable_table_private_endpoint Manages a Private Endpoint to Azure Storage Account for Tables bool false no
environment The Terraform backend environment e.g. public or usgovernment string n/a yes
existing_private_dns_zone Name of the existing private DNS zone any null no
existing_subnet_id ID of the existing subnet any null no
file_share_authentication Storage Account file shares authentication configuration.
object({
directory_type = string
active_directory = optional(object({
storage_sid = string
domain_name = string
domain_sid = string
domain_guid = string
forest_name = string
netbios_domain_name = string
}))
})
null no
file_share_cors_rules Storage Account file shares CORS rule. Please refer to the documentation for more information.
object({
allowed_headers = list(string)
allowed_methods = list(string)
allowed_origins = list(string)
exposed_headers = list(string)
max_age_in_seconds = number
})
null no
file_share_properties_smb Storage Account file shares smb properties.
object({
versions = optional(list(string), null)
authentication_types = optional(list(string), null)
kerberos_ticket_encryption_type = optional(list(string), null)
channel_encryption_type = optional(list(string), null)
multichannel_enabled = optional(bool, null)
})
null no
file_share_retention_policy_in_days Storage Account file shares retention policy in days. number null no
file_shares List of objects to create some File Shares in this Storage Account.
list(object({
name = string
quota_in_gb = number
enabled_protocol = optional(string)
metadata = optional(map(string))
acl = optional(list(object({
id = string
permissions = string
start = optional(string)
expiry = optional(string)
})))
}))
[] no
hns_enabled Is Hierarchical Namespace enabled? This can be used with Azure Data Lake Storage Gen 2 and must be true if nfsv3_enabled is set to true. Changing this forces a new resource to be created. bool false no
https_traffic_only_enabled Boolean flag which forces HTTPS if enabled. bool true no
identity_ids Specifies a list of User Assigned Managed Identity IDs to be assigned to this Storage Account. list(string) null no
identity_type Specifies the type of Managed Service Identity that should be configured on this Storage Account. Possible values are SystemAssigned, UserAssigned, SystemAssigned, UserAssigned (to enable both). string "SystemAssigned" no
lifecycles Configure Azure Storage firewalls and virtual networks list(object({ prefix_match = set(string), tier_to_cool_after_days = number, tier_to_archive_after_days = number, delete_after_days = number, snapshot_delete_after_days = number })) [] no
location Azure region in which instance will be hosted string n/a yes
lock_level (Optional) id locks are enabled, Specifies the Level to be used for this Lock. string "CanNotDelete" no
min_tls_version The minimum supported TLS version for the Storage Account. Possible values are TLS1_0, TLS1_1, and TLS1_2. string "TLS1_2" no
name_prefix Optional prefix for the generated name string "" no
name_suffix Optional suffix for the generated name string "" no
network_bypass Specifies whether traffic is bypassed for 'Logging', 'Metrics', 'AzureServices' or 'None'. list(string)
[
"Logging",
"Metrics",
"AzureServices"
]
no
network_rules_enabled Boolean to enable Network Rules on the Storage Account, requires network_bypass, allowed_cidrs, subnet_ids or default_firewall_action correctly set if enabled. bool true no
nfsv3_enabled Is NFSv3 protocol enabled? Changing this forces a new resource to be created. bool false no
org_name Name of the organization string n/a yes
public_nested_items_allowed Allow or disallow nested items within this Account to opt into being public. bool false no
queue_properties_logging Logging queue properties
object({
delete = optional(bool, true)
read = optional(bool, true)
write = optional(bool, true)
version = optional(string, "1.0")
retention_policy_days = optional(number, 10)
})
{} no
queues List of objects to create some Queues in this Storage Account.
list(object({
name = string
metadata = optional(map(string))
}))
[] no
resource_group_name Name of the workload ressource group string n/a yes
shared_access_key_enabled Indicates whether the Storage Account permits requests to be authorized with the account access key via Shared Key. If false, then all requests, including shared access signatures, must be authorized with Azure Active Directory (Azure AD). bool true no
static_website_config Static website configuration. Can only be set when the account_kind is set to StorageV2 or BlockBlobStorage.
object({
index_document = optional(string)
error_404_document = optional(string)
})
null no
storage_account_custom_name Custom Azure Storage Account name, generated if not set string "" no
storage_blob_cors_rule Storage Account blob CORS rule. Please refer to the documentation for more information.
object({
allowed_headers = list(string)
allowed_methods = list(string)
allowed_origins = list(string)
exposed_headers = list(string)
max_age_in_seconds = number
})
null no
storage_blob_data_protection Storage account blob Data protection parameters.
object({
change_feed_enabled = optional(bool, false)
versioning_enabled = optional(bool, false)
delete_retention_policy_in_days = optional(number, 0)
container_delete_retention_policy_in_days = optional(number, 0)
container_point_in_time_restore = optional(bool, false)
})
{
"change_feed_enabled": true,
"container_delete_retention_policy_in_days": 30,
"container_point_in_time_restore": true,
"delete_retention_policy_in_days": 30,
"versioning_enabled": true
}
no
subnet_ids Subnets to allow access to that Storage Account. list(string) [] no
tables List of objects to create some Tables in this Storage Account.
list(object({
name = string
acl = optional(list(object({
id = string
permissions = string
start = optional(string)
expiry = optional(string)
})))
}))
[] no
use_naming Use the Azure NoOps naming provider to generate default resource name. storage_account_custom_name override this if set. Legacy default name is used if this is set to false. bool true no
use_subdomain Should the Custom Domain Name be validated by using indirect CNAME validation? bool false no
virtual_network_name The name of the virtual network string "" no
workload_name Name of the workload_name string n/a yes

Outputs

Name Description
storage_account_id Created Storage Account ID
storage_account_identity Created Storage Account identity block
storage_account_name Created Storage Account name
storage_account_network_rules Network rules of the associated Storage Account
storage_account_properties Created Storage Account properties
storage_account_uri Created Storage Account name
storage_blob_containers Created blob containers in the Storage Account
storage_file_queues Created queues in the Storage Account
storage_file_shares Created file shares in the Storage Account
storage_file_tables Created tables in the Storage Account
terraform_module Information about this Terraform module

About

Terraform module overlay to create SCCA compliant Azure Storage to use with Azure NoOps.

Resources

License

Security policy

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •