使用Terraform local-exec导出GCP存储桶列表至CSV失败求助
1. 文件名拼写错误
你的local-exec命令里写的是storage_ouput.csv(少了一个t),但null_resource的triggers里定义的是storage_output.csv,导致输出写入了错误的文件,而data.local_file读取的是正确文件名,自然为空。
修正:把命令里的storage_ouput.csv改成storage_output.csv。
2. Shell脚本未输出结果
你的list_buckets.sh只是把curl的结果存到了LIST_BUCKETS变量,但没有任何输出语句,所以即使curl成功获取到了存储桶数据,也不会写入到CSV文件里。
修正:在脚本最后添加echo "$LIST_BUCKETS",或者直接把curl的结果输出到stdout(去掉变量赋值,直接执行curl命令)。
3. Curl命令语法错误
Authorization头的引号拼接有问题:"Authorization: Bearer "${TOKEN}会导致TOKEN被当成单独的参数,正确的写法应该是把整个头信息用双引号包裹:"Authorization: Bearer ${TOKEN}"。
4. 项目参数传递错误
你在命令里给的项目参数是'*<gcp project name in single quote>*',这会让脚本接收到的PROJECT变量包含单引号,导致API请求的project参数无效。直接传递项目名即可,不需要额外单引号。
5. Terraform资源依赖问题
data.local_file.test会在Terraform初始化阶段就读取文件内容,但null_resource的local-exec是在apply阶段执行的,所以读取的是文件的初始空状态。需要给data.local_file添加depends_on,确保它在null_resource执行完成后再读取文件。
修正后的代码
main.tf
data "google_client_config" "default" {} resource "null_resource" "list_all_buckets" { triggers = { filename = "${path.module}/storage_output.csv" } provisioner "local-exec" { command = "bash list_buckets.sh ${data.google_client_config.default.access_token} <你的GCP项目名> >> ${null_resource.list_all_buckets.triggers.filename}" working_dir = "${path.module}" } } data "local_file" "test" { filename = "${null_resource.list_all_buckets.triggers.filename}" depends_on = [null_resource.list_all_buckets] # 添加依赖 } output "result" { value = "${data.local_file.test.content}" }
list_buckets.sh
#!/bin/bash readonly TOKEN="$1" readonly PROJECT="$2" readonly URL="https://storage.googleapis.com/storage/v1/b?project=${PROJECT}" # 修正curl头,并直接输出结果 curl -X GET -H "Authorization: Bearer ${TOKEN}" "${URL}"
额外建议
- 如果需要CSV格式的输出,当前脚本返回的是JSON,你可以用
jq工具把JSON转换成CSV,比如:curl -X GET -H "Authorization: Bearer ${TOKEN}" "${URL}" | jq -r '.items[] | [.name, .location, .storageClass] | @csv' - 给脚本添加错误处理,比如检查参数是否齐全、curl请求是否成功:
if [ $# -ne 2 ]; then echo "Usage: $0 <token> <project>" exit 1 fi curl -X GET -H "Authorization: Bearer ${TOKEN}" "${URL}" || echo "Failed to fetch buckets" >&2
内容的提问来源于stack exchange,提问作者bob

