i try to loop over the geerlingguy.nginx Role to create nginx vhosts. But i dont get it done:
Playbook.yml:
- hosts: some.server
become: true
roles:
- geerlingguy.nginx
tasks:
- name: looping vhosts
include_tasks: vhosts.yml
loop:
- { name: 'vhost1.bla.com', state: 'present' }
- { name: 'vhost1.bla.com', state: 'present' }
For this Server i create a Host_vars File:
host_vars.yml
nginx_worker_processes: "auto"
nginx_worker_connections: 768
nginx_extra_http_options: |
gzip on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
nginx_vhosts:
- listen: "443 ssl http2"
server_name: '{{ item.name }}'
server_name_redirect: " {{ item.name }} "
root: "/var/www/{{ item.name }}"
index: "index.php index.html index.htm"
access_log: "/var/www/{{ item.name }}/logs/access_{{ item.name }}.log"
error_log: "/var/www/{{ item.name }}/logs/erro_{{ item.name }}.log"
state: "{{ item.state }}"
template: "{{ nginx_vhost_template }}"
filename: "{{ item.name }}"
extra_parameters: |
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
This is the vhost.yml from the geerlingguy.nginx Role:
- name: Remove default nginx vhost config file (if configured).
file:
path: "{{ nginx_default_vhost_path }}"
state: absent
when: nginx_remove_default_vhost | bool
notify: restart nginx
- name: Ensure nginx_vhost_path exists.
file:
path: "{{ nginx_vhost_path }}"
state: directory
mode: 0755
notify: reload nginx
- name: Add managed vhost config files.
template:
src: "{{ item.template|default(nginx_vhost_template) }}"
dest: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}"
force: true
owner: root
group: "{{ root_group }}"
mode: 0644
when: item.state|default('present') != 'absent'
with_items: "{{ nginx_vhosts }}"
notify: reload nginx
tags:
- skip_ansible_lint
- name: Remove managed vhost config files.
file:
path: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}"
state: absent
when: item.state|default('present') == 'absent'
with_items: "{{ nginx_vhosts }}"
notify: reload nginx
tags:
- skip_ansible_lint
- name: Remove legacy vhosts.conf file.
file:
path: "{{ nginx_vhost_path }}/vhosts.conf"
state: absent
notify: reload nginx
So, when i run the playbook i got:
fatal: [some.server]: FAILED! => {
"msg": "[{'listen': '443 ssl http2', 'server_name': '{{ item.name }}'... HIGH:!aNULL:!MD5;\\n'}]: 'item' is undefined
I try it in different ways but always get the same error, would be greate if someone could help me. Thanks!
CodePudding user response:
Your approach doesn't work, you won't get anything out of a loop at this point. Furthermore, it is not possible to define a variable or data structure and have the Jinja logic evaluate it later.
The implementation of geerlingguy provides that the variable nginx_vhosts
is defined. This variable must be a list of dicts, and this list is then automatically processed.
You have two main options:
Option 1
You create nginx_vhosts
as a list of dicts for all your virtual hosts.
nginx_vhosts:
- listen: "443 ssl http2"
server_name: "vhost1.bla.com"
server_name_redirect: "www.vhost1.bla.com"
root: "/var/www/vhost1.bla.com"
index: "index.php index.html index.htm"
error_page: ""
access_log: "/var/www/vhost1.bla.com/logs/access_vhost1.bla.com.log"
error_log: "/var/www/vhost1.bla.com/logs/error_vhost1.bla.com.log"
state: "present"
template: "{{ nginx_vhost_template }}"
filename: "vhost1.bla.com.conf"
extra_parameters: |
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
- listen: "443 ssl http2"
server_name: "vhost2.bla.com"
server_name_redirect: "www.vhost2.bla.com"
root: "/var/www/vhost2.bla.com"
index: "index.php index.html index.htm"
error_page: ""
access_log: "/var/www/vhost2.bla.com/logs/access_vhost2.bla.com.log"
error_log: "/var/www/vhost2.bla.com/logs/error_vhost2.bla.com.log"
state: "present"
template: "{{ nginx_vhost_template }}"
filename: "vhost2.bla.com.conf"
extra_parameters: |
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
Option 2
A bit more complicated, but I think that was your wish, with the loop.
Create a separate file for your tasks myvhost.yml
with the following content:
---
- name: define nginx_vhosts variable
set_fact:
nginx_vhosts:
- listen: "443 ssl http2"
server_name: '{{ item.name }}'
server_name_redirect: " {{ item.name }} "
root: "/var/www/{{ item.name }}"
index: "index.php index.html index.htm"
access_log: "/var/www/{{ item.name }}/logs/access_{{ item.name }}.log"
error_log: "/var/www/{{ item.name }}/logs/erro_{{ item.name }}.log"
state: "{{ item.state }}"
# template: "{{ nginx_vhost_template }}"
filename: "{{ item.name }}"
extra_parameters: |
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
- name: include vhosts.yml from geerlingguy
include_tasks: vhosts.yml
Here you set the variable nginx_vhosts
with new values, a list with a single dict. Then you perform the import of the role from geerlingguy.
In your playbook, on the other hand, you import your new myvhost.yml
with the loop.
- name: looping vhosts
include_tasks: myvhost.yml
loop:
- { name: 'vhost1.bla.com', state: 'present' }
- { name: 'vhost2.bla.com', state: 'present' }