Terraform External数据源未解析Docker命令标准输出问题排查
问题分析与解决方案
核心原因:Docker的-ti参数适配问题
你在Docker命令中使用了-ti参数,其中-t会分配伪终端,-i会保持标准输入打开。但Terraform调用外部脚本时处于非交互式环境,没有终端交互支持,这会导致Docker命令的输出被抑制或无法正确传递到后续的sed管道,最终变量X为空,生成的JSON是无效空对象,或者输出混杂终端控制字符导致解析失败。
修正步骤
1. 修复Docker命令与sed匹配逻辑
移除Docker命令中的-ti参数(非交互式场景不需要终端交互),同时修正sed表达式中的匹配错误(原表达式少了*导致无法正确匹配键值内容):
X=$(docker run --rm psono/psono-server:latest python3 ./psono/manage.py generateserverkeys | \ sed -e "/^\(\s\|#\)/d" | \ sed -e "$ ! s/[^: \s]*'/',/" \ -e "s/^/'/" \ -e "s/:/':/" \ -e "s/'/\"/g")
2. 输出纯净标准JSON
确保脚本只输出合法JSON,不要混入任何额外内容(比如测试用的echo语句会破坏JSON结构)。修正后的完整test.sh:
#!/bin/bash X=$(docker run --rm psono/psono-server:latest python3 ./psono/manage.py generateserverkeys | \ sed -e "/^\(\s\|#\)/d" | \ sed -e "$ ! s/[^: \s]*'/',/" \ -e "s/^/'/" \ -e "s/:/':/" \ -e "s/'/\"/g") # 生成标准压缩格式JSON echo "{ $X }" | jq . -c -M
验证说明
- 终端手动执行
docker run -ti ...能正常工作,是因为终端是交互式环境,-ti参数适配这种场景;但Terraform调用脚本时无终端支持,-ti会导致Docker程序输出异常。 - 移除
-ti后,Docker以非交互式模式运行,输出直接传递给sed处理,生成正确的键值对格式,最终通过jq输出标准JSON,Terraform的external数据源就能正确解析出result映射。
错误复盘
- 手动echo命令输出能工作,是因为输出的是纯净字符串,没有终端交互带来的干扰;
- 脚本中额外添加
echo $(docker run -ti ...)时,输出的PRIVATE_KEY: 'xxx'会混在JSON前,导致Terraform解析时遇到非JSON字符('P')报错,这也证明Docker命令在非交互式脚本中的输出未被正确捕获。
内容的提问来源于stack exchange,提问作者Tom Stock
相关产品推荐
相关产品推荐

