TL;DR at the end.
I am completely new to terragrunt and I am trying to use it to take advantage of the DRY (don't repeat yourself) feature it offers. My tree is shown below, I plan to use this repository for aws, gcp and azure, and in this use case I am only focusing on azure, once I will have understand the usage of terragrunt I should be able to apply the logic for other providers. My tree might be one of the issues so do not hesitate to let me know if I did it wrong.
I would like to reuse my code instead of copy pasting the same thing over and over again. Focusing azure, the end goal here is to create only a resource group with an azure key vault inside it to be able to understand how works the usage of terragrunt.
From my understanding creating the tenant.hcl, subcription.hcl and env.hcl allow me to not have to change this value in my code.
About the rest I might have forgotten some dependencies according to my error messages... I am positionning myself in IaC/deployments/subscription-test-1/dev/client-test/ and running a "terragrunt plan" but then get some failures with the following errors messages:
Error message:
The system cannot find the path specified. time=2023-03-30T09:26:00+02:00 level=error msg=Unable to determine underlying exit code, so Terragrunt will exit with error code 1
IaC/
├─ deployments/
│ ├─ azure/
│ │ ├─ subscription-test-1/
│ │ │ ├─ dev/
│ │ │ │ ├─ client-test/
│ │ │ │ │ ├─ terragrunt.hcl
│ │ │ │ ├─ env.hcl
│ │ │ ├─ ppd/
│ │ │ ├─ subscription.hcl
│ │ ├─ subscription-test-2/
│ │ │ ├─ dev/
│ │ │ ├─ ppd/
│ │ ├─ subscription-test-3/
│ │ │ ├─ prd/
│ │ │ ├─ sbx/
│ ├─ aws/
│ ├─ gcp/
│ ├─ tenant.hcl
├─ modules/
│ ├─ aws/
│ ├─ azuread/
│ │ ├─ security-groups/
│ │ ├─ spn/
│ ├─ azurerm/
│ │ ├─ akv/
│ │ │ ├─ main.tf
│ │ │ ├─ variables.tf
│ │ ├─ rg/
│ │ │ ├─ main.tf
│ │ │ ├─ variables.tf
│ ├─ databricks/
│ ├─ gcp/
├─ project-templates/
│ ├─ aws/
│ ├─ azure/
│ │ ├─ project-template-solution-1/
│ │ │ ├─ akv.tf
│ │ │ ├─ main.tf
│ │ │ ├─ rg.tf
│ │ │ ├─ variables.tf
│ │ │ ├─ terragrunt.hcl
│ │ ├─ project-template-solution-2/
│ │ ├─ project-template-solution-3/
│ ├─ gcp/
├─ terragrunt.hcl
Below is the terragrunt & terraform code per folders:
IaC/terragrunt.hcl
locals {
# Automatically load subscription variables
subscription_vars = read_terragrunt_config(find_in_parent_folders("subscription.hcl"))
# Automatically load tenant-level variables
tenant_var = read_terragrunt_config(find_in_parent_folders("tenant.hcl"))
# Automatically load environment-level variables
env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl"))
environment = local.env_vars.locals.environment
subscription_id = local.subscription_vars.locals.subscription_id
}
IaC/modules/azurerm/akv/main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.42.0"
}
}
}
#Configure the Azure Resource Management Provider
provider "azurerm" {
subscription_id = var.azure_subscription_id
tenant_id = var.azure_tenant_id
features {
key_vault {
purge_soft_delete_on_destroy = true
recover_soft_deleted_key_vaults = true
}
}
}
#create azure key vault
resource "azurerm_key_vault" "akv" {
name = lower("${var.azure_project_code}-${var.azure_env_code}-akv-01")
location = var.azure_resource_group_location
resource_group_name = var.azure_rg_name
enabled_for_disk_encryption = true
tenant_id = var.azure_tenant_id
soft_delete_retention_days = 7
purge_protection_enabled = false
sku_name = "standard"
}
IaC/modules/azurerm/akv/variables.tf
variable "azure_subscription_id" {
type = string
description = "Azure Subscription Id"
}
variable "azure_tenant_id" {
type = string
description = "Azure Tenant Id"
}
variable "azure_rg_name" {
type = string
description = "Azure Resource Group Name"
}
variable "azure_resource_group_location" {
default = "west europe"
description = "Location of the resource group."
}
variable "azure_env_code" {
type = string
description = "Azure Environment Code"
}
variable "azure_project_code" {
type = string
description = "Azure Project Code"
}
IaC/modules/azurerm/rg/main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.42.0"
}
}
}
provider "azurerm" {
subscription_id = var.azure_subscription_id
tenant_id = var.azure_tenant_id
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
#create azure resource group
resource "azurerm_resource_group" "rg" {
name = var.azure_rg_name
location = var.azure_resource_group_location
}
IaC/modules/azurerm/rg/variables.tf
variable "azure_subscription_id" {
type = string
description = "Azure Subscription Id"
}
variable "azure_tenant_id" {
type = string
description = "Azure Tenant Id"
}
variable "azure_rg_name" {
type = string
description = "Azure Resource Group Name"
}
variable "azure_resource_group_location" {
default = "west europe"
description = "Location of the resource group."
}
IaC/project-template-solution-1/terragrunt.hcl
include {
path = find_in_parent_folders()
}
IaC/project-template-solution-1/akv.tf
module "akv" {
source ="../..//modules/azurerm/akv/"
azure_subscription_id = var.azure_subscription_id
azure_tenant_id = var.azure_tenant_id
azure_rg_name = var.azure_rg_name
azure_resource_group_location = var.azure_resource_group_location
azure_project_code = var.azure_project_code
azure_env_code = var.azure_env_code
}
IaC/project-template-solution-1/rg.tf
module "rg" {
source ="../..//modules/azurerm/rg/"
azure_subscription_id = var.azure_subscription_id
azure_tenant_id = var.azure_tenant_id
azure_rg_name = var.azure_rg_name
azure_resource_group_location = var.azure_resource_group_location
}
IaC/project-template-solution-1/main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.42.0"
}
}
}
provider "azurerm" {
subscription_id = var.azure_subscription_id
tenant_id = var.azure_tenant_id
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
IaC/project-template-solution-1/variables.tf
variable "azure_subscription_id" {
type = string
description = "Azure Subscription Id"
}
variable "azure_tenant_id" {
type = string
description = "Azure Tenant Id"
}
variable "azure_rg_name" {
type = string
description = "Azure Resource Group Name"
}
variable "azure_resource_group_location" {
default = "west europe"
description = "Location of the resource group."
}
variable "azure_env_code" {
type = string
description = "Azure Environment Code"
}
variable "azure_project_code" {
type = string
description = "Azure Project Code"
}
IaC/deployments/azure/tenant.hcl
locals {
tenant_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
IaC/deployments/azure/subscription-test-1/subscription.hcl
locals {
subscription_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
IaC/deployments/azure/subscription-test-1/dev/env.hcl
locals {
environment = "dev"
}
TL;DR: I am trying to deploy architecture mixing terraform and terragrunt by using modules (modules folder) and "calling modules" (project-templates folder). To deploy at first with azure a resource group with an azure key vault inside it.
I tried to upload my code to GitHub but this is my first time using it so I might've done mistakes. You can find it here if you want to download it and edit it and send me your updates. https://github.com/leanne-kami/IaC
Thanks for anyone who will take the time to help me :)
A friend helped me to fix the issue with the two following steps:
IaC/deployments/azure/subscription-test-1/dev/client-test/terragrunt.hcl
IaC/project-templates/azure/project-template-solution-1/akv.tf
and
rg.tf
to make the directory understand the actual location of module
folders. module "rg" {
source ="../..//modules/azurerm/rg/"
azure_subscription_id = var.azure_subscription_id
azure_tenant_id = var.azure_tenant_id
azure_rg_name = var.azure_rg_name
azure_resource_group_location = var.azure_resource_group_location
}