I have this jinja2 template:
# {{ ansible_managed }}
{% for vhost in nginx_vhosts %}
{%- if vhost.name == item.name -%}
# redirect www to non-www
server {
listen {{ nginx_port }};
listen [::]:{{ nginx_port }};
port_in_redirect off;
server_name www.{{ vhost.name }};
return 301 http://{{ vhost.name }}$request_uri;
}
{%- endif -%}
{%- endfor -%}
An ansible role with an yaml file vhosts.yml containing definitions like this:
nginx_vhosts:
- name: "test1.com"
repo: "git1"
branch: master
state: present
- name: "test2.com"
repo: "git2"
branch: master
state: present
...
- name: "test101.com"
repo: "git101"
branch: master
state: present
A task inside playbook.yml:
- name: "Generate nginx vhost configuration file"
template:
src: templates/nginx-vhost-template.j2
dest: "{{ nginx_vhosts_dir }}/{{ item.name }}.conf"
owner: "{{ nginx_user }}"
group: "{{ nginx_group }}"
mode: 0640
with_items:
- "{{ nginx_vhosts }}"
when:
- item.state == 'present'
notify:
- nginx-restart
I ran a taks like:
ansible-playbook -l web1 playbook.yml --tags=nginx-vhost-config
which is working fine, it will create from template a nginx vhost configuration file on the remote server as domain1.com.conf and so on for all the found definitions.
Assuming that in the vhosts.yml file I have test1.com up to test100.com, I'll add let's say test101.com and I want to run the tasks strictly for that test101.com and not for all previous hosts. So I tried something like this:
ansible-playbook -l web1 playbook.yml --tags=nginx-vhost-config -e "{ 'nginx_vhosts': { 'name': 'test101.com', 'state': 'present', 'repo': 'git101', 'branch': 'master' }}"
The issue with this is that it results in an error when trying to replace values from the jinja2 template.
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible.errors.AnsibleUndefinedVariable: 'ansible.parsing.yaml.objects.AnsibleUnicode object' has no attribute 'name'
I've also tried using loop instead of with_items but no luck.
I understand that when using the extra-vars, the provided content is in JSON format but I was not able to find a different way to pass the content from vhosts.yml as extra vars for one single entry. Is there any way to make this functional?
Is there a better approach maybe?