Skip to content

ultratendency/terraform-azurerm-secure-storage-account

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Secure Storage Account Terraform module

Quality Gate Status

Terraform module which creates a Storage Account on Azure with secure defaults.

Usage

The simplest usage of this module is shown below. It requires a few parameters to passed in and already uses the recommended default configuraton values. Please note that the resource group used for the deployment will not be created by this module.

data "azurerm_resource_group" "tstate" {
  name = "tstate"
}

module "terraform_state_storage_account" {
  source  = "ultratendency/secure-storage-account/azurerm"
  version = "4.0.0"

  storage_account_name                = "tstate"
  storage_account_resource_group_name = data.azurerm_resource_group.tstate.name
  storage_account_location            = "westeurope"
  storage_container_name              = "tstate"
  key_vault_name                      = "tstate-vault"
  key_vault_key_name                  = "tstate-vault-key"
  key_vault_key_expiration_date       = "2023-12-30T20:00:00Z"
}

A complete example looks like the following, where all inputs are configured. Please note that the following is only a descriptive example and does not follow recommended configuration values.

data "azurerm_resource_group" "tstate" {
  name = "tstate"
}

module "terraform_state_storage_account" {
  source  = "ultratendency/secure-storage-account/azurerm"
  version = "4.0.0"

  storage_account_name                                                   = "tstate"
  storage_account_resource_group_name                                    = data.azurerm_resource_group.tstate.name
  storage_account_location                                               = "westeurope"
  storage_account_account_tier                                           = "Premium"
  storage_account_account_replication_type                               = "GRS"
  storage_account_min_tls_version                                        = "TLS1_1"
  storage_account_https_traffic_only_enabled                             = false
  storage_account_queue_encryption_key_type                              = "Account"
  storage_account_table_encryption_key_type                              = "Account"
  storage_account_infrastructure_encryption_enabled                      = true
  storage_account_allow_nested_items_to_be_public                        = true
  storage_account_shared_access_key_enabled                              = true
  storage_account_queue_properties_logging_delete                        = false
  storage_account_queue_properties_logging_read                          = false
  storage_account_queue_properties_logging_write                         = false
  storage_account_queue_properties_logging_version                       = "1.0"
  storage_account_queue_properties_logging_retention_policy_days         = 20
  storage_account_queue_properties_hour_metrics_include_apis             = false
  storage_account_queue_properties_hour_metrics_version                  = "1.0"
  storage_account_queue_properties_hour_metrics_retention_policy_days    = 20
  storage_account_queue_properties_minute_metrics_include_apis           = false
  storage_account_queue_properties_minute_metrics_version                = "1.0"
  storage_account_queue_properties_minute_metrics_retention_policy_days  = 20
  storage_account_blob_properties_change_feed_enabled                    = false
  storage_account_blob_properties_change_feed_retention_in_days          = 14
  storage_account_blob_properties_versioning_enabled                     = false
  storage_account_blob_properties_container_delete_retention_policy_days = 14
  storage_account_blob_properties_delete_retention_policy_days           = 14

  storage_container_name                  = "tstate"
  storage_container_container_access_type = "blob"

  key_vault_name                       = "tstate-vault"
  key_vault_sku_name                   = "premium"
  key_vault_enable_rbac_authorization  = false
  key_vault_purge_protection_enabled   = false
  key_vault_soft_delete_retention_days = 7

  key_vault_key_name            = "tstate-vault-key"
  key_vault_key_key_type        = "EC"
  key_vault_key_key_size        = "1024"
  key_vault_key_key_opts        = ["decrypt", "encrypt", "sign", "unwrapKey", "verify"]
  key_vault_key_expiration_date = "2023-12-30T20:00:00Z"
}

Microsoft Entra user account as the authentication method

When leaving the variable storage_account_shared_access_key_enabled with the default value false shared access keys are turned off on the storage account. This needs some configuration on the storage account itself, as outlined below

Permissions

The user principal running Terraform needs to have the Storage Blob Data Contributor role assigned. Please note that having the Owner or Contributor role assigned is not sufficient as the user prinicipal needs one of the Storage Blob Data xxx roles to access data within the storage blob.

Permissions can also directly assigned via the storage_account_role_assignments variable (or the respective key_vault_role_assignments variable for the Key Vault), similar to the following example

...
storage_account_role_assignments = {
  user_1 = {
    principal_id         = "123"
    role_definition_name = "Storage Blob Data Contributor"
  }
  user_2 = {
    principal_id         = "456"
    role_definition_name = "Storage Blob Data Contributor"
  }
}
...

Storage Container configuration

With the use of storage_account_shared_access_key_enabled the authentication method for the storage container will be switched to Microsoft Entra user account. Ensure that this change happened.

Terraform backend configuration

The recommended usage for the storage account as a Terraform backend is to use the authentication method Service Principal or User Assigned Managed Identity via OIDC (Workload identity federation) with Azure AD as the storage account authentication type. To configure both, the Terraform backend should contain the following configuration values

...
use_azuread_auth = true,
use_oidc         = true,
...

A complete Terraform backend configuration would look like the following

terraform {
  backend "azurerm" {
    resource_group_name  = "tstate"
    storage_account_name = "tstate"
    container_name       = "tstate"
    key                  = "terraform.tfstate"
    use_azuread_auth     = true
    use_oidc             = true
  }
}

For a detailed look into available options, see the available configuration options.

Terraform provider configuration

To let the Terraform provider access the storage account without a shared access key, the following configuration needs to be set on the provider

...
storage_use_azuread = true
...

A complete Terraform provider configuration would look like the following

provider "azurerm" {
  use_oidc            = true
  storage_use_azuread = true
  features {}
}

Requirements

Name Version
terraform >= 1.0
azurerm >= 4.9.0

Providers

Name Version
azurerm >= 4.9.0

Resources

Name Type
azurerm_key_vault.this resource
azurerm_key_vault_key.this resource
azurerm_role_assignment.this_key_vault resource
azurerm_role_assignment.this_storage_account resource
azurerm_storage_account.this resource
azurerm_storage_account_queue_properties.this resource
azurerm_storage_container.this resource
azurerm_client_config.current data source

Inputs

Name Description Type Default Required
key_vault_enable_rbac_authorization (optional) Indicates whether the key vault uses Role Based Access Control (RBAC) for authorization of data actions bool true no
key_vault_key_expiration_date Expiration UTC datetime of the key vault key string n/a yes
key_vault_key_key_opts (optional) A list of JSON web key operations list(string)
[
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey"
]
no
key_vault_key_key_size (optional) The size of the RSA key to create in bytes number 4096 no
key_vault_key_key_type (optional) The key type to use for this key vault key string "RSA" no
key_vault_key_name The name of the key vault key string n/a yes
key_vault_name The name of the key vault string n/a yes
key_vault_purge_protection_enabled (optional) Indicates whether purge protection is enabled for the key vault bool true no
key_vault_role_assignments (optional) A map of role assignments to be created for the key vault
map(object({
principal_id = string
role_definition_name = string
}))
{} no
key_vault_sku_name (optiona) The name of the SKU used for the key vault string "standard" no
key_vault_soft_delete_retention_days (optional) The number of days that items should be retained for once soft-deleted number 90 no
storage_account_account_replication_type (optional) The type of replication to use for this storage account string "LRS" no
storage_account_account_tier (optional) The tier to use for this storage account string "Standard" no
storage_account_allow_nested_items_to_be_public (optional) Allow or disallow nested items within this storage account to opt into being public bool false no
storage_account_blob_properties_change_feed_enabled (optional) Indicates whether the blob service properties for change feeds are enabled bool true no
storage_account_blob_properties_change_feed_retention_in_days (optional) The number of days that change feed eents will be retained number 7 no
storage_account_blob_properties_container_delete_retention_policy_days (optional) The number of days that the container should be retained number 7 no
storage_account_blob_properties_delete_retention_policy_days (optional) The number of days that the blob should be retained number 7 no
storage_account_blob_properties_versioning_enabled (optional) Indicates whether versioning is enabled bool true no
storage_account_https_traffic_only_enabled (optional) Boolean flag which forces HTTPS if enabled bool true no
storage_account_infrastructure_encryption_enabled (optional) Boolean flag which forces infrastructure encryption bool false no
storage_account_location The location of the storage account string n/a yes
storage_account_min_tls_version (optional) The minimum supported TLS version for this storage account string "TLS1_2" no
storage_account_name The name of the storage sccount string n/a yes
storage_account_queue_encryption_key_type (optional) The encryption of the queue service string "Service" no
storage_account_queue_properties_hour_metrics_include_apis (optional) Indicates whether metrics should generate summary statistics for called API operations bool true no
storage_account_queue_properties_hour_metrics_retention_policy_days (optional) The number of days that logs will be retained number 10 no
storage_account_queue_properties_hour_metrics_version (optional) The version of the storage analytics to configure string "1.0" no
storage_account_queue_properties_logging_delete (optional) Indicates whether all delete requests should be logged bool true no
storage_account_queue_properties_logging_read (optional) Indicates whether all read requests should be logged bool true no
storage_account_queue_properties_logging_retention_policy_days (optional) The number of days that logs will be retained number 10 no
storage_account_queue_properties_logging_version (optional) The version of storage analytics to configure string "1.0" no
storage_account_queue_properties_logging_write (optional) Indicates whether all write requests should be logged bool true no
storage_account_queue_properties_minute_metrics_include_apis (optional) Indicates whether metrics should generate summary statistics for called API operations bool true no
storage_account_queue_properties_minute_metrics_retention_policy_days (optional) The number of days that logs will be retained number 10 no
storage_account_queue_properties_minute_metrics_version (optional) The version of storage analytics to configure string "1.0" no
storage_account_resource_group_name The name of the resource group to use string n/a yes
storage_account_role_assignments (optional) A map of role assignments to be created for the storage account
map(object({
principal_id = string
role_definition_name = string
}))
{} no
storage_account_shared_access_key_enabled (optional) Indicates whether the storage account permits requests to be authorized with the account access key bool false no
storage_account_table_encryption_key_type (optional) The encryption type of the table service string "Service" no
storage_container_container_access_type (optional) The access level configured for the container string "private" no
storage_container_name The name of the container which should be created within the storage account string n/a yes
tags General variables map(string) {} no

Outputs

Name Description
azurerm_key_vault_id The ID of the key vault
azurerm_key_vault_key_id The ID of the key vault key
azurerm_storage_account_id The ID of the storage account
azurerm_storage_container_id The ID of the storage container

Examples

An simple example of the default configuration can be found below:

provider "azurerm" {
  features {}
}

data "azurerm_resource_group" "tstate" {
  name = "tstate"
}

module "terraform_state_storage_account" {
  source  = "ultratendency/secure-storage-account/azurerm"
  version = "4.0.0"

  storage_account_name                = "tstate"
  storage_account_resource_group_name = data.azurerm_resource_group.tstate.name
  storage_account_location            = "westeurope"
  storage_container_name              = "tstate"
  key_vault_name                      = "tstate-vault"
  key_vault_key_name                  = "tstate-vault-key"
  key_vault_key_expiration_date       = "2023-12-30T20:00:00Z"
}

A more complex example can be found below:

provider "azurerm" {
  features {}
}

data "azurerm_resource_group" "tstate" {
  name = "tstate"
}

module "terraform_state_storage_account" {
  source  = "ultratendency/secure-storage-account/azurerm"
  version = "4.0.0"

  storage_account_name                                                   = "tstate"
  storage_account_resource_group_name                                    = data.azurerm_resource_group.tstate.name
  storage_account_location                                               = "westeurope"
  storage_account_account_tier                                           = "Premium"
  storage_account_account_replication_type                               = "GRS"
  storage_account_min_tls_version                                        = "TLS1_1"
  storage_account_https_traffic_only_enabled                             = false
  storage_account_queue_encryption_key_type                              = "Account"
  storage_account_table_encryption_key_type                              = "Account"
  storage_account_infrastructure_encryption_enabled                      = true
  storage_account_allow_nested_items_to_be_public                        = true
  storage_account_shared_access_key_enabled                              = true
  storage_account_queue_properties_logging_delete                        = false
  storage_account_queue_properties_logging_read                          = false
  storage_account_queue_properties_logging_write                         = false
  storage_account_queue_properties_logging_version                       = "1.0"
  storage_account_queue_properties_logging_retention_policy_days         = 20
  storage_account_queue_properties_hour_metrics_include_apis             = false
  storage_account_queue_properties_hour_metrics_version                  = "1.0"
  storage_account_queue_properties_hour_metrics_retention_policy_days    = 20
  storage_account_queue_properties_minute_metrics_include_apis           = false
  storage_account_queue_properties_minute_metrics_version                = "1.0"
  storage_account_queue_properties_minute_metrics_retention_policy_days  = 20
  storage_account_blob_properties_change_feed_enabled                    = false
  storage_account_blob_properties_change_feed_retention_in_days          = 14
  storage_account_blob_properties_versioning_enabled                     = false
  storage_account_blob_properties_container_delete_retention_policy_days = 14
  storage_account_blob_properties_delete_retention_policy_days           = 14

  storage_container_name                  = "tstate"
  storage_container_container_access_type = "blob"

  key_vault_name                       = "tstate-vault"
  key_vault_sku_name                   = "premium"
  key_vault_enable_rbac_authorization  = false
  key_vault_purge_protection_enabled   = false
  key_vault_soft_delete_retention_days = 7

  key_vault_key_name            = "tstate-vault-key"
  key_vault_key_key_type        = "EC"
  key_vault_key_key_size        = "1024"
  key_vault_key_key_opts        = ["decrypt", "encrypt", "sign", "unwrapKey", "verify"]
  key_vault_key_expiration_date = "2023-12-30T20:00:00Z"
}

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages