[英]Terraform - /usr/local/bin/jq: Argument list too long
這是之前提出的問題的變體。
我在 Terraform 中使用外部數據源來請求它提供 AWS Dublin 中的卷快照列表,並在模板文件中使用 JQ 來提取快照 ID。
data "external" "volsnapshot_ids" {
program = [
"bash",
"-c",
templatefile("cli.tftpl", {input_string = "aws ec2 describe-snapshots --region=eu-west-1", top = "Snapshots", next = "| .SnapshotId"})]
}
它使用這個模板文件:
#!/bin/bash
set -e
OUTPUT=$(${input_string} | jq -r -c '.${top}[] ${next}' | jq -R -s -c 'split("\n")' | jq '.[:-1]')
jq -n -c --arg output "$OUTPUT" '{"output":$output}'
JQ 的基本 CLI 命令可以正常工作,如下所示:
aws ec2 describe-snapshots --region=eu-west-1 | jq -r -c '.Snapshots[] | .SnapshotId' | jq -R -s -c 'split("\n")' | jq '.[:-1]' | wc -l
它返回很多快照 ID。
但是,當我通過 Terraform 運行它時,它會出錯:
Error: External Program Execution Failed
│
│ with data.external.volsnapshot_ids,
│ on data.tf line 304, in data "external" "volsnapshot_ids":
│ 304: program = [
│ 305: "bash",
│ 306: "-c",
│ 307: templatefile("cli.tftpl", {input_string = "aws ec2 describe-snapshots --region=eu-west-1", top = "Snapshots", next = "| .SnapshotId"})]
│
│ The data source received an unexpected error while attempting to execute
│ the program.
│
│ Program: /bin/bash
│ Error Message: bash: line 6: /usr/local/bin/jq: Argument list too long
│
│ State: exit status 1
我認為這是返回的數據集的大小,因為它適用於快照 ID 較少的地區——倫敦適用。
從規模上看,這里是倫敦:
aws ec2 describe-snapshots --region=eu-west-2 | jq -r -c '.Snapshots[] | .SnapshotId' | jq -R -s -c 'split("\n")' | jq '.[:-1]' | wc -l
20000
這里是都柏林:
aws ec2 describe-snapshots --region=eu-west-1 | jq -r -c '.Snapshots[] | .SnapshotId' | jq -R -s -c 'split("\n")' | jq '.[:-1]' | wc -l
42500
有沒有辦法修復我的模板文件中的 JQ,以便它可以處理 JSON 大文件?
我不建議在 TF 數據源中使用命令。 可能很難調試。 EBS 快照有一個data_source 。
至於模板中的命令,為了調試它,您需要模擬相同的環境。 例如,不要按原樣運行,而是嘗試重復模板中的內容,例如bash -c
等。 也可以加output查看渲染出來的模板,看看有沒有問題。
滾動到答案底部。
aws... \ | jq -rc '.${top}[] ${next}' \ | jq -Rsc './"\n"' \ | jq -c '.[:-1]' | jq -Rc '{output:.}'
請注意,您可能可以將大部分單獨的 jq 調用組合到一個 jq 程序中。
這個jq調用管道是一個非常非常復雜的非解決方案。 為什么在字符串和 JSON 對象之間來回轉換,再次解析這些字符串,而 jq 已經可以直接處理數據了?
{"output":"[\"snap-cafebabe\",\"snap-deadbeef\",\"snap-0123abcd\"]"}
示例 output:
top=Snapshots
next=SnapshotId
aws ... | jq --arg top "$top" --arg next "$next" -c '{ output: .[$top] | map(.[$next]) | tostring }'
如果必須使用變量:
top=Snapshots next=SnapshotId aws... | jq --arg top "$top" --arg next "$next" -c '{ output: .[$top] | map(.[$next]) | tostring }'
或.[$top] | map(.[$next]) | tostring | { output: . }
.[$top] | map(.[$next]) | tostring | { output: . }
.[$top] | map(.[$next]) | tostring | { output: . }
或.[$top] | map(.[$next]) | { output: tostring }
.[$top] | map(.[$next]) | { output: tostring }
.[$top] | map(.[$next]) | { output: tostring }
。
即使您想要或需要將多個jq
調用串在一起,如果您已經以 stream 形式完美地構造了 JSON 項,那么使用原始輸入 ( -R
) 並嘗試解析它也沒有什么意義。
如果您想通過多個步驟完成它,但始終停留在 JSON 區域(而不是在結構化文本 881569990078588 和非結構化文本之間打乒乓球),這就是它的樣子:
top=Snapshots
next=SnapshotId
aws ... \
| jq --arg top "$top" --arg next "$next" '.[$top] | map(.[$next])' \
| jq -c '{ output: tostring }'
或等效的:
top=Snapshots next=SnapshotId aws... \ | jq --arg top "$top" --arg next "$next" '.[$top] | map(.[$next])' \ | jq -c '{ output: tostring }'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.