Linguagem de Query

Introdução

Bem-vindo a terceira parte do guia. Você aprenderá a linguagem de query que permite “trabalhar” os resultados de um comando.

Linguagem de Query

A linguagem de query pode ser habilitada incluindo a opção --query. Ela serve para filtrar ou formatar os dados apresentados na saída evitando trabalho adicional (grep, sed e awk).

Suponha que você precise listar todas as políticas IAM, mas apenas mostrando o nome, o Arn e a data de criação. O comando aws iam list-policies pode trazer todas estas informações, vamos dar uma olhada.

aws iam list-policies
{
    "Policies": [
        {
            "PolicyName": "Policy01",
            "PolicyId": "XXXXXXXXXXXXXXXXXXXAA",
            "Arn": "arn:aws:iam::000000000000:policy/Policy01",
            "Path": "/",
            "DefaultVersionId": "v1",
            "AttachmentCount": 2,
            "PermissionsBoundaryUsageCount": 0,
            "IsAttachable": true,
            "CreateDate": "2015-11-20T00:45:44+00:00",
            "UpdateDate": "2015-11-20T00:45:44+00:00"
        },
        {
            "PolicyName": "Policy02",
            "PolicyId": "XXXXXXXXXXXXXXXXXXXBB",
            "Arn": "arn:aws:iam::000000000000:policy/Policy02",
            "Path": "/",
            "DefaultVersionId": "v2",
            "AttachmentCount": 1,
            "PermissionsBoundaryUsageCount": 0,
            "IsAttachable": true,
            "CreateDate": "2015-03-12T21:11:31+00:00",
            "UpdateDate": "2015-03-12T21:21:30+00:00"
        },
        ...
        {
            "PolicyName": "Police99",
            "PolicyId": "XXXXXXXXXXXXXXXXXXXZZ",
            "Arn": "arn:aws:iam::aws:policy/service-role/Policy99",
            "Path": "/service-role/",
            "DefaultVersionId": "v27",
            "AttachmentCount": 1,
            "PermissionsBoundaryUsageCount": 0,
            "IsAttachable": false,
            "CreateDate": "2015-12-10T22:04:18+00:00",
            "UpdateDate": "2018-03-27T19:04:35+00:00"
        }
    ]
}

Apesar do comando trazer os campos necessários, a saída retorna mais dados do que você precisa. Isto pode ser inconveniente, pois polui a apresentação e o ocupa mais espaço se for guardar o resultado em um arquivo.

Filtrando Chaves

Então precisamos remover as informações que não queremos da saída. Se você está acostumado com Linux, deve ter pensando em encadear a resposta com o grep (ou jq) para limpá-la.

aws iam list-policies | grep "PolicyName\|Arn\|CreateDate"
            "PolicyName": "Policy01",
            "Arn": "arn:aws:iam::000000000000:policy/Policy01",
            "CreateDate": "2015-11-20T00:45:44+00:00",
            "PolicyName": "AllowGroupToSeeBucketListInTheConsole",
            "Arn": "arn:aws:iam::000000000000:policy/Policy02",
            "CreateDate": "2015-03-12T21:11:31+00:00",
            ...
            "PolicyName": "Policy99",
            "Arn": "arn:aws:iam::000000000000:policy/service-role/Policy99",
            "CreateDate": "2018-04-11T17:30:15+00:00",

Ficou mais limpo, mas vamos treinar como a opção --query para entender como ela pode ajudar. Com esta opção, você pode informar quais dados serão apresentados.

O primeiro passo é entender a estrutura do JSON de saída. No exemplo acima, todas as políticas são apresentadas dentro do campo Policies. Ele é uma lista JSON ([]), sendo que cada elemento da lista é um objeto JSON (map) com as chaves e valores.

"Policies": [
    {
            "PolicyName": "Policy01",
            "PolicyId": "XXXXXXXXXXXXXXXXXXXAA",
            ...
            "CreateDate": "2015-12-10T22:04:18+00:00",           
            "UpdateDate": "2018-03-27T19:04:35+00:00"
    }
]

Como a Policies é uma lista JSON, você pode usar a opção --query para obter apenas um único elemento da lista, neste caso, o primeiro (índice 0).

aws iam list-policies --query "Policies[0]"
{
    "PolicyName": "Policy01",
    "PolicyId": "XXXXXXXXXXXXXXXXXXXAA",
    "Arn": "arn:aws:iam::000000000000:policy/Policy01",
    "Path": "/",
    "DefaultVersionId": "v1",
    "AttachmentCount": 2,
    "PermissionsBoundaryUsageCount": 0,
    "IsAttachable": true,
    "CreateDate": "2015-11-20T00:45:44+00:00",
    "UpdateDate": "2015-11-20T00:45:44+00:00"
}

Note que ao filtrar, você recebeu no retorno apenas o que solicitou, isto é, a reposta não inclui Policies e nem os outros elementos da lista.

Mas não estamos interessados no primeiro elemento e sim na lista toda. Para isto, você pode usar a sintaxe --query "Policies[*] (note a estrela *) para indicar todos os elementos da lista. Vamos testar!

AVISO: Vários comandos do AWS CLI possuem um limite máximo de elementos por resposta. Se a sua lista for grande, provavelmente precisará se preocupar com paginação.

aws iam list-policies --query "Policies[*]"
[
    {
        "PolicyName": "Policy01",
        "PolicyId": "XXXXXXXXXXXXXXXXXXXAA",
        "Arn": "arn:aws:iam::000000000000:policy/Policy01",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 2,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2015-11-20T00:45:44+00:00",
        "UpdateDate": "2015-11-20T00:45:44+00:00"
    },
    ...
    {
        "PolicyName": "Police99",
        "PolicyId": "XXXXXXXXXXXXXXXXXXXZZ",
        "Arn": "arn:aws:iam::aws:policy/service-role/Policy99",
        "Path": "/service-role/",
        "DefaultVersionId": "v27",
        "AttachmentCount": 1,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": false,
        "CreateDate": "2015-12-10T22:04:18+00:00",
        "UpdateDate": "2018-03-27T19:04:35+00:00"
    }
]

Agora que já aprendeu o básico, vamos aplicar um filtro nos campos retornados.

Primeiro, vamos tentar apresentar somente um campo de cada elemento, por exemplo, só o campo PolicyName. Para isto, você pode usar .NomeDoCampo como mostrado a seguir.

aws iam list-policies --query "Policies[*].PolicyName"
[
    "Policy01",
    ...
    "Policy10"
    ...
    "Policy99"
]

Porém, queremos três campos (PolicyName, Arn e CreateDate), neste caso, podemos usar uma lista de campos, isto é, [PolicyName,Arn,CreateDate]. Basta complementar a query adicionando a lista de campos desejados Policies[*].[PolicyName,Arn,CreateDate]. Basicamente, a sintaxe diz:

Policies[*].[PolicyName,Arn,CreateDate]
todas as políticascomapenas as chaves mencionadas nesta lista
aws iam list-policies --query "Policies[*].[PolicyName,Arn,CreateDate]"
[
    [
        "Policy01",
        "arn:aws:iam::000000000000:policy/Policy01",
        "2015-11-20T00:45:44+00:00"
    ],
    ...
    [
        "Policy99",
        "arn:aws:iam::000000000000:policy/service-role/Policy99",
        "2018-04-11T17:30:15+00:00",
    ]
]

Ficou até melhor que usando grep, pois cada elemento está dentro de um grupo, não? Olhando bem, parece que não, pois os chaves sumiram. Como saberá se é o dado é PolicyName, Arn e CreateDate? Este formato, pode ser útil sem as chaves dependendo do que vai fazer com os dados, mas queremos mostrá-los. Neste caso, usaremos uma sintaxe levemente diferente. Ao invés de uma lista de chaves, usaremos um mapa de chaves, isto é, {} ao invés de [].

Para isto, você deve usar a sintaxe Policies[*].{Alias:Chave,...} que ainda permite renomear as chaves por um nome mais amigável (Alias), por exemplo, colocando uma abreviação ou traduzindo. Então para obter o que estamos buscando, podemos usar a query Policies[*].{Nome:PolicyName,Id:Arn,Data:CreateDate}.

aws iam list-policies --query "Policies[*].{Nome:PolicyName,Id:Arn,Data:CreateDate}"
[
    {
        "Nome": "Policy01",
        "Id": "arn:aws:iam::000000000000:policy/Policy01",
        "Data": "2015-11-20T00:45:44+00:00"
    }
    {
        "Nome": "Policy99",
        "Id": "arn:aws:iam::000000000000:policy/service-role/Policy99",
        "Data": "2018-04-11T17:30:15+00:00"
    }
]

E pronto, você aprendou como usar AWS CLI para filtrar chaves e chegar no resultado desejado!

Filtrando Valores

Agora vamos aproveitar e explorar mais uma funcionalidade, filtrar por valores.

Ao invés de listar todas as políticas, queremos obter apenas as que foram criadas recentemente, isto é, as que possuem o valor de CreateDate superior a uma parâmetro. Para isto, ao invés de falar todas as políticas ([*]), você deve aplicar o filtro desejado começando por ? que indica o uso de um filtro e seguindo o formato ?Chave Operador 'Valor'. Por exemplo, Policies[?CreateDate>='2020-01-01']

O filtro é aplicado no lado do seu computador, portanto se o resultado for grande, o AWS CLI terá que baixar todas as informações para depois aplicá-lo, isto é, pode demorar.

Vamos combinar isto com o exemplo da sessão anterior.

aws iam list-policies --query "Policies[?CreateDate>='2020-01-01'].{Nome:PolicyName,Id:Arn,Data:CreateDate}"
[
    {
        "Nome": "Policy17",
        "Id": "arn:aws:iam::000000000000:policy/Policy17",
        "Data": "2020-11-20T00:45:44+00:00"
    }
    ...
    {
        "Nome": "Policy56",
        "Id": "arn:aws:iam::000000000000:policy/service-role/Policy56",
        "Data": "2020-04-11T17:30:15+00:00"
    }
]

Você pode aprender mais detalhes sobre como usar filtros em CLI output format.

Praticando

Hora de por em prática as queries e filtros. Usando o AWS CLI, tente preparar um comando que liste todos os usuários da conta mostrando apenas os seguintes campos UserName,Arn,CreateDate,UserId,PasswordLastUsed e renomeando os nomes (UserName=>Usuario). Segue um exemplo da saída:

[
    {
        "Usuario": "usuario1",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:user/usuario1",
        "CriadoEm": "2020-08-30T09:20:12+00:00",
        "Id": "AIDAXXXXXXXXXXXX",
        "SenhaUsadaEm": "2020-10-16T22:07:17+00:00"
    },
    ...
    {
        "Usuario": "usuarioN",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:user/usuarioN",
        "CriadoEm": "2021-01-30T10:20:12+00:00",
        "Id": "AIDAXXXXXXXXXXXX",
        "SenhaUsadaEm": "2021-05-26T22:07:17+00:00"
    }
]

Depois que tiver completado o passo anterior, veja se consegue filtrar os resultados e mostrar apenas os usuários que não usaram a senha recentemente (PasswordLastUsed). Com este comando você pode rapidamente identificar um usuário que não renova a senha há algum tempo ou que parou de usar a console.

Fechando

Nesta parte do guia você aprendeu a:

  • usar a linguagem de query para formatar a saída
  • usar a linguagem de query para filtrar a saída escolhendo os campos necessários
  • usar a linguagem de query para filtrar a saída usando valores

Se você gostou deste guia, não esqueça de deixar o seu comentário abaixo e o que gostaria ver nas próximas partes.

Referências


Comentários

comments powered by Disqus