Search code examples
terraformterraform-provider-awsterraform-modules

Terraform-AWS-Modules-using subnet-id of a VPC child module in another ec2 child module


I will start by thanking you for your time and I have been googling and reading and maybe just overlooking something very simple. I have tried my best with some articles on medium and the terraform documentation.

So, my problem is.. I have a root module that looks like this

module "VPC" {
    source = "/home/jamie/Terraform_Project/modules/vpc/"
}

module "Key_Pair" {
    source = "/home/jamie/Terraform_Project/modules/key_pair/"
}

module "EC2_VPN" {
    source = "/home/jamie/Terraform_Project/modules/ec2_vpn/"
}

and three child modules as you can see. I cannot reference the "Public_Subnet_ID" from my VPC module in my EC2 module. I will show my main.tfs and my output.tfs below. I think its worth mentioning that I have tried various things I have found on google and don't seem to get anywhere below is my latest attempt. i have seen other answers on stackoverflow but they have not worked for me or i am still doing something wrong.

VPC - main.tf (will show subnet bit only)

/* Public Subnet */
resource "aws_subnet" "public_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
  map_public_ip_on_launch = true

  tags = {
    Name = "Public"
    Project = var.project
    Architect = var.architect
  }
}

VPC - output.tf

output "public_subnet_id" {
    value = aws_subnet.public_subnet.id
}

**EC2 - main.tf (problem bit)

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
  subnet_id = var.public_subnet_id
  key_name = "${var.project}_Key"

  tags = {
    Name = "VPN_Server"
    Project = var.project
    Architect = var.architect
  }
}

i also tried the above with variable (maybe wrong from another thread/guide)

my first errors where the "module.1_VPC.Public_Subnet_id" wasnt referenced but managed to get that bit but now it just ends up with

Error: creating EC2 Instance: InvalidSubnetID.NotFound: The subnet ID 'module.1_VPC.Public_Subnet_id' does not exist │ status code: 400, request id: 00fa3944-4ea3-450b-9fd4-39645785269f │ │ with module.EC2_VPN.aws_instance.web, │ on .terraform/modules/EC2_VPN/main.tf line 17, in resource "aws_instance" "web": │ 17: resource "aws_instance" "web" {

Again thankyou for taking the time, I am learning and trying to build / learn as I go not just copy and paste other templates.

tried various guides / terraform docs (most ref modules but in same file not separated folders)

i just need to be able to export a resourse_id for use in another child modules. once i can do this i will be able to duplicate for security groups and anything else i need to ref.


Solution

  • DISCLAIMER: Module development is very dynamic and sometimes subjective. Below are some points to start with and to support with your query.

    There seem to be many things to be addressed in your modules but I would try to share the minimal info you need to fix and initialize this.

    1. In your VPC child module you usually do not need the subnet_id attribute.

    module "VPC" {
        source = "/home/jamie/Terraform_Project/modules/1_VPC/"
    
    
        # subnet_id = "module.VPC.Public_Subnet_id"
    }
    
    • Because you are creating the subnet itself in the child module it is not required.
    • Only required inputs are needed to be defined here, in simple words variables definitions whose default values are not set or which you want to override are needed in the root module while calling the child module.
    • Output for subnet_id and any other attribute which makes sense to be used by other modules should be defined.

    2. Parameterize the EC2 child module

    resource "aws_instance" "web" {
      ami           = data.aws_ami.ubuntu.id
      instance_type = "t3.micro"
      subnet_id     = var.subnet_id
      key_name      = "${var.project}_Key"
    
      tags = {
        Name      = "VPN_Server"
        Project   = "${var.project}"
        Architect = "${var.architect}"
      }
    }
    
    • You can/should parameterize all the inputs which are dynamic just like in any module development so that it can be overridden/set on the root module if required.

    • One side note that "${var.project}" is not mandatory var.project is totally fine with recent terraform versions.

    In this case, I have updated subnet_id = var.subnet_id

    3. Adapt the EC2 root module with new changes.

    module "EC2_VPN" {
        source = "/home/jamie/Terraform_Project/modules/3_EC2_VPN/"
    
        subnet_id = module.VPC.subnet_id
    }
    
    • As mentioned in 2. point you need a variable defined in your child module of EC2 and output for subnet_id in your VPC child module with the value of subnet_id you need here to pass.

    Helpful documentation