4

I'm trying to setup some IaC for a new project using Hashicorp Terraform on AWS. I'm using modules because I want to be able to reuse stuff across multiple environments (staging, prod, dev, etc.)

I'm struggling to understand where I have to set an output variable within a module, and how I then use that in another module. Any pointers to this would be greatly appreciated!

I need to use some things created in my VPC module (subnet IDs) when creating EC2 machines. My understanding is that you can't reference something from one module in another, so I am trying to use an output variable from the VPC module.

I have the following in my site main.tf

module "myapp-vpc" {
  source     = "dev/vpc"
  aws_region = "${var.aws_region}"
}

module "myapp-ec2" {
 source     = "dev/ec2"
 aws_region = "${var.aws_region}"
 subnet_id  = "${module.vpc.subnetid"}
}

dev/vpc simply sets some values and uses my vpc module:

module "vpc" {
  source = "../../modules/vpc"

  aws_region = "${var.aws_region}"

  vpc-cidr            = "10.1.0.0/16"
  public-subnet-cidr  = "10.1.1.0/24"
  private-subnet-cidr = "10.1.2.0/24"
}

In my vpc main.tf, I have the following at the very end, after the aws_vpc and aws_subnet resources (showing subnet resource):

resource "aws_subnet" "public" {
  vpc_id                  = "${aws_vpc.main.id}"
  map_public_ip_on_launch = true
  availability_zone       = "${var.aws_region}a"
  cidr_block              = "${var.public-subnet-cidr}"
}

output "subnetid" {
  value = "${aws_subnet.public.id}"
}

When I run terraform plan I get the following error message:

Error: module 'vpc': "subnetid" is not a valid output for module "vpc"

1
  • After adding syntax highlighting to your question, I noticed there is a missing double quotes (") to your subnetid output in the last code block which may have caused your initial error. Commented Feb 27, 2019 at 14:18

1 Answer 1

16

Outputs need to be passed up through each module explicitly each time.

For example if you wanted to output a variable to the screen from a module nested below another module you would need something like this:

child-module.tf

output "child_foo" {
  value = "foobar"
}

parent-module.tf

module "child" {
  source = "path/to/child"
}

output "parent_foo" {
  value = "${module.child.child_foo}"
}

main.tf

module "parent" {
  source = "path/to/parent"
}

output "main_foo" {
  value = "${module.parent.parent_foo}"
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.