Se você usa o AWS (Amazon Web Services), vira e mexe suas instâncias te avisam coisas ou o próprio AWS te notifica que algo ocorre. Uma manutenção programada, um alarme do CloudWatch, coisas do gênero. Normalmente esses avisos possuem o ID da instância afetada. Mas e se você tem um montão de instâncias espalhadas mundo afora? Saber onde ela está é bem chato. Até agora.

Eventualmente você recebe um email desse do AWS:

Amazon EC2 Maintenance - Maintenance [AWS Account: %ACCOUNT%]

Dear Amazon EC2 Customer,

One or more of your Amazon EC2 instances is scheduled for maintenance on %YYYY-MM-DD% for %H% hours starting at %HH:MM% UTC. During this time, the following instances in the %REGION% region will be unavailable and then rebooted:

i-%INSTANCEID%

Se sua instância faz parte de um auto-scaling group, você não precisa fazer nada. A instância vai morrer na data e hora marcada pelo AWS e o auto-scaling vai recriá-la (se necessário) em outro lugar.

Mas se o seu serviço não usa auto-scaling, então você tem coisas a fazer. Tipicamente, essa tarefa consiste em desligar a instância pelo tempo da manutenção prevista e religá-la depois disso. Toca pro console do AWS, faz login e sai caçando nas diversas regiões onde está a maldita instância.

Ou, se você usa o AWS CLI, tem que rodar isso:

aws ec2 describe-instance --region %REGION% --instance-id %INSTANCEID% --output table

No comando acima, uso a saída do tipo tabela para uma visualização mais fácil das informações da instância. Mas mesmo ela não é lá tão amigável em função da quantidade de informações associadas a cada instância. Os outros formatos, json e texto, nem se fala.

Note ainda que somos obrigados a informar a região. Se você usa muitas regiões, precisará rodar o comando acima várias vezes, cada um com uma região diferente (ap-northeast-1, us-east-1, sa-east-1 etc) até que encontre a instância que precisa. Quão chato é isso?

E mais: uma linha de comando que tem uso cotidiano com pelo menos 86 caracteres? Aff!

Bash e jq

Associar o AWS CLI com o bash e o jq é algo que permite automatizar praticamente qualquer coisa no AWS sem que você se torne um refém dele. Naturalmente, o AWS faz de tudo para que seu negócio e você sejam o mais dependente possível dele (o tal vendor lock-in). O bash e o jq juntos são a fuga do cárcere.

Mas aqui vamos usar os poderes da dupla para algo bem menos dramático: listar nossas instâncias de um jeito bonitinho e facinho.

Antes de prosseguir, faça isso:

  1. Instale o jq;
  2. Se já não tiver instalado, instale o AWS CLI;
  3. Configure o AWS CLI com uma chave de acesso IAM.

Funções pra toda hora

Com os requisitos prontos, adicione essas duas funções no seu ~/.bashrc:

# List AWS instances in all regions
#===============================================================================
awsid () {
  REGIONS="ap-northeast-1 us-east-1 sa-east-1"
  for region in $REGIONS; do
    echo -e "\033[00;34m\033[1mAWS instances in: \033[00;32m\033[1m${region}\033[0m"
    aws ec2 describe-instances --region $region --output json | \
      jq '.Reservations[].Instances[] | (.Tags | from_entries) as $tags | {"i-ID": .InstanceId, Name: $tags.Name, Stat: .State.Name}, "--"' | \
      grep -v '{\|}' | sed 's/'\"'\|,//g' | column -t
  done
}

# List an especific AWS instance
#===============================================================================
awsids () {
  if [ -z $1 ]; then
    echo "Usage: awsids <instance-id>"
    return 1
  fi
  awsid | grep -A 2 --color=never $1
}

Notou a variável REGIONS? É ali que você configura quais as regiões do seu interesse. Coloque nela apenas as regiões existem instâncias do seu serviço. Você pode obter a lista de regiões com:

aws ec2 describe-regions --output table

Veja também que eu estou usando a tag Name para obter o nome da instância. Nomear suas instâncias de um modo significativo à operação é crucial não só pra você usar isso aqui, mas para a vida!

Para os críticos que diriam 'mas o AWS CLI já tem filtros! Não precisa do jq pra isso!`, eu digo: sim, tem. Mas o jq é muito mais flexível nesse quesito e ainda possibilita formatar a saída do jeito que o freguês quer.

Quando terminar, recarregue com . ~/.bashrc ou simplesmente logout/login e pronto.

Listando Instâncias

Vamos ver o que isso faz? É simples.

$ awsid
AWS instances in: ap-northeast-1
i-ID:  i-e12233c5
Name:  myservice.role.an
Stat:  running
--
AWS instances in: us-east-1
i-ID:  i-cf667167
Name:  myservice.role.ue
Stat:  stopped
--
AWS instances in: sa-east-1
i-ID:  i-30c7d136
Name:  myservice.role.sa
Stat:  stopped
--

Viu que lindo? Com um comandinho apenas você vê os IDs das instâncias, seus nomes e estados em todas as regiões de uma vez. A saída acima não mostra, mas o rótulo AWS instances in: us-east-1 é coloridinho. Tão fofo!

Mas e se você tem milhares de instâncias e uma listona com todas elas não ajuda muito? Então rode:

$ awsids cf667167
i-ID:  i-cf667167
Name:  myservice.role.ue
Stat:  stopped

Tcharãn! Só a instância que você pediu. O nome dela me informa em qual região ela está, mas só se você tem nomes bons para a nuvem.

Isso é útil pra você? Tem mais dicas legais para o uso do AWS CLI? Conta aí nos comentários.