如何调整jq表达式,修改tfstate后输出完整JSON文档?
问题
在Terraform提供商迁移过程中,需要修改大型tfstate JSON文件修复bug:将指定kops_cluster资源的attributes中的config_base值移至config_store的数组对象中,并删除config_base字段。当前编写的jq表达式仅输出修改后的.resources[].instances[].attributes块,而非整个JSON文档,如何调整表达式以输出完整文档?
原JSON结构
{ "resources": [ { "provider": "something_else", "type": "foo" }, { "provider": "provider[\"registry.terraform.io/eddycharly/kops\"]", "type": "kops_cluster", "instances": [{ "attributes": { "another_attr": "hello world", "config_base": "s3://foo-bucket/bar-env", "config_store": "" } }] }, { "provider": "something_else", "type": "foo" } ] }
目标JSON结构
{ "resources": [ { "provider": "something_else", "type": "foo" }, { "provider": "provider[\"registry.terraform.io/eddycharly/kops\"]", "type": "kops_cluster", "instances": [{ "attributes": { "another_attr": "hello world", "config_store": [{ "base": "s3://foo-bucket/bar-env" }] } }] }, { "provider": "something_else", "type": "foo" } ] }
现有jq表达式
.resources[] | select( .provider == "provider[\"registry.terraform.io/eddycharly/kops\"]" and .type == "kops_cluster" ) | .instances[].attributes | .config_base as $config_base | .config_store |= [{ "base":$config_base }] | del(.config_base)
当前输出
{ "another_attr": "hello world", "config_store": [ { "base": "s3://foo-bucket/bar-env" } ] }
解决方案
原表达式直接遍历并输出匹配资源的子节点,破坏了原文档结构。需要用map函数处理resources数组,仅修改符合条件的元素,其余元素保持原样,以此保留完整JSON结构。
修改后的jq表达式:
.resources |= map( if .provider == "provider[\"registry.terraform.io/eddycharly/kops\"]" and .type == "kops_cluster" then .instances[].attributes |= ( .config_base as $config_base | .config_store = [{ "base": $config_base }] | del(.config_base) ) | . else . end )
关键说明:
.resources |= map(...):对resources数组做映射处理,将修改后的数组赋值回原字段,确保整个文档结构不丢失。- 条件判断逻辑:仅对匹配
kops_cluster的资源执行修改操作,其余资源直接原样返回。 .instances[].attributes |= (...):针对目标资源的attributes字段应用修改逻辑,把config_base的值转移到config_store数组,同时删除原config_base字段。
执行该表达式后,会输出完整的修改后JSON文档,完全符合目标结构要求。
内容的提问来源于stack exchange,提问作者Sammitch
相关产品推荐
相关产品推荐

