Al fin después de tanto trabajar pudimos encontrar la respuesta de esta inconveniente que algunos los lectores de este sitio web han tenido. Si quieres aportar algún detalle puedes compartir tu conocimiento.
Solución:
Solución 1:
Hay bastante sobre este tema en la documentación:
- Incluye vs. Importaciones
- Dinámico frente a estático
La principal diferencia es:
Todos
import*
Las declaraciones se procesan previamente en el momento en que se analizan los libros de jugadas.
Todosinclude*
Las declaraciones se procesan como se encontraron durante la ejecución del libro de jugadas.
Entonces import
es static, include
es dinámico.
Desde mi experiencia, deberías usar import
cuando se trata de “unidades” lógicas. Por ejemplo, separe la lista larga de tareas en archivos de subtareas:
main.yml:
- import_tasks: prepare_filesystem.yml
- import_tasks: install_prerequisites.yml
- import_tasks: install_application.yml
Pero usarías include
para lidiar con diferentes flujos de trabajo y tomar decisiones basadas en algunos hechos recopilados dinámicamente:
install_prerequisites:
- include_tasks: prerequisites_ lower .yml
Solución 2:
Las importaciones son static, incluye son dinámicos. Las importaciones se realizan en el momento del análisis, se incluyen en el tiempo de ejecución.
Las importaciones básicamente reemplazan la tarea con las tareas del archivo. No hay tareas de importación en tiempo de ejecución. Entonces, attributes igual que tags
, y when
(y probablemente el resto) se copian en cada tarea importada.
Las inclusiones se ejecutan de hecho. tags
y when
de una tarea incluida se aplican solo a la tarea en sí.
Las tareas etiquetadas de un archivo importado se ejecutan si una tarea de importación no está etiquetada. No se ejecuta ninguna tarea desde un archivo incluido si una tarea de inclusión no está etiquetada.
Todas las tareas de un archivo importado se ejecutan si se etiqueta una tarea de importación. Solo se ejecutan las tareas etiquetadas de un archivo incluido si se etiqueta una tarea de inclusión.
Limitaciones de las importaciones:
- no se puede usar con
with_*
oloop
attributes - no se puede importar un archivo, cuyo nombre depende de una variable
Limitaciones de incluye:
--list-tags
no muestra etiquetas de archivos incluidos--list-tasks
no muestra las tareas de los archivos incluidos- no se puede utilizar
notify
para activar un nombre de controlador que proviene del interior de una inclusión dinámica - no se puede utilizar
--start-at-task
para comenzar la ejecución en una tarea dentro de una inclusión dinámica
Más sobre esto aquí y aquí.
Para mí, eso se reduce básicamente al hecho de que las importaciones no se pueden utilizar con el loop
attribute.
las importaciones ciertamente fallarían en casos como este:
# playbook.yml
- import_tasks: set-x.yml
when: x is not defined
# set-x.yml
- set_fact
x: foo
- debug:
var: x
debug
no se ejecuta, ya que hereda when
desde el import_tasks
tarea. Por lo tanto, no importa archivos de tareas que cambien las variables utilizadas en la tarea de importación. when
attribute.
Tenía una política para comenzar con las importaciones, pero una vez que necesité una inclusión, me aseguré de que el archivo incluido o sus hijos no importaran nada. Pero eso es muy difícil de mantener. Y todavía no está claro si me protegerá de los problemas. Quiero decir, no se recomienda mezclar incluye e importaciones.
No puedo usar solo importaciones, ya que ocasionalmente necesito bucles. Probablemente podría cambiar a solo incluye. Pero decidí cambiar a las importaciones en todas partes, excepto en los casos en los que necesito bucles. Decidí experimentar todos esos casos complicados de primera mano. Quizás no haya ninguno en mis libros de jugadas. O con suerte encontraré una manera de hacerlo funcionar.
UPD Un truco posiblemente útil para crear un archivo de tarea que se puede importar muchas veces, pero ejecutado solo una vez:
- name: ...
...
when: not _file_executed | default(False)
- name: ...
...
when: not _file_executed | default(False)
...
- name: Set _file_executed
set_fact:
_file_executed: True
UPD Un efecto realmente no esperado de la mezcla de inclusiones e importaciones es que las vars de una tarea de inclusión anulan las de las tareas importadas:
playbook.yml
:
- hosts: all
tasks:
- import_tasks: 2.yml
vars:
v1: 1
- include_tasks: 2.yml
vars:
v1: 1
2.yml
:
- import_tasks: 3.yml
vars:
v1: 2
3.yml
:
- debug:
var: v1 # 2 then 1
Probablemente porque include_tasks
primero importa los archivos y luego aplica su vars
directiva.
De hecho, también se puede reproducir así:
playbook.yml
:
- hosts: all
tasks:
- import_tasks: 2.yml
vars:
v1: 1
- include_tasks: 2.yml
vars:
v1: 1
2.yml
:
- debug:
var: v1 # 2 then 1
vars:
v1: 2
UPD Otro caso de mezcla incluye e importaciones.
playbook.yml
:
- hosts: all
tasks:
# say, you're bound to use include here (because you need a loop)
- include_tasks: 2.yml
vars:
https: yes
2.yml
:
- import_tasks: 3.yml
when: https
3.yml
:
- import_tasks: 4.yml
vars:
https: no # here we're trying to temporarily override the https var
- import_tasks: 4.yml
4.yml
:
- debug:
var: https
Obtenemos true
y true
, ver el caso anterior (include_tasks
‘vars tienen prioridad sobre import_tasks
‘ unos). Para evitar eso, podemos cambiar a inclusiones en 3.yml
. Pero luego el primero incluye en 3.yml
se omite. Ya que hereda when: https
de la tarea principal, por lo que la primera tarea básicamente dice:
- import_tasks: 4.yml
vars:
https: no # here we're trying to temporarily override the https var
when: https
La solución es cambiar a inclusiones en 2.yml
así como. Eso evita la propagación de when: https
a las tareas del niño.
Aquí puedes ver las comentarios y valoraciones de los lectores
Eres capaz de añadir valor a nuestra información dando tu veteranía en las ilustraciones.