TERRAFORM LOCALS VS VARIABLES IN MODULES

March 19, 2024by Oladapo Babalola0

Some users can get overly ambitious, and I’ll tell you why. A developer reached out to me asking for a way to deploy EC2 instances programmatically in their development workspace. Being the helpful engineer that I am, I provided them with a Terraform project configuration file. This file called an EC2 module with customizable provisioners, allowing the developer to install all the dependencies needed for their code base.

However, they came back to me with a question: why couldn’t they overwrite the default AMI (Amazon Machine Image) and instance type defined in the project.tf file to a larger size? This situation made me realize the power of using locals and variables in Terraform configurations. Now, I’ll explain a simple way to implement this, especially when sharing modules with cross-functional teams.

In layman’s terms, let’s understand the difference between using locals and variables in Terraform modules when you want to restrict users from changing certain parameters, like the default port of an application within a module.

Using Variables:

When you define a variable in a module, it’s like leaving a space for someone to fill in. Users can provide their own values when they call the module. For instance, if you define a variable app_port, users can set it to whatever port they want, including changing the default port.

So, if you have a security group module in AWS where the default port has been changed from port 22 (SSH) to something else, users can potentially change it to any other port they desire leaving room for exploitation from the internet.

Using Locals:

Locals, on the other hand, are like internal notes that only the module itself can read. They are defined within the module and are not exposed for users to change directly. You can use locals to set default values that cannot be overridden by users.

If you define the default port as a local value within the module, users won’t have direct access to change it when calling the module. For example, if you set the default port to 5249 using locals, users won’t be able to overwrite this value to set a different port 22.

So, in the context of a security group on AWS:

If you use variables for specifying ports, users can freely change those ports to anything they want when using the module.

If you use locals to define default ports within the module, users won’t have the ability to change those default ports when calling the module. This ensures that certain critical parameters, like security group ports, remain consistent and secure across all deployments.

Find the terraform configuration samples below:

I’ll define a Security Group Module called sg.tf in a separate folder

# modules/security_group/sg.tf
resource “aws_security_group” “security_group” {
  name        = “terraform-example-sg”
  description = “Allow SSH inbound traffic”
  # Define ingress rules
  ingress {
    from_port   = local.app_port
    to_port     = local.app_port
    protocol    = “tcp”
    cidr_blocks = [“0.0.0.0/0”] # Allow SSH access from anywhere
  }
  # Allow all outbound traffic
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = “-1”
    cidr_blocks = [“0.0.0.0/0”]
  }
}
locals {
  app_port = 5249
}
variable “app_port” {
}

Next up is to define the project file that would be given to the developer

provider “aws” {
  region = “us-west-2”
}
# Include the security group module
module “security_group” {
  source   = “../../modules/security_group/”
  app_port = 22
}

Running terraform plan here would output the execution plan and you’d see that even if a developer manually inputs a variable as seen above (app_port = 22) the terraform output would display the right port of 5249.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright by DevOps as a Service Nigeria. All rights reserved.

Copyright by DevOps as a Service Nigeria. All rights reserved.