Amazon ec2 查找带有不正确或缺少标记的ec2实例

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' [

我试图简单地输出一个不遵循特定标记约定的所有实例ID的列表

  • 缺少标记(标记键:环境或财务)
  • 环境标记值不是(prod、stg、test、dev)之一
  • 财务标记值不是(组A、组B)之一

  • 对于(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中解析
    VS

    • 试图在JQ中解决输出问题
    第(2)和(3)款。以下是CLI的一对输出,我已尝试将其发送到JQ,以使用示例输出对2个实例进行解析:

    CLI示例输出[A]Tag.Value和Tag.Key在搜索时需要配对,然后对一组搜索进行否定/反转

    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)”
    返回的结果数据集是所有内容的列表,包括dev和prod

    示例问题1.5 我可以通过链接contain-excludes来解决逻辑问题,但随后我发现“contains”对我不起作用,因为它会拾取仍然碰巧包含所讨论字符串的打字错误:

    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我相信我已经找到了解决方案。这可能不是最优的,但我找到了一种方法来对精确的字符串进行管道链排除:

      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'
      
      我通过将环境标记从“ops”更改为“oops”来验证这一点

      运行此查询时,它返回带有oops标记的单个实例


      我相信我已经找到了解决办法

      它可以大大简化。首先,在这种情况下,不需要调用jq两次<代码>jq'.[].|jq…相当于
      jq'.[].[].'

      其次,“选择”过滤器的长管道可以压缩为:

      select(.EnvTag[]
        | (. != "dev" and . != "stg" and . != "prod" and . != "test" and . != "ops"))
      
      或者,如果您的jq有
      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[]) )