MP32
MP32

Reputation: 721

vpc_id argument is not expected here

I’m new to using modules in Terraform and I’m getting an error from my main.tf in my root module, saying “an argument vpc_id is not expected here” and this error is occurring for my “sg” module block at the bottom.

Here is my main.tf in my root module

  access_key = var.my_access_key
  secret_key = var.my_secret_key
  region     = var.region
}

provider "random" {
}

resource "random_id" "prefix" {
  byte_length = 8
}

module "ec2" {
  source = "./modules/ec2"
  infra_env = var.infra_env
  public_ssh_key = var.public_ssh_key
  allow_rdp = module.sg.allow_rdp.id
  allow_winrm = module.sg.allow_winrm.id
}

module "iam" {
  source = "./modules/iam"
  infra_env = var.infra_env
}

module "s3" {
  source = "./modules/s3"
  infra_env = var.infra_env
}

module "sg" {
  source = "./modules/sg" 
  infra_env = var.infra_env
  vpc_id = module.vpc.vpc_1.id
  }

module "vpc" {
  source = "./modules/vpc"
  infra_env = var.infra_env
}

Here is the Main.tf of my “SG” module- I thought I only had to put “module.vpc.vpc_1.id” to get the input from that module

terraform {
  required_version = ">= 1.1.5"
}

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

    infra_env = var.infra_env
  }

# Allow WinRM to set adminstrator password
resource "aws_security_group" "allow_winrm" {
  name        = "allow_winrm"
  description = "Allow access the instances via WinRM over HTTP and HTTPS"
  vpc_id      = module.vpc.vpc_1.id

  ingress {
    description = "Access the instances via WinRM over HTTP and HTTPS"
    from_port   = 5985
    to_port     = 5986
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.infra_env}-allow-winrm"
  }
}

# Allow RDP connectvity to EC2 instances
resource "aws_security_group" "allow_rdp" {
  name        = "allow_rdp"
  description = "Allow access the instances via RDP"
  vpc_id      = module.vpc.vpc_1.id

  ingress {
    description = "Allow access the instances via RDP"
    from_port   = 3389
    to_port     = 3389
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.infra_env}-allow-rdp"
  }
}

Here are the outputs for my VPC module, located in my VPC module:

output "subnet_1" {
  value = aws_subnet.subnet_1
}

output "vpc_1" {
  value = aws_vpc.vpc_1.id
}

output "gw_1" {
  value = aws_internet_gateway.gw_1
}

Upvotes: 0

Views: 3691

Answers (1)

Marko E
Marko E

Reputation: 18108

There are a couple of problems with your code. In the outputs, you have written this:

output "vpc_1" {
  value = aws_vpc.vpc_1.id
}

This means that the output value will already provide the VPC ID you want. It is enough to reference it only by name: module.vpc.vpc_1. More information about referencing module outputs is available in [1].

Second issue here is that you are trying to reference an output of a child module (VPC) in another child module (SG):

vpc_id      = module.vpc.vpc_1.id

However, it would be enough to specify a variable in the child module (i.e., SG). For example, you could define a variable like this:

variable "vpc_id" {
  description = "VPC ID."
  type        = string
}

Then, you would just write the above as:

vpc_id      = var.vpc_id

When calling the SG module, you would use the following:

module "sg" {
  source = "./modules/sg"
 
  infra_env = var.infra_env
  vpc_id    = module.vpc.vpc_1
}

Note that the same change with var.vpc_id should be done everywhere in the SG module where module.vpc.vpc_1.id was referenced.


[1] https://www.terraform.io/language/values/outputs#accessing-child-module-outputs

Upvotes: 3

Related Questions