Terraform:如何引用For_Each中未包含在映射中的变量,例如file_system_id



也许这是可能的,也许不是。我正试图使用var.ec2_server映射中存储的一些值装载EFS目标,该映射包括子网、EBS卷等。

我遇到的问题是,我使用for_each语句创建了EFS文件系统;由于efs_file_system是用for_each创建的,所以在引用其他变量中的资源时,我必须引用指定实例中的属性。

file_system_id只有在创建后才知道,那么我如何在映射或其他for_each语句中的其他变量中引用它,例如下面定义的aws_efs_mount_target资源?我所做的会起作用吗?

我正在使用过时的资源;变量.tf>terraform.tfvars(config(样式代码:

ec2.tf文件:

###############################################################################
# EC2 Instance
resource "aws_instance" "ec2" {
for_each = var.ec2_servers
ami                     = data.aws_ami.ec2[each.key].id
disable_api_termination = var.disable_api_termination
iam_instance_profile    = aws_iam_instance_profile.ec2[each.key].id
instance_type           = each.value.instance_type
monitoring              = true
vpc_security_group_ids  = [aws_security_group.ec2[each.key].id]
subnet_id               = each.value.subnet_name != null ? aws_subnet.private["${each.value.vpc_name}.${each.value.subnet_name}.${each.value.availability_zone}"].id : null
key_name                = aws_key_pair.ec2.key_name
user_data               = each.value.user_data == "" ? null : templatefile("./${each.value.user_data}", { region = data.aws_region.current.name })
private_ip              = each.value.private_ip
metadata_options {
http_endpoint = "enabled"
http_tokens   = "required"
}
root_block_device {
delete_on_termination = true
encrypted             = true
volume_size           = each.value.root_volume_size
volume_type           = "gp2"
tags = {
Name = replace("${var.project_name}-${each.value.vpc_name}-${each.key}-EBS", " ", "")
}
}
dynamic "ebs_block_device" {
for_each = each.value.ebs_volumes
content {
volume_type = ebs_block_device.value.volume_type
volume_size = ebs_block_device.value.volume_size
device_name = ebs_block_device.value.device_name
tags = {
Name = replace("${var.project_name}-${each.value.vpc_name}-${each.key}-EBS", " ", "") }
}
}
tags = {
Name   = replace("${var.project_name}-${each.value.vpc_name}-${each.key}-EC2", " ", "")
Backup = "true"
}
}

efs.tf文件:

###############################################################################
# Create EFS File System
resource "aws_efs_file_system" "efs" {
for_each = {
for object, property in var.efs_config : object => property if var.efs_config.efs_enabled
}
creation_token = var.efs_config.efs_creation_token
encrypted      = var.efs_config.efs_encrypt
kms_key_id     = aws_kms_key.efs_kms.arn
tags = {
Name = replace("${var.project_name}-${var.efs_config.efs_vpc}-EFS", " ", "")
}
}
resource "aws_efs_backup_policy" "efs_backup_policy" {
file_system_id  = "NEEDS TO BE DETERMINED"
backup_policy {
status = "ENABLED"
}
}
resource "aws_efs_mount_target" "efs_mount_target" {
for_each = var.ec2_servers
file_system_id  = "NEEDS TO BE DETERMINED"
subnet_id       = each.value.subnet_name == "app" ? aws_subnet.private["${each.value.vpc_name}.${each.value.subnet_name}.${each.value.availability_zone}"].id : null
ip_address      = lookup(var.efs_config, "efs_private_ip")
security_groups = [aws_security_group.ec2[each.key].id]
}

variables.tf文件:

variable "ec2_servers" {
description = "A configurable map of EC2 settings."
type        = map(any)
}

terraform.tfvars文件:

###############################################################################
# EFS Configurations
efs_config = {
efs_enabled        = true
efs_creation_token = "Prod_EFS"
efs_encrypt        = true
efs_vpc            = "Prod"
efs_private_ip     = "10.200.0.5"
}
# Server Configurations
ec2_servers = {
EC201 = {
ami_owner        = "XXXXXXXXXXXX"
ami_name         = "xxxxx-xxxxxx"
instance_type    = "t2.micro"
root_volume_size = "10"
ebs_volumes = [
{
volume_size = "20"
volume_type = "gp3"
device_name = "/dev/xvdba"
},
{
volume_size = "20"
volume_type = "gp3"
device_name = "/dev/xvdbb"
}
]
vpc_name          = "Prod"
subnet_name       = "web"
set_ec2_hostname  = false
ec2_hostname      = "xxxxxxxxx"
availability_zone = "a"
public_dns        = false
private_dns       = true
policy_names      = []
s3_storage        = false
transfer_files    = false
user_data         = "setup_ssm_linux.tftpl"
private_ip        = "10.200.0.132"
ingress = {
ssh = {
description = "Internal address"
from_port   = 22
to_port     = 22
protocol    = "tcp"
cidr_blocks = [
"10.200.0.0/22"
]
}
}
}
}

我尝试了很多事情,比如为aws_efs_mount_target创建数据资源,但我所做的似乎都不起作用。如果有人能提供一点见解,我的项目负责人和我本人都将不胜感激!

如果我在这里遗漏了什么,请告诉我,我会用相关信息更新问题。

您的aws_efs_backup_policy也需要一个for_each,因为您需要为每个EFS卷创建一个:

resource "aws_efs_backup_policy" "efs_backup_policy" {
for_each = aws_efs_file_system.efs
file_system_id  = each.id
backup_policy {
status = "ENABLED"
}
}

对于EFS装载目标,我将使用与EFS卷相同的for_each

resource "aws_efs_mount_target" "efs_mount_target" {
for_each = {
for object, property in var.efs_config : object => property if var.efs_config.efs_enabled
}
file_system_id  = aws_efs_file_system.efs[each.key].id
...
}

我认为您需要通过将这些值移动到efs_config变量中来清理aws_efs_mount_target中的其他查找。

最新更新