Dans ansible, je dois vérifier si une ligne particulière est présente dans un fichier ou non. Fondamentalement, je dois convertir la commande suivante en une tâche ansible. Mon but est seulement de vérifier.
grep -Fxq "127.0.0.1" /tmp/my.conf
- name: Check whether /tmp/my.conf contains "127.0.0.1"
command: grep -Fxq "127.0.0.1" /tmp/my.conf
register: checkmyconf
check_mode: no
ignore_errors: yes
changed_when: no
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: checkmyconf.rc == 0
Update 2017-08-28: Les anciennes versions de Ansible doivent utiliser always_run: yes
au lieu de check_mode: no
.
Utilisez check_mode, register et failed_when en concert. La tâche échoue si le module lineinfile apporte des modifications au fichier en cours de vérification. Check_mode garantit que rien ne changera, même si cela devait changer autrement.
- name: "Ensure /tmp/my.conf contains '127.0.0.1'"
lineinfile:
name: /tmp/my.conf
line: "127.0.0.1"
state: present
check_mode: yes
register: conf
failed_when: (conf is changed) or (conf is failed)
Avec la solution acceptée, même si vous ignorez les erreurs, vous obtiendrez toujours une sortie d'erreur rouge laide sur la première tâche s'il n'y a pas de correspondance:
TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
failed: [localhost] => {"changed": false, "cmd": "grep -Fxq "127.0.0.1" /tmp/my.conf", "delta": "0:00:00.018709", "end": "2015-09-27 17:46:18.252024", "rc": 1, "start": "2015-09-27 17:46:18.233315", "stdout_lines": [], "warnings": []}
...ignoring
Si vous souhaitez une sortie moins détaillée, vous pouvez utiliser awk
au lieu de grep
. awk
ne renverra pas d'erreur sur une non-correspondance, ce qui signifie que la première tâche de vérification ci-dessous ne provoquera pas d'erreur, qu'il y ait correspondance ou non-correspondance:
- name: Check whether /tmp/my.conf contains "127.0.0.1"
command: awk /^127.0.0.1$/ /tmp/my.conf
register: checkmyconf
changed_when: False
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: checkmyconf.stdout | match("127.0.0.1")
Notez que ma deuxième tâche utilise le filtre de correspondance car awk renvoie la chaîne correspondante si elle trouve une correspondance.
L'alternative ci-dessus produira la sortie suivante, que la tâche de vérification ait une correspondance ou non:
TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
ok: [localhost]
IMHO c'est une meilleure approche car vous n'ignorerez pas les autres erreurs dans votre première tâche (par exemple, si le fichier spécifié n'existait pas).
Utilisez la commande ansible lineinfile, mais cette commande mettra à jour le fichier avec la ligne si elle n’existe pas.
- lineinfile: dest=/tmp/my.conf line='127.0.0.1' state=present
Une autre méthode consiste à utiliser le "module de remplacement", puis le "module lineinfile".
L'algo est proche de celui utilisé lorsque vous voulez changer les valeurs de deux variables.
Exemple:
# Vars
- name: Set parameters
set_fact:
newline : "hello, i love ansible"
lineSearched : "hello"
lineModified : "hello you"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : '{{ lineModified }} '
regexp : '{{ lineSearched }}$'
backup : yes
register : checkIfLineIsHere
- name: Line is here, change it
lineinfile:
state : present
dest : /dir/file
line : '{{ newline }}'
regexp : '{{ lineModified }}$'
when: checkIfLineIsHere.changed
Avec la même idée, vous pouvez faire quelque chose si la ligne recherchée est ici:
# Vars
- name: Set parameters
set_fact:
newline : "hello, i love ansible"
lineSearched : "hello"
lineModified : "hello you"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : '{{ lineModified }} '
regexp : '{{ lineSearched }}$'
backup : yes
register : checkIfLineIsHere
# If the line is here, I want to add something.
- name: If line is here, do something
lineinfile:
state : present
dest : /dir/file
line : '{{ newline }}'
regexp : ''
insertafter: EOF
when: checkIfLineIsHere.changed
# But 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
La méthode regexp
& absent
de robo est assez propre, je l'ai donc développée ici pour une utilisation facile:
- name: Ensure /tmp/my.conf contains 127.0.0.1
lineinfile:
path: /tmp/my.conf
regexp: '^127\.0\.0\.1.*whatever'
state: absent
check_mode: yes
register: out
- debug:
msg: "Yes, line exists."
when: out.changed
- debug:
msg: "Line does NOT exist."
when: not out.changed