Is there a way to override a template defined into an ansible galaxy role?
Asked Answered
G

3

9

I'm trying to set up a server with ansible and I'd like to use this galaxy role.

It defines a template that I'd like to customize, but I don't know how.

Right now I defined the role into requirements.yml and I installed it using:

ansible-galaxy install -r requirements.yml

which installed the role somewhere on my system.

I tried by recreating the folder tree into my repository where I store my playbooks:

roles
  |- ansible-role-passenger
     |- templates
        |- passenger.j2

but it does not work. When I run my playbook, ansible uses the passenger.j2 file from inside the galaxy role.

I think I can fork the galaxy role on github and just edit the file passenger.j2 like I want, but I don't know if this is there is a "better" way to do it :)

Gingivitis answered 18/4, 2019 at 9:18 Comment(0)
P
19

Your findings are unfortunately true. Overriding a hardcoded template in a role from a calling playbook is merely impossible unless the role's author implemented that as a feature. Note that this is also true for simple files in the files directory.

The best way I have found so far: given that the role contains the default template in templates/passenger.j2, add a var in default/main.yml such as passenger_config_template: passenger.j2 and use that var in the role. The user can then override that var in its playbook/inventory and use a different name for the template which will be fetched in an other role or directly in a templates directory at playbook level.

You can have a look at a similar issue and an accepted PR I once made to @geerlingguy on his ansible-role-gitlab. He might consider doing the same thing on his passenger role (or might accept your PR if you propose one).

Propound answered 18/4, 2019 at 16:10 Comment(3)
I am currently writing a role in which I want to allow users to override the hardcoded templates folder, if desired. Any suggestions on the best way to do this?Oxy
overriding the template folder is going to be hard IMO as this is actually a list ansible looks into.Propound
@Propound - Sorry, I didn't make myself clear; I'm hoping to allow the user to override the entire templates folder. I.e., force the search for templates/ to start from an arbitrary folder, rather than {{ role_folder }}. I had reasoned out your particular method of allowing the use of a single file, but was hoping for more... and it just occurred to me to define a templates_base fact with a default of roles_folder and provide a complete path to the search. Nevermind. Thanks!Oxy
P
2

The reply from @Zeitounator above is totally legit.

But in the case where the author of an Ansible role is not responsive or playing dumb, there is another simpler approach.

Steps:

1) Execute the role as you would do, don't change anything

2) Write a small piece of Ansible code to simply override any file or template yourself.

Simple approach and is a no-brainer for all.

cheers

Pharmacopoeia answered 7/5, 2020 at 9:58 Comment(1)
I would prefer forking the role and make the modifications myself, or even write a new one. Your approach is indeed simple and no brainer. But it will override the given templated file twice on each playbook run, blowing away idempotence, with all possible risks in between of running an app, even for only a few seconds, with a bad configuration. That is a total no-go for me.Propound
G
1

@Zeitounator response helped me a lot, and I'd like to give more details here (in a comment, the format is too limited), but big thanks to @Zeitounator! :)

To give a concrete example, in your role:

roles
`-- passenger
    |-- defaults
    |   `-- main.yml
    |-- tasks
    |   `-- main.yml
    `-- templates
        `-- passenger.j2

In the defaults/main.yml:

passenger_config_template: passenger.j2

In the tasks/main.yml:

- name: Template passenger to /etc/passenger
  ansible.builtin.template:
    src: "{{ passenger_config_template }}"
    dest: /etc/passenger

By default, Ansible will try to find the file in the role's directory templates for the ansible.builtin.template module (and files directory for the ansible.builtin.copy module)

More about Ansible path resolution: https://docs.ansible.com/ansible/latest/user_guide/playbook_pathing.html

Now, in your playbook, to overwrite the default role's template passenger.j2, you would have this directory layout:

your_ansible_directory
|-- templates
|   `-- passenger.j2  <-- your custom template
|-- ansible.cfg
`-- playbook.yml

In the playbook.yml:

- hosts: your_host
  tasks:
    - ansible.builtin.import_role:
        name: passenger
      vars:
        passenger_config_template: "{{ playbook_dir }}/templates/passenger.j2"

Note: I've renamed the role name on purpose to give an example of a good role name: role names shouldn't be prefixed by ansible- or ansible-role- and should use only _ (underscore) characters, not - (hypen) or . (dot) characters.

Read more about role naming: https://galaxy.ansible.com/docs/contributing/creating_role.html#role-names

Ghoul answered 9/9, 2022 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.