Estoy usando Ansible para algunas tareas simples de administración de usuarios con un pequeño grupo de computadoras. Actualmente, tengo mis playbooks configurados hosts: all
y mi archivo de hosts es solo un grupo con todas las máquinas enumeradas:
# file: hosts
[office]
imac-1.local
imac-2.local
imac-3.local
Me he encontrado frecuentemente teniendo que apuntar a una sola máquina. El ansible-playbook
comando puede limitar jugadas como esta:
ansible-playbook --limit imac-2.local user.yml
Pero eso parece algo frágil, especialmente para un libro de jugadas potencialmente destructivo. Dejar fuera la limit
bandera significa que el libro de jugadas se ejecutará en todas partes. Dado que estas herramientas solo se usan ocasionalmente, parece que vale la pena tomar medidas para una reproducción infalible, por lo que no atacaremos accidentalmente algo dentro de unos meses.
¿Existe alguna práctica recomendada para limitar las ejecuciones del libro de jugadas a una sola máquina? Idealmente, los libros de jugadas deben ser inofensivos si se omiten algunos detalles importantes.
fuente
--limit office[0]
'{{ target }}'
- de acuerdo con docs.ansible.com/…run_once
todavía podría ser destructivo, por lo que no es una buena idea.-e
es el equivalente de--extra-vars
hosts: "{{ target | default('no_hosts')}}"
También hay un pequeño y lindo truco que te permite especificar un solo host en la línea de comando (o múltiples hosts, supongo), sin un inventario intermedio:
Tenga en cuenta la coma ( , ) al final; esto indica que es una lista, no un archivo.
Ahora, esto no lo protegerá si accidentalmente pasa un archivo de inventario real, por lo que puede no ser una buena solución para este problema específico. ¡Pero es un truco útil para saber!
fuente
skipping: no hosts matched
. ¿Quizás este truco ya no funciona desde que--limit
funciona?$ ansible-playbook -kK --limit=myhost1 myplaybook.yml
. Ver la respuesta de Marwan.all
en la (s) obra (s) - esto me llevó un tiempo descubrir ...Este enfoque se cerrará si se proporciona más de un host al verificar la variable play_hosts . El módulo de falla se usa para salir si no se cumple la condición de host único. Los siguientes ejemplos usan un archivo de hosts con dos hosts alice y bob.
user.yml (libro de jugadas)
Ejecute el libro de jugadas sin filtros de host
Ejecute el libro de jugadas en un solo host
fuente
--limit
es el camino a seguirplay_hosts
está en desuso en Ansible 2.2 y se reemplaza conansible_play_hosts
. Para ejecutar en un host sin necesidad--limit
, puede usarwhen: inventory_hostname == ansible_play_hosts[0]
.[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{ play_hosts|length }} == ''
en Ansible 2.8.4.Hay en mi humilde opinión una forma más conveniente. De hecho, puede solicitar de forma interactiva al usuario las máquinas a las que desea aplicar el libro de jugadas gracias a
vars_prompt
:fuente
--extra-vars
y una var normal en tu libro de jugadas ...{{ hosts }}
se evalúa antes de ingresar el valor, ¿o hay algún truco especial?Para ampliar la respuesta de joemailer, si desea tener la capacidad de coincidencia de patrones para hacer coincidir cualquier subconjunto de máquinas remotas (tal como lo hace el
ansible
comando), pero aún así quiere que sea muy difícil ejecutar accidentalmente el libro de jugadas en todas las máquinas, esto es lo que se me ocurrió:El mismo libro de jugadas que en la otra respuesta:
Tengamos los siguientes hosts:
Ahora, para ejecutar el comando en todos los dispositivos, debe establecer explícitamente la variable de destino en "todos"
Y para limitarlo a un patrón específico, puede establecer
target=pattern_here
o, alternativamente, puede salir
target=all
y agregar el--limit
argumento, por ejemplo:es decir.
ansible-playbook user.yml --extra-vars "target=all" --limit imac-1* --list-hosts
lo que resulta en:
fuente
Realmente no entiendo cómo todas las respuestas son tan complicadas, la forma de hacerlo es simplemente:
El
check
modo le permite ejecutar en modo de ejecución en seco, sin realizar ningún cambio.fuente
--check
, así que supongo que esto todavía es útil en cuanto a documentación, ya que esta pregunta puede ser muy fácil de encontrarLos usuarios de AWS que usan la secuencia de comandos de inventario externo EC2 pueden simplemente filtrar por ID de instancia:
Esto funciona porque el script de inventario crea grupos predeterminados .
fuente
Tenemos algunos libros de jugadas genéricos que pueden ser utilizados por una gran cantidad de equipos. También tenemos archivos de inventario específicos del entorno, que contienen múltiples declaraciones de grupo.
Para obligar a alguien que llama a un libro de jugadas a especificar un grupo contra el cual correr, colocamos una entrada ficticia en la parte superior del libro de jugadas:
Luego incluimos la siguiente verificación como primer paso en el libro de jugadas compartido:
Si el servidor ficticio aparece en la lista de hosts con los que está programado ejecutar este libro de jugadas (ansible_play_batch), la persona que llamó no especificó un grupo y la ejecución del libro de jugadas fallará.
fuente
ansible_play_batch
enumera solo el lote actual, por lo que cuando se usa el procesamiento por lotes, esto todavía no es seguro. Es mejor usaransible_play_hosts
en su lugar.Desde la versión 1.7 ansible tiene la opción run_once . La sección también contiene una discusión de varias otras técnicas.
fuente
Esto muestra cómo ejecutar los libros de jugadas en el servidor de destino.
Esto es un poco más complicado si desea utilizar una conexión local. Pero esto debería estar bien si usa una variable para la configuración de hosts y en el archivo hosts crea una entrada especial para localhost.
En (todos) los libros de jugadas tienen los hosts: línea establecida en:
En el archivo de hosts de inventario, agregue una entrada para el host local que establece la conexión como local:
Luego, en la línea de comandos, ejecute comandos para establecer explícitamente el objetivo, por ejemplo:
Esto también funcionará cuando use ansible-pull:
Si olvida establecer la variable en la línea de comando, el comando generará un error de forma segura (¡siempre que no haya creado un grupo de hosts llamado 'no_hosts'!) Con una advertencia de:
Y como se mencionó anteriormente, puede apuntar a una sola máquina (siempre que esté en su archivo de hosts) con:
o un grupo con algo como:
fuente
Tengo un script de envoltura llamado provision que te obliga a elegir el objetivo, por lo que no tengo que manejarlo en otro lugar.
Para aquellos que son curiosos, uso ENV vars para las opciones que usa mi archivo vagrant (agregando el argumento ansible correspondiente para sistemas en la nube) y dejo pasar el resto de los argumentos ansibles. Cuando estoy creando y aprovisionando más de 10 servidores a la vez, incluyo un reintento automático en servidores fallidos (siempre y cuando se esté progresando, descubrí que al crear aproximadamente 100 servidores a la vez, a menudo algunos fallaban la primera vez )
fuente
Una solución ligeramente diferente es utilizar la variable especial
ansible_limit
que es el contenido de la--limit
opción CLI para la ejecución actual de Ansible.No es necesario definir una variable adicional aquí, solo ejecute el libro de jugadas con la
--limit
bandera.fuente