如何用Python脚本将AWS CLI输出的EC2信息转换为指定JSON格式?
问题描述
我在Jenkins脚本中执行AWS CLI命令获取EC2实例信息,命令如下:
def ec2Output = sh(returnStdout: true, script: "aws ec2 describe-instances --region ${Region} --filters Name=tag:Environment,Values=${Environment} --query 'Reservations[].Instances[].[Tags[?Key==`Version`].Value|[0],InstanceId]'") echo "${ec2Output}"
执行后得到如下输出(注:原输出存在语法错误,每个子数组元素间缺少逗号,已修正):
[ [ "2023_v1", "i-0xxxxxxxxxx", "Dev" ], [ "2023_v2", "i-0xxxxxxxxxx", "Dev" ], [ "2023_v2", "i-xxxxxxxxxx", "Prod" ] ]
需要将上述输出转换为指定格式的JSON:
{ "Dev": { "Release": "2023", "Version": "v1", "ID": "i-0xxxxxxxxxx" }, "Dev": { "Release": "2023", "Version": "v2", "ID": "i-0xxxxxxxxxx" }, "Prod": { "Release": "2023", "Version": "v2", "ID": "i-xxxxxxxxxx" } }
解决方案
首先说明:你预期的JSON格式存在重复键Dev,这不符合JSON规范,解析时后一个Dev会覆盖前一个,无法保留所有实例信息。下面提供两种处理方案,一种尽量贴近你的需求,另一种是符合JSON规范的合理格式。
1. 修正AWS CLI命令
原命令的query参数没有明确获取Environment标签的值,而输出中的第三个元素正是该标签值,先修正命令确保能正确取出所需字段:
def ec2Output = sh(returnStdout: true, script: "aws ec2 describe-instances --region ${Region} --filters Name=tag:Environment,Values=${Environment} --query 'Reservations[].Instances[].[Tags[?Key==`Version`].Value|[0],InstanceId,Tags[?Key==`Environment`].Value|[0]]'") echo "${ec2Output}"
2. 使用jq转换格式
方案A:贴近预期格式(存在重复键,不推荐)
通过jq将原始数组转换为你想要的结构,但重复键会被覆盖,最终只能保留每个环境的最后一个实例:
def ec2Output = sh(returnStdout: true, script: "aws ec2 describe-instances --region ${Region} --filters Name=tag:Environment,Values=${Environment} --query 'Reservations[].Instances[].[Tags[?Key==`Version`].Value|[0],InstanceId,Tags[?Key==`Environment`].Value|[0]]' | jq 'reduce .[] as \$item ({}; .[\$item[2]] = {\"Release\": (\$item[0] | split(\"_\")[0]), \"Version\": (\$item[0] | split(\"_\")[1]), \"ID\": \$item[1]})'") echo "${ec2Output}"
方案B:符合JSON规范的合理格式(推荐)
将同一环境的实例放到数组中,这样能完整保留所有实例信息:
def ec2Output = sh(returnStdout: true, script: "aws ec2 describe-instances --region ${Region} --filters Name=tag:Environment,Values=${Environment} --query 'Reservations[].Instances[].[Tags[?Key==`Version`].Value|[0],InstanceId,Tags[?Key==`Environment`].Value|[0]]' | jq 'reduce .[] as \$item ({}; .[\$item[2]] += [{\"Release\": (\$item[0] | split(\"_\")[0]), \"Version\": (\$item[0] | split(\"_\")[1]), \"ID\": \$item[1]}])'") echo "${ec2Output}"
转换后的输出为:
{ "Dev": [ { "Release": "2023", "Version": "v1", "ID": "i-0xxxxxxxxxx" }, { "Release": "2023", "Version": "v2", "ID": "i-0xxxxxxxxxx" } ], "Prod": [ { "Release": "2023", "Version": "v2", "ID": "i-xxxxxxxxxx" } ] }
3. Jenkins脚本中解析JSON(可选)
如果需要在Jenkins中进一步处理转换后的JSON,可以用Groovy的JsonSlurper解析:
import groovy.json.JsonSlurper def ec2Json = new JsonSlurper().parseText(ec2Output) // 示例:遍历Dev环境的所有实例 ec2Json.Dev.each { instance -> echo "版本:${instance.Version},实例ID:${instance.ID}" }
内容的提问来源于stack exchange,提问作者fahri
相关产品推荐
相关产品推荐

