Introduction
In this project, an organized structure for the deployment of an infrastructure in Azure using Terraform and Terragrunt is presented. The solution makes it easy to create and manage Storage Account resources, optimizing configuration reuse between different environments, such as development and production, through well-structured configuration files.
The project structure allows for a modular and reusable implementation, separating the configuration of specific environments from the main deployment files. Terraform and Terragrunt offer a robust approach to managing common and environment-specific variables and state, facilitating infrastructure management and scalability in enterprise environments.
Project Structure
The organization of the project is as follows:
├── env
│ ├── code
│ │ └── storage
│ │ └── 00
│ │ ├── backend.tf
│ │ ├── data.tf
│ │ ├── endpoint.tf
│ │ ├── locals.tf
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── provider.tf
│ │ └── variables.tf
│ └── dev
│ ├── storage
│ │ └── 00
│ │ ├── terragrunt.hcl
│ │ └── vars.tfvars
│ └── varEnvironment.hcl
├── varCommon.hcl
└── varDataState.hclThe folder env contains environment-specific settings, while code hosts the Terraform configuration files for the Storage Account deployment. The folder dev contains configuration files specific to the development environment. terragrunt.hcl, varCommon.hcl and varDataState.hcl They are configuration files for Terragrunt and common variables.
Terraform Configuration
Now, let's dive into the Terraform configuration files needed to deploy Storage Account.
backend.tf
terraform {
backend "azurerm" {
}
required_version = "~>0.14"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.47.0"
}
}
}data.tf
The file data.tf contains data blocks that allow Terraform to access information from existing resources in Azure. These blocks are essential for reusing existing infrastructure and ensuring that new resources are deployed consistently.
data "terraform_remote_state" "rg" {
backend = "azurerm"
config = {
subscription_id = var.lz_subscription_id
resource_group_name = var.lz_resource_group_name
storage_account_name = var.lz_storage_account_name
container_name = var.lz_container_name
key = "${var.ProjectName}/${var.ServiceName}/env/${var.Environment}/${var.mapProjectPathKey.rg}/terraform.tfstate"
}
}
data "azurerm_resource_group" "rg_net" {
name = var.rg_net_name
}
#State Vnet
data "azurerm_virtual_network" "vnet" {
name = var.vnet_net_name
resource_group_name = data.azurerm_resource_group.rg_net.name
}
data "azurerm_subnet" "sbn_data" {
name = var.sbn_data_net_name
virtual_network_name = data.azurerm_virtual_network.vnet.name
resource_group_name = data.azurerm_resource_group.rg_net.name
}
data "azurerm_resource_group" "hub_rg" {
provider = azurerm.hub
name = var.hub_resource_group_name
}
data "azurerm_private_dns_zone" "zone_01" {
provider = azurerm.hub
name = var.private_dns_zone_name_01
resource_group_name = data.azurerm_resource_group.hub_rg.name
}
data "azurerm_private_dns_zone" "zone_02" {
provider = azurerm.hub
name = var.private_dns_zone_name_02
resource_group_name = data.azurerm_resource_group.hub_rg.name
}Explanation:
1. data “terraform_remote_state” “rg”
This block accesses the remote state of Terraform to reuse configurations already existing elsewhere (for example, resources defined in a different project). It is commonly used in multi-modular configurations.
- backend: Defines the type of backend (in this case, Azure Resource Manager,
azurerm) where the Terraform state is stored. - config: Contains the configuration necessary to connect to the remote state:
- subscription_id- ID of the Azure subscription where the status is located.
- resource_group_name: Name of the resource group that contains the storage account.
- storage_account_name: Name of the storage account that hosts the state.
- container_name: Name of the blob container within the storage account.
- key: Specific path to the remote state file, organized using variables such as the project, service, environment, and a path mapping (
mapProjectPathKey).
2. data “azurerm_resource_group” “rg_net”
This block retrieves information about an existing resource group in Azure.
- yam: Name of the resource group you want to consult. It is defined by the variable
var.rg_net_name.
3. data “azurerm_virtual_network” “vnet”
Gets details about a specific virtual network.
- yam: Name of the target virtual network, defined by
var.vnet_net_name. - resource_group_name: Name of the resource group where this virtual network is located. It is obtained dynamically from
data.azurerm_resource_group.rg_net.name.
4. data “azurerm_subnet” “sbn_data”
Retrieves information about a subnet within a specific virtual network.
- yam: Name of the subnet, specified by
var.sbn_data_net_name. - virtual_network_name: Name of the virtual network associated with the subnet. It is extracted from
data.azurerm_virtual_network.vnet.name. - resource_group_name: Virtual network resource group. It is obtained from
data.azurerm_resource_group.rg_net.name.
5. data “azurerm_resource_group” “hub_rg”
Gets information from a group of resources that acts as hub.
- provider: Associates a specific provider for operations related to this resource group (
azurerm.hub). - yam: Name of the hub resource group, defined by
var.hub_resource_group_name.
6. data “azurerm_private_dns_zone” “zone_01”
Gets information about a private DNS zone to resolve internal domain names.
- provider: Use the provider configured as
azurerm.hubto perform operations in this DNS zone. - yam: Name of the private DNS zone, defined by
var.private_dns_zone_name_01. - resource_group_name: Resource group that hosts the private DNS zone. Obtained from the resource
data.azurerm_resource_group.hub_rg.name.
7. data “azurerm_private_dns_zone” “zone_02”
Another block similar to the previous one, but for a second private DNS zone.
- provider: Same as above, use
azurerm.hub. - yam: Defines the name of the private DNS zone (for example,
privatelink.web.core.windows.net) throughvar.private_dns_zone_name_02. - resource_group_name: Associated with the resource group
data.azurerm_resource_group.hub_rg.name.
endpoint.tf
This file defines the resource Private Endpoint, allowing private connection to the Storage Account. This Private Endpoint is associated with the specified subnet and private DNS zone.
resource "azurerm_private_endpoint" "pren_01" {
name = upper(join("-", [ var.Environment, var.BussinessUnitExtended, var.Provider, var.ServiceName, var.storage_account_name, "pren-01"]))
resource_group_name = data.terraform_remote_state.rg.outputs.name
location = var.region
subnet_id = data.azurerm_subnet.sbn_data.id
private_service_connection {
name = upper(join("-", [ var.Environment, var.BussinessUnitExtended, var.Provider, var.ServiceName, var.storage_account_name, "pren-01"]))
private_connection_resource_id = azurerm_storage_account.storage_01.id
is_manual_connection = false
subresource_names = ["blob"]
}
private_dns_zone_group {
name = data.azurerm_private_dns_zone.zone_01.name
private_dns_zone_ids = [data.azurerm_private_dns_zone.zone_01.id]
}
tags = local.tags
lifecycle {
ignore_changes = [
tags["CreationDate"]
]
}
}Explanation:
resource “azurerm_private_endpoint” “pren_01”:
This resource defines a Private Endpoint which allows a secure and private connection to a storage account in Azure.
- yam:
Name of the Private Endpoint, dynamically generated from several variables (Environment,BussinessUnitExtended,Provider,ServiceName,storage_account_name). This format ensures consistency with corporate nomenclature. Converted to uppercase usingupper(). - resource_group_name:
Specifies the resource group where the Private Endpoint.
Obtained from the Terraform remote state (data.terraform_remote_state.rg.outputs.name), which centralizes the definition of the resource group. - location:
Region where the Private Endpoint.
It is defined through the variablevar.region. - subnet_id:
ID of the subnet where the Private Endpoint.
It is obtained fromdata.azurerm_subnet.sbn_data.id, which retrieves the details of the corresponding subnet.
Block private_service_connection
Configures the private connection to the target resource, in this case, a storage account.
- yam:
Name of the private connection, generated in a similar way to the name of the Private Endpoint. - private_connection_resource_id:
ID of the destination resource to which the Private Endpoint.
In this case, it corresponds to the storage account ID (azurerm_storage_account.storage_01.id). - is_manual_connection:
Established asfalse, indicating that the private connection is automatically managed by Azure. - subresource_names:
Specifies the subresource within the service to connect to.
In this case, it is the subresourceblobof the storage account.
Block private_dns_zone_group
Defines the relationship between the Private Endpoint and a private DNS zone to resolve internal domain names.
- yam:
Name of the private DNS zone, obtained fromdata.azurerm_private_dns_zone.zone_01.name. - private_dns_zone_ids:
List of private DNS zone IDs associated with the Private Endpoint.
Here the ID is useddata.azurerm_private_dns_zone.zone_01.id.
tags
Applies tags defined in local.tags, which makes it easier to organize and track the resource within the environment.
Block lifecycle
Configure Terraform's behavior regarding changes to the resource.
locals.tf
The file locals.tf defines local variables that can be reused in multiple parts of Terraform code. Local variables are useful for centralizing values that are used across multiple resources, improving code clarity and maintainability.
locals {
storage_name = lower(join("", [var.Environment, var.BussinessUnitExtended, var.Provider, var.ServiceName, "st01"]))
tags = var.tags
}Explanation:
Defines a dynamic name for a resource, in this case probably a storage account.
Components:
lower()- Converts the generated value to lowercase to comply with resource name restrictions in Azure (for example, storage account names must be lowercase).join("", [...]): Combines the values in a list into a single string, without separators.- List of values used:
var.Environment: Variable that represents the environment, such as "dev", "prod", etc.var.BussinessUnitExtended: Identifies the business unit.var.Provider: Specifies the provider or technology used, such as "azr" for Azure.var.ServiceName: Name of the service related to the resource."st01": Fixed suffix to indicate that this is a storage account.
main.tf
in the file main.tf The main infrastructure resources are defined. In this case, an Azure Storage Account resource is being created that will serve to store secrets and other sensitive values, thus ensuring the security of the information.
resource "azurerm_storage_account" "storage_01" {
name = local.storage_name
resource_group_name = data.terraform_remote_state.rg.outputs.name
location = var.region
account_tier = var.storage_account_tier
account_replication_type = var.storage_account_replication_type
access_tier = var.storage_account_access_tier
min_tls_version = var.storage_account_min_tls_version
account_kind = var.storage_account_kind
is_hns_enabled = var.storage_account_is_nhs_enabled
public_network_access_enabled = false
tags = local.tags
lifecycle {
ignore_changes = [
tags["CreationDate"]
]
}
blob_properties {
container_delete_retention_policy {
days = 7
}
delete_retention_policy {
days = 7
}
}
}Explanation
1. Resource definition
resource "azurerm_storage_account" "storage_01": Defines a resource of typeazurerm_storage_account(Azure Storage Account) in Terraform.
The identifierstorage_01is used to reference this resource in other parts of the code.
2. Main attributes
name:
Build storage account name using local variablelocal.storage_name, which dynamically combines values such as the environment, business unit, provider and service. This guarantees a unique and standard name.
(Example:devfinanceazrbackupst01)resource_group_name:
Specifies the resource group where the storage account will be created.
The name is obtained from the Terraform remote state (terraform_remote_state.rg.outputs.name), ensuring consistency with other resources that share the same group.location:
Defines the region where the storage account will be located, specified by the variablevar.region.
(Example:eastus)account_tier:
Defines the performance level of the storage account.
Could beStandardeitherPremium, depending on the intended use.
(Example:Standard)account_replication_type:
Specifies the type of replication to ensure redundancy.
Possible values:LRS,GRS,ZRS, etc.
(Example:LRS)access_tier:
Determines whether the data is accessed frequently (Hot) or sporadically (Cool).
(Example:Hot)min_tls_version:
Configures the minimum TLS version allowed for connections. Improves security by only accepting modern versions.
(Example:TLS1_2)account_kind:
Storage account type.
(Example:StorageV2)is_hns_enabled:
Enables support for Azure Data Lake Storage Gen2, enabling a hierarchical access model for Big Data.
(Example:true)public_network_access_enabled:
Established infalseto restrict access from public networks, improving security by limiting use to private networks or private endpoints.
3. Advanced settings
tags:
Applies tags defined inlocal.tagsto organize the resource. These tags help with classification and search in Azure.
(Example:{ Environment = "dev", Owner = "John Doe" })lifecycle:
The blocklifecycleindicates that Terraform should ignore any changes to the labelCreationDate. This prevents unnecessary updates from being made to the resource when only this tag changes.
4. Blob properties
The block blob_properties defines policies for data lifecycle management:
container_delete_retention_policy: Retains deleted containers for 7 days, allowing them to be recovered.delete_retention_policy: Retains deleted blobs for 7 days before final deletion.
outputs.tf
The file outputs.tf exposes relevant information about the resource azurerm_storage_account for ease of use in other modules or to provide key data to Terraform users. This includes endpoints, locations, access keys, among others.
# IDs
output "id" {
value = azurerm_storage_account.storage_01.id
description = "The ID of the Storage Account."
}
output "primary_location" {
value = azurerm_storage_account.storage_01.primary_location
description = "The primary location of the storage account"
}
output "secondary_location" {
value = azurerm_storage_account.storage_01.secondary_location
description = "The secondary location of the storage account"
}
output "primary_blob_endpoint" {
value = azurerm_storage_account.storage_01.primary_blob_endpoint
description = "The primary blob endpoint of the storage account"
}
output "primary_blob_host" {
value = azurerm_storage_account.storage_01.primary_blob_host
description = "The primary blob host of the storage account"
}
output "secondary_blob_endpoint" {
value = azurerm_storage_account.storage_01.secondary_blob_endpoint
description = "The secondary blob endpoint of the storage account"
}
output "secondary_blob_host" {
value = azurerm_storage_account.storage_01.secondary_blob_host
description = "The secondary blob host of the storage account"
}
output "primary_access_key" {
value = azurerm_storage_account.storage_01.primary_access_key
description = "The primary access key of the storage account"
}
output "secondary_access_key" {
value = azurerm_storage_account.storage_01.secondary_access_key
description = "The secondary access key of the storage account"
}
output "primary_web_endpoint" {
value = azurerm_storage_account.storage_01.primary_web_endpoint
description = "The primary web endpoint of the storage account"
}
output "primary_web_host" {
value = azurerm_storage_account.storage_01.primary_web_host
description = "The primary web host of the storage account"
}
output "secondary_web_endpoint" {
value = azurerm_storage_account.storage_01.secondary_web_endpoint
description = "The secondary web endpoint of the storage account"
}
output "secondary_web_host" {
value = azurerm_storage_account.storage_01.secondary_web_host
description = "The secondary web host of the storage account"
}
output "primary_connection_string" {
value = azurerm_storage_account.storage_01.primary_connection_string
description = "The primary connection string of the storage account"
}
output "secondary_connection_string" {
value = azurerm_storage_account.storage_01.secondary_connection_string
description = "The secondary connection string of the storage account"
}
output "identity" {
value = azurerm_storage_account.storage_01.identity
description = "The identity of the storage account"
}
Explanation
-
output "id"- Provides the unique ID of the Azure Storage Account resource.
- Useful for cross-referencing or integrations with other Azure services.
(Example:/subscriptions/{subscription-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/{storage-name})
-
output "primary_location"andoutput "secondary_location"- They indicate the primary and secondary location of the storage account.
- Relevant in configurations with geographic replication to identify the regions in use.
(Example:eastus,westus)
-
output "primary_blob_endpoint"andoutput "secondary_blob_endpoint"- They show the primary and secondary endpoints of the Blob service.
- These are used to access and manage blobs stored in the account.
(Example:https://{storage-name}.blob.core.windows.net/)
-
output "primary_blob_host"andoutput "secondary_blob_host"- They expose the host names associated with the Blob endpoints.
(Example:{storage-name}.blob.core.windows.net)
- They expose the host names associated with the Blob endpoints.
-
output "primary_access_key"andoutput "secondary_access_key"- They return the primary and secondary access keys for the account.
- These keys are essential for authentication when managed identity is not used.
(Note: Handle with caution and access to this output should be restricted in sensitive environments.)
-
output "primary_web_endpoint"andoutput "secondary_web_endpoint"- They provide the primary and secondary endpoints for the associated web service.
(Example:https://{storage-name}.web.core.windows.net/)
- They provide the primary and secondary endpoints for the associated web service.
-
output "primary_connection_string"andoutput "secondary_connection_string"- They contain the primary and secondary connection strings, used by applications to interact with the storage account.
(Example:DefaultEndpointsProtocol=https;AccountName={storage-name};AccountKey={key};EndpointSuffix=core.windows.net)
- They contain the primary and secondary connection strings, used by applications to interact with the storage account.
-
output "identity"- Exposes the managed identity associated with the storage account, if configured.
(Example:{"principal_id": "...", "tenant_id": "...", "type": "SystemAssigned"})
- Exposes the managed identity associated with the storage account, if configured.
provider.tf
in the file provider.tf infrastructure providers are configured, in this case the Azure provider (azurerm). Here you define two configurations for the Azure provider, one by default and one with an alias. This allows working with multiple Azure subscriptions within the same Terraform project
provider "azurerm" {
subscription_id = var.Subscription
tenant_id = var.Tenant
features {}
}
provider "azurerm" {
alias = "hub"
subscription_id = var.subscription_hub_id
tenant_id = var.Tenant
features {}
}Explanation:
- First block
provider "azurerm":subscription_id: This property defines the Azure subscription ID which will be used to provision and manage resources. It is obtained from the variablevar.Subscription, which must be previously configured.tenant_id: He Azure Active Directory tenant ID to which the Azure provider should be associated. In this case, it is taken fromvar.Tenant.features {}: A block required by the Azure provider (azurerm) which may contain additional settings. Although in this case it is empty, it is necessary to correctly initialize the provider.
- Second block
provider "azurerm"with aliashub:alias: The alias"hub"allows you to create a second Azure provider within the same Terraform configuration, which is useful when you need to work with multiple subscriptions. By assigning an alias, you can reference this specific provider later in your resources or data so that it can be differentiated from the default provider.subscription_id: Similar to the first block, this property is defined viavar.subscription_hub_id, which represents the Azure subscription ID for the hub configuration.tenant_id: He tenant ID remains the same and is taken fromvar.Tenantto maintain consistency in the environment.features {}: Like the first block, this block is required even if it does not contain additional settings.
variables.tf
in the file variables.tf All variables used throughout the Terraform infrastructure are defined. This file centralizes configurable parameters that can change depending on the environment, subscription, resource name, etc. This allows code reuse and makes it easier to manage.
######################
# VARIABLES COMUNES #
######################
variable "lz_subscription_id" {
type = string
description = "ID de la susbcriptcion de los tfstate"
default = ""
}
variable "lz_resource_group_name" {
type = string
description = "Nombre del resoruce group de los tfstate"
default = ""
}
variable "lz_storage_account_name" {
type = string
description = "Nombre del storage account de los tfstate"
default = ""
}
variable "lz_container_name" {
type = string
description = "Nombre del container name de los tfstate"
default = ""
}
variable "Tenant" {
type = string
description = "Nombre del tenant"
default = ""
}
variable "Subscription" {
type = string
description = "Nombre de la subscripcion"
default = ""
}
variable "Provider" {
type = string
description = "Nombre del Provider cloud"
default = ""
}
variable "Environment" {
type = string
description = "(Required) Specifies the Environment where the Resources should exist."
default = ""
}
variable "BussinessUnit" {
type = string
description = "(Required) Bussiness Unit."
default = ""
}
variable "BussinessUnitExtended" {
type = string
description = "(Required) Bussiness Unit Extended."
default = ""
}
variable "ProjectName" {
type = string
description = "(Required) ProjectName."
default = ""
}
variable "ServiceName" {
type = string
description = "(Required) ServiceName."
default = ""
}
variable "mapProjectPathKey" {
type = map(string)
default = {}
description = "Mapa de rutas de los elementos"
}
variable "region" {
type = string
description = "(Required) Region Name"
default = ""
}
#############################
# VARIABLES DATAS #
#############################
variable "rg_net_name" {
type = string
description = "Name rg of net"
default = ""
}
variable "vnet_net_name" {
type = string
description = "Name of vnet of net"
default = ""
}
variable "sbn_data_net_name" {
type = string
description = "Name of Subnet Data of net"
default = ""
}
variable "rg_bkp_name" {
type = string
description = "Name of resource group of bkp"
default = ""
}
variable "st_bkp_name" {
type = string
description = "Name of storage Account of bkp"
default = ""
}
variable "EntityName" {
type = string
description = "(Required) Entity Name."
default = ""
}
#############################
# VARIABLES Storage Account #
#############################
variable "storage_account_name" {
type = string
description = "Nombre del storage account"
default = ""
}
variable "storage_account_tier" {
type = string
description = "Tier of storage account"
default = ""
}
variable "storage_account_replication_type" {
type = string
description = "Replication type of storage account"
default = ""
}
variable "storage_account_access_tier" {
type = string
description = "Access tier storage account"
default = ""
}
variable "storage_account_min_tls_version" {
type = string
description = "Min tls version storage account"
default = ""
}
variable "storage_account_kind" {
type = string
description = "Storage account kind"
default = ""
}
variable "storage_account_is_nhs_enabled" {
type = bool
description = "is nhs storage account enabled"
default = true
}
######################
# VARIABLE TAGS #
######################
variable "tags" {
type = map(string)
default = {}
description = "(Optional) A mapping of tags which should be assigned to the Resource Group."
}
##########################
# Variables Provider HUB #
##########################
variable "hub_resource_group_name" {
type = string
default = ""
description = "Nombre del resource group de HUB"
}
variable "private_dns_zone_name_01" {
type = string
default = ""
description = "Nombre del private dns zone name de HUB"
}
variable "private_dns_zone_name_02" {
type = string
default = ""
description = "Nombre del private dns zone name de HUB"
}
variable "virtual_network_appgw_name" {
type = string
default = ""
description = "Nombre del network appgw de HUB"
}
variable "subnet_appgw_name" {
type = string
default = ""
description = "Nombre del subnet appgw de HUB"
}
variable "subscription_hub_id" {
type = string
default = ""
description = "Nombre de la subscripcion de HUB"
}
Explanation:
1. Common variables
These variables allow you to set basic settings for remote state, subscription, and other key parameters:
-
lz_subscription_idandlz_resource_group_name- Subscription ID and name of the resource group where the remote state will be stored.
- They facilitate the management of remote backend in Terraform, typically stored in Azure Storage.
-
lz_storage_account_nameandlz_container_name- Configuration of the Storage Account and container used to store remote state (
tfstate).
- Configuration of the Storage Account and container used to store remote state (
-
Tenant,Subscription,Provider- Information related to the Azure tenant, the subscription and the provider in use.
-
Environment,BussinessUnit,ProjectNameandServiceName- They detail the environment, business unit, project name, and service associated with the deployment.
- These values are usually used in the tag definition (
tags) or in resource names.
-
region- Defines the Azure region where the resources will be deployed.
- (Example:
eastus,westeurope)
2. Network specific variables (DATAS)
These variables are necessary to configure the environment network:
rg_net_name: Name of the resource group that contains the virtual network.vnet_net_name: Name of the associated virtual network.sbn_data_net_name: Name of the subnet within the virtual network.rg_bkp_nameandst_bkp_name: Resources related to backups, such as resource group and Storage Account.EntityName: Identifier name of the entity associated with the deployment.
3. Variables for the Storage Account
These variables allow you to customize the storage configuration:
-
storage_account_name- Name of the Storage Account. (Example:
stproject001) - This value usually has to be globally unique.
- Name of the Storage Account. (Example:
-
storage_account_tier- Determines the level of performance, such as
StandardeitherPremium.
- Determines the level of performance, such as
-
storage_account_replication_type- Replication type:
LRS,GRS,ZRS, etc. - (Example:
LRSfor local replication,GRSfor geographic replication).
- Replication type:
-
storage_account_access_tier- Access to data in storage:
HoteitherCool.
- Access to data in storage:
-
storage_account_min_tls_version- Minimum TLS version for secure connections. (Example:
TLS1_2)
- Minimum TLS version for secure connections. (Example:
-
storage_account_kind- Account type:
Storage,StorageV2, etc.
- Account type:
-
storage_account_is_nhs_enabled- Indicates whether storage is enabled for NHS (Network Hierarchy Storage).
4. Tag variables
tags- Optional mapping to assign tags to resources.
- Makes it easy to organize and filter resources in Azure. (Example:
{"Environment" = "Dev", "Owner" = "TeamA"})
5. HUB provider specific variables
These variables are useful when the deployment involves integration or communication with a secondary subscription of type HUB (shared network, App Gateway, etc.):
-
hub_resource_group_name- HUB Resource Group.
-
private_dns_zone_name_01andprivate_dns_zone_name_02- Private DNS zones used in the HUB environment. (Example:
privatelink.blob.core.windows.net)
- Private DNS zones used in the HUB environment. (Example:
-
virtual_network_appgw_nameandsubnet_appgw_name- Network and subnet configuration for an Application Gateway.
-
subscription_hub_id- ID of the subscription associated with the HUB.
terragrunt.hcl
The file terragrunt.hcl What you provide sets up an environment to manage infrastructure using Terragrunt, which is a tool for managing Terraform configurations in a modular way. Here is a detailed breakdown of what this file does:
dependencies {
paths = [
"../../rg/00/"
]
}
include "varEnvironment" {
path = find_in_parent_folders("varEnvironment.hcl")
expose = true
}
include "varCommon" {
path = find_in_parent_folders("varCommon.hcl")
expose = true
}
include "varDataState" {
path = find_in_parent_folders("varDataState.hcl")
expose = true
}
locals {
mapProjectPathKey = jsonencode(include.varEnvironment.inputs.mapProjectPathKey)
tags = jsonencode(merge({
Managed_By = "Terraform"
Provider = "AZR"
},
include.varCommon.inputs.globalTags,
include.varEnvironment.inputs.environmentTags
))
}
generate "backend"{
path = "backend.tfvars"
if_exists = "overwrite" # "overwrite" "skip" "overwrite_terragrunt"
contents = <<EOF
subscription_id = "${include.varDataState.inputs.lz_subscription_id}"
key = "${include.varCommon.inputs.ProjectName}/${include.varCommon.inputs.ServiceName}/${get_path_from_repo_root()}/terraform.tfstate"
resource_group_name = "${include.varDataState.inputs.lz_resource_group_name}"
storage_account_name = "${include.varDataState.inputs.lz_storage_account_name}"
container_name = "${include.varDataState.inputs.lz_container_name}"
EOF
}
generate "vars"{
path = "vars.tfvars"
if_exists = "overwrite"
contents = <<EOF
###############################
# VALORES DATA DataState #
###############################
lz_subscription_id = "${include.varDataState.inputs.lz_subscription_id}"
lz_resource_group_name = "${include.varDataState.inputs.lz_resource_group_name}"
lz_storage_account_name = "${include.varDataState.inputs.lz_storage_account_name}"
lz_container_name = "${include.varDataState.inputs.lz_container_name}"
###############################
# VALORES GENERALES #
###############################
region = "${include.varEnvironment.inputs.region}"
Environment = "${include.varEnvironment.inputs.Environment}"
BussinessUnit = "${include.varCommon.inputs.BussinessUnit}"
ProjectName = "${include.varCommon.inputs.ProjectName}"
ServiceName = "${include.varCommon.inputs.ServiceName}"
Subscription = "${include.varEnvironment.inputs.Subscription}"
Tenant = "${include.varCommon.inputs.Tenant}"
# ApplicationName = null
mapProjectPathKey = ${local.mapProjectPathKey}
##################################
# Valores Container Provider HUB #
##################################
hub_resource_group_name = "PRO-NWHUB-RGP-01"
private_dns_zone_name_01 = "privatelink.blob.core.windows.net"
private_dns_zone_name_02 = "privatelink.web.core.windows.net"
subscription_hub_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
##############################
# Valores Storage Account #
##############################
rg_net_name = "${include.varEnvironment.inputs.NetworkResourceGroup}"
vnet_net_name = "${include.varEnvironment.inputs.Network}"
sbn_data_net_name = "${include.varEnvironment.inputs.SubnetworkFront}"
storage_account_name = "st01"
storage_account_tier = "Standard"
storage_account_replication_type = "LRS"
storage_account_access_tier = "Hot"
storage_account_min_tls_version = "TLS1_2"
storage_account_is_nhs_enabled = "false"
storage_account_kind = "StorageV2"
###########################
# VALORES TAGS #
###########################
tags = ${local.tags}
EOF
}
terraform {
source = "../../..//code/storage/00/"
before_hook "print_tags" {
commands = ["plan", "apply"] #["${get_terraform_commands_that_need_vars()}"]
execute = ["echo", "tags", "=", "${local.tags}", ">", "vars.tfvars"]
}
before_hook "copy_vars" {
commands = ["plan", "apply"] #["${get_terraform_commands_that_need_vars()}"]
execute = ["cp", "-f", "vars.tfvars", "${get_original_terragrunt_dir()}/vars.tfvars"]
}
extra_arguments "backend_vars" {
commands = ["init"]
arguments = [
"-backend-config=backend.tfvars"
]
}
extra_arguments "vars_vars" {
commands = ["plan", "apply", "destroy", "import"]
arguments = [
"-var-file=vars.tfvars"
]
}
}Explanation:
dependencies: This block defines the Terragrunt dependencies. In this case, no dependency paths are specified, since the blockpathsIt is empty.
include: These blocks include external variable files (varEnvironment.hcl,varCommon.hcl,varDataState.hcl) in Terragrunt. The included files can expose their variables to be used in this Terragrunt file.
locals: This block defines local variables that are used within this Terragrunt file.
mapProjectPathKey: Encode the map as JSONmapProjectPathKeyfrom the filevarEnvironment.hcl.
tags: JSON-encodes a set of tags by combining a fixed set of tags (Managed_ByandProvider), the global labels defined invarCommon.hcland the environment-specific tags defined invarEnvironment.hcl.
generate "backend": This block generates a file calledbackend.tfvars. This file is used to configure the Terraform backend. It contains variables likesubscription_id,key,resource_group_name,storage_account_name, andcontainer_name. The values of these variables are obtained from the included files (varDataState.hclandvarCommon.hcl).
generate "vars": This block generates a file calledvars.tfvars. This file is used to provide variable values to Terraform. Contains values for specific variables defined in the included files (varDataState.hcl,varCommon.hcl,varEnvironment.hcl). The values are interpolated from the included variables.
terraform: This block provides additional settings for Terraform.
source: Specifies the source path of the Terraform module. In this case, the origin is set to a relative directory../../..//code/rg/00/.
before_hook: This block defines execution hooks that will be executed before certain Terraform commands, such asplanandapply. In this case, two hooks are executed:print_tagsandcopy_vars.
extra_arguments: This block specifies additional arguments to be passed to Terraform commands (init,plan,apply,destroy,import). In this case, additional arguments are specified for the backend configuration (backend_vars) and for the variables (vars_vars).
varEnvironment.hcl
locals {
region = "northeurope"
Environment = "dev"
EnvironmentLetter = "d"
Subscription = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
NetworkResourceGroup = "DEV-REDORBITA-RG-01"
Network = "DEV-REDORBITA-NET-01"
SubnetworkFront = "DEV-REDORBITA-SBN-01"
SubnetworkVint = "DEV-REDORBITA-VINT-SBN-01"
mapProjectPathKey = {
rg = "rg/00",
sbnVint00 = "networking/sbn/vint00",
storage = "storage/00"
}
}
inputs = {
region = local.region
Environment = local.Environment
EnvironmentLetter = local.EnvironmentLetter
Subscription = local.Subscription
NetworkResourceGroup = local.NetworkResourceGroup
Network = local.Network
SubnetworkFront = local.SubnetworkFront
SubnetworkVint = local.SubnetworkVint
environmentTags = {
Enviroment = "${upper(local.Environment)}"
}
mapProjectPathKey = local.mapProjectPathKey
}
}varCommon.hcl
This file contains a structured definition of local values and common entries which are used to organize and parameterize resources within Terraform. The combination of locals and inputs allows configurations to be separated by environment and facilitates code reuse across multiple projects. Each section is detailed below:
locals {
EntityName = "RO"
ProjectName = "RedOrbita"
ServiceName = "RedOrbita"
BussinessUnit = "XX"
Subscription = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
Tenant = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
Provider = "azr"
required_version = "~>0.14"
globalTags = {
Company = "Red-Orbita"
Owner = "xxxx@redorbita.com"
ProjectName = "XXXX"
"Service Description" = "XXXX"
Status = "Implementacion"
Provider = "Azure"
Cluster = "N/A"
"Operating System" = "N/A"
Temporal = "NO"
"App ID" = "N/A"
}
storage_account = "protfdata"
container_name = "iasearch"
subscription_hub_id2 = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
location = "northeurope"
}
inputs = {
##############################
# VARIABLES COMMON #
##############################
EntityName = local.EntityName
ProjectName = local.ProjectName
ServiceName = local.ServiceName
BussinessUnit = local.BussinessUnit
Subscription = local.Subscription
Tenant = local.Tenant
Provider = local.Provider
required_version = local.required_version
globalTags = local.globalTags
}
inputs = {
##############################
# VARIABLES COMMON #
##############################
EntityName = local.EntityName
ProjectName = local.ProjectName
ServiceName = local.ServiceName
BussinessUnit = local.BussinessUnit
# Subscription = local.Subscription
# Subscription_pro = local.Subscription_pro
Tenant = local.Tenant
Provider = local.Provider
required_version = local.required_version
id_project = local.id_project
globalTags = local.globalTags
}-
Block
localsIn this block, local variables are defined within the file that can be used within the file itself or by other Terraform modules:
- EntityName: It is the name of the entity associated with the project, in this case, "RO". It is generally used as an identifier for a project or unit within the organization.
- ProjectName: The name of the project, in this case, "RedOrbita", which identifies the name of the initiative under which the resources are managed.
- ServiceName: The name of the service related to the project, here it is also defined as "RedOrbita". Refers to the main service or solution that will be implemented.
- BusinessUnit: Specifies the business unit associated with the project, here represented by "XX".
- Subscription- The ID of the Azure subscription associated with the project. It is a single value that is used to manage resources within the Azure subscription.
- Tenant- The Azure tenant ID, which represents a unique directory within Azure Active Directory.
- Provider: The infrastructure provider to use. In this case, "azr" refers to Azure.
- required_version: Specifies the version of Terraform required to run this file. In this case, any version compatible with “0.14.x” is required.
- globalTags: Defines a set of global tags that will be applied to all resources. Tags include details such as company name, project owner, project status, service description, infrastructure provider, etc.
- storage_account: The name of the Azure storage account, in this case “protfdata”.
- container_name: The name of the container within the Azure storage account, “iasearch”.
- subscription_hub_id2: A second subscription ID, possibly related to the network hub or specific resources.
- location: Specifies the Azure region where the resources will be deployed, in this case, "northeurope."
-
Block
inputsThe block of
inputstakes the values defined in the blocklocalsand passes them as inputs to be used in other modules or resources within the project. The common variables defined inlocalsThey are referenced here to ensure consistency of values throughout the project. In this case, the same entries are repeated for the defined variables, allowing their reuse in other Terraform modules.-
EntityName, ProjectName, ServiceName, BusinessUnit, Subscription, Tenant, Provider, required_version, globalTags: These inputs are assigned directly to the local variables defined above, ensuring that the values are consistent throughout the project.
-
project_id: Reference is made to a variable called
id_project, although this is not defined in the premises. This suggests that this variable can be defined elsewhere or used for specific projects.
-
varDataState.hcl
This file varDataState.hcl It is used to define and organize variables related to the state of Terraform data and infrastructure in the workbench. This file contains configurations for storing Terraform state in Azure, which is crucial for managing infrastructure resources and their persistence. The purpose and use of the settings defined in this file are explained below:
locals {
lz_subscription_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
lz_resource_group_name = "PRO-HUB-01"
lz_storage_account_name = "storage"
lz_container_name = "storage"
path_resources_terraform_state = jsonencode({
rg = "rg/00"
})
}
inputs = {
##############################
# VARIABLES FOR DATA STATES #
##############################
lz_subscription_id = local.lz_subscription_id
lz_resource_group_name = local.lz_resource_group_name
lz_storage_account_name = local.lz_storage_account_name
lz_container_name = local.lz_container_name
path_resources_terraform_state = local.path_resources_terraform_state
}1. Block locals
The block locals defines local variables within this file, which can be reused within the file or in other Terraform modules. Local variables defined here include:
- lz_subscription_id: The ID of the Azure subscription used to manage resources in the infrastructure. This value is unique for each Azure subscription.
- lz_resource_group_name: The name of the Azure resource group that will be used to store the Terraform resources, in this case
PRO-HUB-01. Resource groups are logical units that group related resources in Azure. - lz_storage_account_name: The name of the Azure storage account, in this case
storage, which will be used to store Terraform state and other persistent resources. - lz_container_name: The name of the container within the Azure storage account, here named
storage, where the Terraform state files will be stored. - path_resources_terraform_state: A value in JSON format that defines the path within the storage container where Terraform state files will be saved. In this case, the route is defined as
rg/00.
2. Block inputs
The block inputs It is used to define the inputs of the variables that will be passed to the Terraform modules. These entries correspond to the local variables that were previously defined and will be used to configure Terraform state storage in Azure. The input variables are:
- lz_subscription_id- The ID of the Azure subscription that is passed as input to the modules.
- lz_resource_group_name: The name of the resource group to pass as input.
- lz_storage_account_name: The name of the storage account that will be used to manage the state.
- lz_container_name: The name of the container where the state will be stored.
- path_resources_terraform_state: The path where the Terraform state will be stored within the container.
:wq!
Comments