Search code examples
terraformterragrunt

Why is Terragrunt asking for input variables that shouldn't exist in the version of the module I'm calling in the "terraform" block?


I have two Terragrunt repositories in GitLab:

  • infrastructure-modules
  • infrastructure-live

In the infrastructure-modules repository I have an ec2 module with several versions that are indicated with git tags (eg. "v.0.0.12", "v.0.0.13", "v0.1.0" etc.).

I'm trying to call version "v.0.0.13" of the ec2 module in my infrastructure-live repository and launch a single EC2 instance with this code:

include "root" {
  path = find_in_parent_folders()
}

terraform {
  source = "../../../modules-ref//REDACTED-ec2?ref=v.0.0.13"
}
inputs = {
  name                        = "temp-ec2"
  ami                         = "ami-REDACTED"
  instance_type               = "t3a.small"
  num_servers                 = 1
  vpc_id                      = "vpc-REDACTED"
  subnet_ids                  = [
    "subnet-REDACTED"
  ]
  security_groups             = [
    "sg-REDACTED"
  ]

  key_name                    = "REDACTED"
  volume_size                 = 16
  tags = {
      environment             = "dev"
      createdby               = "REDACTED"
      CreatorName             = "REDACTED"
      approvedby              = "REDACTED"
      owner                   = "REDACTED"
      Product                 = "REDACTED"
      Customer                = "REDACTED"
      Tenant                  = "REDACTED"
      requester               = "REDACTED"
      Manager                 = "REDACTED"
    }
}

When I run the planning stage of the pipeline in GitLab, it fails with this error:

Error: No value for required variable │ │ on vars.tf line 42: │
42: variable "private_ips" { │ │ The root module input variable "private_ips" is not set, and has no default │ value. Use a -var or -var-file command line argument to provide a value for │ this variable.

This is unexpected, because the variable "private_ips" was not added until a later version ("v0.1.0" to be specific).

The tf.vars file where I have my input variables defined for this module looks like this in "v.0.0.13":

variable "ami" {
  description = "The AMI image (eg. ami-830c94e3)"
  type        = string
  #default = "ami-REDACTED"
}

variable "instance_type" {
  description = "This instance type (eg. t3a.small)"
  type        = string
  #default = "t3a.small"
}

variable "num_servers" {
  description = "The number of servers to be created (eg. 5)"
  type        = number
  #default = 2
}

variable "vpc_id" {
  description = "VPC ID (eg. vpc-abcdef1234567)"
  type        = string
  #default = "vpc-REDACTED"
}

variable "subnet_ids" {
  description = "List of subnet ids (eg. [\"subnet-abc123\", \"subnet-def456\", \"subnet-ghi789\"])"
  type        = list
  #default = [
  #  "subnet-REDACTED",
  #  "subnet-REDACTED"
  #]
}

variable "security_groups" {
  description = "List of security groups (eg. [\"sg-abc123\", \"sg-def456\"])"
  type        = list
  #default = [
  #  "sg-REDACTED"
  #]
}


variable "name" {
  description = "An appropriate name for your servers (eg. REDACTED)"
  type        = string
  #default = "alb-module-test"
}

variable "volume_size" {
  description = "The size of the root volume in GB (eg. 32)"
  type        = number
  #default = 16
}

variable "key_name" {
  description = "The keypair to be used for ssh (eg. my-keypair)"
  type        = string
  #default = "REDACTED"
}

variable "tags" {
  description = "A map of tags to add to all resources"
  type        = map(string)
  default     = {
  #    environment             = "REDACTED"
  #    createdby               = "REDACTED"
  #    CreatorName             = "REDACTED"
  #    approvedby              = "REDACTED"
  #    owner                   = "REDACTED"
  #    Product                 = "REDACTED"
  #    Customer                = "REDACTED"
  #    Tenant                  = "REDACTED"
  #    requester               = "REDACTED"
  #    Manager                 = "REDACTED"
  }                                                     
}

I can't figure out why Terragrunt is asking me for an input variable from "v0.1.0" when I'm calling version "v.0.0.13" of the module. At first glance it looks like I've mistakenly added an extra dot after the "v" in the tag name, but that is what the actual tag looks like in GitLab... it was a typo in early versions that I fixed starting with "v0.1.0".

Below is the module code from "main.tf" file in version "v.0.0.13":

resource "aws_instance" "app_servers" {

    ami                                  = var.ami
    instance_type                        = var.instance_type
    count                                = var.num_servers
    subnet_id                            = var.subnet_ids[count.index]
    associate_public_ip_address          = false
    security_groups                      = var.security_groups
    key_name                             = var.key_name

    root_block_device {
        delete_on_termination            = true
        encrypted                        = true
        volume_type                      = "gp3"
        volume_size                      = var.volume_size
        throughput                       = 125
        iops = 3000
    }

    tags = merge(
    {
      "Name" = "TF-MANAGED-${var.name}-${count.index}"
    },
    var.tags
  )

}

Any other ideas or troubleshooting steps I can take would be greatly appreciated as I'm completely stumped.

The only thing I can think might be happening is that there's some kind of mistake in how I'm calling the version of the module, and it's reverting to the latest version as a default... but I'm not sure what that mistake is if I've made one.


Solution

  • It's working now.

    I needed to change this:

    terraform {
      source = "../../../modules-ref//REDACTED-ec2?ref=v.0.0.13"
    }
    

    to this:

    terraform {
      source = "git::../../../modules-ref//REDACTED-ec2?ref=v.0.0.13"
    }
    

    With the original code, Terraform was treating my module source type as a local path and most likely dropping the query string that specified the version of the git repo I wanted. By adding "git::" to the beginning of the path it tells Terraform to use Git as the source type, and pulls the version specified in the query string at the end of the path.

    More details can be found in Hashicorp's documentation on Terraform module sources:

    Terraform Module Sources - Hashicorp