Ansible: use el valor predeterminado si una variable no está definida
ansible-2.x (5)
En caso de que use la búsqueda para establecer la lectura predeterminada del entorno, también ha establecido el segundo parámetro predeterminado en verdadero:
- set_facts:
ansible_ssh_user: "{{ lookup(''env'', ''SSH_USER'') | default(''foo'', true) }}"
También puede concatenar múltiples definiciones predeterminadas:
- set_facts:
ansible_ssh_user: "{{ some_var.split(''-'')[1] | default(lookup(''env'',''USER''), true) | default(''foo'') }}"
Estoy personalizando la creación de
users
Linux dentro de mi rol.
Necesito permitir que los usuarios de mi rol personalicen
home_directory
,
group_name
,
name
,
password
.
Me preguntaba si hay una forma más flexible de hacer frente a los valores predeterminados.
Sé que el siguiente código es posible:
- name: Create default
user:
name: "default_name"
when: my_variable is not defined
- name: Create custom
user:
name: "{{my_variable}}"
when: my_variable is defined
Pero como mencioné, hay muchas variables opcionales y esto crea muchas posibilidades.
¿Hay algo como el código de arriba?
user:
name: "default_name", "{{my_variable}}"
El código debe establecer
name="default_name"
cuando
my_variable
no está definido.
Podría establecer todas las variables en
defaults/main.yml
y crear el usuario así:
- name: Create user
user:
name: "{{my_variable}}"
Pero esas variables están dentro de un hash realmente grande y hay algunos hash dentro de ese hash que no pueden ser predeterminados.
No está totalmente relacionado, pero también puede verificar la variable
undefined
Y
empty
(por ejemplo,
my_variable:
.
(NOTA: solo funciona con la versión ansible> 1.9, ver:
link
)
- name: Create user
user:
name: "{{ ((my_variable == None) | ternary(''default_value'', my_variable)) /
if my_variable is defined else ''default_value'' }}"
Puedes usar el
default
de Jinja:
- name: Create user
user:
name: "{{ my_variable | default(''default_value'') }}"
Si alguien está buscando una opción que maneje variables anidadas, hay varias opciones en este tema de github .
En resumen, debe usar el filtro "predeterminado" para cada nivel de variables anidadas. Para una variable "a.nested.var" se vería así:
- hosts: ''localhost''
tasks:
- debug:
msg: "{{ ((a | default({})).nested | default({}) ).var | default(''bar'') }}"
o puede establecer valores predeterminados de dictos vacíos para cada nivel de vars, tal vez usando el filtro "combinar". O use el filtro "json_query". Pero la opción que elegí me parece más simple si solo tiene un nivel de anidamiento.
Si tiene una sola jugada que desea recorrer sobre los elementos, defina esa lista en group_vars / all o en otro lugar que tenga sentido:
all_items:
- first
- second
- third
- fourth
Entonces su tarea puede verse así:
- name: List items or default list
debug:
var: item
with_items: "{{ varlist | default(all_items) }}"
Pase varlist como una matriz JSON:
ansible-playbook <playbook_name> --extra-vars=''{"varlist": [first,third]}''
Antes de eso, es posible que también desee una tarea que verifique que cada elemento en varlist también esté en all_items :
- name: Ensure passed variables are in all_items
fail:
msg: "{{ item }} not in all_items list"
when: item not in all_items
with_items: "{{ varlist | default(all_items) }}"