El módulo Ansible lineinfile se puede utilizar para insertar una línea, modificar una línea existente, eliminar una línea existente o reemplazar una línea.
Insertar una línea
Primero, veremos cómo escribir una línea en un archivo, si no está presente.
Podemos establecer la ruta del archivo a modificar utilizando el parámetro path(>Ansible 2.3)/dest. Y estableceremos la línea a insertar utilizando el parámetro line.
El siguiente ejemplo escribirá la línea ‘Insertar una línea en un archivo’ en el archivo ‘remote_server.txt’. La nueva línea se añadirá al EOF. Si la línea ya existe, entonces no se añadirá.
La nueva línea se añadirá al EOF. Si la línea ya existe, entonces no se añadirá.
También hemos establecido el parámetro create, que dice que si el archivo no está presente, entonces crea un nuevo archivo. El valor por defecto para el estado está presente. Pero lo añado de todos modos para mayor claridad.
El valor por defecto para el estado está presente. Pero lo estoy añadiendo de todos modos para la claridad.
- hosts: loc tasks: - name: Ansible insert lineinfile example lineinfile: dest: /home/mdtutorials2/remote_server.txt line: Inserting a line in a file. state: present create: yes
Issue1:
Si obtiene el siguiente error,
lineinfile unsupported parameter for module: path
Probablemente se deba al problema con el parámetro path. Hasta ansible 2.3 este parámetro era ‘dest’. Así que si su versión de ansible es inferior a la 2.3, entonces cambie el parámetro a ‘dest’. Esto debería resolver el problema.
Asunto 2:
Si el archivo de destino no existe, entonces Ansible lanzará un error como el siguiente. Puede asegurarse de que el archivo existe en el archivo remoto o puede establecer el parámetro ‘create’ en yes para resolver este problema.
El destino /home/mdtutorials2/hello.txt no existe
Inserción de una nueva línea después/antes de un patrón
No siempre queremos que la línea se inserte hasta el EOF. El módulo lineinfile da la opción de insertar la línea después de un patrón o antes de un patrón. Podemos usar los parámetros insertafter e insertbefore respectivamente para esto.
En el siguiente ejemplo, quiero insertar la línea antes de la línea » en el archivo ansible.cfg. He escapado el » ya que son caracteres especiales regex.
- name: Ansible lineinfile insert after example lineinfile: dest: /etc/ansible/ansible.cfg line: 'inventory = /home/fedora/inventory.ini' insertafter: '\'
Si necesita insertar una línea antes de un patrón, puede utilizar el parámetro insertbefore. El siguiente ejemplo insertará la línea antes del patrón ‘#library’ en ansible.cfg.
- name: Ansible lineinfile insertbefore example lineinfile: dest: /etc/ansible/ansible.cfg line: 'inventory = /home/mdtutorials/inventory.ini' insertbefore: '#library'
Eliminando una línea
Puede establecer el parámetro state a absent, para eliminar las líneas especificadas. Se eliminarán todas las apariciones de esa línea.
- hosts: loc tasks: - name: Ansible lineinfile remove line example lineinfile: dest: /home/mdtutorials2/remote_server.txt line: Removed lines. state: absent
Eliminar una línea utilizando la regexp de Ansible
También puede especificar una regexp para eliminar una línea. Así que usted puede decir eliminar todas las líneas que comienzan con la palabra ‘hola’, etc.
Damos la expresión regular utilizando el parámetro regexp de lineinfile. El siguiente ejemplo eliminará todas las líneas que empiecen por DevOps.
- hosts: loc tasks: - name: Ansible lineinfile regexp example lineinfile: dest: /home/mdtutorials2/remote_server.txt regexp: '^DevOps' state: absent
Reemplazando/Modificando una línea usando Regex
Para modificar una línea necesitamos usar el parámetro Ansible backrefs junto con el parámetro regexp. Esto debe usarse con state=present.
Si la regexp no coincide con ninguna línea, entonces el archivo no se modifica. Si la regexp coincide con una línea/múltiples líneas, entonces se reemplazará la última línea coincidente. Además, los elementos agrupados en la regexp se rellenan y se pueden utilizar para la modificación.
En el siguiente ejemplo estamos comentando una línea. La línea completa se captura la línea mediante la colocación de ellos dentro de los paréntesis a ‘\1’. El ‘#\1’ reemplaza la línea con ‘#’ seguido de lo que fue capturado.
Puede tener múltiples capturas y llamarlas usando ‘\1’, ‘\2’, ‘\3’ etc. Si necesita aprender más información sobre la agrupación, consulte regular-expression.info.
Comentar una línea con Ansible lineinfile backrefs
- name: Ansible lineinfile regexp replace example lineinfile: dest: /etc/ansible/ansible.cfg regexp: '(inventory = /home/fedora/inventory.ini.*)' line: '#' backrefs: yes
Descomentar la línea con lineinfile regexp
- name: Ansible lineinfile backrefs example lineinfile: dest: /etc/ansible/ansible.cfg regexp: '#(inventory = /home/fedora/inventory.ini.*)' line: '' backrefs: yes
Podemos descomentar la misma línea con pequeñas modificaciones. Aquí estoy colocando la línea comentada con el ‘#’ fuera de la agrupación. Así que ahora sólo la parte después de ‘#’ se captura en \1. Y después de ejecutar el script, puedes ver que la línea está descomentada.
Líneas de archivo múltiples
Esta sección es para reemplazar múltiples tareas de archivo de línea con una sola tarea y con_items. Si su intención es añadir múltiples líneas a un archivo, debe utilizar el módulo blockinfile.
Puede utilizar with_items para recorrer una lista de hashes. Puede especificar el dest, la línea, el regexp, etc. para cada tarea de la lista. Básicamente, se puede utilizar en lugar de escribir múltiples tareas.
El siguiente ejemplo cambiará dos archivos: ansible.cfg y remote_server.txt.
- hosts: loc tasks: - name: Ansible lineinfile multiple lines with_items example lineinfile: dest: "{{ item.dest }}" regexp: "{{ item.regexp }}" line: "{{ item.line }}" backrefs: yes with_items: - {dest: '/etc/ansible/ansible.cfg', regexp: 'config file for ansible', line: 'line changed'} - {dest: '/home/dinoopblogger/remote_server.txt', regexp: 'hello', line: 'world'}