Terraform如何创建动态map 为SQS批量生成对应SSM参数
报错原因
Terraform 中variable块的default字段仅支持静态常量值,不允许引用资源属性、其他变量或动态表达式,你在变量默认值里直接写aws_sqs_queue.FirstStandardSQSQueue.url这类资源引用,就会触发Variables not allowed报错。
实现方案
不需要单独定义Queues变量,直接在SQS模块调用SSM模块的代码块内,动态构造包含所有队列URL、ARN的映射表传入for_each即可。模块块所在的上下文支持引用同模块下的资源属性,Terraform会自动识别依赖关系,保证SQS队列全部创建完成后再生成对应的SSM参数。
修改后的SQS模块中SSM调用部分代码如下:
# 保留你原来的4个aws_sqs_queue资源定义不变,删除原来定义的Queues变量,替换ssm模块调用代码为以下内容 module "ssm" { source = "../ssm/" for_each = { "FirstStandardSQSQueueUrl" = aws_sqs_queue.FirstStandardSQSQueue.url "FirstStandardSQSQueueArn" = aws_sqs_queue.FirstStandardSQSQueue.arn "FirstDeadLetterQueueUrl" = aws_sqs_queue.FirstDeadLetterQueue.url "FirstDeadLetterQueueArn" = aws_sqs_queue.FirstDeadLetterQueue.arn "SecondStandardSQSQueueUrl" = aws_sqs_queue.SecondStandardSQSQueue.url "SecondStandardSQSQueueArn" = aws_sqs_queue.SecondStandardSQSQueue.arn "SecondDeadLetterQueueUrl" = aws_sqs_queue.SecondDeadLetterQueue.url "SecondDeadLetterQueueArn" = aws_sqs_queue.SecondDeadLetterQueue.arn } name = "/new/${var.stage}/${each.key}" type = "SecureString" value = each.value }
如果你不需要存储死信队列的URL和ARN,直接删掉for_each映射里对应死信队列的4个键值对即可。
可选优化写法
如果后续需要新增队列,不想每次手动维护映射表,可以用local块加for表达式自动批量生成所有队列的参数映射,减少硬编码:
locals { # 归集所有需要生成SSM参数的SQS队列 all_managed_queues = { FirstStandardSQSQueue = aws_sqs_queue.FirstStandardSQSQueue FirstDeadLetterQueue = aws_sqs_queue.FirstDeadLetterQueue SecondStandardSQSQueue = aws_sqs_queue.SecondStandardSQSQueue SecondDeadLetterQueue = aws_sqs_queue.SecondDeadLetterQueue } # 自动生成每个队列URL、ARN对应的SSM参数键值对 queue_ssm_params = merge([ for queue_key, queue in local.all_managed_queues : { "${queue_key}Url" = queue.url "${queue_key}Arn" = queue.arn } ]...) } module "ssm" { source = "../ssm/" for_each = local.queue_ssm_params name = "/new/${var.stage}/${each.key}" type = "SecureString" value = each.value }
说明
- 原有SSM模块的代码不需要做任何修改,可以直接复用。
- Terraform会自动处理资源依赖顺序,不需要额外添加
depends_on配置。
内容的提问来源于stack exchange,提问作者Somethingwhatever
相关产品推荐
相关产品推荐

