1

In ansible we are trying to access different templates based on variable.

We have following template files like:

templates app1.conf.j2 app2.conf.j2 app3.conf.j2 taks app.yml 

In tasks we need to copy template file based on the app name. for eg: we will specify a variable named "instance_name" to either app1 or app2 or app3.

Now based on the variable we need to copy the app file to /opt/(( instance_name }}/conf.d/.

we created ansbile task as follows but its not working.

- name: 'Copy {{ instance_name }} file to /opt/conf.d/ Directory'     template:       src: "{{ instance_name }}.conf.j2"       dest: "/opt/{{ instance_name }}/conf.d/"       owner: root       group: root       mode: 0644 

     

When we hard code "src" to app1.conf.j2 its working for app1.

From this url https://docs.ansible.com/ansible/latest/modules/template_module.html#parameter-src it specifies value can be a relative or an absolute path.

Please let us know is it possible with this method? We are having around 20 apps and whats the best method to simplify the ansible playbook to specify only the variable.

1
  • Please define "not working", include any error. And show where you defined instance_name, including where in the tree the file is. Commented Mar 29, 2020 at 12:38

1 Answer 1

1

There are no best practices, only opinions on how elegant a solution is for a particular problem. Especially true for Ansible, given the flexibility in how it allows you to do things how you want.


Roles are great. Could make a role per app group, and each contains config templates it needs, such as roles/app1/templates/app1.conf.j2 Possibly it has multiple tasks and templates, say if the app starts some process via the service manager, ensures host firewall allows it, and also hooks things up via some service mesh.

app1's defaults/main.yml might contain

instance_name: app1 

Which can then get used by tasks/main.yml (some parameters omitted for brevity, perhaps they were moved to module defaults on a block.)

- name: 'Copy config to /opt/conf.d/' template: src: "{{ instance_name }}.conf.j2" dest: "/opt/{{ instance_name }}/conf.d/" 

If this all were in one tree alongside your playbook (not required, roles in particular could be stored elsewhere), it might look like the content organization example in the documentation:

playbook.yml roles/ app1/ tasks/ main.yml templates/ app1.conf.j2 app2/ tasks/ main.yml templates/ app2.conf.j2 

And the playbook then just needs to list them:

roles: - app1 - app2 

Implementation of such roles can be repetitive as every role needs to do the same thing. If roles only differ by a couple variables, make a generic role and call it multiple times with different role parameters.

roles: - role: appgeneric vars: instance_name: app1 - role: appgeneric vars: instance_name: app2 

Variables for module parameters is great, the answer to your question is yes. However, variable task names doesn't really work. Task names are global and parsed early, so maybe --extra-vars cli arguments but not say a loop iteration or a host specific variable.

So what to do if you have a generic named role and a generic named task going through 20 app deploys? Errors should be informative, if template cannot load a file it will tell you which file name. Increasing verbosity a bit with ansible-playbook -vv helps understand what's going on, but is messy and verbose. Consider playbook logging software on top of Ansible, like ARA or AWX/Tower. Reports those have showing which execution loaded which variables can provide context.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.