0

I'm trying to run my terraform scripts and it's throwing the above errors.

Project Synopsis: I'm creating an AWS multi-account infrastructure using AWS organizations to create a dev and prod environment. Scripts shown here is only for the dev_account

I created a module for the organizational unit (ou) and accounts differently and called them in the root module

Root main.tf

# Root main.tf 

module "dev_account" {
  source    = "./modules/accounts"
  name      = "development_account"
  parent_id = aws_organizations_organizational_unit.development.id
  email     = "myemail@gmail.com"
}

organizational unit(ou) module

# ./modules/ous/main.tf

data "aws_organizations_organization" "root" {}

locals {
  root_id = data.aws_organizations_organization.root.roots[0].id
}

resource "aws_organizations_organizational_unit" "development" {
  name      = "development_ou"
  parent_id = local.root_id
}

Accounts module

# ./modules/accounts/main.tf
# Showing only dev_account

resource "aws_organizations_account" "dev_account" {
  name      = var.name
  email     = var.email
  parent_id = var.parent_id
}

resource "aws_iam_account_password_policy" "dev_account" {
  max_password_age               = var.max_password_age
  minimum_password_length        = var.minimum_password_length
  allow_users_to_change_password = var.allow_users_to_change_password
  hard_expiry                    = var.hard_expiry
  password_reuse_prevention      = var.password_reuse_prevention
  require_lowercase_characters   = var.require_lowercase_characters
  require_uppercase_characters   = var.require_uppercase_characters
  require_numbers                = var.require_numbers
  require_symbols                = var.require_symbols
}

Accounts module variables

# ./modules/accounts/variables.tf

variable "name" {
    default = "development_account"
}

variable "email" {
    default = "myemail@gmail.com"
}

variable "parent_id" {
    description = "parent of root organization"
}

variable "max_password_age" {
    default = "90"
}
               
variable "minimum_password_length" {
    default = "8"
}
       
variable "allow_users_to_change_password" {
    default = "true"
}

variable "hard_expiry" {
    default = "true"
}
                  
variable "password_reuse_prevention" {
    default = "true"
}
      
variable "require_lowercase_characters" {
    default = "true"
}
   
variable "require_uppercase_characters" {
    default = "true"
}
   
variable "require_numbers" {
    default = "true"
}
                
variable "require_symbols" {
    default = "false"
}

Error

 Error: Reference to undeclared resource
│ 
│   on main.tf line 16, in module "dev_account":
│   16:   parent_id = aws_organizations_organizational_unit.development.id
│ 
│ A managed resource "aws_organizations_organizational_unit" "development" has not been declared in the root module.

I'm currently stuck in how to resolve this

sam hassan
  • 197
  • 3
  • 14
  • We need to see the declaration of the `ou` module. – Matthew Schuchard Jan 13 '22 at 19:02
  • @MattSchuchard The above is my entire scripts. The ou module contents is in the `main.tf` as shown above. The roote module is the first script in `main.tf`. That's all that I've got – sam hassan Jan 13 '22 at 21:38
  • So just to confirm: the `ou` module is not declared nor has outputs? – Matthew Schuchard Jan 13 '22 at 22:01
  • Absolutely. Nothing more aside what you can see – sam hassan Jan 13 '22 at 22:07
  • Yup, so Matt asked a good question: you can't use the output of a resource created within a module unless you specifically define an output that corresponds to `aws_organizations_ogranizational_unit.development.id` and use that output in the root module. – Marko E Jan 14 '22 at 08:41

1 Answers1

1

I don't know if you are mentioning it just as an example but in your module "dev_account" you are referring to the ID that was already passed as input in the module definition itself.

Therefore, to be more generic, in order to use a resource output, you need to specify it. As a detailed response, the process to do it is the following:

  1. Create an output.tf inside your organizational unit(ou) module.
  2. Add the following block:
output "development_account_id" {
  description = "Development account ID"
  value       = aws_organizations_organizational_unit.development.id
}
  1. Now in main.tf file, in the calling module you can use it like following:
parent_id = module.development.development_account_id

Now your module has an input that could be used by another module in your root main file. Please adjust the naming accordingly. I hope this was helpful.

Ouma
  • 598
  • 1
  • 4
  • 15