Nunca usé Ansible, pero desde hace unas semanas, trato de descubrir qué tan bueno podría ser Ansible en comparación con los scrips de shell, lo que demuestra, al menos en mi caso, que las inquietantes campañas publicitarias que ejecutan son efectivas. Después de muchos intentos fallidos, lo que demuestra cómo su documentación no responde a una de las preguntas más obvias, creo que finalmente lo entendí:
Ahora, veamos el video de introducción y veamos al azar como un nuevo usuario potencial a través del material de introducción a Ansible y comparémoslo con lo que un programador experto puede producir de inmediato.
Mi conclusión es que sobre las secuencias de comandos de shell, Ansible esencialmente ofrece 1. La posibilidad de verificar que un sistema esté de acuerdo con un estado deseado, 2. la capacidad de integrarse con Ansible Tower, que es un sistema de pago que parece incluir habilidades de monitoreo. En algunos casos importantes, como cuando se implementa el patrón de servidor inmutable, el punto 1 probablemente no sea muy útil, por lo que la lista es bastante delgada.
Mi conclusión es que los beneficios ofrecidos por Ansible sobre las secuencias de comandos de shell, como los presenta la documentación, podrían ser sensibles en algunos pocos casos optimistas bien cubiertos por los módulos disponibles, pero son pequeños o incluso hipotéticos en el caso general. Para un programador de shell experto, estos beneficios probablemente se vean contrarrestados por otros aspectos de la compensación.
¡Pero esto tal vez solo pruebe cuán malo es el material de introducción!
El video de inicio rápido:
Hay un video de inicio rápido . Comienza con una página que dice que ... bueno, estas no son realmente afirmaciones, son listas de viñetas, un artefacto comúnmente utilizado para suspender el juicio crítico en las presentaciones (ya que la lógica no se muestra, ¡no se puede criticar!)
1. Ansible es simple:
1.1 Automatización legible por humanos - Las especificaciones son documentos técnicos, ¿cómo podrían
name: upgrade all packages
yum:
name: '*'
state: latest
ser más fácil de leer que la invocación yum correspondiente encontrada en un shell-script? Además, cualquiera que haya tenido contacto con AppleScript muere de risa cuando lee "automatización legible por humanos".
1.2 No se requieren habilidades especiales de codificación: ¿qué es la codificación si no se escriben especificaciones formales? Tienen condicionales, variables, entonces, ¿cómo es que no está codificando? ¿Y por qué necesitaría algo que no puedo programar, que en adelante sería inflexible? ¡La afirmación es felizmente inexacta!
1.3 Tareas ejecutadas en orden: Bueno, tal vez algunos aficionados al codegolf conocen los lenguajes que ejecutan tareas en desorden, pero ejecutar tareas en orden difícilmente parece excepcional.
1.4 Sea productivo rápidamente: los programadores expertos de shell son productivos ahora. Este contraargumento es tan serio como el argumento inicial.
2. Ansible es poderoso
Un truco popular del vendedor para vender artefactos es engañar a las personas para que crean que adquirirán el "poder" de estos artefactos. La historia de la publicidad de automóviles o bebidas isotónicas debería proporcionar una lista convincente de ejemplos.
Aquí Ansible puede hacer "implementación de la aplicación", pero el script de shell seguramente lo hace, "administración de la configuración", pero esta es una mera declaración del propósito de la herramienta, no una característica, y la "orquestación del flujo de trabajo" que parece un poco pretenciosa, pero no hay ningún ejemplo más allá de lo que GNU Parallel puede hacer.
3. Ansible es sin agente
Para llenar la columna, escribieron de tres maneras diferentes que esto solo necesita ssh, que, como todos saben, es un demonio y no tiene nada que ver con estos agentes que impregnan la gestión de la configuración mundial.
El resto del video
El resto del video presenta inventarios, que son listas estáticas de recursos (como servidores) y muestra cómo implementar Apache en tres servidores simultáneamente. Esto realmente no coincide con mi forma de trabajar, donde los recursos son muy dinámicos y pueden enumerarse mediante herramientas de línea de comandos proporcionadas por mi proveedor de la nube y consumidas por mis funciones de shell utilizando el |
operador de canalización . Además, no implemento Apache en tres servidores simultáneamente, sino que construyo una imagen de instancia maestra que luego uso para iniciar 3 instancias que son réplicas exactas una de la otra. Por lo tanto, la parte de "orquestación" de la argumentación no parece muy pertinente.
Documentación aleatoria paso 1: Integración con EC2
EC2 es el servicio informático de Amazon, la interacción con él es compatible con algún módulo Ansible . (También se proporcionan otros proveedores populares de computación en la nube):
# demo_setup.yml
- hosts: localhost
connection: local
gather_facts: False
tasks:
- name: Provision a set of instances
ec2:
key_name: my_key
group: test
instance_type: t2.micro
image: "{{ ami_id }}"
wait: true
exact_count: 5
count_tag:
Name: Demo
instance_tags:
Name: Demo
register: ec2
El script de shell correspondiente sería esencialmente idéntico con YAML reemplazado por JSON:
provision_a_set_of_instances()
{
aws --output=text ec2 run-instances --image-id …
}
o la versión JSON
provision_a_set_of_instances()
{
aws --output=text ec2 run-instances --cli-input-json "$(provision_a_set_of_instances__json)"
}
provision_a_set_of_instances__json()
{
cat <<EOF
{
"ImageId": …
}
EOF
}
Ambas versiones son esencialmente idénticas, la mayor parte de la carga útil es la enumeración de los valores de inicialización en estructuras YAML o JSON.
Documentación aleatoria paso 2: Entrega continua y actualizaciones continuas
La mayor parte de esta guía no muestra ninguna característica realmente interesante: ¡presenta variables (IIRC, los scripts de shell también tienen variables)! Y un módulo Ansible maneja mysql, de modo que si en lugar de buscar después “¿cómo creo un usuario mysql? con privilegios en XY "y termina con algo como
# Create Application DB User
mysql --host "${mysql_host}" --user "${mysql_user}" --password "${mysql_password}" "${mysql_table}" <<EOF
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
EOF
busca "cómo creo un usuario de mysql con privilegios en XY en ansible " y termina con
- name: Create Application DB User
mysql_user: name={{ dbuser }} password={{ upassword }}
priv=*.*:ALL host='%' state=present
La diferencia probablemente todavía no sea muy significativa. En esa página también descubrimos que Ansible tiene un lenguaje de meta-programación de plantillas.
{% for host in groups['monitoring'] %}
-A INPUT -p tcp -s {{ hostvars[host].ansible_default_ipv4.address }} --dport 5666 -j ACCEPT
{% endfor %}
Cuando veo esto, estoy realmente en mi zona de confort. ¡Este tipo de metaprogramación simple para lenguajes declarativos es exactamente el mismo paradigma teórico que BSD Makefiles! Lo que he programado extensamente Este extracto nos muestra que la promesa de trabajar con el archivo YAML está rota (por lo que no puedo ejecutar mis libros de jugadas a través de un analizador YAML, por ejemplo ). También nos muestra que Ansible debe analizar el arte sutil del orden de evaluación: tenemos que decidir si las variables se expanden en la "parte declarativa" del lenguaje o en la metaparte "imperativa" del lenguaje. Aquí la programación de shell es más simple, no hay metaprogramación, aparte de la fuente de script explícito eval
o externo. El extracto hipotético de concha equivalente
enumerate_group 'monitoring' | {
while read host; do
…
done
}
cuya complejidad en comparación con la variante Ansible es probablemente tolerable: solo utiliza las construcciones simples, regulares y aburridas del lenguaje.
Documentación aleatoria paso 3: estrategias de prueba
Por último, nos encontramos con lo que resulta ser la primera característica realmente interesante de Ansible: “Los recursos de Ansible son modelos del estado deseado. Como tal, no debería ser necesario probar que los servicios se inician, los paquetes están instalados u otras cosas similares. Ansible es el sistema que asegurará que estas cosas sean declarativamente verdaderas. En lugar de eso, afirma estas cosas en tus libros de jugadas ”. Ahora comienza a ser un poco interesante, pero:
Además de un puñado de situaciones estándar implementadas fácilmente por los módulos disponibles, tendré que alimentar los bits que implementan la prueba yo mismo, lo que probablemente involucrará algunos comandos de shell.
La comprobación de la conformidad de las instalaciones puede no ser muy relevante en el contexto donde se implementa el patrón de servidor inmutable: donde todos los sistemas en ejecución generalmente se generan a partir de una imagen maestra (imagen de instancia o imagen de acoplador, por ejemplo) y nunca se actualizan; se reemplazan por nuevo en su lugar.
Preocupación no abordada: la mantenibilidad
El material introductorio de Ansible ignora la cuestión de la mantenibilidad. Básicamente, sin un sistema de tipos, el scripting de shell tiene la facilidad de mantenimiento de JavaScript, Lisp o Python: las refactorizaciones extensas solo se pueden lograr con éxito con la ayuda de un extenso conjunto de pruebas automatizado, o al menos diseños que permiten pruebas interactivas fáciles. Dicho esto, si bien las secuencias de comandos de shell son la lengua franca de la configuración y el mantenimiento del sistema, casi cada lenguaje de programación tiene una interfaz con el shell. Por lo tanto, es totalmente factible aprovechar la ventaja de mantenimiento de los lenguajes avanzados, utilizándolos para unir los diversos bits de bits de configuración de shell. Para OCaml, escribí Rashell eso esencialmente proporciona una mano de patrones de interacción comunes para subprocesos, lo que hace que la traducción de scripts de configuración a OCaml sea esencialmente trivial.
Por el lado de Ansible, la estructura muy débil de los libros de jugadas y la presencia de una función de metaprogramación hacen que la situación sea esencialmente tan mala como lo es para las secuencias de comandos de shell, con los puntos negativos de que no es obvio cómo escribir pruebas unitarias para Ansible , y el argumento de introducir ad-hoc un lenguaje de nivel superior no se puede imitar.
Idempotencia de los pasos de configuración
La documentación de Ansible llama la atención sobre la necesidad de escribir pasos de configuración idempotentes. Más precisamente, los pasos de configuración deben escribirse de modo que la secuencia de pasos aba pueda simplificarse a ab , es decir, no necesitamos repetir el paso de configuración. Esta es una condición más fuerte que la idempotencia. Dado que Ansible permite que los libros de jugadas utilicen comandos de shell arbitrarios, Ansible no puede garantizar que se respete esta condición más fuerte. Esto solo se basa en la disciplina del programador.