#amazon-web-services #terraform #terraform-provider-aws
#amazon-веб-сервисы #terraform #terraform-поставщик-aws
Вопрос:
У нас довольно сложная среда, в которой у нас много учетных записей AWS в разных регионах, и все они подключены к транзитной сети через VPN-туннели.
На данный момент мы развертываем клиентские шлюзы через модуль «VPC» для каждого VPC в регионе, но проблема, с которой мы сталкиваемся, заключается в том, что развертывание первого VPC проходит нормально, но последующие развертывания VPC вызывают проблемы с тем фактом, что CGW уже существует, и поэтому нам нужно импортировать его, прежде чем мы сможем продолжить, чтоэто не идеальное место для работы, и я также думаю, что есть риск, что если мы отключим VPC, он может попытаться уничтожить CGW, который используется другими VPN.
То, что я хочу сделать, это развернуть CGW отдельно от VPC, а затем VPC выполняет поиск данных для CGW.
Я думал, что, возможно, мы можем использовать наше «базовое» задание для предоставления CGW, которые определены в файле переменных, но пока ничего из того, что я пробовал, не сработало.
Определение переменной будет:
variable "region_data" {
type = list(object({
region = string
deploy_cgw = bool
gateways = any
}))
default = [
{
region = "eu-west-1"
deploy_cgw = true
gateways = [
{
name = "gateway1"
ip = "1.2.3.4"
},
{
name = "gateway2"
ip = "2.3.4.5"
}
]
},
{
region = "us-east-1"
deploy_cgw = true
gateways = [
{
name = "gateway1"
ip = "2.3.4.5"
},
{
name = "gateway2"
ip = "3.4.5.6"
}
]
}
]
}
Я попробовал несколько вещей, таких как:
locals {
regions = [for region in var.region_data : region if region.deploy_cgw]
cgws = flatten([
for region in local.regions : [
for gateway in region.gateways : {
region = region.region
name = gateway.name
ip = gateway.ip
}
]
])
}
provider "aws" {
region = "eu-west-1"
alias = "eu-west-1"
}
provider "aws" {
region = "us-east-1"
alias = "us-east-1"
}
module "cgw" {
source = "../../../modules/customer-gateway"
for_each = { for cgw in local.cgws: "${cgw.region}.${cgw.name}" => cgw }
name_tag = each.value.name
ip_address = each.value.ip
providers = {
aws = "aws.${each.value.region}"
}
}
Но с этим я получаю:
Error: Invalid provider configuration reference
on main.tf line 439, in module "cgw":
439: aws = "aws.${each.value.region}"
A provider configuration reference must not be given in quotes.
Если я перемещу поставщика AWS в модуль и передам регион в качестве параметра, я получу следующее:
Error: Module does not support for_each
on main.tf line 423, in module "cgw":
423: for_each = { for cgw in local.testing : "${cgw.region}.${cgw.name}" => cgw }
Module "cgw" cannot be used with for_each because it contains a nested
provider configuration for "aws", at
Я провел довольно много исследований, и последнее, что я понимаю, — это то, в отношении чего Terraform занимает жесткую позицию.
Возможно ли то, о чем я спрашиваю?
Ответ №1:
for_each
не может использоваться в модулях, в которых определены поставщики. Я тоже был разочарован, узнав об этом. Они делают это потому, что наличие вложенных поставщиков вызывает кошмары, если этот поставщик исчезнет, у вас будут потерянные ресурсы в состоянии, которым вы не можете управлять, и ваши планы потерпят неудачу. Однако это вполне возможно в https://www.pulumi.com /. Мне надоели ограничения в terraform, и я перееду в пулуми. Но это не то, что вы просили, поэтому я продолжу.
Определенно не продолжайте импортировать его. В итоге вы получите несколько частей вашей terraform, управляющих одним и тем же ресурсом.
Просто создайте cgw один раз для каждого региона. Затем передайте идентификатор в свой модуль vpc. Вы не можете перебирать поставщиков, поэтому используйте один модуль для каждого поставщика. Другими словами, для каждого из всех виртуальных серверов в одной учетной записи и в одном регионе для каждого вызова модуля.
resource "aws_customer_gateway" "east" {
bgp_asn = 65000
ip_address = "172.83.124.10"
type = "ipsec.1"
}
resource "aws_customer_gateway" "west" {
bgp_asn = 65000
ip_address = "172.83.128.10"
type = "ipsec.1"
}
module "east" {
source = "../../../modules/customer-gateway"
for_each = map(
{
name = "east1"
ip = "1.2.3.4"
},
{
name = "east2"
ip = "1.2.3.5"
},
)
name_tag = each.value.name
ip_address = each.value.ip
cgw_id = aws_customer_gateway.east.id
providers = {
aws = "aws.east"
}
}
module "west" {
source = "../../../modules/customer-gateway"
for_each = map(
{
name = "west1"
ip = "1.2.3.4"
},
{
name = "west2"
ip = "1.2.3.5"
},
)
name_tag = each.value.name
ip_address = each.value.ip
cgw_id = aws_customer_gateway.west.id
providers = {
aws = "aws.west"
}
}