Amazon ec2 查找带有不正确或缺少标记的ec2实例
我试图简单地输出一个不遵循特定标记约定的所有实例ID的列表Amazon ec2 查找带有不正确或缺少标记的ec2实例,amazon-ec2,tags,command-line-interface,jq,Amazon Ec2,Tags,Command Line Interface,Jq,我试图简单地输出一个不遵循特定标记约定的所有实例ID的列表 缺少标记(标记键:环境或财务) 环境标记值不是(prod、stg、test、dev)之一 财务标记值不是(组A、组B)之一 对于(1),我可以使用以下内容: aws ec2 describe-instances --output json --query 'Reservations[*].Instances[?!not_null(Tags[?Key==`Environment`].Value)] | [].InstanceId' [
对于(1),我可以使用以下内容:
aws ec2 describe-instances --output json --query 'Reservations[*].Instances[?!not_null(Tags[?Key==`Environment`].Value)] | [].InstanceId'
[
"i-12345678901234567",
"i-76543210987654321"
]
但我仍然需要(2)和(3)。如果标记存在但为空,或者值中有输入错误,该怎么办 “ec2--query”的功能是有限的,我还没有找到一种方法让它得到我(2)或(3),特别是当它涉及到反转结果时 我来回试着
- 修改CLI的输出,使其更易于在JQ中解析
- 试图在JQ中解决输出问题
aws ec2 describe-instances --output json --query 'Reservations[].Instances[].{ID:InstanceId, Tag: Tags[]}' | jq '.[]'
{
"Tag": [
{
"Value": "GroupA",
"Key": "Finance"
},
{
"Value": "stg",
"Key": "Environment"
},
{
"Value": "true",
"Key": "Backup"
},
{
"Value": "Another Server",
"Key": "Name"
}
],
"ID": "i-87654321"
}
{
"Tag": [
{
"Value": "GroupB",
"Key": "Finance"
},
{
"Value": "Server 1",
"Key": "Name"
},
{
"Value": "true",
"Key": "Backup"
},
{
"Value": "stg",
"Key": "Environment"
}
],
"ID": "i-12345678"
}
CLI示例输出[B]在尝试“jq-map”或“jq-select”之类的操作时,数组中的标记值足以触发语法错误
我发现,大多数时候,当我试图从一个更简单的用例中扩展某个解决方案时,由于传入数据集的结构中存在一些奇怪之处,我最终只会出现神秘的语法错误
示例问题1 下面是反向/反向失败的示例。这是使用CLI输出B:
aws ec2 describe-instances --output json --query 'Reservations[].Instances[].{ID:InstanceId, EnvTag: Tags[?Key==`Environment`].Value, FinTag: Tags[?Key==`Finance`].Value}' | jq '.[]' | jq 'select(.EnvTag[] | contains ("prod", "dev") | not)'
我希望上面的代码会返回除prod和dev之外的所有内容。但看起来每个项目的逻辑都是相反的,而不是包含的集合:
- “!A+!B”而不是“!(A或B)”
aws ec2 describe-instances --output json --query 'Reservations[].Instances[].{ID:InstanceId, EnvTag: Tags[?Key==`Environment`].Value, FinTag: Tags[?Key==`Finance`].Value}' | jq '.[]' | jq 'select(.EnvTag[] | contains ("dev") | not) | select(.EnvTag[] | contains ("stg") | not) | select(.EnvTag[] | contains ("test") | not) | select(.EnvTag[] | contains ("prod") | not) | select (.EnvTag[] | contains ("foo") | not)'
- 戳!=生产
- “prod”包含(“prod”)=true
- “production”包含(“prod”)=true我相信我已经找到了解决方案。这可能不是最优的,但我找到了一种方法来对精确的字符串进行管道链排除:
我通过将环境标记从“ops”更改为“oops”来验证这一点 运行此查询时,它返回带有oops标记的单个实例aws ec2 describe-instances --output json --query 'Reservations[].Instances[].{ID:InstanceId, EnvTag: Tags[?Key==`Environment`].Value, FinTag: Tags[?Key==`Finance`].Value}' | jq '.[]' | jq 'select(.EnvTag[] != "dev") | select (.EnvTag[] != "stg") | select (.EnvTag[] != "prod") | select (.EnvTag[] != "test") | select (.EnvTag[] != "ops") | .ID'
我相信我已经找到了解决办法 它可以大大简化。首先,在这种情况下,不需要调用jq两次<代码>jq'.[].|jq…相当于
其次,“选择”过滤器的长管道可以压缩为:jq'.[].[].'
或者,如果您的jq有select(.EnvTag[] | (. != "dev" and . != "stg" and . != "prod" and . != "test" and . != "ops"))
,更简洁地说:all/2
select( . as $in | all( ("dev", "stg", "prod", "test", "ops"); . != $in.EnvTag[]) )
谢谢你的改进。至于额外的jq调用,这只是试图快速改进descripe实例调用的输出与实际jq逻辑的产物。我会给缩短版本一个旋转,因为这确实有助于清理通话。最后,我不知道all/2是什么,我认为当我不可避免地需要在接下来的6个月里重温这一点时,第一个浓缩的解决方案更容易阅读:)jq为一种简单形式的多态性提供了支持。此处
中的all/2
表示函数的版本,例如接受两个参数的/2
版本all
select( . as $in | all( ("dev", "stg", "prod", "test", "ops"); . != $in.EnvTag[]) )