Reputation: 448
I run my ansible playbooks through a cron job every night as I add to them every now and then.
I want my output of each to only say changed=(num) if there is actually a change, but a few specific modules say changed when they were not changed at all.
EX:
- name: (name)
file:
state: touch
path: (path)
group: (group)
mode: (perms)
The path before the task is run contains the same group and permissions as the requested permissions and group. So they don't change when the task is run, but the result ansible says it has "changed".
I looked this issue up and found https://github.com/ansible/ansible/issues/21124 but I'm running ansible 2.2.1.0. So it's my understanding from this that they are indicating that the file module is idempotent.
Are there any suggestions to make it idempotent?
Upvotes: 4
Views: 7103
Reputation: 68144
A simple idempotent option of how to touch a file would be
- ansible.builtin.command: touch file
args:
creates: file
Upvotes: 1
Reputation: 683
The problem is that state: touch
by default changes the access and modification time of the target path. So even if nothing else changes, touch result in a change.
Since Ansible 2.7 you can use the variables access_time
and modification_time
to make file
with touch
idempotent.
- name: Touch file
file:
path: /etc/file.conf
state: touch
access_time: preserve
modification_time: preserve
(original solution by Nklya)
Upvotes: 4
Reputation: 339
In order to idempotently create a file using the file module in ansible you have to separate checking if the file exists, creating it, and setting any permissions (as you want those to be set correctly whether the file already existed or not).
This can be accomplished using 3 tasks as follows:
- name: Check if file exists
stat:
path: /tmp/file
register: tmp_file
- name: Create file
file:
path: /tmp/file
state: touch
when: tmp_file.stat.exists == false
- name: Set perms of file
file:
path: /tmp/file
state: file
owner: user
group: group
mode: 0600
Upvotes: 3
Reputation: 68559
they don't change when the task is run, but the result Ansible says it has "changed".
It says it changed, because when you run a touch
command against a file, the timestamps change.
Don't use touch
, use another appropriate state (file
, directory
, link
).
Otherwise you can set changed_when: false
, but I don't think it makes sense considering you want check the output.
Upvotes: 1