You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform external数据源调用bash脚本报jq空迭代错误如何解决

报错原因排查与解决方案

核心报错原因

  • data "external"数据源有强制协议要求:执行的脚本输出到stdout的所有内容必须是单层JSON键值对结构,不能直接输出公钥字符串,也不能有多余的空行、日志内容
  • 脚本中通过terraform console获取变量的方式在Terraform运行生命周期中不可靠:执行external数据源时可能存在工作目录不一致、变量未完全渲染、状态锁等问题,导致拿到的do_token为空。curl请求权限异常返回的响应中没有ssh_keys字段,jq遍历null时直接抛出你遇到的报错
  • droplet资源中引用external数据源的方式错误,不能直接引用整个数据源对象,需要从result属性中读取对应输出字段

修复步骤

  1. 修改external数据源定义,将token通过内置参数传递给脚本,不要在脚本内自行读取变量:
data "external" "fetchssh" {
  program = ["bash", "${path.module}/get_ssh_key.sh"]
  query = {
    do_token = var.do-token
  }
}
  1. 重写bash脚本,适配external数据源的输入输出规则:
#!/bin/bash
set -euo pipefail

# 读取Terraform通过stdin传入的JSON参数,提取token
DO_TOKEN=$(jq -r '.do_token')

# 请求接口获取公钥
PUB_KEY=$(curl -X GET -s -H "Authorization: Bearer ${DO_TOKEN}" "https://api.digitalocean.com/v2/account/keys?page=1" | jq -r --arg queryname "User's key" '.ssh_keys[] | select(.name == $queryname).public_key')

# 输出符合要求的JSON格式结果
jq -n --arg pub_key "$PUB_KEY" '{"public_key": $pub_key}'
  1. 修正droplet资源的公钥引用方式:
resource "digitalocean_droplet" "web" {
  image  = "ubuntu-18-04-x64"
  name   = "web-1"
  region = "lon1"
  size   = "s-1vcpu-1gb"
  tags = [digitalocean_tag.devops.id, digitalocean_tag.your_email.id]
  ssh_keys = [digitalocean_ssh_key.user.id, data.external.fetchssh.result.public_key]
}

额外排查点

  • 确认你的DO token已开通account:read权限,无权限时接口返回的响应没有ssh_keys字段也会触发相同报错
  • 可临时在curl命令后加tee /tmp/do_api_res.json把接口返回内容写入本地文件,执行terraform plan后查看文件内容确认请求是否正常

内容的提问来源于stack exchange,提问作者PatrickHellman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 19:45:06