A partir do segundo commit, calquera código pasa a ser legado, porque as ideas iniciais comezan a diverxer da dura realidade. Isto non é nin bo nin malo, é un feito que é difícil de discutir e que hai que vivir. Parte deste proceso é a refactorización. Refactorización da infraestrutura como código. Que comece a historia de como refactorizar Ansible nun ano e non volverse tolo.
O nacemento do legado
Día #1: Paciente Cero
Había unha vez un proxecto condicional. Tiña un equipo de desenvolvemento de desenvolvemento e enxeñeiros de operacións. Estaban resolvendo o mesmo problema: como despregar servidores e executar unha aplicación. O problema foi que cada equipo resolveu este problema á súa maneira. No proxecto, decidiuse usar Ansible para sincronizar o coñecemento entre os equipos de Dev e Ops.
Día #89: O nacemento do legado
Sen decatarse eles mesmos, quixeron facelo o mellor posible, pero resultou ser un legado. Como ocorre isto?
Temos unha tarefa urxente aquí, imos facer un hack sucio e despois solucionalo.
Non tes que escribir documentación e todo está claro o que está a pasar aquí.
Coñezo Ansible/Python/Bash/Terraform! Mira como podo esquivar!
Son un programador de Full Stack Overflow e copiei isto de stackoverflow, non sei como funciona, pero parece xenial e resolve o problema.
Como resultado, pódese conseguir un tipo de código incomprensible para o que non hai documentación, non está claro o que fai, se é necesario, pero o problema é que hai que desenvolvelo, modificalo, engadir muletas e soportes. , facendo a situación aínda peor.
O modelo de IaC concibido e implementado inicialmente xa non cumpre os requisitos dos usuarios/empresas/outros equipos, e o tempo para facer cambios na infraestrutura deixa de ser aceptable. Neste momento, chega a entender que é hora de tomar medidas.
Refactorización de IaC
Día #139: ¿Realmente necesitas refactorización?
Antes de apurar a refactorización, debes responder a unha serie de preguntas importantes:
Por que necesitas todo isto?
Tes tempo?
É suficiente o coñecemento?
Se non sabes como responder ás preguntas, entón a refactorización rematará antes de que comece, ou só pode empeorar. Porque tiña experiencia ( O que aprendín probando 200 liñas de código de infraestrutura), entón o proxecto recibiu unha solicitude de axuda para fixar os roles e cubrilos con probas.
Día #149: Preparación da refactorización
O primeiro é preparar. Decide o que imos facer. Para iso, comunicámonos, atopamos áreas problemáticas e buscamos formas de resolvelos. Rexistramos os conceptos resultantes dalgún xeito, por exemplo un artigo en confluencia, de xeito que cando xorde a pregunta "que é o mellor?" ou "cal é correcto?" Non perdemos o camiño. No noso caso, seguimos a idea divide e goberna: dividimos a infraestrutura en pequenos anacos/ladrillos. Este enfoque permítelle tomar unha peza illada de infraestrutura, comprender o que fai, cubrila con probas e cambiala sen medo a romper nada.
Resulta que as probas de infraestruturas convértense na pedra angular e aquí paga a pena mencionar a pirámide de probas de infraestruturas. Exactamente a mesma idea que está en desenvolvemento, pero para infraestruturas: estamos pasando de probas rápidas baratas que verifican cousas sinxelas, como sangría, a probas caras e completas que despregan toda a infraestrutura.
Intentos de proba Ansible
Antes de describir como cubrimos as probas de Ansible no proxecto, describirei os intentos e enfoques que tiven a oportunidade de utilizar anteriormente para comprender o contexto das decisións tomadas.
Día no -997: prestación da SDS
A primeira vez que probei Ansible foi nun proxecto para desenvolver SDS (Software Defined Storage). Hai un artigo separado sobre este tema Como romper bicicletas por muletas ao probar a súa distribución, pero en resumo, acabamos cunha pirámide de probas invertida e as probas pasamos 60-90 minutos nun papel, o que é moito tempo. A base foron probas e2e, é dicir. implantamos unha instalación completa e despois probámola. O que aínda era máis agravante foi a invención da súa propia bicicleta. Pero debo admitir que esta solución funcionou e permitiu unha versión estable.
Día # -701: Ansible e cociña de proba
O desenvolvemento da idea de proba de Ansible foi o uso de ferramentas preparadas, a saber, probar cociña / cociña-ci e inspeccionar. A elección foi determinada polo coñecemento de Ruby (para máis detalles, consulte o artigo sobre Habré: Os programadores de YML soñan con probar Ansible?) funcionou máis rápido, uns 40 minutos para 10 papeis. Creamos un paquete de máquinas virtuais e realizamos probas dentro.
En xeral, a solución funcionou, pero había algún sedimento debido á heteroxeneidade. Cando o número de persoas probadas aumentou a 13 roles básicos e 2 meta roles que combinan roles máis pequenos, de súpeto as probas comezaron a executarse durante 70 minutos, o que é case 2 veces máis. Era difícil falar de prácticas de XP (programación extrema) porque... ninguén quere esperar 70 minutos. Este foi o motivo para cambiar o enfoque
Día # -601: Ansible e molécula
Conceptualmente, isto é semellante a testkitchen, só que movemos a proba de roles a docker e cambiamos a pila. Como resultado, o tempo reduciuse a uns 20-25 minutos estables para 7 papeis.
Ao aumentar a 17 o número de papeis probados e 45 papeis, executámolo en 28 minutos en 2 escravos jenkins.
Día #167: Engadindo probas de Ansible ao proxecto
O máis probable é que non sexa posible facer a tarefa de refactorización con présa. A tarefa debe ser medible para poder rompela en anacos pequenos e comer o elefante anaco a anaco cunha culleriña. Debe haber unha comprensión de se está a moverse na dirección correcta, canto tempo falta.
En xeral, non importa como se faga, podes escribir nun papel, pór adhesivos no armario, podes crear tarefas en Jira ou podes abrir Google Docs e anotar o estado actual. alí. As pernas medran polo feito de que o proceso non é inmediato, será longo e tedioso. É pouco probable que alguén queira que se queime de ideas, se canse e se desborde durante a refactorización.
A refactorización é sinxela:
Coma.
Durmir.
Código.
Proba IaC.
Repetir
e repetimos isto ata acadar o obxectivo previsto.
Quizais non sexa posible comezar a probar todo de inmediato, polo que a nosa primeira tarefa foi comezar coa linting e comprobando a sintaxe.
Día #181: Mestre de construción verde
Linting é un pequeno primeiro paso cara a Green Build Master. Isto non romperá case nada, pero permitirache depurar procesos e facer construcións verdes en Jenkins. A idea é desenvolver hábitos entre o equipo:
As probas vermellas son malas.
Vin para arranxar algo e ao mesmo tempo facer o código un pouco mellor do que era antes.
Día #193: Do listing ás probas unitarias
Unha vez construído o proceso de incorporación do código ao mestre, podes comezar o proceso de mellora paso a paso: substituíndo a linting por roles de lanzamento, incluso podes facelo sen idempotencia. Debe entender como aplicar os roles e como funcionan.
Día #211: Das probas unitarias ás probas de integración
Cando a maioría dos papeis están cubertos con probas unitarias e todo está ligado, podes pasar a engadir probas de integración. Eses. probando non un só ladrillo na infraestrutura, senón unha combinación deles, por exemplo, unha configuración de instancia completa.
Usando jenkins, xeramos moitas etapas que aliñaban roles/playbooks en paralelo, despois probas unitarias en contedores e, finalmente, probas de integración.
Jenkins + Docker + Ansible = Probas
Paga o repositorio e xera fases de compilación.
Executar as fases do libro de pelusas en paralelo.
Executar fases de rol de pelusa en paralelo.
Executar fases de función de comprobación de sintaxe en paralelo.
Executar fases de rol de proba en paralelo.
Papel de pelusa.
Comproba a dependencia doutros roles.
Comproba a sintaxe.
Crear instancia docker
Executa molecule/default/playbook.yml.
Comprobar a idempotencia.
Realiza probas de integración
Rematar
Día #271: Bus Factor
Nun primeiro momento, a refactorización realizábase por un pequeno grupo de dúas ou tres persoas. Revisaron o código no master. Co paso do tempo, o equipo desenvolveu coñecementos sobre como escribir código e a revisión do código contribuíron á difusión do coñecemento sobre a infraestrutura e como funciona. O máis destacado aquí foi que os revisores foron seleccionados un por un, segundo un calendario, é dicir. con certo grao de probabilidade subirás a unha nova peza de infraestrutura.
И здесь должно быть удобно. Удобно делать ревью, видеть в рамках какой задачи оно сделано, историю обсуждений. Мы интегрировали jenkins + bitbucket + jira.
Pero como tal, unha revisión non é unha panacea; dalgún xeito, entramos no código mestre, o que nos fixo probas de fracaso:
Co paso do tempo, houbo máis probas, as construcións foron máis lentas, ata unha hora no peor dos casos. Nun dos retros había unha frase como "é bo que haxa probas, pero son lentas". Como resultado, abandonamos as probas de integración en máquinas virtuais e adaptámolas para Docker para facelo máis rápido. Tamén substituímos testinfra por un verificador ansible para reducir o número de ferramentas utilizadas.
En rigor, houbo unha serie de medidas:
Cambiar ao docker.
Elimina as probas de roles, que se duplican debido ás dependencias.
Aumentar o número de escravos.
Orde de execución de proba.
Capacidade de pelusa TODOS localmente cun comando.
Como resultado, Pipeline on jenkins tamén se unificou
Xerar fases de construción.
Lint todo en paralelo.
Executar fases de rol de proba en paralelo.
Rematar.
As leccións aprendidas
Evite as variables globais
Ansible usa variables globais, hai unha solución parcial no formulario variables_papel_privada, pero esta non é unha panacea.
O curioso é que o resultado dos playbooks dependerá de cousas que non sempre son obvias, como a orde na que se enumeran os papeis. Desafortunadamente, esta é a natureza de Ansible e o mellor que se pode facer é usar algún tipo de acordo, por exemplo, dentro dun rol, use só a variable descrita neste rol.
BOA: Nos roles para variables, use as variables co prefixo do nome do rol; isto, ao observar o inventario, facilitará a comprensión do que está a suceder.
Acordamos empregar prefixos variables; non sería superfluo comprobar que están definidos como esperamos e, por exemplo, non foron substituídos por un valor baleiro
BOA: Comproba as variables.
- name: "Verify that required string variables are defined"
assert:
that: ahs_var is defined and ahs_var | length > 0 and ahs_var != None
fail_msg: "{{ ahs_var }} needs to be set for the role to work "
success_msg: "Required variables {{ ahs_var }} is defined"
loop_control:
loop_var: ahs_var
with_items:
- ahs_item1
- ahs_item2
- ahs_item3
Evite os dicionarios hash, use estrutura plana
Se un rol espera un hash/dicionario nalgún dos seus parámetros, entón se queremos cambiar un dos parámetros fillos, teremos que anular todo o hash/dicionario, o que aumentará a complexidade da configuración.
Os papeis e os libros de xogo deben ser idempotentes, porque reduce a deriva da configuración e o medo a romper algo. Pero se usas molécula, este é o comportamento predeterminado.
Evite usar módulos de shell de comandos
Usar un módulo de shell dá como resultado un paradigma de descrición imperativo, en lugar do declarativo, que é o núcleo de Ansible.
Proba os teus papeis a través dunha molécula
A molécula é unha cousa moi flexible, vexamos algúns escenarios.
Molécula Múltiples instancias
В molecule.yml na sección platforms pode describir moitos hosts que pode implementar.
En Molecule é posible usar ansible para comprobar que a instancia foi configurada correctamente, ademais, esta é a predeterminada desde a versión 3. Non é tan flexible como testinfra/inspec, pero podemos comprobar que o contido do ficheiro coincide coas nosas expectativas:
Ou implementa o servizo, agarda a que estea dispoñible e fai unha proba de fume:
---
- name: Verify
hosts: solr
tasks:
- command: /blah/solr/bin/solr start -s /solr_home -p 8983 -force
- uri:
url: http://127.0.0.1:8983/solr
method: GET
status_code: 200
register: uri_result
until: uri_result is not failed
retries: 12
delay: 10
- name: Post documents to solr
command: /blah/solr/bin/post -c master /exampledocs/books.csv
Pon lóxica complexa en módulos e complementos
Ansible defende un enfoque declarativo, polo que cando fai ramificación de código, transformación de datos, módulos de shell, o código faise difícil de ler. Para combater isto e que sexa sinxelo de entender, non sería superfluo combater esta complexidade creando os seus propios módulos.
Resume Consellos e Trucos
Evite as variables globais.
Prefixo de variables de rol.
Use a variable de control de bucle.
Comprobar as variables de entrada.
Evite os dicionarios hash, use estrutura plana.
Crea libros e papeis idempotentes.
Evite usar módulos de shell de comandos.
Proba os teus papeis a través dunha molécula.
Pon lóxica complexa en módulos e complementos.
Conclusión
Non podes ir e refactorizar a infraestrutura nun proxecto, aínda que teñas IaC. Este é un proceso longo que require paciencia, tempo e coñecemento.
UPD1 2020.05.01/20/30 XNUMX:XNUMX — Para o perfil principal dos libros de xogo que podes usar callback_whitelist = profile_tasks comprender o que funciona exactamente durante moito tempo. Despois pasamos Clásicos de aceleración Ansible. Tamén podes probar mitógeno UPD2 2020.05.03/16/34 XNUMX:XNUMX - Versión en inglés