tower - Ansible: insertar línea si no existe
ansible tutorial (5)
Estoy tratando de insertar una línea en un archivo de propiedades utilizando ansible. Quiero agregar alguna propiedad si no existe, pero no reemplazarla si tal propiedad ya existe en el archivo.
Añado a mi rol de ansible.
- name: add couchbase host to properties
lineinfile: dest=/database.properties regexp="^couchbase.host" line="couchbase.host=127.0.0.1"
Pero esto reemplaza el valor de la propiedad de nuevo a 127.0.0.1 si ya existe en el archivo.
¿Qué estoy haciendo mal?
El módulo lineinfile
hace lo que se supone que debe hacer: garantiza que la línea, tal como se define en la line
esté presente en el archivo y la línea esté identificada por su regexp
. Entonces, no importa qué valor tenga su configuración, su nueva line
anulará.
Si no desea anular la línea, primero debe probar el contenido y luego aplicar esa condición al módulo de lineinfile
. No hay un módulo para probar el contenido de un archivo, por lo que probablemente necesite ejecutar grep
con un comando de shell
y revisar el .stdout
. Algo como esto (no probado):
- name: Test for line
shell: grep "^couchbase.host" /database.properties
register: test_grep
Y luego aplique la condición a su tarea de línea de lineinfile
:
- name: add couchbase host to properties
lineinfile:
dest: /database.properties
line: couchbase.host=127.0.0.1
when: test_grep.stdout != ""
La regexp
se puede eliminar ya que ya se aseguró de que la línea no existiera, por lo que nunca coincidiría.
Pero tal vez estás haciendo las cosas al revés. ¿De dónde viene esa línea en el archivo? Cuando administre su sistema con Ansible, no debe haber otros mecanismos que interfieran con los mismos archivos de configuración. ¿Quizás pueda solucionar esto agregando un valor default
a su rol?
Esta es la única manera en que pude hacer que esto funcionara.
- name: checking for host
shell: cat /database.properties | grep couchbase.host | wc -l
register: test_grep
- debug: msg="{{test_grep.stdout}}"
- name: adding license server
lineinfile: dest=/database.properties line="couchbase.host=127.0.0.1"
when: test_grep.stdout == "0"
La misma idea que se presenta aquí: https://.com/a/40890850/7231194
Los pasos son:
- Trate de reemplazar la línea.
- Si reemplaza mod, modifícalo, restaura
- Si reemplazar mod no cambia, agregue la línea
Ejemplo
# Vars
- name: Set parameters
set_fact:
ipAddress : "127.0.0.1"
lineSearched : "couchbase.host={{ ipAddress }}"
lineModified : "couchbase.host={{ ipAddress }} hello"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : ''{{ lineModified }} ''
regexp : ''{{ lineSearched }}$''
backup : yes
register : checkIfLineIsHere
# If the line not is here, I add it
- name: Add line
lineinfile:
state : present
dest : /dir/file
line : ''{{ lineSearched }}''
regexp : ''''
insertafter: EOF
when: checkIfLineIsHere.changed == false
# If the line is here, I still want this line in the file, Then restore it
- name: Restore the searched line.
lineinfile:
state : present
dest : /dir/file
line : ''{{ lineSearched }}''
regexp : ''{{ lineModified }}$''
when: checkIfLineIsHere.changed
Ok, aquí está mi solución ingenua ... probablemente no sea un Ansible multiplataforma y nativo (acabo de comenzar a usar esta herramienta y aún la aprendo), pero definitivamente más breve:
- name: Update /path/to/some/file
shell: grep -q ''regex'' /path/to/some/file && echo exists || echo ''text-to-append'' >> /path/to/some/file
register: result
changed_when: result.stdout.find(''exists'') == -1
Por un largo camino de "Pruebas y errores" llego a esto:
- name: check existence of line in the target file
command: grep -Fxq "ip addr add {{ item }}/32 dev lo label lo:{{ app | default(''app'') }}" /etc/rc.local
changed_when: false
failed_when: false
register: ip_test
with_items:
- "{{ list_of_ips }}"
- name: add autostart command
lineinfile: dest=/etc/rc.local
line="ip addr add {{ item.item }}/32 dev lo label lo:{{ app | default(''app'') }}"
insertbefore="exit 0"
state=present
when: item.rc == 1
with_items:
- "{{ ip_test.results }}"