Bem-vindo a terceira parte do guia. Você aprenderá a linguagem de query que permite “trabalhar” os resultados de um comando.
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.
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íticas | com | apenas 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!
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.
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.
Nesta parte do guia você aprendeu a:
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.