Terraform调用AWS SSM参数返回空值及容错执行问题
解决方案
1. 修复External数据源返回空的问题
Terraform的external数据源要求调用的命令必须输出合法的JSON格式,你之前的调用可能没处理好输出结构,或者没兼容参数不存在的场景。
用这条命令替代直接调用aws ssm get-parameter,它会精准提取参数值,且在参数不存在时输出合法的空JSON字符串:
aws ssm get-parameter --name "/你的参数路径" --query "Parameter.Value" --output json || echo "\"\""
--query "Parameter.Value"直接提取参数的实际值,避免返回多余的JSON结构--output json强制输出JSON格式,符合external的要求|| echo "\"\""命令失败(参数不存在)时输出空字符串的JSON,防止external数据源报错中断
2. Terraform中配置External数据源
把上面的命令整合到Terraform代码里:
data "external" "ssm_param" { program = ["bash", "-c", "aws ssm get-parameter --name \"/你的参数路径\" --query \"Parameter.Value\" --output json || echo \"\\\"\\\"\""] } # 解析出参数值,空字符串代表参数不存在 locals { ssm_param_value = data.external.ssm_param.result["0"] }
注意:external会把命令输出的单个JSON值放到result["0"]这个key下,所以要用这个路径取值。
3. 用参数值控制资源创建(比如安全组规则)
通过count参数判断参数是否有效,决定是否创建资源:
resource "aws_security_group_rule" "ssh_access" { # 参数值非空就创建,空就不创建 count = local.ssm_param_value != "" ? 1 : 0 type = "ingress" from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = [local.ssm_param_value] security_group_id = aws_security_group.main.id }
额外提示
- 如果是加密的SecureString参数,要在命令里加
--with-decryption:aws ssm get-parameter --name "/你的加密参数路径" --query "Parameter.Value" --with-decryption --output json || echo "\"\"" - 可以把参数名做成变量,方便复用:
variable "ssm_param_name" { type = string default = "/你的参数路径" } data "external" "ssm_param" { program = ["bash", "-c", "aws ssm get-parameter --name \"${var.ssm_param_name}\" --query \"Parameter.Value\" --output json || echo \"\\\"\\\"\""] } - 确保Terraform执行环境的AWS凭证和你终端一致(比如环境变量、~/.aws/credentials)
内容的提问来源于stack exchange,提问作者cien
相关产品推荐
相关产品推荐

