terraform variable inside variable

6,643

Terraform doesn't support this sort of "dynamic interpolation"; it's expected that within a particular module the graph is well-defined, because everything in a module is in the same scope and thus relationships between things shouldn't be changing constantly.

You didn't really mention what real-world problem you were trying to solve here, but it looks like you're trying to generalize subnet creation so you can use the same configuration for multiple subnets in different VPCs. In that case, the suggested pattern would be to create a separate module for the subnet part, and then pass in the VPC id as a module variable. Here's what the subnet module might look like:

variable "vpc_id" {
}

variable "name" {
}

resource "aws_subnet" "public" {
    vpc_id = "${var.vpc_id}"
    ...
    ...     
    tags {
        Name = "${var.name}"
    }
}

With this module defined, you can then instantiate it many times from within another module:

resource "aws_vpc" "test_vpc" {
    cidr_block = "${var.test_vpc_cidr}"

    tags {
        Name = "test_vpc"
    }
}

resource "aws_vpc" "production_vpc" {
    cidr_block = "${var.production_vpc_cidr}"

    tags {
        Name = "production_vpc"
    }
}

module "test_subnet" {
    source = "./subnet" # specify where the subnet module can be found

    name = "test_subnet_1"
    vpc_id = "${aws_vpc.test_vpc.id}"
}

module "production_subnet" {
    source = "./subnet" # specify where the subnet module can be found

    name = "production_subnet_1"
    vpc_id = "${aws_vpc.production_vpc.id}"
}

Here the child module just contains a subnet, since that's what you gave in your example. If you have other resources that depend on the VPC, you can group them all together into a single module then you can achieve your goal of being able to change the VPC in just one place: you just change the value of the module argument in the calling module, and all of the interpolations of the variable inside the module will automatically be updated for the next run.

Share:
6,643

Related videos on Youtube

Deepak Deore
Author by

Deepak Deore

Updated on September 18, 2022

Comments

  • Deepak Deore
    Deepak Deore over 1 year

    I am creating a vpc, and then subnets, route table and other vpc components, in many resources vpc id needs to be provided, in aws_subnet resource of below example, I have to provide vpc_id = "${aws_vpc.test_vpc.id}"

    # Create vpc
    resource "aws_vpc" "test_vpc" {
        cidr_block = "${var.vpc_cidr}"
    
        tags {
            Name = "test_vpc"
        }
    }
    
    # Create public subnets
    resource "aws_subnet" "public" {
        vpc_id = "${aws_vpc.test_vpc.id}"
        ...
        ...     
        tags {
            Name = "subnet_1"
        }
    }
    

    In case of changing vpc resource name, I have to find and replace vpc_id in all places, is there a better way of doing it? I tried using variable inside variable but it doesn't work.

    # Create vpc
    resource "aws_vpc" "${var.vpc_name}" {
        cidr_block = "${var.vpc_cidr}"
    
        tags {
            Name = "${var.vpc_name}"
        }
    }
    
    # Create public subnets
    resource "aws_subnet" "public" {
        vpc_id = "${aws_vpc.${var.vpc_name}.id}"
        ...
        ...     
        tags {
            Name = "subnet_1"
        }
    }