37

I am new to terraform and trying to build an infrastructure with two subnets and VPC. I have created two modules

  • VPC
  • subnet

The VPC module will create a VPC and will return vpc_id as output, the same return vpc_id I am trying to use in the subnet module, but when I run the terraform plan, it asks me for the enter vpc_id input.

I want the vpc_id from the output value of the VPC module, can anyone please help me on the same.

Below is the code,

root tf file,

 provider "aws" {
  shared_credentials_file = var.shared_cred
  profile                 = "default" 
  region                  = var.aws_region
}

module "vpc" {
  source = "./vpc"
  name   = "terraformVPC"
  cidr   = "10.50.40.0/27"
}

module "private_subnet" {
  source      = "./subnet"
  subnet_name = "private_subnet"
  subnet_cidr = "10.50.40.16/28"
  #VPC_id = aws_vpc.moduleVPC.id
  VPCid = module.vpc.outvpc_id # this is the issue
}

module "public_subnet" {
  source      = "./subnet"
  subnet_name = "public_subnet"
  subnet_cidr = "10.50.40.0/28"
  VPCid      = module.vpc.outvpc_id
}

Subnet resource

resource "aws_subnet" "module_subnet" {
  cidr_block = var.subnet_cidr
  vpc_id     = var.VPCid

  tags = {
    Name = var.subnet_name
  }
}

Subnet module variable declaration

variable "subnet_name" {
  description = " define th subnet name"
}

variable "subnet_cidr" {
  description = "define th subnet cidr block"
}

variable "VPCid" {
  description = "Assign VPC id to subnet"
}

VPC output

output "outvpc_id" {
  value = "${aws_vpc.moduleVPC.id}"
}
3
  • should be value = aws_vpc.moduleVPC.id not value = "${aws_vpc.moduleVPC.id}". You should have an error message I think that tells you this? Commented Sep 25, 2020 at 13:58
  • Hi Liam, I don't get an error, but asks for the input variable for vpc_id and I thnk both perform the same action value = aws_vpc.moduleVPC.id and value = "${aws_vpc.moduleVPC.id}" Commented Sep 26, 2020 at 12:26
  • I have use same flow my project with this module composition. But when every time particular module get imported from another module only for referencing variables from that module. But instead of that Terraform plan showing same recourse to be create (duplicate) again. Can anyone know how to prevent that? Commented Jul 23, 2023 at 4:10

4 Answers 4

41

This is called "Module Composition". The important thing to remember is that you reference outputs of another module.

The format is: module.<object-name>.<output-name>

module "network" {
  source = "./modules/aws-network"

  base_cidr_block = "10.0.0.0/8"
}

module "consul_cluster" {
  source = "./modules/aws-consul-cluster"

  vpc_id     = module.network.vpc_id       # < output of module.network
  subnet_ids = module.network.subnet_ids   # < output of module.network
}
Sign up to request clarification or add additional context in comments.

Comments

1

When I use terraform for aws... My module name it's "network.ts" I don't think you need two tf files to manage your vpc and the subnets of that VPC.

network.tf

resource "aws_vpc" "vpc" {
  cidr_block           = "10.50.40.0/27"
  enable_dns_hostnames = true // only if you need
  tags                 = {
    Name = "desa-vpc-spotify" //Use your own name
  }
}

resource "aws_subnet" "private_subnet" {
  vpc_id            = aws_vpc.vpc.id
  availability_zone = "us-east-1a" //your own region
  cidr_block        = "10.50.40.16/28"
  tags = {
    Name = "desa-subnet-private-spotify"
  }
}

resource "aws_subnet" "public_subnet" {
  vpc_id            = aws_vpc.vpc.id
  availability_zone = "us-east-1a"//your own region
  cidr_block        = "10.50.40.0/28"
  tags = {
    Name = "desa-subnet-public-spotify"
  }
}

if you want vpc on another tf

(and if you want to have two files... only call the vpc like this)

another.tf

data "aws_vpc" "vpcs" {
  tags = {
    Name = "desa-vpc-spotify" //only put the name of the vpc of the network tf
  }
}


2 Comments

Thank you, Derek. I was just testing how to call variables between modules but looks like I am calling them in wrong way.
@Mahesh - would you mind posting the answer for everyone's benefit? I have this same scenario where I need help in passing output from 1 module to another. If you could publish the full code that does this that'd be really helpful. Thanks!
0

I notice that you have listed "VPCid =". When you run terraform validate does it throw an error? I would trying changing it to "vpc_id" instead and see if that works.

1 Comment

This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker.
0

I think this can help you better achieve what you are trying to do:

Root.tf

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.14.0"

  name = var.vpc_name
  cidr = var.vpc_cidr

  azs             = var.vpc_azs
  private_subnets = var.vpc_private_subnets
  public_subnets  = var.vpc_public_subnets

  enable_nat_gateway = var.vpc_enable_nat_gateway

  tags = var.vpc_tags
}

module "ec2_instances" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "3.5.0"
  count   = 2

  name = "my-ec2-cluster"

  ami                    = "ami-0c5204531f799e0c6"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [module.vpc.default_security_group_id]
  subnet_id              = module.vpc.public_subnets[0]

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

var.tf

variable "vpc_name" {
  description = "Name of VPC"
  type        = string
  default     = "example-vpc"
}

variable "vpc_cidr" {
  description = "CIDR block for VPC"
  type        = string
  default     = "10.0.0.0/16"
}

variable "vpc_azs" {
  description = "Availability zones for VPC"
  type        = list(string)
  default     = ["us-west-2a", "us-west-2b", "us-west-2c"]
}

variable "vpc_private_subnets" {
  description = "Private subnets for VPC"
  type        = list(string)
  default     = ["10.0.1.0/24", "10.0.2.0/24"]
}

variable "vpc_public_subnets" {
  description = "Public subnets for VPC"
  type        = list(string)
  default     = ["10.0.101.0/24", "10.0.102.0/24"]
}

variable "vpc_enable_nat_gateway" {
  description = "Enable NAT gateway for VPC"
  type        = bool
  default     = true
}

variable "vpc_tags" {
  description = "Tags to apply to resources created by VPC module"
  type        = map(string)
  default = {
    Terraform   = "true"
    Environment = "dev"
  }
}

You can get more info from https://learn.hashicorp.com/tutorials/terraform/module-use

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.