When I setup HashiCorp Vault, I setup backups for it. These use a token that, by default, expires after 32 days. A new one, therefore, needs to be generated periodically. I decided to write a playbook to automate this with Ansible.

In my existing hashicorp-vault role’s tasks/main.yaml, I moved the task to update the backup token into its own tasks file and included that:

- name: Deploy backup secrets
  ansible.builtin.include_tasks: backup-config.yaml

The new tasks/backup-config.yaml task file just has the old task in - note this old role uses lookups inside the role, which is something I have since decided is bad practice and no longer do. Instead I use variables and, if using a lookup, populate them outside the role to make the role more generic and reusable however this role has not been fixed yet.

---
- name: Deploy backup secrets
  become: yes
  ansible.builtin.copy:
    dest: /etc/vault-backup.conf
    owner: vault-backup
    group: vault-backup
    mode: 00440
    content: |
      VAULT_ADDR={{ lookup('ansible.builtin.env', 'VAULT_ADDR', default='https://127.0.0.1:8200/') }}
      VAULT_TOKEN={{ lookup('community.hashi_vault.vault_read', '/kv/vault/backup/token').data.token }}
  no_log: true  # Don't log or display secrets
...

The agument spec for the new entry point reiterates the technical debt present in a comment:

backup-config:
  short_description: Just update the backup script's config file
  author: Laurence Alexander Hurst
  # This entry point has no options (which is bad - should be
  # variables, not using lookups internally).

Finally, I created the playbook to update the token:

---
- name: Token is updated
  hosts: localhost
  tasks:
    - name: New token is generated
      community.hashi_vault.vault_token_create:
        display_name: backup
        role_name: backup
      register: new_backup_token
    - name: New token is stored in vault
      community.hashi_vault.vault_write:
        path: kv/vault/backup/token
        data:
          token: "{{ new_backup_token.login.auth.client_token }}"
      # Token is sensitive - do not allow it to be logged
      no_log: true
- name: Token is updated on all vault hosts
  hosts: hashicorp_vault_servers
  gather_facts: false
  tasks:
    - ansible.builtin.import_role:
        name: hashicorp-vault
        tasks_from: backup-config
...