# Proposed named policy for module "backup" parameter

**URL:** <https://forum.ansible.com/t/proposed-named-policy-for-module-backup-parameter/11168>\
**Category:** Project Discussions\
**Tags:** module, backup-files, ansible-core\
**Created:** [November 26, 2024, 7:18pm UTC](https://forum.ansible.com/t/proposed-named-policy-for-module-backup-parameter/11168 "2024-11-26T19:18:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [November 26, 2024, 7:18pm UTC](https://forum.ansible.com/t/proposed-named-policy-for-module-backup-parameter/11168/1 "2024-11-26T19:18:42Z")

</div>

Several modules support a “`backup:`” parameter:

- `ansible.builtin.copy`
- `ansible.builtin.template`
- (others?)
- conspicuously absent: `ansible.builtin.file`

This is a very simple – dare I say, naive – mechanism which makes a backup copy of an existing file on a target host when making a change to that file.

Multiple raised issues, forum topics, and draft PRs address some aspect of handling these backup files. ( [Delete a file, create a backup and mark the task as changed when it is](http://forum.ansible.com/t/delete-a-file-create-a-backup-and-mark-the-task-as-changed-when-it-is/4146), [make backup file names confiugrable #83536](https://github.com/ansible/ansible/pull/83536) ) Each of these addresses a valid issue, scratching someone’s particular itch.

However, fixing any one of these issues in isolation would be a mistake in my opinion. Such changes would only make a real fix messier to implement, since each of these issues is – I’m claiming – merely a symptom of the _Real Problem_™.

**The _Real Problem_ is that there’s no clear path to automation of the entire backup file life-cycle.** The naive strategy of “Create a backup file including the timestamp information so you can get the original file back if you somehow clobbered it incorrectly” – to quote the [`copy` module’s description](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html#parameter-backup) of the `backup:` parameter – leads to an ever-increasing set of unmanaged files on each target host.

Sure, you can write additional tasks to “handle” such a backup file set. Every. Single. One. Even encapsulate it into a role that you can call – over and over and over. You could even make it flexible enough to deal with some of the issues alluded to above.

This is not something I want cluttering up my projects’ task files or my logs. I want it to work as transparently as the current modules’ “`backup:`” parameter works. What I really want is for the `copy`, `template`, or _`whatever`_ module to follow a named “`backup_policy`” selectable at the task level with a parameter of the same name.

So what would such a named backup policy do? For starters, one named “`default`” would do exactly what specifying “`backup: true`” currently does. Other named policies would contain a subset of additional optional settings. For example:

```yaml
backup_policies:
  - name: default # Backwards compatible! Could be redefined though.
  - name: two_week_3_12 # naming things is hard
    retention:
      min: 3 # default is infinite
      max: 12 # default is undef/not specified
      span: 14d # default is undef/not specified
    path: ../bkups # default is '.'; could be relative or absolute.

```

Applying a policy at the task level might look like any of the following:

```yaml
- name: Do the same old thing
  ansible.builtin.template:
    src: foo.j2
    dest: '{{ wherever }}/foo'
    backup: true # backwards compatible - unless
                  # backup_policies.default has been set.

- name: Do a thing
  ansible.builtin.template:
    src: foo.j2
    dest: '{{ wherever }}/foo'
    backup: true
    backup_policy: two_week_3_12

- name: Do a different thing
  ansible.builtin.template:
    src: bar.j2
    dest: '{{ elsewhere }}/bar'
    backup: true
    backup_policy:
      name: two_week_3_12 # Apply this policy's parameters...
      max: 8 # but override 'max: 12' with this setting.

- name: Do an even more different thing
  ansible.builtin.template:
    src: baz.j2
    dest: '{{ undisclosed_location }}/baz'
    backup: true
    backup_policy: # No 'name:'; we're augmenting 'default' policy.
      min: 4
      max: 8
      span: 30d

```

I have not included any options for tweaking a backup’s _filename template_ in these examples, but that could certainly be a part of it. (See the 2nd link above.) That complicates the bit of policy implementing deletion of old backup files, though. For instance, what if you configure the _filename template_ such that ordering of backup files is not obvious, or that all backup files have the same name!? (That’s on you, I say!)

You have interesting resolution issues when either `retention.min` or `retention.max` conflicts with `retention.span`. My gut instinct is to go with whichever one retains the most backups. Feel free to change my mind.

And what about the `path:`, specifically when the specified path doesn’t exist?  
Should the task fail outright, or is it a non-issue unless it tries to make a backup? Should it make an attempt to create the path, and fail the task if it can’t? My lean is to fail the task outright. Certainly not to make the behavior in this case configurable!

Making backup file life-cycle manageable through named policy like this makes it simple for users to apply different policies to different tasks as appropriate. It gives a clean mechanism to address issues raised here in the Forum and github without breaking existing behavior. Users could simply define `backup_policies.default` to upgrade from legacy naive unmanaged backup files to rational life-cycle managed backup files across all tasks that currently set “`backup: true`”.

Thanks for reading. I’m looking forward to your thoughts and discussion.

---

<div class="post-metadata">

**Author:** ![chris](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/chris/32/293_2.png) [@chris](https://forum.ansible.com/u/chris)\
**Post date:** [November 26, 2024, 10:29pm UTC](https://forum.ansible.com/t/proposed-named-policy-for-module-backup-parameter/11168/2 "2024-11-26T22:29:59Z")

</div>

> [@utoddl](#):
>
> - conspicuously absent: `ansible.builtin.file`

Indeed, I often make up for this like this:

```yaml
- name: Set a fact for the backup extension
  ansible.builtin.set_fact:
    file_to_delete: /etc/foo/bar.conf
    file_backup: "{{ file_to_delete | ansible.builtin.dirname }}/.{{ file_to_delete | ansible.builtin.basename }}.{{ ansible_facts.date_time.iso8601_basic_short }}.bak"

- name: Delete the file, creating a backup
  ansible.builtin.command: "mv {{ file_to_delete }} {{ file_backup }}"
  args:
    removes: "{{ file_to_delete }}"

```

---

<div class="post-metadata">

**Author:** ![tanganellilore](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/tanganellilore/32/178_2.png) [@tanganellilore](https://forum.ansible.com/u/tanganellilore)\
**Post date:** [December 3, 2024, 9:54pm UTC](https://forum.ansible.com/t/proposed-named-policy-for-module-backup-parameter/11168/3 "2024-12-03T21:54:30Z")

</div>

Hi,

This is a interested topic. Probably i suggest you to change the title because to me was not very clear and I think that is not ‘clickbait’ so ansible core team will not focus on it.

I think that this type of management require some work on module side (not necessary hard) and a lot of time to be approved ( and will be porte on oldest ansible version?) but nobody block us to use a template/copy/file create by community and not present on builtin core.

I will think on it and check the core code if this implementation can be easy to implementat in a new community collection
