Search code examples
terraformterraform-aws-modules

Terraform - Unable to pass string variable to child module


I have terraform setup with a number of nested modules. Simplified it looks like this

├── modules
│   ├── sec-groups
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   ├── variables.tf
│   │   └── versions.tf
├── dev
│   ├── env.dev.tfvars
│   ├── main.tf
│   ├── versions.tf
│   └── variables.tf
└── prod
    ├── env.prod.tfvars
    ├── main.tf
    ├── versions.tf
    └── variables.tf



Where in dev:

main.tf

module "aws_dev_sec-groups" {
  source = "../modules/sec-groups"

  vpc_name   = aws_vpc.dev_bp_vpc
  vpc_id     = aws_vpc.dev_bp_vpc.id

  localip  = var.localip
}

variables.tf

variable "localip" {
  type = string
}

env.dev.tfvars

localip = "1.1.1.1/32"



And in the sec-groups module:

main.tf

resource "aws_security_group" "servers_sg" {
  name = "servers_sg"
  description = "Traffic allowed to and from Servers"
  vpc_id = var.vpc_id
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.localip]
  }
}

variables.tf

variable vpc_id {}
variable localip {
  type = string
}

--

'terraform init' produces expected results. However, 'terraform plan' produces the following error. To me this suggests an empty localip variable, which means I'm not correctly declaring the variable, is this the case?

Error: "" is not a valid CIDR block: invalid CIDR address:

  on ../modules/sec-groups/main.tf line 63, in resource "aws_security_group" "servers_sg":
  63: resource "aws_security_group" "servers_sg" {
  }

Thanks in advance

--

% terraform -v
    Terraform v0.13.0
    + provider registry.terraform.io/hashicorp/aws v3.2.0
    + provider registry.terraform.io/hashicorp/random v2.3.0

Solution

  • It turns out I has completely miss-understood how modules work. I assumed that submodules needed to use variables from the parent or other submodules by specifying multiple module blocks within the submodule. I found I was passing variables from multiple submodules to every submodule, which seems odd in hindsight but didn't at the time.

    This meant some submodules were trying to re-instantiate multiple times, in a loop, hence the error messages. I now realise the beast approach is for the parent module to call the output values of submodules to pass to other submodules and that submodules should not reference one another using the same variables as those in the parent module.

    Thanks for all the pointers with this, apologies for the red-herring reference the localip variable.