L8 Idempotentence with Ansible play
$ tree .
.
├── create.yml
├── files
│ └── idempotent.txt
├── idempotent.yml
└── state.yml
1 directory, 4 files
1、Idempotent "prototype" model
---
- hosts: k8s_master
tasks:
- name: an idempotent create command
copy:
src: files/idempotent.txt
dest: $HOME/tmp/idempotent.txt
tags:
- create
- name: an idempotent command
lineinfile:
dest: $HOME/tmp/idempotent.txt
regexp: '^(.*)is an(.*)$'
backrefs: true
line: '\1is really an\2'
tags:
- create
- name: a non idempotent command
shell: "echo this is a non-idempotent file >> $HOME/tmp/non-idempotent.txt"
tags:
- create
- name: remove the file we created
file:
path: $HOME/tmp/{{ item }}
state: absent
with_items:
- non-idempotent.txt
- idempotent.txt
tags:
- destroy
$ ansible-playbook -i ../inventory.ini idempotent.yml --tags create
lineinfile
– Manage lines in text files
- This module ensures a particular line is in a file, or replace an existing line using a back-referenced regular expression.
- This is primarily useful when you want to change a single line in a file only.
regexp
: The regular expression to look for in every line of the file.backrefs: true
: If set,line
can contain backreferences (both positional and named) that will get populated if theregexp
matches.line
: The line to insert/replace into the file.
After run twice and check non-idempotent file
$ cat non-idempotent.txt
this is a non-idempotent file
this is a non-idempotent file
After run twice and check idempotent file
$ cat idempotent.txt
this is really an idempotent file
Remove multiple files inside directory
- name: remove the file we created
file:
path: $HOME/tmp/{{ item }}
state: absent
with_items:
- non-idempotent.txt
- idempotent.txt
tags:
- destroy
$ ansible-playbook -i ../inventory.ini idempotent.yml --tags destroy
TASK [remove the file we created] **********************************************************************
changed: [k8s-jx] => (item=non-idempotent.txt)
changed: [k8s-jx] => (item=idempotent.txt)
2、Registering discovered state
- hosts: k8s_master
vars:
target: $HOME/tmp/idempotent.txt
tasks:
- name: an idempotent create command
copy:
src: files/idempotent.txt
dest: '{{target}}'
tags:
- create
- name: modify the file
command: sed -ie 's/is an/is really an/' {{target}}
tags:
- create
- name: remove the file
file:
path: '{{target}}'
state: absent
tags:
- destroy
- name: remove the backup file
file:
path: $HOME/tmp/idempotent.txte
state: absent
tags:
- destroy
- name: discover state
command: grep 'is really an' {{target}}
register: grep_state
tags:
- create
- destroy
ignore_errors: true
- name: show the state of the file
debug:
var: grep_state.rc
tags:
- create
- destroy
2-1 sed -ie
-i[SUFFIX]
(-ie)
Edit files in place (this makes a backup with file extension SUFFIX, if SUFFIX is supplied).
After run modify the file
, generate a new backup file idempotent.txt
2-2 register and debug
register: grep_state
debug:
var: grep_state.rc
When you execute a task and save the return value in a variable for use in later tasks, you create a registered variable.
2-3 Ignoring Failed Commands
Generally playbooks will stop executing any more steps on a host that has a task fail. Sometimes, though, you want to continue on. To do so, write a task that looks like this:
ignore_errors: true
2-4 grep_state
return true after create
ansible-playbook -i ../inventory.ini state.yml --tags create
TASK [show the state of the file] ********************************************************************
ok: [k8s-jx] => {
"grep_state.rc": "0"
}
2-5 grep_state
return false after destroy
$ ansible-playbook -i ../inventory.ini state.yml --tags destroy
TASK [show the state of the file] ********************************************************************
ok: [k8s-jx] => {
"grep_state.rc": "2"
}
3、Creating an idempotent play
---
- hosts: k8s_master
vars:
target: $HOME/tmp/idempotent.txt
tasks:
- name: discover state
command: grep 'is really an' {{target}}
register: grep_state
tags:
- create
- destroy
ignore_errors: true
- name: show the state of the file
debug:
var: grep_state.rc
- name: an idempotent create command
copy:
src: files/idempotent.txt
dest: '{{target}}'
when: grep_state.rc != 0
tags:
- create
- destroy
- name: modify the file
command: sed -ie 's/is/is really an/' {{target}}
when: grep_state.rc != 0
tags:
- create
- destroy
- name: remove the file
file:
path: '{{target}}'
state: absent
tags:
- destroy
- name: remove the backup file
file:
path: $HOME/tmp/idempotent.txte
state: absent
tags:
- destroy
- Check the state of file
- Show the state of the file
- Create and modify file when
grep_state
is fasle - delete both
So after first run, the task an idempotent create command
and modify the file
will skip