Zabbix auto-deregister com AWS autoscaling

· by Raphael Rabelo · Read in about 5 min · (1053 Words)

Intro

Quem trabalha com instâncias em autoscaling na AWS e monitoramento em Zabbix deve ter passado por um problema conhecido: Remover as máquinas do zabbix server para não alarmarem quando o scale down agir.

Todas as novas instâncias em autoscaling na AWS já são provisionadas automaticamente para atender a demanda sem a necessidade de instalação de pacotes, deploy etc… Inclusive já se registram no Zabbix Server via auto-registration. Cool!

O Problema é que o Zabbix não tem um auto-deregister, que remove as máquinas, o resultado? Depois que demanda diminui e as instâncias em idle são terminadas pelo autoscaling, o Zabbix fica alertando no painel e disparando emails para toda equipe de operações.

Diante do problema, pensei em diversas formas de resolve-lo e acabei optando pela mais ‘simples’: SNS + SQS + Python.


Obs: O procedimento foi testando utilizando Zabbix Server 3.0.3, mas pode funcionar normalmente para a versão 2.


Como funciona

O que faremos é:

  1. Criar um tópico SNS para notificações do autoscaling;
  2. Criar um fila SQS para receber essas notificações;
  3. Com o script em python, iremos ler essa fila e pegar o IntanceID da instância que foi terminada;
  4. Com esse InstanceId iremos fazer uma busca através da API do zabbix e desabilitar o servidor do monitoramento;
  5. Após o host desabilitado, removeremos a mensagem da fila SQS.


Configuração

Parte 1 - Zabbix Server

Antes de mais nada, precisamos fazer algumas configurações no Zabbix Server: Criar um HostGroup dedicado para nossas máquinas de autoscaling e alterar nossa action de auto-Registration e setar o modo de inventário Automático:


Criando HostGroup

A criação do HostGroup é apenas para facilitar o discovery da instância pela API do Zabbix, assim através do script definimos qual será o HostGroup que a máquina está, isso facilita pois dependendo da quantidade de servidores cadastrados a busca pode demorar.


Configuration > Host groups > Create new host group


No meu caso, irei utilizar o nome ‘AWS - Autoscaling’

Para obter o grouId, clique no Hostgroup que acabou de criar e olhe para a URL no browser:


GroupID


Anote esse numero, ele servirá mais tarde para configurar o script.


Configurar Inventory Mode

Habilite a opção em Configuration > Actions escolha a ação e edite. Na aba Operations adicione uma nova Action e defina os campos:


Operation Type: Set host inventory mode

Inventory mode: Automatic


inventory mode: automatic


Aproveite e adicione outra Action que insira o host no HostGroup que acabamos de criar.


Operation Type: Add to host group

Host groups: AWS - Autoscaling


Criando um novo template

Assim como criamos um HostGroup para facilitar na busca do servidor, o template nos ajudará na tarefa de achar o nosso servidor pelo instanceId, e não por IP ou DNS. Utilizando instanceId, podemos evitar alguns acidente, como por exemplo a não atualiação do DNS, ou ip incorreto.

Nesse template, teremos apenas 1 item, que será responsável por popular o inventório do servidor com o InstanceId.


Configuration > Templates > Create Template


Vou usar o mesmo nome do Hostgroup para facilitar: AWS - Autoscaling

Salve o template, e adicione um item:


Name: InstanceId

Type: Zabbix agent

Type of information: text

Key: instance-id

Update Interval: 30

Populates host inventory field: tag


Com isso vamos precisar adicionar um UserParameter no nosso arquivo de configuração dos agents zabbix-agentd.conf

UserParameter=instance-id[*],/opt/aws/bin/ec2-metadata -i | cut -d' ' -f2

Por último, precisamos de um usuário de acesso ao zabbix via API, esse usuário precisa ter permissão para Leitura e também para Desabilitar hosts.


Crie o usuário em Administration > User


Vou chamar o meu usuário de api-user.

Finalizadas as configurações do Zabbix, vamos ao próximo passo:


Parte 2 - AWS

A configuração na AWS consiste em criar um tópico sns, uma fila SQS e configurar o nosso autoscaling para enviar uma mensagem sempre que uma instância for terminada.


IAM Role

Vamos começão criando um usuário no console da AWS que usaremos em nosso script para ter acesso a fila SQS e leitura de tags das instâncias EC2.

Chamarei o meu usuário de zabbix-deregister, com usuário criado, você precisará adicionar as permissões para esse usuário:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "sqs:DeleteMessage",
                    "sqs:ReceiveMessage",
                    "ec2:DescribeTags"
                ],
                "Resource": [
                    "*"
                ]
            }
        ]
    }

Nesse exemplo, estou utilizando ‘ * ‘ nos resources para propósito de testes, depois que tiver todos os recursos criados altere com o ARN de cada resource.

SNS topic

Crie um novo tópico SNS chamado asg-terminate

Verifique que foi gerado um ARN do tópico SNS, diante disso vamos criar uma fila SQS:

O nome da minha fila será asg-terminate, configure as opções como abaixo:


Default Visibility Timeout: 70 seconds

Message Retention Period: 1 days

Maximum Message Size: 10 KB

Delivery Delay: 0 seconds

Receive Message Wait Time: 2 seconds


SQS Topic


Anote a URL de endpoint, usaremos mais tarde.

Feito isso, selecione a nova fila criada, clique em Queue Actions > Subscribe queue to SNS topic

Selecione o topico SNS que criamos, o ARN deverá ser preenchido automaticamente.


subscribe_sns


Feito isso, todas as mensagens que forem enviadas para o tópico SNS irão para a fila do ‘asg-terminate’ do SQS.

Precisamos agora configurar nosso autoscaling group para enviar uma mensagem para o SNS toda vez que uma instância for terminada, para isso, escolha o autoscaling group que deseja, clique em Notifications > Create Notification

Defina as opções:


Send a notification to: asg-terminate

Whenever instances : terminate


asg_notification.jpg


Finalizamos a configuração da AWS!

Parte 3 - Script

Com Zabbix e AWS configurados, vamos ao script que irá fazer a mágica.

Baixe aqui.

Edite o script com os seus dados:

# Set the zabbix server informations
ZABBIX_SERVER_URL = 'http://url.to.zabbix'
ZABBIX_API_USER = 'api-user'
ZABBIX_API_PASSWORD = 'segredo'
ZABBIX_GROUP_ID = '182'

# Set the SQS endpoint url to read messages
queueUrl='<SET_SQS_ENDPOINT>'


Acesse o zabbix server via ssh e coloque o script para rodar via crontab, com a frequencia que desejar, no meu caso será a cada 2 minutos.


*/2 * * * * python /path/to/script/auto-deregister.py >> /var/log/zabbix/auto-deregister.log 2>&1


Conclusão

Pode não ser a melhor maneira de fazer isso, mas no meu caso o problema foi resolvido.

É possível colocar esse script em Lambda ao invés de adicionar na crontab do servidor, em breve pretendo fazer isso.

Com o tempo, o zabbix fica com vários servidores desabilitados atrelados ao HostGroup, é possível remover manualmente, ou alterar o script para deletar o Host, ao invés de desabilitar… use por sua conta e risco ;)


<ESC>:wq