debops/debops-playbooks

New hook format proposal

patrickheeney opened this issue · 2 comments

This is a proposal to alter the pre_tasks and post_tasks with using functionality native to ansible. I tested a dozen different methods and this seems to be the best option. The goal is to remove the dependency on task_src so it is must easier to use from galaxy while still preserving the functionality.

Playbook

- name: "Test"
  hosts: local
  sudo: False
  remote_user: vagrant
  vars:
    debops_pre_tasks_users: 'hook.yml'
  roles:
    - { role: test, tags: [test] }
  tasks:
    - debug: var=debops_pre_tasks_users

File: test/hook.yml

- debug: msg="Hook Fired"

File: test/main.yml

- set_fact:
    debops_pre_tasks_users_fact: 'hook.yml'
    debops_fire_hooks: True

# - debug: msg="Firing test 0"
# - name: DebOps pre_tasks hook
#   include: "{{ lookup('task_src', 'users/pre_main.yml') }}"
# ERROR: Failed to template {{ lookup('task_src', 'users/pre_main.yml') }}: lookup plugin (task_src) not found

# - debug: msg="Firing test 1"
# - include: '{{ debops_pre_tasks_users_fact }}'
#   when: debops_pre_tasks_users_fact is defined
# ERROR: file could not read: /Users/patrickheeney/Dev/infrastructure/playbooks/roles/test/tasks/{{ debops_pre_tasks_users_fact }}

# - debug: msg="Firing test 2"
# - include: '{{ lookup("file", debops_pre_tasks_users_fact) }}'
#   when: debops_pre_tasks_users_fact is defined
# ERROR: file could not read: /Users/patrickheeney/Dev/infrastructure/playbooks/roles/test/tasks/{{ lookup("file", debops_pre_tasks_users_fact) }}

- debug: msg="Firing test 3"
- include: hook.yml
  when: debops_fire_hooks is defined and debops_fire_hooks

- debug: msg="Firing test 4"
- include: "{{ debops_pre_tasks_users_fact | default('empty.yml') }}"

- debug: msg="Firing test 5"
- include: "{{ debops_pre_tasks_users_doesnt_exist | default('empty.yml') }}"

- debug: msg="Firing test 6"
- include: "{{ debops_pre_tasks_users | default('empty.yml') }}"

- debug: msg="Firing test 7"
- include: "{{ debops_pre_tasks_users }}"
  when: debops_pre_tasks_users is defined

File: test/empty.yml

- debug: msg="Empty"

This successfully fires test 5, 6, 7. Test 4 doesn't work when using facts. I also explored using symlinks and file module to check if it exists before including, but this approach is much better. Test 7 looks to be the most ideal, however it fails when debops_pre_tasks_users is not defined anywhere. Test 6 seems to work in all scenarios I tested, which is similar to other popular playbooks that utilize hooks.

This same principle could be applied for template_src to be something like:

#  template:
#    src: '{{ lookup("template_src", "etc/ssh/authorized_keys_lookup.d/" + item + ".j2") }}'
#    dest: '/etc/ssh/authorized_keys_lookup.d/{{ item }}'

  template:
    src: '{{ debops_template_src_authorized_lookup_folder | default("etc/ssh/authorized_keys_lookup.d/") + item + ".j2" }}'
    dest: '/etc/ssh/authorized_keys_lookup.d/{{ item }}'

I tested this with:

- debug: msg="Firing test 8"
- debug: msg="{{ debops_template_src_authorized_lookup_folder | default("etc/ssh/authorized_keys_lookup.d/") + item + ".j2" }}"
  with_items:
    - "test"

There are other popular roles using this format like https://github.com/ansistrano/deploy . I only tested setting vars within the playbook. There may be other ways to set the variable to have it recognized by the time it is included.

I don't think ansible 2.0 will solve this with the block module as the playbook searches for the lookups and it won't be found. If include + with_items or with_first_found starts working again, then it will be another way to expand upon this syntax.

If this proposal is accepted, I can help submit pull requests to individual repositories. Debops would likely need to create a naming structure to be consistent with hook variables and template variables.

I'm writing a longer response later, for now put this code in a git repository in a format that is used by Ansible roles, so it can be tested.

I have put together a sample playbook for testing native ansible hooks here: https://github.com/patrickheeney/ansible-hooks .

I currently have no need for these native hooks any longer since I created a few lookup modules to remove the debops dependency. These lookup modules can be found here: https://github.com/protobox/protobox-core/tree/master/plugins/lookup_plugins which emulate the debops lookups but do not search any custom paths.