ProHoster > Blog > administração > Instruções: como testar funções ansible e descobrir problemas antes da produção
Instruções: como testar funções ansible e descobrir problemas antes da produção
Olá a todos!
Trabalho como engenheiro DevOps em um serviço de reserva de hotéis. Ostrovok.ru. Neste artigo, quero falar sobre nossa experiência em testar funções ansible.
Em Ostrovok.ru, usamos ansible como gerenciador de configuração. Recentemente, chegamos à necessidade de testar funções, mas descobrimos que não existem tantas ferramentas para isso - a mais popular, talvez, seja a estrutura Molecule, então decidimos usá-la. Mas descobriu-se que sua documentação não menciona muitas armadilhas. Não conseguimos encontrar um manual suficientemente detalhado em russo, por isso decidimos escrever este artigo.
molécula
Molécula - uma estrutura para ajudar a testar funções ansible.
Descrição simplificada: A molécula cria uma instância na plataforma que você especifica (nuvem, máquina virtual, contêiner; para mais detalhes, consulte a seção Dirigir), executa sua função nele, executa testes e exclui a instância. Em caso de falha em uma das etapas, a Molécula irá informá-lo.
Agora mais.
Um pouco de teoria
Considere duas entidades principais da Molécula: Cenário e Driver.
Cenário
O script contém uma descrição do que, onde, como e em que sequência será executado. Uma função pode ter vários scripts e cada um é um diretório ao longo do caminho <role>/molecule/<scenario>, que contém descrições das ações necessárias para o teste. O script deve ser incluído default, que será criado automaticamente se você inicializar a função com uma molécula. Os nomes dos scripts a seguir são com você.
A sequência de ações de teste em um script é chamada matriz, e por padrão é:
(Etapas rotuladas ?, ignorado por padrão se não for especificado pelo usuário)
lint - executando linters. Por padrão são usados yamllint и flake8,
destroy - exclusão de instâncias do último lançamento da Molécula (se houver),
dependency? — instalação da dependência ansible da função testada,
syntax - verificar a sintaxe da função usando ansible-playbook --syntax-check,
create - criando uma instância,
prepare? — preparação da instância; por exemplo, verifique/instale python2
converge — lançamento do manual que está sendo testado,
idempotence - reiniciar o manual para o teste de idempotência,
side_effect? - ações não diretamente relacionadas à função, mas necessárias para testes,
verify - executar testes da configuração resultante usando testinfra(padrão) /goss/inspec,
cleanup? - (em novas versões) - grosso modo, “limpar” a infraestrutura externa afetada pela Molécula,
destroy - Excluindo uma instância.
Esta sequência cobre a maioria dos casos, mas pode ser alterada se necessário.
Cada uma das etapas acima pode ser executada separadamente com molecule <command>. Mas deve ser entendido que para cada comando cli pode haver sua própria sequência de ações, que você pode descobrir executando molecule matrix <command>. Por exemplo, ao executar o comando converge (executando o playbook em teste), as seguintes ações serão executadas:
$ molecule matrix converge
...
└── default # название сценария
├── dependency # установка зависимостей
├── create # создание инстанса
├── prepare # преднастройка инстанса
└── converge # прогон плейбука
A sequência dessas ações pode ser editada. Se algo da lista já tiver sido feito, será ignorado. O estado atual, bem como a configuração das instâncias, o Molecule armazena no diretório $TMPDIR/molecule/<role>/<scenario>.
Adicione etapas com ? você pode descrever as ações desejadas no formato ansible-playbook e definir o nome do arquivo de acordo com a etapa: prepare.yml/side_effect.yml. Espere que esses arquivos da molécula estejam na pasta do script.
Dirigir
Um driver é uma entidade onde as instâncias de teste são criadas.
A lista de drivers padrão para os quais o Molecule possui templates prontos é a seguinte: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegado.
Na maioria dos casos, os modelos são arquivos create.yml и destroy.yml na pasta de script que descreve a criação e exclusão de uma instância, respectivamente.
As exceções são Docker e Vagrant, pois as interações com seus módulos podem ocorrer sem os arquivos mencionados.
Vale destacar o driver Delegado, pois caso ele seja utilizado nos arquivos de criação e exclusão de instância, apenas é descrito o trabalho com configuração de instâncias, o restante deverá ser descrito pelo engenheiro.
O driver padrão é Docker.
Agora vamos praticar e considerar outros recursos.
Introdução
Como um "olá mundo", vamos testar uma função simples de instalação do nginx. Vamos escolher o docker como driver - acho que a maioria de vocês o tem instalado (e lembrem-se de que o docker é o driver padrão).
A próxima etapa é inicializar a nova função.
A inicialização de uma nova função, bem como de um novo script, é realizada usando o comando molecule init <params>:
> molecule init role -r nginx
--> Initializing new role nginx...
Initialized role in <path>/nginx successfully.
> cd nginx
> tree -L 1
.
├── README.md
├── defaults
├── handlers
├── meta
├── molecule
├── tasks
└── vars
6 directories, 1 file
Acabou sendo um típico papel ansible. Além disso, todas as interações com moléculas CLI são feitas a partir da raiz da função.
Vamos ver o que está no diretório role:
> tree molecule/default/
molecule/default/
├── Dockerfile.j2 # Jinja-шаблон для Dockerfile
├── INSTALL.rst. # Немного информации об установке зависимостей сценария
├── molecule.yml # Файл конфигурации
├── playbook.yml # Плейбук запуска роли
└── tests # Директория с тестами стадии verify
└── test_default.py
1 directory, 6 files
Vamos analisar a configuração molecule/default/molecule.yml (substitua apenas a imagem do docker):
Shell é apenas um shell de comando usado caso o Galaxy e o Gilt não atendam às suas necessidades.
Não vou ficar aqui por muito tempo, está bastante descrito em documentação.
motorista
O nome do motorista. O nosso é docker.
cotão
O linter é yamllint.
Opções úteis nesta parte da configuração são a capacidade de especificar um arquivo de configuração para o yamllint, encaminhar variáveis de ambiente ou desabilitar o linter:
Descreve a configuração das instâncias.
No caso do docker como driver, a molécula é iterada nesta seção e cada elemento da lista está disponível em Dockerfile.j2 como uma variável item.
No caso de um driver que exija create.yml и destroy.yml, a seção está disponível neles como molecule_yml.platforms, e as iterações sobre ele já estão descritas nesses arquivos.
Como o Molecule fornece controle de instâncias para módulos ansible, a lista de configurações possíveis também deve ser procurada lá. Para docker, por exemplo, o módulo é usado docker_container_module. Quais módulos são usados em outros drivers podem ser encontrados em documentação.
Bem como exemplos do uso de vários drivers podem ser encontrados nos testes da própria molécula.
Substitua aqui centos:7 em ubuntu.
provedor
“Fornecedor” – entidade que gerencia instâncias. No caso do Molecule, isso é ansible, o suporte para outros não está planejado, portanto esta seção pode ser chamada de configuração estendida ansible com uma ressalva.
Aqui você pode especificar muitas coisas, vou destacar os pontos principais, na minha opinião:
cartilhas: você pode especificar quais playbooks devem ser usados em determinados estágios.
Nome e descrição das sequências de script.
Você pode alterar a matriz de ação padrão de qualquer comando adicionando a chave <command>_sequence e como um valor para isso, definindo a lista de etapas que precisamos.
Digamos que queremos alterar a sequência de ações ao executar o comando run do playbook: molecule converge
Nosso papel simples foi testado sem problemas.
Vale lembrar que caso haja problemas durante a obra molecule test, então, se você não alterou a sequência padrão, o Molecule excluirá a instância.
Os seguintes comandos são úteis para depuração:
> molecule --debug <command> # debug info. При обычном запуске Молекула скрывает логи.
> molecule converge # Оставляет инстанс после прогона тестируемой роли.
> molecule login # Зайти в созданный инстанс.
> molecule --help # Полный список команд.
Função existente
Adicionar um novo script a uma função existente é do diretório de funções com os seguintes comandos:
# полный список доступных параметров
> molecule init scenarion --help
# создание нового сценария
> molecule init scenario -r <role_name> -s <scenario_name>
Caso este seja o primeiro cenário da função, então o parâmetro -s pode ser omitido pois criará um script default.
Conclusão
Como você pode ver, o Molecule não é muito complexo e, usando seus próprios modelos, a implantação de um novo script pode ser reduzida à edição de variáveis nos manuais de criação e exclusão de instâncias. A molécula se integra perfeitamente aos sistemas de CI, o que permite aumentar a velocidade de desenvolvimento, reduzindo o tempo de teste manual de playbooks.
Obrigado pela sua atenção. Se você tem experiência em testar papéis ansible, e isso não está relacionado à Molécula, conte-nos nos comentários!