Dorilds
Dorilds

Reputation: 448

ansible change permissions using file module idempotent

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

Answers (4)

Vladimir Botka
Vladimir Botka

Reputation: 68144

A simple idempotent option of how to touch a file would be

    - ansible.builtin.command: touch file
      args:
        creates: file

Upvotes: 1

fap
fap

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

vqqnda1
vqqnda1

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

techraf
techraf

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

Related Questions