terraform是否可以有两个主文件,一个接着一个运行?
我需要在main1调用main2之前完全运行它,因为我的main2有for_each
,这需要先创建资源。与main3相同。
因此,必须先完全运行main1(地形规划/应用(,然后再运行main2。
我的树状结构
├── README.md
├── config
│ ├── prod
│ └── sandbox
│ └── us_east_2
│ ├── nonprod.tfvars
│ └── prod.tfvars
├── init
│ ├── prod
│ └── sandbox
│ └── us_east_2
│ ├── nonprod.tfvars
│ └── prod.tfvars
├── main.tf
├── modules
│ ├── create_transit_gateway
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── ec2
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── transit_gateway
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── transit_gateway_asso_prop
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── transit_gateway_locals
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── vpc
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── output.tf
└── variables.tf
provider "aws" {
region = var.REGION
}
module "create_transit_gateway" {
source = "./modules/create_transit_gateway"
REGION_SHORTHAND = var.REGION_SHORTHAND
TGW_LOCAL = var.TGW_LOCAL
ENV_NAME = var.ENV_NAME
AMAZON_SIDE_ASN = var.AMAZON_SIDE_ASN
}
module "vpc" {
depends_on = [module.create_transit_gateway]
source = "./modules/vpc"
NETWORK_VPC = var.NETWORK_VPC
SUBNETS = var.SUBNETS
ROUTE_TABLES = var.ROUTE_TABLES
ENV_NAME = var.ENV_NAME
TGW_LOCAL = var.TGW_LOCAL
REGION_SHORTHAND = var.REGION_SHORTHAND
}
module "ec2" {
depends_on = [module.create_transit_gateway, module.vpc]
source = "./modules/ec2"
FW_ASNS = var.FW_ASNS
FIREWALLS = var.FIREWALLS
AMI_IMAGE_KEY = var.AMI_IMAGE_KEY
REGION_SHORTHAND = var.REGION_SHORTHAND
ENV_NAME = var.ENV_NAME
VPC_ID = module.vpc.VPC_ID
AWS_SUBNETS = module.vpc.AWS_SUBNETS
}
module "transit_gateway" {
depends_on = [module.create_transit_gateway, module.ec2, module.vpc]
source = "./modules/transit_gateway"
REGION = var.REGION
TGW_LOCAL = var.TGW_LOCAL
ENV_NAME = var.ENV_NAME
SITE_CUSTOMER_GATEWAYS = var.SITE_CUSTOMER_GATEWAYS
EIP_FW1_NICS = module.ec2.EIP_FW1_NICS
EIP_FW2_NICS = module.ec2.EIP_FW2_NICS
AWS_SUBNETS = module.vpc.AWS_SUBNETS
FW_ASNS = var.FW_ASNS
TGW_PEERS = var.TGW_PEERS
VPC_ID = module.vpc.VPC_ID
TGW_ROUTE_TABLES = var.TGW_ROUTE_TABLES
REGION_SHORTHAND = var.REGION_SHORTHAND
AWS_ACCOUNT_ID = var.AWS_ACCOUNT_ID
}
module "transit_gateway_locals" {
depends_on = [module.create_transit_gateway, module.transit_gateway]
source = "./modules/transit_gateway_locals"
REGION = var.REGION
TGW_PEERS = var.TGW_PEERS
TGA_VPC_ATTACHMENT = module.vpc.TG_VPC_ATTACHMENT
ENV_NAME = var.ENV_NAME
AWS_ACCOUNT_ID = var.AWS_ACCOUNT_ID
NETWORK_S2S_VPN = module.transit_gateway.NETWORK_S2S_VPN
NETWORK_TGW_RT = module.transit_gateway.NETWORK_TGW_RT
TGW_PEERS_RESOURCE = module.transit_gateway.TGW_PEERS_RESOURCE
PEER_ACCEPTOR_STATUS = module.transit_gateway.PEER_ACCEPTOR_STATUS
}
module "transit_gateway_asso_prop" {
depends_on = [module.transit_gateway_locals]
source = "./modules/transit_gateway_asso_prop"
REGION = var.REGION
VPC_ASSO_LIST = module.transit_gateway_locals.VPC_ASSO_LIST
VPC_PROP_LIST = module.transit_gateway_locals.VPC_PROP_LIST
VPN_ASSO_LIST = module.transit_gateway_locals.VPN_ASSO_LIST
VPN_PROP_LIST = module.transit_gateway_locals.VPN_PROP_LIST
PEER_ASSO_LIST = module.transit_gateway_locals.PEER_ASSO_LIST
SEC_STATIC_LIST = module.transit_gateway_locals.SEC_STATIC_LIST
TGW_PEERS = var.TGW_PEERS
ENV_NAME = var.ENV_NAME
}
我需要模块transit_gateway_asso_prop
在应用上述模块后运行。由于VPN_PROP_LIST
、VPN_ASSO_LIST
等变量将在应用transit_gateway_locals
和其他上述模块后创建
Error: Invalid for_each argument
on modules/transit_gateway_asso_prop/main.tf line 325, in resource "aws_ec2_transit_gateway_route_table_propagation" "NETWORK-TGW-VPNPROPAGATION":
325: for_each = var.VPN_PROP_LIST
The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.
遗憾的是,您无法做到这一点。构建代码的正确方法是将代码分成模块。因此,您必须将main1
和main2
转换为子模块,然后创建顶级main.tf
。在main
中创建main1
和main2
模块将确保正确的顺序。
.
├── main.tf
└── modules
├── main1
│ └── main.tf
└── main2
└── main.tf
然后在main.tf
中,您将创建两个模块:
module "main1" {
source = "./modules/main1/main"
VAR2 = var.VAR2
}
module "main2" {
source = "./modules/main1/main"
VAR2 = module.main2.id
}
对于一个如此精心设计的例子,很难给出具体的建议,而是一些一般的观察结果:
-
;要一起创建/修改的基础设施集合";是单独的配置,而不是同一配置中的单独模块。如果您将配置分为两部分,并使用数据源,以便第二部分可以读取第一部分的结果,那么您可以分两步应用整个系统,从而确保正确的顺序。
-
话虽如此,对于
for_each
值在规划过程中未知的问题,通常(但并不总是(有不同的方法来构建事物,这样Terraform至少可以在规划时看到地图的关键。只要键是已知的,这些值就可能是未知的。如果你想了解更多关于这方面的信息,那么我建议你在Stack Overflow上开始一个新的问题,分享一个更现实的配置版本,并描述潜在的问题,从那时起,回答者可以建议具体的重构或重组,这可能会带来一个有效的解决方案。
-
在Terraform中,
depends_on
的大量使用,特别是在module
块中,通常是一种代码气味,因为这表明模块没有正确封装,因此它们依赖外部注释才能正确运行。这并不总是正确的,同样,如果没有一个真实的例子,很难具体说明,但有更好的技术可以告诉Terraform不同模块中对象之间的关系,这通常可以使模块在默认情况下正确运行,而无需额外的注释。
您可以使用-target来完成此操作。你做什么并不理想。
terraform plan -target=module.mymodule.aws_instance.myinstance ```
terraform apply
This might help: https://stackoverflow.com/questions/46762047/i-would-like-to-run-terraform-only-for-a-specific-resource
我在if循环中有if rt_att_id.rt_id != null
条件。
因为每一个都不能引用未知的资源,这就是它出错的原因。
我修改了我的循环,通过数据获取路由表id,并使用特定的名称,而不是循环整个路由表。
谢谢大家的帮助。