Terragrunt not writing outputs?

It’s not immediately clear to me if this is actually coming from terragrunt or somewhere in between, but when I’m running terragrunt to apply a third party module, I’m not getting any outputs in my terraform state.

For example, using https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/v2.24.0 as a test case, when I call this module via:

instance.tfvars:

instance = {
  vpc_name = "ec2-test"
  vpc_cidr = "10.100.0.0/16"

  enable_nat_gateway = true
  enable_vpn_gateway = false

  private_subnets = [
    "10.100.1.0/24",
    "10.100.2.0/24",
    "10.100.3.0/24"
  ]

  public_subnets = [
    "10.100.101.0/24",
    "10.100.102.0/24",
    "10.100.103.0/24"
  ]

  tags = {
    terraform = "true"
    environment = "dev"
  }

}

infra and vpc-directory specific terragrunt.hcl:

terraform {
  source = "git@github.com:some-repo/my-units.git//aws-vpc?ref=aws-vpc-playground"
}

include {
  path = find_in_parent_folders()
}

the unit:

terraform {
  backend "s3" {}
}

provider "aws" {
  region = local.inputs.aws_region
}

module "vpc" {
  source             = "terraform-aws-modules/vpc/aws"
  version            = "2.24.0"
  name               = local.inputs.vpc_name
  cidr               = local.inputs.vpc_cidr
  azs                = local.inputs.availability_zones
  private_subnets    = local.inputs.private_subnets
  public_subnets     = local.inputs.public_subnets
  enable_nat_gateway = local.inputs.enable_nat_gateway
  single_nat_gateway = "${lookup(local.inputs, "single_nat_gateway", true)}"
  enable_vpn_gateway = local.inputs.enable_vpn_gateway
  tags               = local.inputs.tags
}

If I run terraform directly against this module without a ‘unit’ in between and/or terragrunt involved, the outputs are added as expected.

I suspect this outputs issue could be related to the outputs issue I was seeing at the start of Examples of 3-Tier Module Structure.

Is there something I need to be doing in the ‘units’ to ensure that outputs are getting written correctly, or is it possible that this something that terragrunt is not handling properly?

Answer:

I needed to define an output in the ‘unit’ or ‘root’ module, e.g.

the unit:

terraform {
  backend "s3" {}
}

provider "aws" {
  region = local.inputs.aws_region
}

module "vpc" {
  source             = "terraform-aws-modules/vpc/aws"
  version            = "2.24.0"
  name               = local.inputs.vpc_name
  cidr               = local.inputs.vpc_cidr
  azs                = local.inputs.availability_zones
  private_subnets    = local.inputs.private_subnets
  public_subnets     = local.inputs.public_subnets
  enable_nat_gateway = local.inputs.enable_nat_gateway
  single_nat_gateway = "${lookup(local.inputs, "single_nat_gateway", true)}"
  enable_vpn_gateway = local.inputs.enable_vpn_gateway
  tags               = local.inputs.tags
}

output {
  value = module.vpn
}

I needed to define an output in the ‘unit’ or ‘root’ module, e.g.

Yes, exactly this! If you want to pass along outputs from any modules you’re using, you need to expose them through an output of your own in your code. Your example captures it perfectly.