Назад | Перейти на главную страницу

переменная terraform внутри переменной

Я создаю vpc, а затем подсети, таблицу маршрутов и другие компоненты vpc, во многих ресурсах необходимо указать идентификатор vpc, в ресурсе aws_subnet в приведенном ниже примере я должен предоставить vpc_id = "$ {aws_vpc.test_vpc.мне бы}"

# 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"
    }
}

В случае изменения имени ресурса vpc мне нужно найти и заменить vpc_id во всех местах, есть ли лучший способ сделать это? Я пробовал использовать переменную внутри переменной, но это не сработало.

# 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"
    }
}

Terraform не поддерживает такого рода «динамическую интерполяцию»; ожидается, что в конкретном модуле граф будет четко определен, потому что все в модуле находится в одной и той же области и, следовательно, отношения между вещами не должны постоянно меняться.

Вы на самом деле не упомянули, какую реальную проблему вы пытались решить здесь, но похоже, что вы пытаетесь обобщить создание подсети, чтобы вы могли использовать одну и ту же конфигурацию для нескольких подсетей в разных VPC. В этом случае предлагаемый шаблон заключался бы в создании отдельного модуль для подсети, а затем передайте идентификатор VPC в качестве переменной модуля. Вот как может выглядеть модуль подсети:

variable "vpc_id" {
}

variable "name" {
}

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

Определив этот модуль, вы можете многократно создавать его экземпляры из другого модуля:

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}"
}

Здесь дочерний модуль просто содержит подсеть, поскольку это то, что вы указали в своем примере. Если у вас есть другие ресурсы, которые зависят от VPC, вы можете сгруппировать их все вместе в один модуль, тогда вы можете достичь своей цели - иметь возможность изменять VPC только в одном месте: вы просто меняете значение аргумента модуля в вызывающий модуль, и все интерполяции переменной внутри модуля будут автоматически обновлены для следующего запуска.

Интерполяция теперь доступно. Следующая документация:

resource "aws_instance" "web" {
  subnet = "${var.env == "production" ? var.prod_subnet : var.dev_subnet}"
}