如何在 AWS IAM 策略上使用 jq?
How to use jq on an AWS IAM policy?
问题 - 为什么 jq 生成带有值的行,而不是生成内置的 json 数组? (我尝试使用 [.[]]
但没有成功)
代码片段@jqplay.org - https://jqplay.org/s/IDhVa5KID8
挑战 - 生成一组允许的动作 (Effect == Allow
).
IAM 策略(输入)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "cloudformation:UpdateStack",
"Resource": "arn:aws:cloudformation:eu-west-1:123456789012:stack/sokker-stack-dev/*",
"Effect": "Allow"
},
{
"Action": [
"lambda:UpdateFunctionConfiguration",
"lambda:InvokeFunction"
],
"Resource": "arn:aws:lambda:eu-west-1:123456789012:function:sokker-api-dev-GetApiKeyValueFunction-MYDISTRIBID",
"Effect": "Allow"
},
{
"Action": [
"cloudfront:GetDistribution",
"cloudfront:UpdateDistribution"
],
"Resource": "arn:aws:cloudfront::*:distribution/MYDISTRIBID",
"Effect": "Allow"
},
{
"Action": [
"apigateway:GET",
"apigateway:HEAD",
"apigateway:OPTIONS",
"apigateway:PUT",
"iam:GetRole",
"iam:PassRole",
"lambda:GetFunctionConfiguration"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
我的解决方案(不够好):
jq '.Statement | map(select(.Effect == "Allow"))[].Action | if type == "string" then . else .[] end' iampolicy.json
我的解决方案的输出:
# Why is it a list of values? Why isn't it a json array?
"cloudformation:UpdateStack"
"lambda:UpdateFunctionConfiguration"
"lambda:InvokeFunction"
"cloudfront:GetDistribution"
"cloudfront:UpdateDistribution"
"apigateway:GET"
"apigateway:HEAD"
"apigateway:OPTIONS"
"apigateway:PUT"
"iam:GetRole"
"iam:PassRole"
"lambda:GetFunctionConfiguration"
期望输出:
[
"cloudformation:UpdateStack",
"lambda:UpdateFunctionConfiguration",
"lambda:InvokeFunction",
"cloudfront:GetDistribution",
"cloudfront:UpdateDistribution",
"apigateway:GET",
"apigateway:HEAD",
"apigateway:OPTIONS",
"apigateway:PUT",
"iam:GetRole",
"iam:PassRole",
"lambda:GetFunctionConfiguration"
]
您的 jq 管道的最后一部分是:
| .[]
这会导致您不想要的流。因此,一种解决方案是将整个表达式括在方括号中;几个更好的选择之一是:
.Statement
| [.[]
| select(.Effect == "Allow")
| .Action
| if type == "string" then . else .[] end ]
好吧,这很愚蠢,用 []
包围我的最终输出就成功了
.Statement | [map(select(.Effect == "Allow"))[].Action | if type == "string" then . else .[] end]
问题 - 为什么 jq 生成带有值的行,而不是生成内置的 json 数组? (我尝试使用 [.[]]
但没有成功)
代码片段@jqplay.org - https://jqplay.org/s/IDhVa5KID8
挑战 - 生成一组允许的动作 (Effect == Allow
).
IAM 策略(输入)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "cloudformation:UpdateStack",
"Resource": "arn:aws:cloudformation:eu-west-1:123456789012:stack/sokker-stack-dev/*",
"Effect": "Allow"
},
{
"Action": [
"lambda:UpdateFunctionConfiguration",
"lambda:InvokeFunction"
],
"Resource": "arn:aws:lambda:eu-west-1:123456789012:function:sokker-api-dev-GetApiKeyValueFunction-MYDISTRIBID",
"Effect": "Allow"
},
{
"Action": [
"cloudfront:GetDistribution",
"cloudfront:UpdateDistribution"
],
"Resource": "arn:aws:cloudfront::*:distribution/MYDISTRIBID",
"Effect": "Allow"
},
{
"Action": [
"apigateway:GET",
"apigateway:HEAD",
"apigateway:OPTIONS",
"apigateway:PUT",
"iam:GetRole",
"iam:PassRole",
"lambda:GetFunctionConfiguration"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
我的解决方案(不够好):
jq '.Statement | map(select(.Effect == "Allow"))[].Action | if type == "string" then . else .[] end' iampolicy.json
我的解决方案的输出:
# Why is it a list of values? Why isn't it a json array?
"cloudformation:UpdateStack"
"lambda:UpdateFunctionConfiguration"
"lambda:InvokeFunction"
"cloudfront:GetDistribution"
"cloudfront:UpdateDistribution"
"apigateway:GET"
"apigateway:HEAD"
"apigateway:OPTIONS"
"apigateway:PUT"
"iam:GetRole"
"iam:PassRole"
"lambda:GetFunctionConfiguration"
期望输出:
[
"cloudformation:UpdateStack",
"lambda:UpdateFunctionConfiguration",
"lambda:InvokeFunction",
"cloudfront:GetDistribution",
"cloudfront:UpdateDistribution",
"apigateway:GET",
"apigateway:HEAD",
"apigateway:OPTIONS",
"apigateway:PUT",
"iam:GetRole",
"iam:PassRole",
"lambda:GetFunctionConfiguration"
]
您的 jq 管道的最后一部分是:
| .[]
这会导致您不想要的流。因此,一种解决方案是将整个表达式括在方括号中;几个更好的选择之一是:
.Statement
| [.[]
| select(.Effect == "Allow")
| .Action
| if type == "string" then . else .[] end ]
好吧,这很愚蠢,用 []
包围我的最终输出就成功了
.Statement | [map(select(.Effect == "Allow"))[].Action | if type == "string" then . else .[] end]