gruntwork-io / terragrunt

Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.
https://terragrunt.gruntwork.io/
MIT License
8.04k stars 975 forks source link

A managed resource "azurerm_resource_group" "rg" has not been declared in the root module #1151

Closed aditya-ambati closed 4 years ago

aditya-ambati commented 4 years ago

Terragrunt version terragrunt version v0.23.10

Terraform version Terraform v0.12.24

Directory Structure terraform-live/ ├── prod │   └── resource_group │   ├── main.tf │   └── terragrunt.hcl └── terragrunt.hcl

contents of terraform-live/terragrunt.hcl

    backend = "azurerm"
    config = {
        key = "${path_relative_to_include()}/terraform.tfstate"
        resource_group_name = "common-rg"
        storage_account_name = "testsa01"
        container_name = "tfstate"
      }
}

contents of terraform-live/prod/resource_group/main.tf

backend "azurerm" {}
}

contents of terraform-live/prod/resource_group/terragrunt.hcl

terraform {
  source = "git::git@github.com:adi4dpeople/terraform_modules.git//resource_group?ref=v0.0.1"
}

# Include all settings from the root terragrunt.hcl file
include {
  path = find_in_parent_folders()
}

# These are the variables we have to pass in to use the module specified in the terragrunt configuration above
inputs = {
  location = "westus"
  rg_name  = "testrg01"
}

When i run terragrunt plan, i get the following error:

[terragrunt] 2020/04/24 22:24:39 Reading Terragrunt config file at /home/aditya/terraform-live/prod/resource_group/terragrunt.hcl
[terragrunt] [/home/aditya/terraform-live/prod/resource_group] 2020/04/24 22:24:39 Running command: terraform --version
[terragrunt] 2020/04/24 22:24:44 Terraform files in /home/aditya/terraform-live/prod/resource_group/.terragrunt-cache/Hovi5Z9TKrGgHU_Lf1P2xFmhkm0/4M87gZKvnrwMknqj9CwuSBSfiHk/resource_group are up to date. Will not download again.
[terragrunt] 2020/04/24 22:24:44 Copying files from /home/aditya/terraform-live/prod/resource_group into /home/aditya/terraform-live/prod/resource_group/.terragrunt-cache/Hovi5Z9TKrGgHU_Lf1P2xFmhkm0/4M87gZKvnrwMknqj9CwuSBSfiHk/resource_group
[terragrunt] 2020/04/24 22:24:44 Setting working directory to /home/aditya/terraform-live/prod/resource_group/.terragrunt-cache/Hovi5Z9TKrGgHU_Lf1P2xFmhkm0/4M87gZKvnrwMknqj9CwuSBSfiHk/resource_group
[terragrunt] [/home/aditya/terraform-live/prod/resource_group] 2020/04/24 22:24:44 Backend azurerm has not changed.
[terragrunt] [/home/aditya/terraform-live/prod/resource_group] 2020/04/24 22:24:44 Running command: terraform init -backend-config=access_key=xxxxxxxxxxxx -backend-config=container_name=tfstate -backend-config=key=prod/resource_group/terraform.tfstate -backend-config=resource_group_name=testrg01 -backend-config=storage_account_name=testsa01

Initializing the backend...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
[terragrunt] 2020/04/24 22:24:52 Running command: terraform plan
Acquiring state lock. This may take a few moments...

Error: Reference to undeclared resource

  on outputs.tf line 2, in output "id":
   2:   value = azurerm_resource_group.rg.id

A managed resource "azurerm_resource_group" "rg" has not been declared in the
root module.

Error: Reference to undeclared resource

  on outputs.tf line 6, in output "name":
   6:   value = azurerm_resource_group.rg.name

A managed resource "azurerm_resource_group" "rg" has not been declared in the
root module.

Releasing state lock. This may take a few moments...
[terragrunt] 2020/04/24 22:25:01 Hit multiple errors:
exit status 1 
aditya@LAPTOP-6C2MPJDV:~/terraform-live/prod/resource_group$

Followed the directory structure suggested here https://terratest.gruntwork.io/docs/getting-started/quick-start/

Please let me know if this is a bug or I'm missing something here.

tbugfinder commented 4 years ago

Could you share the module source repo?

aditya-ambati commented 4 years ago

@tbugfinder thank you for your quick response. Here are my modules:

aditya@LAPTOP-6C2MPJDV:~/terraform_modules/resource_group$ tree
.├── main.tf
├── outputs.tf
├── vars.tf
└── versions.tf

contents of main.tf

resource "azurerm_resource_group" "rg" {
  name     = var.rg_name
  location = var.location
}

contents of outputs.tf

output "id" {
  value = azurerm_resource_group.rg.id
}
output "name" {
  value = azurerm_resource_group.rg.name
}
variable "rg_name" {
  default     = ""
  description = "Name of the resource group"
}
variable "location" {
  default     = "westus"
  description = "Geographic location of the Resource Group"
}

Before I tried terragrunt, i used to have environments folders for each environment (eg: prod,stage) through which i call the modules and it was working fine but i had too much duplicate data. Below is how i used to call modules before:

module "resource_group" {
  source   = "../../resource_group"
  rg_name  = var.rg_name
  location = var.location
}
tbugfinder commented 4 years ago

Is there a duplicate outputs.tf around?

aditya-ambati commented 4 years ago

No, I have outputs.tf only in my terraform_modules/resource_groups/

Under terraform_modules, I have different modules folders like resource_group, virtual_machine etc, and each folder contains it's corresponding outputs.tf. I used to refer these outputs while calling the modules from my environments main.tf files. Let me know if its a bit confusing for you. I can clarify by providing further artifact's.

tbugfinder commented 4 years ago

Did you verify that referenced repo+tag includes the rg resource? git::git@github.com:adi4dpeople/terraform_modules.git//resource_group?ref=v0.0.1

aditya-ambati commented 4 years ago

As I have already mentioned in the previous comments, in my terraform_modules/resource_group/main.tf it is there. It doesn't seem like the issue is with the module outputs because they have been working for a very long time. The only difference is I'm calling the modules from terragrunt instead of my environment directory. Could you please try to reproduce it at your end because it's only a single and small module.

resource "azurerm_resource_group" "rg" {
  name     = var.rg_name
  location = var.location
}
output "id" {
  value = azurerm_resource_group.rg.id
}
output "name" {
  value = azurerm_resource_group.rg.name
}
aditya-ambati commented 4 years ago

@tbugfinder I have noticed that, when i run terragrunt plan there is .terragrunt-cache folder created which pulls all my modules from github to local. In there i see that module's resource_group/main.tf contents have been replaced by terragrunt with the main.tf contents in my live folder resource_group main.tf so that is why my outputs.tf is throwing error.

image

I tried removing the main.tf in live folder and re ran the terragrunt, but it throws below error:

Found remote_state settings in /home/aditya/terraform-live/prod/resource_group/terragrunt.hcl but no backend block in the Terraform code in /home/aditya/terraform-live/prod/resource_group/.terragrunt-cache/Hovi5Z9TKrGgHU_Lf1P2xFmhkm0/4M87gZKvnrwMknqj9CwuSBSfiHk/resource_group. You must define a backend block (it can be empty!) in your Terraform code or your remote state settings will have no effect! It should look something like this:

terraform {
  backend "azurerm" {}
}
lorengordon commented 4 years ago

@adi4dpeople just rename main.tf in your live folder. can be any other .tf filename, as long as it does not conflict with .tf files in your source module.

lorengordon commented 4 years ago

alternatively, use terragrunt's generate argument in your remote_state configuration. then you can remove that .tf file entirely from your live folder. terragrunt will write a backend config file for you.

  remote_state {
    backend = "azurerm"
    config = {
        key = "${path_relative_to_include()}/terraform.tfstate"
        resource_group_name = "common-rg"
        storage_account_name = "testsa01"
        container_name = "tfstate"
      }
    generate = {
      path      = "backend.tf"
      if_exists = "overwrite_terragrunt"
    }
  }
aditya-ambati commented 4 years ago

Thanks a lot @lorengordon it worked 👍 My final terragrunt.hcl looks like below. I also had to add provider config along with back end config for restricting provider version

remote_state {
    backend = "azurerm"
    config = {
        key = "${path_relative_to_include()}/terraform.tfstate"
        resource_group_name = "bwudhubrg01"
        storage_account_name = "bwudhubtfsa01"
        container_name = "tfstate"
      }
    generate = {
      path      = "backend.tf"
      if_exists = "overwrite_terragrunt"
    }
  }

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider "azurerm" {
  version = "1.36.0"
}
EOF
}