49 Commits
1.3.6 ... 1.4.0

Author SHA1 Message Date
Emilien Mantel
552999c782 Install modules on Debian 9+ or 8 with backports 2018-01-15 22:36:53 +01:00
Emilien Mantel
fe32f8d40a Revert "minor fix"
This reverts commit 5d46daaba8.
2018-01-15 22:33:55 +01:00
Emilien Mantel
5d46daaba8 minor fix 2018-01-15 19:12:22 +01:00
Emilien Mantel
4ca8f9e319 Check nginx_version before install modules 2018-01-15 18:41:17 +01:00
Emilien Mantel
d3d9b5c296 Install modules OK 2017-12-14 20:06:29 +01:00
Emilien Mantel
45886ca9cc Install modules just after nginx 2017-12-14 19:41:05 +01:00
Emilien Mantel
bb74ac804e Donation 2017-12-09 17:05:02 +01:00
Emilien Mantel
2a5a1701f3 Try fix travis: php service not started 2017-12-07 12:40:16 +01:00
Emilien Mantel
a1866f806f Fix test php_index2, fallback in /index.php 2017-12-07 11:14:19 +01:00
Emilien Mantel
0788b6c84f Delete PHP upstream when nginx_php is empty
Closes #31
2017-12-07 11:09:44 +01:00
Emilien Mantel
222998839c Fix site.state == absent
- Site is deleted now
- Doc updated
2017-12-06 12:05:46 +01:00
Emilien Mantel
d00f3301e1 _php template, do not go to /index.php as fallback 2017-12-05 10:40:21 +01:00
Emilien Mantel
8f76b9c68c acme.sh : no_log + fix check created 2017-12-03 02:15:48 +01:00
Emilien Mantel
8dca6c8404 Fix acme when acme_port is not defined 2017-12-03 02:08:32 +01:00
Emilien Mantel
a01f6cd5ea Let's encript certificate with acme.sh 2017-12-03 01:32:56 +01:00
Emilien Mantel
609e4f013d Fix crash when nginx_upstream is not set 2017-11-27 13:43:28 +01:00
Emilien Mantel
c79d370ad6 Add new site template: _php_index2 2017-11-27 13:34:03 +01:00
Emilien Mantel
45f800fe18 With Vagrant 2.* ansible.sudo -> ansible.become 2017-11-27 13:25:04 +01:00
Emilien Mantel
9fc4838b1b Fix loop control 2017-11-03 11:06:57 +01:00
Emilien Mantel
3304934227 Add loop_control.label on site tasks 2017-11-03 10:56:18 +01:00
Emilien Mantel
57968b50c0 Restart nginx on SSL file writes 2017-11-03 10:30:24 +01:00
Emilien Mantel
8675d683ec Tests with uri module (closes #25) 2017-10-27 15:27:16 +02:00
Emilien Mantel
10bd837f54 Setup is now 'handled' 2017-10-26 15:50:59 +02:00
Emilien Mantel
332e28a9d7 YAML cleaning 2017-10-26 15:47:30 +02:00
Emilien Mantel
4b3b857733 Remove heavy code (nginx filename) using a filter 2017-10-26 15:33:00 +02:00
Emilien Mantel
608784ca55 Fix travis 2017-10-26 11:45:20 +02:00
Emilien Mantel
36652f4742 Move upstream templates to conf.d 2017-10-26 11:09:21 +02:00
Emilien Mantel
463ce45105 New PHP management
- New versions (7.x)
- PHP upstream name
- Sites can use : default PHP version, select first one by PHP version,
  select by upstream name
- Add PHP filter plugin
2017-10-26 11:04:38 +02:00
Emilien Mantel
70283ddcc6 Update .travis.yml
Fix failures
2017-10-03 19:57:04 +02:00
Emilien Mantel
de40c07ac5 Better readability 2017-10-03 17:57:35 +02:00
Emilien Mantel
54dd1ef3c0 Remove legacy code 2017-10-03 17:38:06 +02:00
Emilien Mantel
cfe27ef245 Bypasses ansible 2.4.0.0 service issue
On Ansible 2.4, it seems the service is not reloaded/restarted. This
commit skips errors...
2017-10-03 17:35:35 +02:00
Emilien Mantel
6f098475e5 Remove useless vagrant boxes 2017-10-03 16:52:45 +02:00
Emilien Mantel
090875cbde Travis changes
- drop allow failure for stretch and ansible 2.3
- manages ansible 2.4
2017-09-26 09:44:52 +02:00
Emilien Mantel
b72263f7e5 Fix failures on travis 2017-07-27 14:56:43 +02:00
Emilien Mantel
4751eaa3c1 Add missing cont on Vagrant 2017-07-27 14:31:42 +02:00
Emilien Mantel
e83395271d Fix tests for Debian Stretch
- nagios is not available
- curl can use HTTP2 (headers are lowercase)
- bypass tests when htpasswd is empty (bypass issue #28)
2017-07-27 14:25:22 +02:00
Emilien Mantel
6935404939 Improve syntax readability 2017-07-27 12:21:10 +02:00
Emilien Mantel
acf8de8f87 Fix warning on when 2017-07-27 12:01:59 +02:00
Emilien Mantel
50e25d45b8 Elegent fail for htpasswd+stretch (#28 related) 2017-07-27 11:50:48 +02:00
Emilien Mantel
adf53b0d95 Fix redirect_to when filename is set 2017-07-25 17:00:34 +02:00
Emilien Mantel
4d819ac2a1 Add tags to ssl and site configuration 2017-07-19 15:57:41 +02:00
Emilien Mantel
af9fa6a2c3 Update stretch vagrant box (virtualbox) 2017-06-29 15:04:59 +02:00
Emilien Mantel
4486bddb19 Add blank lines, spaces... (readability) 2017-06-14 18:00:30 +02:00
Emilien Mantel
0b99a1c28e Remove ansible 2.3 warnings - fixes #29 2017-06-14 17:54:48 +02:00
Emilien Mantel
d616657f12 travis: missing debian stretch + ansible 2.2 2017-06-09 09:48:24 +02:00
Emilien Mantel
eb0bdcad6f Travis major changes:
- Use Vagrant + Docker
- Test multiple Ansible versions
2017-06-06 14:15:03 +02:00
Emilien Mantel
3ae791ec47 Role can be fully called in check mode 2017-06-01 11:38:22 +02:00
Emilien Mantel
cbdfc741ba Renaming variables *vhost* -> *site*
Vhost is an Apache configuration, not Nginx.
Manages backward compatibility.
2017-04-25 12:27:08 +02:00
46 changed files with 995 additions and 550 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.vagrant* .vagrant*
*.swp *.swp
*.retry *.retry
*.pyc

View File

@@ -1,8 +1,26 @@
env:
- PLATFORM='docker-debian-jessie' ANSIBLE_VERSION='ansible>=2.2,<2.3'
- PLATFORM='docker-debian-jessie-backports' ANSIBLE_VERSION='ansible>=2.2,<2.3'
- PLATFORM='docker-debian-jessie-dotdeb' ANSIBLE_VERSION='ansible>=2.2,<2.3'
- PLATFORM='docker-debian-jessie' ANSIBLE_VERSION='ansible>=2.3,<2.4'
- PLATFORM='docker-debian-jessie-backports' ANSIBLE_VERSION='ansible>=2.3,<2.4'
- PLATFORM='docker-debian-jessie-dotdeb' ANSIBLE_VERSION='ansible>=2.3,<2.4'
- PLATFORM='docker-debian-stretch' ANSIBLE_VERSION='ansible>=2.3,<2.4'
- PLATFORM='docker-debian-stretch-sury' ANSIBLE_VERSION='ansible>=2.3,<2.4'
- PLATFORM='docker-debian-jessie' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- PLATFORM='docker-debian-jessie-backports' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- PLATFORM='docker-debian-jessie-dotdeb' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- PLATFORM='docker-debian-stretch' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- PLATFORM='docker-debian-stretch-sury' ANSIBLE_VERSION='ansible>=2.4,<2.5'
matrix: matrix:
include: allow_failures:
- env: PLATFORM=debian-jessie ORIGIN=debian NGINX_PHP56=true NGINX_PHP70=false NGINX_BACKPORTS=false DOTDEB=false - env: PLATFORM='docker-debian-jessie' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- env: PLATFORM=debian-jessie ORIGIN=backports NGINX_PHP56=true NGINX_PHP70=false NGINX_BACKPORTS=true DOTDEB=false - env: PLATFORM='docker-debian-jessie-backports' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- env: PLATFORM=debian-jessie ORIGIN=dotdeb NGINX_PHP56=true NGINX_PHP70=true NGINX_BACKPORTS=false DOTDEB=true - env: PLATFORM='docker-debian-jessie-dotdeb' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- env: PLATFORM='docker-debian-stretch' ANSIBLE_VERSION='ansible>=2.4,<2.5'
- env: PLATFORM='docker-debian-stretch-sury' ANSIBLE_VERSION='ansible>=2.4,<2.5'
fast_finish: true
sudo: required sudo: required
@@ -13,8 +31,21 @@ language: python
services: services:
- docker - docker
before_install:
- wget https://releases.hashicorp.com/vagrant/2.0.1/vagrant_2.0.1_x86_64.deb
- sudo dpkg -i vagrant_2.0.1_x86_64.deb
install:
- pip install "$ANSIBLE_VERSION"
script: script:
- docker build -f tests/$PLATFORM.Dockerfile -t test-$PLATFORM . && docker run -e "DOTDEB=$DOTDEB" -e "NGINX_PHP56=$NGINX_PHP56" -e "NGINX_PHP70=$NGINX_PHP70" -e "NGINX_BACKPORTS=$NGINX_BACKPORTS" --name $PLATFORM test-$PLATFORM - VAGRANT_DEFAULT_PROVIDER=docker vagrant up $PLATFORM
- >
VAGRANT_DEFAULT_PROVIDER=docker vagrant provision $PLATFORM
| grep -q 'changed=0.*failed=0'
&& (echo 'Idempotence test: pass' && exit 0)
|| (echo 'Idempotence test: fail' && exit 1)
- VAGRANT_DEFAULT_PROVIDER=docker vagrant status
notifications: notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/ webhooks: https://galaxy.ansible.com/api/v1/notifications/

View File

@@ -8,14 +8,15 @@ Install and configure Nginx on Debian/FreeBSD.
Features: Features:
- SSL/TLS "hardened" support - SSL/TLS "hardened" support
- Manage basic auth on vhost / location - Manage basic auth on site / location
- Proxy + Upstream - Proxy + Upstream
- Fast PHP configuration - Fast PHP configuration
- Preconfigured vhost templates (should work on many app) - Preconfigured site templates (should work on many app)
- Auto-configure HTTP2 on SSL/TLS vhosts - Auto-configure HTTP2 on SSL/TLS sites
- Manage dynamic modules (install and loading) - Manage dynamic modules (install and loading)
- Deploy custom facts.d with sites config - Deploy custom facts.d with sites config
- Can listen with proxy protocol - Can listen with proxy protocol
- Generate certificates with acme.sh (let's encrypt) -- *EXPERIMENTAL*
Requirements Requirements
------------ ------------
@@ -53,7 +54,7 @@ FreeBSD:
- `nginx_events_*`: all variables in events block - `nginx_events_*`: all variables in events block
- `nginx_http_*`: all variables in http block - `nginx_http_*`: all variables in http block
- `nginx_custom_http`: instructions list (will put data in `/etc/nginx/conf.d/custom.conf`) - `nginx_custom_http`: instructions list (will put data in `/etc/nginx/conf.d/custom.conf`)
- `nginx_dyn_modules`: dynamic module list to load - `nginx_module_packages`: package list module to install
About modules About modules
------------- -------------
@@ -63,7 +64,7 @@ Last updates from Debian backports loads modules from /etc/nginx/modules-enabled
Fine configuration Fine configuration
------------------ ------------------
[Vhost configuration](doc/vhost.md) [Site configuration](doc/site.md)
[PHP configuration](doc/php.md) [PHP configuration](doc/php.md)
@@ -75,6 +76,7 @@ Fine configuration
[FreeBSD](doc/freebsd.md) [FreeBSD](doc/freebsd.md)
[acme.sh](doc/acme.md)
Note Note
---- ----
@@ -98,6 +100,19 @@ License
GPLv2 GPLv2
Donation
--------
If this code helped you, or if youve used them for your projects, feel free to buy me some :beers:
- Bitcoin: `1BQwhBeszzWbUTyK4aUyq3SRg7rBSHcEQn`
- Ethereum: `63abe6b2648fd892816d87a31e3d9d4365a737b5`
- Litecoin: `LeNDw34zQLX84VvhCGADNvHMEgb5QyFXyD`
- Monero: `45wbf7VdQAZS5EWUrPhen7Wo4hy7Pa7c7ZBdaWQSRowtd3CZ5vpVw5nTPphTuqVQrnYZC72FXDYyfP31uJmfSQ6qRXFy3bQ`
No crypto-currency? :star: the project is also a way of saying thank you! :sunglasses:
Author Information Author Information
------------------ ------------------

95
Vagrantfile vendored
View File

@@ -6,51 +6,80 @@
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
vms_debian = [ vms_debian = [
{ :name => "debian-jessie", :box => "debian/jessie64", :vars => { "nginx_php56": true, "nginx_php70": false, "dotdeb": false, "nginx_backports": false }}, { :name => "debian-jessie", :box => "debian/jessie64", :vars => { "nginx_php": [{"version": "5.6"}] }},
{ :name => "debian-jessie-backports", :box => "debian/jessie64", :vars => { "nginx_php56": true, "nginx_php70": false, "dotdeb": false, "nginx_backports": true }}, { :name => "debian-jessie-backports", :box => "debian/jessie64", :vars => { "nginx_php": [{"version": "5.6"}], "nginx_backports": true }},
{ :name => "debian-jessie-dotdeb", :box => "debian/jessie64", :vars => { "nginx_php56": true, "nginx_php70": true, "dotdeb": true, "nginx_backports": false }}, { :name => "debian-jessie-dotdeb", :box => "debian/jessie64", :vars => { "nginx_php": [{"version": "7.0"}, {"version": "5.6", "upstream_name": "legacy"} ], "dotdeb": true }},
{ :name => "debian-stretch", :box => "sharlak/debian_stretch_64", :vars => { "nginx_php56": false, "nginx_php70": true, "dotdeb": false, "nginx_backports": false }} { :name => "debian-stretch", :box => "debian/stretch64", :vars => { "nginx_php": [{"version": "7.0"}] }},
{ :name => "debian-stretch-sury", :box => "debian/stretch64", :vars => { "nginx_php": [{"version": "7.1"}], "sury": true }}
] ]
vms_freebsd = [ vms_freebsd = [
{ :name => "freebsd-10.2", :box => "freebsd/FreeBSD-10.2-STABLE" } { :name => "freebsd-10.2", :box => "freebsd/FreeBSD-10.2-STABLE" }
] ]
config.vm.provider "virtualbox" do |v| conts = [
v.cpus = 1 { :name => "docker-debian-jessie", :docker => "hanxhx/vagrant-ansible:debian8", :vars => { "nginx_php" => [{"version" => "5.6"}] }},
v.memory = 256 { :name => "docker-debian-jessie-backports", :docker => "hanxhx/vagrant-ansible:debian8", :vars => { "nginx_php": [{"version": "5.6"}], "nginx_backports": true }},
{ :name => "docker-debian-jessie-dotdeb", :docker => "hanxhx/vagrant-ansible:debian8", :vars => { "nginx_php": [{"version": "7.0"}, {"version": "5.6", "upstream_name": "legacy"} ], "dotdeb": true }},
{ :name => "docker-debian-stretch", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "nginx_php": [{"version": "7.0"}] }},
{ :name => "docker-debian-stretch-sury", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "nginx_php": [{"version": "7.1"}], "sury": true }}
]
config.vm.network "private_network", type: "dhcp"
conts.each do |opts|
config.vm.define opts[:name] do |m|
m.vm.provider "docker" do |d|
d.image = opts[:docker]
d.remains_running = true
d.has_ssh = true
end
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.verbose = 'vv'
ansible.become = true
ansible.extra_vars = opts[:vars]
end
end
end end
vms_debian.each do |opts| vms_debian.each do |opts|
config.vm.define opts[:name] do |m| config.vm.define opts[:name] do |m|
m.vm.box = opts[:box] m.vm.box = opts[:box]
m.vm.network "private_network", type: "dhcp" m.vm.provider "virtualbox" do |v|
m.vm.provision "ansible" do |ansible| v.cpus = 1
ansible.playbook = "tests/test.yml" v.memory = 256
ansible.verbose = 'vv'
ansible.sudo = true
ansible.extra_vars = opts[:vars]
end end
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.verbose = 'vv'
ansible.become = true
ansible.extra_vars = opts[:vars]
end
end end
end end
# See: https://forums.freebsd.org/threads/52717/ # See: https://forums.freebsd.org/threads/52717/
vms_freebsd.each do |opts| # vms_freebsd.each do |opts|
config.vm.define opts[:name] do |m| # config.vm.define opts[:name] do |m|
m.vm.box = opts[:box] # m.vm.box = opts[:box]
m.vm.network "private_network", type: "dhcp" # m.vm.provider "virtualbox" do |v|
m.vm.guest = :freebsd # v.vm.cpus = 1
m.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true # v.vm.memory = 256
m.ssh.shell = "sh" # v.vm.guest = :freebsd
m.vm.base_mac = "080027D14C66" # v.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
m.vm.provision "shell", inline: "pkg install -y python bash" # v.vm.base_mac = "080027D14C66"
m.vm.provision "ansible" do |ansible| # end
ansible.playbook = "tests/test.yml" # config.ssh.shell = "sh"
ansible.verbose = 'vv' # m.vm.provision "shell", inline: "pkg install -y python bash"
ansible.sudo = true # m.vm.provision "ansible" do |ansible|
ansible.extra_vars = { # ansible.playbook = "tests/test.yml"
ansible_python_interpreter: '/usr/local/bin/python' # ansible.verbose = 'vv'
} # ansible.become = true
end # ansible.extra_vars = {
end # ansible_python_interpreter: '/usr/local/bin/python'
end # }
# end
# end
# end
end end

View File

@@ -16,8 +16,8 @@ nginx_resolver_valid: '300s'
nginx_resolver_timeout: '5s' nginx_resolver_timeout: '5s'
nginx_error_log_level: 'warn' # http://nginx.org/en/docs/ngx_core_module.html#error_log nginx_error_log_level: 'warn' # http://nginx.org/en/docs/ngx_core_module.html#error_log
nginx_auto_config_httpv2: true nginx_auto_config_httpv2: true
nginx_default_vhost: null nginx_default_site: null
nginx_default_vhost_ssl: null nginx_default_site_ssl: null
nginx_fastcgi_fix_realpath: true nginx_fastcgi_fix_realpath: true
# #
@@ -32,13 +32,7 @@ nginx_helper_dir: '{{ nginx_etc_dir}}/helper'
# #
# PHP # PHP
nginx_php56: false nginx_php: []
nginx_php70: false
nginx_php56_sockets:
- unix_socket: "/run/php5-fpm.sock"
nginx_php70_sockets:
- unix_socket: "/run/php/php7.0-fpm.sock"
nginx_upstreams: []
# #
# Nginx configuration # Nginx configuration
@@ -91,9 +85,14 @@ nginx_http_gzip_disable: '"msie6"'
nginx_custom_http: [] nginx_custom_http: []
# #
# Vhosts # Sites
# #
nginx_vhosts: [] nginx_sites: []
#
# Upstreams
#
nginx_upstreams: []
# #
# htpasswd # htpasswd
@@ -108,7 +107,7 @@ nginx_ssl_pairs: []
# #
# Dynamic modules # Dynamic modules
# #
nginx_dyn_modules: [] nginx_module_packages: []
# #
# Diffie-Hellman # Diffie-Hellman
@@ -117,6 +116,14 @@ nginx_dh: null
nginx_dh_path: '{{ nginx_ssl_dir }}/dhparam.pem' nginx_dh_path: '{{ nginx_ssl_dir }}/dhparam.pem'
nginx_dh_length: 2048 nginx_dh_length: 2048
#
# acme.sh
#
nginx_acmesh: false
nginx_acmesh_dir: "/opt/acme.sh"
nginx_acmesh_git_dir: "/tmp/acme.sh"
nginx_acmesh_test: false
# Extra # Extra
# Note: # Note:

15
doc/acme.md Normal file
View File

@@ -0,0 +1,15 @@
acme.sh
=======
Notes
-----
This feature is experimental.
Variables
---------
- `nginx_acmesh`: (bool) Enable/Disable acme.sh feature
- `nginx_acmesh_dir`: (string) Install directory
- `nginx_acmesh_git_dir`: (string) Git directory (removed after install)
- `nginx_acmesh_test`: (bool) If set to true (default false), uses test mode

View File

@@ -1,10 +1,15 @@
Auth Basic management Auth Basic management
===================== =====================
IMPORTANT
---------
If you use this feature with Debian Stretch, you *MUST* use ansible >= 2.3.2! See: [https://github.com/HanXHX/ansible-nginx/issues/28](#28).
Description Description
----------- -----------
Auth basic is managed in a separate list. Each auth file can be shared between locations or vhosts. Auth basic is managed in a separate list. Each auth file can be shared between locations or sites.
Each htpasswd has few keys: Each htpasswd has few keys:
@@ -19,8 +24,8 @@ Example
------- -------
```yaml ```yaml
nginx_vhosts: nginx_sites:
# htpasswd on all vhost # htpasswd on all site
- name: test.local - name: test.local
htpasswd: 'hello' htpasswd: 'hello'
template: '_base' template: '_base'

View File

@@ -1,18 +1,23 @@
PHP PHP
=== ===
- `nginx_php56` and `nginx_php70`: boolean if you need to preconfigure PHP (default: false) `nginx_php`:
- `nginx_php##_sockets`: list of sockets (see bellow) - `version`: (M) PHP version
- `upstream_name` (O)
- `sockets`: (O) socket list
If `sockets` is not provided, if uses local unix socket (based on PHP version).
You should see [Nginx upstream module doc](http://nginx.org/en/docs/http/ngx_http_upstream_module.html). You should see [Nginx upstream module doc](http://nginx.org/en/docs/http/ngx_http_upstream_module.html).
Each socket have: Each socket have:
- `unix_socket` - `unix`
XOR
- `host` - `host`
- `port` - `port`
- `weight` - `weight`
- `max_fails` - `max_fails`
- `fail_timeout` - `fail_timeout`
With default configuration, it works fine with PHP-FPM.

View File

@@ -1,17 +1,17 @@
Vhost management Site management
================ ===============
You can see many examples in: [tests/test.yml](../tests/test.yml). You can see many examples in: [tests/test.yml](../tests/test.yml).
`nginx_vhosts`: List of dict. A vhost has few keys. See bellow. `nginx_sites`: List of dict. A site has few keys. See bellow.
Common Common
------ ------
- `name`: (M) Domain or list of domain used. - `name`: (M) Domain or list of domain used.
- `template`: (D) template used to create vhost. Optional if you set `delete` to true or using `redirect_tor`. - `template`: (D) template used to create site. Optional if you set `state`=`absent` or using `redirect_to`.
- `filename`: (O) Specify filename in /etc/nginx/sites-*. Do NOT specify default (reserved keyword). It will be used for log filenames and directories creation. - `filename`: (O) Specify filename in /etc/nginx/sites-*. Do NOT specify default (reserved keyword). It will be used for log filenames and directories creation.
- `state`: (O) Vhost status. Can be "present" (default), "absent" and "disabled". - `state`: (O) Site status. Can be "present" (default), "absent" and "disabled".
- `redirect_from`: (O) Domain list to redirect to the first `name`. You can use this key to redirect non-www to www - `redirect_from`: (O) Domain list to redirect to the first `name`. You can use this key to redirect non-www to www
- `redirect_to`: (O) Redirect all requests to this domain. Please set scheme (http:// or https:// or $sheme). - `redirect_to`: (O) Redirect all requests to this domain. Please set scheme (http:// or https:// or $sheme).
- `headers`: (O) Set additionals header as key/value list. You can append "always" to the value. Show [nginx doc](http://nginx.org/en/docs/http/ngx_http_headers_module.html). - `headers`: (O) Set additionals header as key/value list. You can append "always" to the value. Show [nginx doc](http://nginx.org/en/docs/http/ngx_http_headers_module.html).
@@ -23,7 +23,7 @@ Common
- `upstream_params`: (O) Add upstream params (useful when you want to pass variables to PHP) - `upstream_params`: (O) Add upstream params (useful when you want to pass variables to PHP)
- `override_try_files`: (O) overrides default try\_files defined in template - `override_try_files`: (O) overrides default try\_files defined in template
- `manage_local_content`: (O) Boolean. Set to false if you do not want to manage local content (images, css...). This option is useless if you use `_proxy` template or `redirect_to` feature. - `manage_local_content`: (O) Boolean. Set to false if you do not want to manage local content (images, css...). This option is useless if you use `_proxy` template or `redirect_to` feature.
- `htpasswd`: (O) References name key in `nginx_htpasswd`. Enable auth basic on all vhost. Set "false" to disable. - `htpasswd`: (O) References name key in `nginx_htpasswd`. Enable auth basic on all site. Set "false" to disable.
- `proto`: (O) list of protocol used. Default is a list with "http". If you need http and https, you must set a list with "http" and "https". You can only set "https" without http support. - `proto`: (O) list of protocol used. Default is a list with "http". If you need http and https, you must set a list with "http" and "https". You can only set "https" without http support.
- `ssl_name`: (D) name of the key used when using TLS/SSL. Optional when `proto` contains "https". If you don't set this value, it will search by `name`. - `ssl_name`: (D) name of the key used when using TLS/SSL. Optional when `proto` contains "https". If you don't set this value, it will search by `name`.
- `ssl_template` (O) "strong" (default) or "legacy". You can disable SSL helpers and add your own directives by setting "false". - `ssl_template` (O) "strong" (default) or "legacy". You can disable SSL helpers and add your own directives by setting "false".
@@ -57,17 +57,17 @@ About proxy template
Proxy template allow you to use Nginx as reverse proxy. Usefull when you have an application service such as Redmine, Jenkins... Proxy template allow you to use Nginx as reverse proxy. Usefull when you have an application service such as Redmine, Jenkins...
You have many key added to vhost key: You have many key added to site key:
- `upstream_name`: (O) upstream name used to pass proxy - `upstream_name`: (O) upstream name used to pass proxy
- `proxy_params`: (M) list of raw params passed to the vhost - `proxy_params`: (M) list of raw params passed to the site
(O) : Optional (O) : Optional
Default vhosts Default sites
-------------- --------------
You can manage default vhost by setting domain name to these variables. You can manage default site by setting domain name to these variables.
- `nginx_default_vhost` - `nginx_default_site`
- `nginx_default_vhost_ssl` - `nginx_default_site_ssl`

View File

@@ -33,7 +33,7 @@ Tips
---- ----
- Deploying key/cert is not mandatory with this role. You can manage it in other place ([letsencrypt](https://letsencrypt.org/)? :)). You just need to set `dest_cert` and `dest_key`! - Deploying key/cert is not mandatory with this role. You can manage it in other place ([letsencrypt](https://letsencrypt.org/)? :)). You just need to set `dest_cert` and `dest_key`!
- In `nginx_vhosts`, `ssl_name` is mandatory. This role will search in `nginx_ssl_pairs` with vhost `name` (first in list if it's a list). - In `nginx_sites`, `ssl_name` is mandatory. This role will search in `nginx_ssl_pairs` with site `name` (first in list if it's a list).
Diffie-Hellman Diffie-Hellman
-------------- --------------
@@ -44,7 +44,7 @@ Example
------- -------
```yaml ```yaml
nginx_vhosts; nginx_sites;
- name: 'test-ssl.local' - name: 'test-ssl.local'
proto: ['http', 'https'] proto: ['http', 'https']
template: '_base' template: '_base'
@@ -52,6 +52,9 @@ nginx_vhosts;
- name: 'test-ssl2.local' - name: 'test-ssl2.local'
proto: ['http', 'https'] proto: ['http', 'https']
template: '_base' template: '_base'
- name: 'test-ssl3.local'
proto: ['http', 'https']
template: '_base'
nginx_ssl_pairs: nginx_ssl_pairs:
- name: mysuperkey - name: mysuperkey
@@ -64,14 +67,6 @@ nginx_ssl_pairs:
....(snip).... ....(snip)....
-----END CERTIFICATE----- -----END CERTIFICATE-----
- name: test-ssl2.local - name: test-ssl2.local
key: | acme: true
-----BEGIN RSA PRIVATE KEY-----
....(snip)....
-----END RSA PRIVATE KEY-----
cert: |
-----BEGIN CERTIFICATE-----
....(snip)....
-----END CERTIFICATE-----
``` ```

View File

@@ -8,7 +8,7 @@ Note: Few params are unavailable on old Nginx version. But this role do _not_ pu
Upstream params Upstream params
--------------- ---------------
- `name`: upstream name. Can be use in vhost with *proxy_pass http://upstream_name* - `name`: upstream name. Can be use in site with *proxy_pass http://upstream_name*
- `params`: list of param (hash, zone...) - `params`: list of param (hash, zone...)
- `servers`: each upstream MUST have at least 1 server - `servers`: each upstream MUST have at least 1 server
- `state`: Optional. Can be 'absent' or 'present' - `state`: Optional. Can be 'absent' or 'present'

20
filter_plugins/nginx.py Normal file
View File

@@ -0,0 +1,20 @@
def nginx_site_filename(site):
if site.has_key('filename'):
return site['filename']
else:
return nginx_site_name(site)
def nginx_site_name(site):
if isinstance(site['name'], list):
return site['name'][0]
else:
return site['name']
class FilterModule(object):
''' Nginx module '''
def filters(self):
return {
'nginx_site_filename': nginx_site_filename,
'nginx_site_name': nginx_site_name
}

25
filter_plugins/php.py Normal file
View File

@@ -0,0 +1,25 @@
def php_default_upstream_socket(php_version):
if php_version == '5.6':
return '/run/php5-fpm.sock'
else:
return '/run/php/php%s-fpm.sock' % php_version
def php_default_upstream_name(php_version):
return 'default_php_%s' % php_version
def php_fpm_service(php_version):
if php_version == '5.6':
return 'php5-fpm'
else:
return 'php%s-fpm' % php_version
class FilterModule(object):
''' PHP module '''
def filters(self):
return {
'php_default_upstream_socket': php_default_upstream_socket,
'php_default_upstream_name': php_default_upstream_name,
'php_fpm_service': php_fpm_service,
'php_fpm_package': php_fpm_service
}

View File

@@ -1,13 +1,28 @@
--- ---
# Reload wrapper
- name: reload nginx - name: reload nginx
command: nginx -t command: nginx -t
notify: real-reload nginx notify: real-reload nginx
- name: restart nginx
command: nginx -t
notify: real-restart nginx
- name: real-reload nginx - name: real-reload nginx
service: name=nginx state=reloaded service:
name: nginx
state: reloaded
- name: real-restart nginx
service:
name: nginx
state: restarted
- name: restart nginx freebsd - name: restart nginx freebsd
service: name=nginx state=restarted service:
name: nginx
state: restarted
when: ansible_distribution == "FreeBSD" when: ansible_distribution == "FreeBSD"
- name: setup
action: setup

View File

@@ -4,7 +4,7 @@ galaxy_info:
description: Nginx for Debian description: Nginx for Debian
company: company:
license: GPLv2 license: GPLv2
min_ansible_version: 2.0 min_ansible_version: 2.2
platforms: platforms:
- name: Debian - name: Debian
versions: versions:

View File

@@ -1,29 +1,29 @@
--- ---
- name: TEMPLATE | Deploy nginx.conf - name: TEMPLATE | Deploy nginx.conf
template: > template:
src=etc/nginx/nginx.conf.j2 src: "etc/nginx/nginx.conf.j2"
dest="{{ nginx_etc_dir }}/nginx.conf" dest: "{{ nginx_etc_dir }}/nginx.conf"
notify: reload nginx notify: reload nginx
- name: TEMPLATE | Deploy all helpers - name: TEMPLATE | Deploy all helpers
template: > template:
src={{ item }} src: "{{ item }}"
dest={{ nginx_helper_dir }}/{{ item | basename | regex_replace('\.j2$','') }} dest: "{{ nginx_helper_dir }}/{{ item | basename | regex_replace('.j2$','') }}"
with_fileglob: '../templates/etc/nginx/helper/*.j2' with_fileglob: '../templates/etc/nginx/helper/*.j2'
notify: reload nginx notify: reload nginx
- name: TEMPLATE | Deploy custom http configuration - name: TEMPLATE | Deploy custom http configuration
template: > template:
src=etc/nginx/conf.d/custom.conf.j2 src: "etc/nginx/conf.d/custom.conf.j2"
dest="{{ nginx_etc_dir }}/conf.d/custom.conf" dest: "{{ nginx_etc_dir }}/conf.d/custom.conf"
notify: reload nginx notify: reload nginx
- name: LINEINFILE | Fix path - name: LINEINFILE | Fix path
lineinfile: > lineinfile:
regexp='{{ item.0.regexp }}' regexp: '{{ item.0.regexp }}'
line='{{ item.0.line }}' line: '{{ item.0.line }}'
dest='{{ item.1 }}' dest: '{{ item.1 }}'
with_nested: with_nested:
- -
- regexp: '^fastcgi_param SCRIPT_FILENAME' - regexp: '^fastcgi_param SCRIPT_FILENAME'

View File

@@ -1,25 +0,0 @@
---
- name: FAIL | If Dynamic module is not available
fail: msg="{{ item }} dynamic module is not available"
with_items: "{{ nginx_dyn_modules }}"
when: "'{{ item }}=dynamic' not in nginx_modules"
- name: APT | Install nginx modules
apt: >
pkg="libnginx-mod-{{ item | replace('_', '-') }}"
state=present
default_release={{ ansible_distribution_release + '-backports' if nginx_backports else ansible_distribution_release }}
with_items: "{{ nginx_dyn_modules }}"
when: ansible_distribution == 'Debian'
- name: FILE | Creates modules directories
file: >
path="{{ nginx_etc_dir}}/{{ item }}"
state=directory
mode=0755
owner=root
group=root
with_items: ['modules-available', 'modules-enabled']
# TODO: manage freebsd

View File

@@ -1,19 +1,19 @@
--- ---
- name: FILE | Delete htpasswd file - name: FILE | Delete htpasswd file
file: > file:
path={{ nginx_htpasswd_dir }}/{{ item.name }} path: "{{ nginx_htpasswd_dir }}/{{ item.name }}"
state=absent state: absent
with_items: "{{ nginx_htpasswd }}" with_items: "{{ nginx_htpasswd }}"
when: item.state is defined and item.state == 'absent' when: item.state is defined and item.state == 'absent'
no_log: true no_log: true
- name: HTPASSWD | Manage files - name: HTPASSWD | Manage files
htpasswd: > htpasswd:
name={{ item.1.name }} name: "{{ item.1.name }}"
password={{ item.1.password }} password: "{{ item.1.password }}"
state={{ item.1.state | default('present') }} state: "{{ item.1.state | default('present') }}"
path={{ nginx_htpasswd_dir }}/{{ item.0.name }} path: "{{ nginx_htpasswd_dir }}/{{ item.0.name }}"
with_subelements: with_subelements:
- "{{ nginx_htpasswd }}" - "{{ nginx_htpasswd }}"
- users - users

View File

@@ -1,23 +1,42 @@
--- ---
- name: FAIL | Check possible issues
fail:
msg: "This ansible version ({{ ansible_version.full}}) is not compatible with your needs (Debian Stretch + htpasswd). Please see https://github.com/HanXHX/ansible-nginx/issues/28"
when:
ansible_distribution_major_version | version_compare('9', 'ge') and
ansible_version.full | version_compare('2.3.2', 'lt') and
nginx_htpasswd | length > 0
- name: APT | Update cache - name: APT | Update cache
apt: > apt:
update_cache=yes update_cache: yes
cache_valid_time=3600 cache_valid_time: 3600
changed_when: false changed_when: false
- name: APT | Force OpenSSL from backports (fix dependency break) - name: APT | Force OpenSSL from backports (fix dependency break)
apt: > apt:
pkg=openssl pkg: openssl
state=latest state: latest
default_release={{ ansible_distribution_release + '-backports' }} default_release: "{{ ansible_distribution_release + '-backports' }}"
when: nginx_backports when: nginx_backports
- name: APT | Install nginx and dependencies - name: APT | Install nginx and dependencies
apt: > apt:
pkg={{ nginx_apt_package }} pkg: "{{ nginx_apt_package }}"
state=present state: present
default_release={{ ansible_distribution_release + '-backports' if nginx_backports else ansible_distribution_release }} default_release: "{{ ansible_distribution_release + '-backports' if nginx_backports else ansible_distribution_release }}"
- name: APT | Install nginx modules
apt:
pkg: "{{ item }}"
state: present
with_items: "{{ nginx_module_packages }}"
when:
ansible_distribution_major_version | version_compare('9', 'ge') or
nginx_backports
- name: APT | Install python-passlib - name: APT | Install python-passlib
apt: pkg=python-passlib state=present apt:
pkg: python-passlib
state: present

View File

@@ -1,21 +1,26 @@
--- ---
- name: PKGNG | Install nginx and related tools - name: PKGNG | Install nginx and related tools
pkgng: name={{ item }} state=present pkgng:
name: "{{ item }}"
state: present
with_items: with_items:
- "{{ nginx_pkgng_package }}" - "{{ nginx_pkgng_package }}"
- py27-passlib - py27-passlib
- curl - curl
- name: FILE | Create configuration dir (like Debian) - name: FILE | Create configuration dir (like Debian)
file: path="{{ nginx_etc_dir }}/{{ item }}" state=directory file:
path: "{{ nginx_etc_dir }}/{{ item }}"
state: directory
with_items: with_items:
- conf.d - conf.d
- sites-available - sites-available
- sites-enabled - sites-enabled
- name: STAT | Check fastcgi.conf - name: STAT | Check fastcgi.conf
stat: path={{ nginx_etc_dir }}/fastcgi.conf stat:
path: "{{ nginx_etc_dir }}/fastcgi.conf"
register: conf register: conf
- name: COPY | config - name: COPY | config
@@ -24,23 +29,25 @@
notify: reload nginx notify: reload nginx
- name: LINEINFILE | Add fastcgi config - name: LINEINFILE | Add fastcgi config
lineinfile: > lineinfile:
line="fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;" line: "fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;"
dest="{{ nginx_etc_dir }}/fastcgi.conf" dest: "{{ nginx_etc_dir }}/fastcgi.conf"
notify: reload nginx notify: reload nginx
- name: COPY | Populate proxy_params - name: COPY | Populate proxy_params
copy: > copy:
content="proxy_set_header Host $http_host;\nproxy_set_header X-Real-IP $remote_addr;\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;" content: "proxy_set_header Host $http_host;\nproxy_set_header X-Real-IP $remote_addr;\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;"
dest="{{ nginx_etc_dir }}/proxy_params" dest: "{{ nginx_etc_dir }}/proxy_params"
- name: FILE | Create log directory - name: FILE | Create log directory
file: > file:
path={{ nginx_log_dir }} path: "{{ nginx_log_dir }}"
owner={{ nginx_user }} owner: "{{ nginx_user }}"
group=wheel group: wheel
mode=0755 mode: 0755
state=directory state: directory
- name: SERVICE | Enable nginx - name: SERVICE | Enable nginx
service: name=nginx enabled=yes service:
name: nginx
enabled: yes

View File

@@ -2,16 +2,15 @@
- name: INCLUDE_VARS | Related to OS - name: INCLUDE_VARS | Related to OS
include_vars: "{{ ansible_distribution }}.yml" include_vars: "{{ ansible_distribution }}.yml"
tags: ['nginx::site', 'nginx::ssl']
- name: INCLUDE | Install - name: INCLUDE | Install
include: install_{{ ansible_distribution }}.yml include: "install_{{ ansible_distribution }}.yml"
tags: ['nginx::site', 'nginx::ssl']
- name: INCLUDE | Prepare - name: INCLUDE | Prepare
include: prepare.yml include: prepare.yml
tags: ['nginx::site', 'nginx::ssl']
- name: INCLUDE | Manage dynamic modules
include: dyn_modules.yml
when: nginx_version.stdout | version_compare('1.9.11', 'ge')
- name: INCLUDE | Install - name: INCLUDE | Install
include: config.yml include: config.yml
@@ -23,8 +22,9 @@
include: htpasswd.yml include: htpasswd.yml
- name: INCLUDE | SSL configuration - name: INCLUDE | SSL configuration
include: ssl.yml include: ssl/main.yml
tags: ['nginx::ssl']
- name: INCLUDE | Vhosts configuration
include: vhost.yml
- name: INCLUDE | Sites configuration
include: site.yml
tags: ['nginx::site']

View File

@@ -6,6 +6,7 @@
executable: /bin/sh executable: /bin/sh
register: nginx_version register: nginx_version
changed_when: false changed_when: false
check_mode: no
- name: SHELL | Get module list - name: SHELL | Get module list
shell: nginx -V 2>&1 | tr -- - '\n' | grep -A 1 with | grep _module | sed -r 's/_module//g; s/\s+//g' | sort shell: nginx -V 2>&1 | tr -- - '\n' | grep -A 1 with | grep _module | sed -r 's/_module//g; s/\s+//g' | sort
@@ -13,14 +14,21 @@
executable: /bin/sh executable: /bin/sh
register: shell_modules register: shell_modules
changed_when: false changed_when: false
check_mode: no
- name: SET_FACT | Save modules - name: SET_FACT | Save modules
set_fact: set_fact:
nginx_modules: "{{ shell_modules.stdout_lines }}" nginx_modules: "{{ shell_modules.stdout_lines }}"
- name: FILE | Create folders - name: FILE | Create folders
file: dest="{{ item.dir }}" owner="{{ item.owner }}" mode="{{ item.mode }}" state=directory file:
dest: "{{ item.dir }}"
owner: "{{ item.owner }}"
mode: "{{ item.mode }}"
state: directory
with_items: "{{ nginx_dirs }}" with_items: "{{ nginx_dirs }}"
- name: FILE | Create ansible facts dir - name: FILE | Create ansible facts dir
file: path=/etc/ansible/facts.d state=directory file:
path: /etc/ansible/facts.d
state: directory

106
tasks/site.yml Normal file
View File

@@ -0,0 +1,106 @@
---
- name: FAIL | Check filenames
fail:
msg: "Forbidden keyword default on site {{ item | nginx_site_name }}"
when: item.filename is defined and item.filename == 'default'
with_items: "{{ nginx_sites }}"
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FAIL | Check HTTPS redir and proto
fail:
msg: "You can't have HTTP proto and HTTPS redirection at the same time"
when:
((item.proto is defined and 'http' in item.proto) or (item.proto is not defined)) and
(item.redirect_http is defined and item.redirect_http)
with_items: "{{ nginx_sites }}"
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Create root directory
file:
path: "{{ nginx_root }}"
state: directory
- name: FILE | Create root public folders (foreach nginx_sites)
file:
path: "{{ nginx_root }}/{{ item | nginx_site_filename }}/public"
state: directory
owner: "{{ item.owner | default(nginx_user) }}"
group: "{{ item.group | default(nginx_user) }}"
mode: "{{ item.mode | default('0755') }}"
with_items: "{{ nginx_sites }}"
when: >
item.root is not defined and
(item.template is defined and item.template not in nginx_templates_no_dir) and
(item.state is not defined or not item.state != 'absent') and
item.redirect_to is not defined
loop_control:
label: "{{ item | nginx_site_name }}"
- name: TEMPLATE | Create sites
template:
src: "etc/nginx/sites-available/{{ item.template if item.redirect_to is not defined else '_redirect' }}.j2"
dest: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}"
with_items: "{{ nginx_sites }}"
notify: ['reload nginx', 'restart nginx freebsd']
when: item.state is not defined or item.state != 'absent'
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Delete sites
file:
path: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}"
state: absent
with_nested:
- "{{ nginx_sites }}"
- ['sites-available', 'sites-enabled']
notify: ['reload nginx', 'restart nginx freebsd']
when: item.0.state is defined and item.0.state == 'absent'
loop_control:
label: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}"
- name: FILE | Enable sites
file:
src: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}"
dest: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_filename }}"
state: link
with_items: "{{ nginx_sites }}"
notify: ['reload nginx', 'restart nginx freebsd']
when: >
item.state is not defined or item.state == 'present'
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Disable sites
file:
path: "{{ nginx_etc_dir}}/sites-enabled/{{ item | nginx_site_filename }}"
state: absent
with_items: "{{ nginx_sites }}"
notify: ['reload nginx', 'restart nginx freebsd']
when: item.state is defined and item.state == 'disabled'
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Delete default site when explicitely defined
file:
path: "{{ nginx_etc_dir }}/sites-enabled/default"
state: absent
notify: ['reload nginx', 'restart nginx freebsd']
when: nginx_default_site is not none
- name: FILE | Auto set default site
file:
src: "{{ nginx_etc_dir }}/sites-available/default"
dest: "{{ nginx_etc_dir }}/sites-enabled/default"
state: link
notify: ['reload nginx', 'restart nginx freebsd']
when: nginx_default_site is none
- name: TEMPLATE | Deploy facts
template:
src: etc/ansible/facts.d/nginx.fact.j2
dest: /etc/ansible/facts.d/nginx.fact
mode: 0644
notify: ['setup']

83
tasks/ssl/acme.yml Normal file
View File

@@ -0,0 +1,83 @@
---
- name: APT | Install git
apt: pkg=git
- name: SET_FACT | Assign default..
set_fact:
acme_create: []
- name: STAT | Check acme.sh is installed
stat:
path: "{{ nginx_acmesh_dir }}"
register: acme
- block:
- name: GIT | Get acme.sh
git:
repo: 'https://github.com/Neilpang/acme.sh.git'
dest: '{{ nginx_acmesh_git_dir }}'
update: no
- name: SHELL | Install acme.sh
shell: ./acme.sh --install --home {{ nginx_acmesh_dir }} --cert-home {{ nginx_acmesh_dir }}
args:
chdir: "{{ nginx_acmesh_git_dir }}"
creates: "{{ nginx_acmesh_dir }}"
when: not acme.stat.exists
- name: STAT | Check if certificates are already installed
stat:
path: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.crt"
with_items: "{{ nginx_ssl_pairs }}"
when: item.acme is defined and item.acme
register: acme_installed_certs
- name: SET_FACT | Assign var with certificates to create
set_fact:
acme_create: "{{ acme_create | default([]) + [ (item.item | combine({'listen': ([item.item.acme_port|default(80)]) }) ) ] }}"
with_items: "{{ acme_installed_certs.results }}"
when: item.skipped is not defined and not item.stat.exists
- name: TEMPLATE | Create fake site
template:
src: "etc/nginx/sites-available/_base.j2"
dest: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf"
with_items: "{{ acme_create }}"
register: fake_site
- name: SERVICE | Reload nginx
service:
name: nginx
state: reloaded
when: fake_site.changed
- name: SHELL | Get certificates
shell: '{{ nginx_acmesh_bin }} --issue{% if item.name is string %} -d {{ item.name }}{% else %}{% for name in item.name %} -d {{ name }}{% endfor %}{% endif %} --nginx {% if nginx_acmesh_test %}--test{% endif %}'
args:
creates: "/root/.acme.sh/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.key"
with_items: "{{ acme_create }}"
register: acme_get
failed_when: acme_get.rc != 0 and acme_get.rc != 2
no_log: true
- name: FILE | Create SSL dir per site
file:
path: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}"
with_items: "{{ acme_create }}"
- name: SHELL | Install certificates
shell: '{{ nginx_acmesh_bin }} --install-cert -d {{ item | nginx_site_name }} --fullchain-file {{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.crt --key-file {{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.key'
args:
creates: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}/{{ item | nginx_site_name }}.key"
with_items: "{{ nginx_ssl_pairs }}"
when: item.acme is defined and item.acme
notify: restart nginx
- name: FILE | Delete fake sites
file:
path: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf"
state: absent
with_items: "{{ acme_create }}"

8
tasks/ssl/main.yml Normal file
View File

@@ -0,0 +1,8 @@
---
- name: INCLUDE | standard.yml
include: standard.yml
- name: INCLUDE | acme.yml
include: acme.yml
when: nginx_acmesh

View File

@@ -5,48 +5,49 @@
args: args:
creates: "{{ nginx_dh_path }}" creates: "{{ nginx_dh_path }}"
when: nginx_dh is not string when: nginx_dh is not string
notify: reload nginx notify: restart nginx
async: 1000 async: 1000
register: dh register: dh
- name: COPY | Deploy DH file from vars - name: COPY | Deploy DH file from vars
copy: > copy:
content="{{ nginx_dh }}" content: "{{ nginx_dh }}"
dest="{{ nginx_dh_path }}" dest: "{{ nginx_dh_path }}"
when: nginx_dh is string when: nginx_dh is string
notify: reload nginx notify: restart nginx
- name: FILE | Create SSL directories - name: FILE | Create SSL directories
file: > file:
path="{{ nginx_ssl_dir + '/' + item.name }}" path: "{{ nginx_ssl_dir + '/' + item.name }}"
state=directory state: directory
with_items: "{{ nginx_ssl_pairs }}" with_items: "{{ nginx_ssl_pairs }}"
when: item.dest_key is not defined or item.dest_cert is not defined when: item.dest_key is not defined or item.dest_cert is not defined
no_log: true no_log: true
- name: COPY | Deploy SSL keys - name: COPY | Deploy SSL keys
copy: > copy:
content="{{ item.key }}" content: "{{ item.key }}"
dest="{{ nginx_ssl_dir + '/' + item.name + '/' + item.name + '.key' if item.dest_key is not defined else item.dest_key }}" dest: "{{ nginx_ssl_dir + '/' + item.name + '/' + item.name + '.key' if item.dest_key is not defined else item.dest_key }}"
mode=0640 mode: 0640
with_items: "{{ nginx_ssl_pairs }}" with_items: "{{ nginx_ssl_pairs }}"
when: item.key is defined when: item.key is defined
notify: reload nginx notify: restart nginx
no_log: true no_log: true
- name: COPY | Deploy SSL certs - name: COPY | Deploy SSL certs
copy: > copy:
content="{{ item.cert }}" content: "{{ item.cert }}"
dest="{{ nginx_ssl_dir + '/' + item.name + '/' + item.name + '.crt' if item.dest_cert is not defined else item.dest_cert }}" dest: "{{ nginx_ssl_dir + '/' + item.name + '/' + item.name + '.crt' if item.dest_cert is not defined else item.dest_cert }}"
mode=0644 mode: 0644
with_items: "{{ nginx_ssl_pairs }}" with_items: "{{ nginx_ssl_pairs }}"
when: item.cert is defined when: item.cert is defined
notify: reload nginx notify: restart nginx
no_log: true no_log: true
- name: Check DH command status - name: Check DH command status
async_status: jid={{ dh.ansible_job_id }} async_status:
jid: "{{ dh.ansible_job_id }}"
register: job_result register: job_result
until: job_result.finished until: job_result.finished
retries: 30 retries: 30
when: nginx_dh is not string when: not ansible_check_mode and nginx_dh is not string

View File

@@ -1,29 +1,30 @@
--- ---
- name: SET_FACT | Backward compatibility with old version of this role
set_fact: >
nginx_php56: true
when: nginx_php is defined and nginx_php
- name: TEMPLATE | Deploy PHP upstream to Nginx - name: TEMPLATE | Deploy PHP upstream to Nginx
template: > template:
src=etc/nginx/upstream/php.conf.j2 src: "etc/nginx/conf.d/php.conf.j2"
dest="{{ nginx_etc_dir }}/conf.d/php.conf" dest: "{{ nginx_etc_dir }}/conf.d/php.conf"
when: nginx_php56 or nginx_php70 when: nginx_php | length > 0
notify: reload nginx notify: reload nginx
- name: FILE | Delete PHP upstream
file:
path: "{{ nginx_etc_dir }}/conf.d/php.conf"
state: absent
when: nginx_php | length == 0
- name: TEMPLATE | Deploy other upstreams - name: TEMPLATE | Deploy other upstreams
template: > template:
src=etc/nginx/upstream/upstream.conf.j2 src: "etc/nginx/conf.d/_upstream.conf.j2"
dest={{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf dest: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf"
with_items: "{{ nginx_upstreams }}" with_items: "{{ nginx_upstreams }}"
when: item.state is not defined or item.state == 'present' when: item.state is not defined or item.state == 'present'
notify: reload nginx notify: reload nginx
- name: FILE | Delete other upstreams - name: FILE | Delete other upstreams
file: > file:
path={{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf path: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf"
state=absent state: absent
with_items: "{{ nginx_upstreams }}" with_items: "{{ nginx_upstreams }}"
when: item.state is defined and item.state == 'absent' when: item.state is defined and item.state == 'absent'
notify: reload nginx notify: reload nginx

View File

@@ -1,90 +0,0 @@
---
- name: FAIL | Check filenames
fail: msg="Forbidden keyword default on vhost {{ item.name if item.name is string else item.name[0] }}"
when: item.filename is defined and item.filename == 'default'
with_items: "{{ nginx_vhosts }}"
- name: FAIL | Check HTTPS redir and proto
fail: msg="You can't have HTTP proto and HTTPS redirection at the same time"
when: >
((item.proto is defined and 'http' in item.proto) or (item.proto is not defined)) and
(item.redirect_http is defined and item.redirect_http)
with_items: "{{ nginx_vhosts }}"
- name: FILE | Create root directory
file: >
path={{ nginx_root }}
state=directory
- name: FILE | Create root public folders (foreach nginx_vhosts)
file: >
path={{ nginx_root }}/{{ item.filename | default(item.name if item.name is string else item.name[0]) }}/public
state=directory
owner={{ item.owner | default(nginx_user) }}
group={{ item.group | default(nginx_user) }}
mode={{ item.mode | default('0755') }}
with_items: "{{ nginx_vhosts }}"
when: >
item.root is not defined and
(item.template is defined and item.template not in nginx_templates_no_dir) and
(item.state is not defined or not item.state != 'absent') and
item.redirect_to is not defined
- name: TEMPLATE | Create vhosts
template: >
src=etc/nginx/sites-available/{{ item.template if item.redirect_to is not defined else '_redirect' }}.j2
dest={{ nginx_etc_dir }}/sites-available/{{ item.filename | default(item.name if item.name is string else item.name[0]) }}
with_items: "{{ nginx_vhosts }}"
notify: ['reload nginx', 'restart nginx freebsd']
when: item.state is not defined or item.state != 'absent'
- name: FILE | Delete vhosts
file: path={{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0.filename | default(item.0.name if item.0.name is string else item.0.name[0]) }} state=absent
with_nested:
- "{{ nginx_vhosts }}"
- ['sites-available', 'sites-enabled']
notify: ['reload nginx', 'restart nginx freebsd']
when: item.state is defined and item.state == 'absent'
- name: FILE | Enable vhosts
file: >
src={{ nginx_etc_dir }}/sites-available/{{ item.filename | default(item.name if item.name is string else item.name[0]) }}
dest={{ nginx_etc_dir }}/sites-enabled/{{ item.filename | default(item.name if item.name is string else item.name[0]) }}
state=link
with_items: "{{ nginx_vhosts }}"
notify: ['reload nginx', 'restart nginx freebsd']
when: >
item.state is not defined or item.state == 'present'
- name: FILE | Disable vhosts
file: path={{ nginx_etc_dir}}/sites-enabled/{{ item.filename | default(item.name if item.name is string else item.name[0]) }} state=absent
with_items: "{{ nginx_vhosts }}"
notify: ['reload nginx', 'restart nginx freebsd']
when: item.state is defined and item.state == 'disabled'
- name: FILE | Delete default vhost when explicitely defined
file: >
path={{ nginx_etc_dir }}/sites-enabled/default
state=absent
notify: ['reload nginx', 'restart nginx freebsd']
when: nginx_default_vhost is not none
- name: FILE | Auto set default vhost
file: >
src={{ nginx_etc_dir }}/sites-available/default
dest={{ nginx_etc_dir }}/sites-enabled/default
state=link
notify: ['reload nginx', 'restart nginx freebsd']
when: nginx_default_vhost is none
- name: TEMPLATE | Deploy facts
template:
src=etc/ansible/facts.d/nginx.fact.j2
dest=/etc/ansible/facts.d/nginx.fact
mode=0644
register: fact
- name: SETUP
action: setup
when: fact.changed

View File

@@ -1,4 +1,4 @@
{ {
"fact_nginx_vhosts": "fact_nginx_sites":
{{ nginx_vhosts | to_nice_json(indent=8) }} {{ nginx_sites | to_nice_json(indent=8) }}
} }

View File

@@ -0,0 +1,20 @@
#
# {{ ansible_managed }}
#
{% for php in nginx_php %}
upstream {{ php.upstream_name | default((php.version | php_default_upstream_name)) }} {
{% for sock in php.sockets | default([]) %}
{% if php.host is defined %}
server {{ sock.host }}:{{ sock.port }} weight={{ sock.weight | default('1') }} max_fails={{ sock.max_fails | default('5') }} fail_timeout={{ sock.fail_timeout | default('10s') }};
{% else %}
server unix:{{ sock.unix | default((php.version | php_default_upstream_socket)) }} weight={{ sock.weight | default('1') }};
{% endif %}
{% else %}
server unix:{{ php.version | php_default_upstream_socket }} weight=1;
{% endfor %}
}
{% endfor %}
# vim:filetype=nginx

View File

@@ -1,5 +1,5 @@
{% set __proto = item.proto | default(['http']) %} {% set __proto = item.proto | default(['http']) %}
{% set __main_name = item.filename | default(item.name if item.name is string else item.name[0]) %} {% set __main_name = item | nginx_site_filename %}
{% set __listen = item.listen | default([80]) %} {% set __listen = item.listen | default([80]) %}
{% set __listen_ssl = item.listen_ssl | default([443]) %} {% set __listen_ssl = item.listen_ssl | default([443]) %}
{% set __http_proxy_protocol_port = item.http_proxy_protocol_port | default([]) %} {% set __http_proxy_protocol_port = item.http_proxy_protocol_port | default([]) %}
@@ -42,12 +42,12 @@ server {
server { server {
{% if 'http' in __proto %} {% if 'http' in __proto %}
{% for port in __listen %} {% for port in __listen %}
listen {{ port }}{% if nginx_default_vhost == __main_name %} default_server{% endif %}{% if port | int in __http_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }}{% if nginx_default_site == __main_name %} default_server{% endif %}{% if port | int in __http_proxy_protocol_port %} proxy_protocol{% endif %};
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if 'https' in __proto %} {% if 'https' in __proto %}
{% for port in __listen_ssl %} {% for port in __listen_ssl %}
listen {{ port }}{% if nginx_default_vhost_ssl == __main_name %} default_server{% endif %} ssl{% if nginx_auto_config_httpv2 and 'http_v2' in nginx_modules %} http2{% endif %}{% if port | int in __https_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }}{% if nginx_default_site_ssl == __main_name %} default_server{% endif %} ssl{% if nginx_auto_config_httpv2 and 'http_v2' in nginx_modules %} http2{% endif %}{% if port | int in __https_proxy_protocol_port %} proxy_protocol{% endif %};
{% endfor %} {% endfor %}
{{ ssl(__ssl_name) }} {{ ssl(__ssl_name) }}
{% if item.ssl_template is not defined or item.ssl_template != false %} {% if item.ssl_template is not defined or item.ssl_template != false %}
@@ -170,7 +170,7 @@ server {
listen {{ port }}{% if port | int in __http_proxy_protocol_port %} proxy_protocol{% endif %}; listen {{ port }}{% if port | int in __http_proxy_protocol_port %} proxy_protocol{% endif %};
{% endfor %} {% endfor %}
server_name {% if item.redirect_from is string %}{{ item.redirect_from }}{% else %}{{ "\n\t\t" }}{{ item.redirect_from | join("\n\t\t") }}{% endif %}; server_name {% if item.redirect_from is string %}{{ item.redirect_from }}{% else %}{{ "\n\t\t" }}{{ item.redirect_from | join("\n\t\t") }}{% endif %};
return 301 $scheme://{{ __main_name }}$request_uri; return 301 $scheme://{{ item.name if item.name is string else item.name[0] }}$request_uri;
} }
{% endif %} {% endif %}

View File

@@ -1,22 +1,14 @@
{% extends "_base.j2" %} {% extends "_base.j2" %}
{% macro phpv(version) %}
{% if version == 56 or version == "56" or version == "5.6" %}
{{ nginx_upstream_php56 -}}
{% elif version == 70 or version == "70" or version == "7.0" %}
{{ nginx_upstream_php70 -}}
{% else %}
{# Hack... define another upstream #}
{{ version -}}
{% endif %}
{%- endmacro -%}
{% if item.php_version is defined %} {% if item.php_version is defined %}
{% set php_upstream = phpv(item.php_version) %} {% set php_info = 'Explicit PHP version on site' %}
{% elif nginx_php56 %} {% set php_upstream = (nginx_php|selectattr('version', 'equalto', item.php_version)|first).upstream_name | default(item.php_version | php_default_upstream_name) %}
{% set php_upstream = phpv(56) %} {% elif item.php_upstream is defined %}
{% elif nginx_php70 %} {% set php_info = 'Explicit Nginx/PHP upstream on site' %}
{% set php_upstream = phpv(70) %} {% set php_upstream = item.php_upstream %}
{% else %}
{% set php_info = 'Warning: using first PHP version on config' %}
{% set php_upstream = nginx_php.0.upstream_name | default(nginx_php.0.version | php_default_upstream_name) %}
{% endif %} {% endif %}
{% block template_index %} {% block template_index %}
@@ -24,11 +16,12 @@
{% endblock %} {% endblock %}
{% block template_try_files %} {% block template_try_files %}
try_files {{ override_try_files | default('$uri $uri/ /index.php') }}; try_files {{ override_try_files | default('$uri $uri/ =404') }};
{% endblock %} {% endblock %}
{% block template_upstream_location %} {% block template_upstream_location %}
location ~ \.php$ { location ~ \.php$ {
# {{ php_info }}
fastcgi_pass {{ php_upstream }}; fastcgi_pass {{ php_upstream }};
fastcgi_index index.php; fastcgi_index index.php;
{% if item.upstream_params is defined and item.upstream_params is iterable %} {% if item.upstream_params is defined and item.upstream_params is iterable %}

View File

@@ -2,6 +2,7 @@
{% block template_upstream_location %} {% block template_upstream_location %}
location = /index.php { location = /index.php {
# {{ php_info }}
fastcgi_pass {{ php_upstream }}; fastcgi_pass {{ php_upstream }};
fastcgi_index index.php; fastcgi_index index.php;
{% if item.upstream_params is defined and item.upstream_params is iterable %} {% if item.upstream_params is defined and item.upstream_params is iterable %}

View File

@@ -0,0 +1,23 @@
{% extends "_php.j2" %}
{% block template_try_files %}
try_files {{ override_try_files | default('$uri $uri/ /index.php') }};
{% endblock %}
{% block template_upstream_location %}
location = /index.php {
# {{ php_info }}
fastcgi_pass {{ php_upstream }};
fastcgi_index index.php;
{% if item.upstream_params is defined and item.upstream_params is iterable %}
{% for param in item.upstream_params %}
{{ param }}
{% endfor %}
{% endif %}
{% if nginx_version.stdout | version_compare('1.6.1', 'lt') %}
include fastcgi_params;
{% else %}
include fastcgi.conf;
{% endif %}
}
{% endblock %}

View File

@@ -1,30 +0,0 @@
#
# {{ ansible_managed }}
#
{% if nginx_php56 %}
upstream {{ nginx_upstream_php56 }} {
{% for item in nginx_php56_sockets %}
{% if item.unix_socket is defined %}
server unix:{{ item.unix_socket }} weight={{ item.weight | default('1') }};
{% else %}
server {{ item.host }}:{{ item.port }} weight={{ item.weight | default('1') }} max_fails={{ item.max_fails | default('5') }} fail_timeout={{ item.fail_timeout | default('10s') }};
{% endif %}
{% endfor %}
}
{% endif %}
{% if nginx_php70 %}
upstream {{ nginx_upstream_php70 }} {
{% for item in nginx_php70_sockets %}
{% if item.unix_socket is defined %}
server unix:{{ item.unix_socket }} weight={{ item.weight | default('1') }};
{% else %}
server {{ item.host }}:{{ item.port }} weight={{ item.weight | default('1') }} max_fails={{ item.max_fails | default('5') }} fail_timeout={{ item.fail_timeout | default('10s') }};
{% endif %}
{% endfor %}
}
{% endif %}
# vim:filetype=nginx

View File

@@ -1,4 +0,0 @@
FROM williamyeh/ansible:debian8-onbuild
RUN apt-get update
CMD ["sh", "tests/travis.sh"]

View File

@@ -1,11 +1,21 @@
--- ---
- name: APT | Install web apps - name: APT | Install webapps
apt: pkg={{ item }} state=present install_recommends=no apt:
pkg: "{{ item }}"
state: present
install_recommends: no
with_items: with_items:
- backuppc - backuppc
- nagios3
# - owncloud # - owncloud
- name: APT | Install nagios3 (only on old Debian releases)
apt:
pkg: nagios3
state: present
when: ansible_distribution_major_version | version_compare('9', 'lt')
- name: SERVICE | Ensure backuppc is started - name: SERVICE | Ensure backuppc is started
service: name=backuppc state=started service:
name: backuppc
state: started

View File

@@ -1,7 +1,9 @@
--- ---
- name: APT | Install web apps - name: APT | Install web apps
pkgng: pkg={{ item }} state=present pkgng:
pkg: "{{ item }}"
state: present
with_items: with_items:
- nagios - nagios
- backuppc - backuppc
@@ -12,17 +14,17 @@
creates=/usr/local/etc/backuppc/config.pl creates=/usr/local/etc/backuppc/config.pl
- name: FILE | Fix backuppc permissions - name: FILE | Fix backuppc permissions
file: > file:
path=/usr/local/etc/backuppc/config.pl path: /usr/local/etc/backuppc/config.pl
owner=backuppc owner: backuppc
group=backuppc group: backuppc
- name: FILE | Fix fcgiwrap permission - name: FILE | Fix fcgiwrap permission
file: > file:
path={{ nginx_fcgiwrap_sock }} path: "{{ nginx_fcgiwrap_sock }}"
mode=0640 mode: 0640
owner={{ nginx_user }} owner: "{{ nginx_user }}"
group={{ nginx_user }} group: "{{ nginx_user }}"
# #
# We don't manage BackupPC on FreeBSD... too dirty. :/ # We don't manage BackupPC on FreeBSD... too dirty. :/

View File

@@ -1,47 +1,118 @@
--- ---
- name: APT_REPOSITORY | Install backports - name: APT_REPOSITORY | Install backports
apt_repository: repo='deb http://httpredir.debian.org/debian {{ ansible_distribution_release }}-backports main' state=present apt_repository:
repo: 'deb http://httpredir.debian.org/debian {{ ansible_distribution_release }}-backports main'
state: present
when: nginx_backports
- block: - block:
- name: APT | Install DotDeb key - name: APT | Install DotDeb key
apt_key: url='http://www.dotdeb.org/dotdeb.gpg' state=present apt_key:
url: 'http://www.dotdeb.org/dotdeb.gpg'
state: present
- name: APT_REPOSITORY | Install dotdeb (PHP 7) - name: APT_REPOSITORY | Install dotdeb (PHP 7)
apt_repository: repo='deb http://packages.dotdeb.org {{ ansible_distribution_release }} all' state=present apt_repository:
repo: 'deb http://packages.dotdeb.org {{ ansible_distribution_release }} all'
state: present
- name: LINEFILEFILE | Dotdeb priority (prevent install nginx from dotdeb) - name: LINEFILEFILE | Dotdeb priority (prevent install nginx from dotdeb)
copy: > copy:
content="Package: *\nPin: release o=packages.dotdeb.org\nPin-Priority: 100" content: "Package: *\nPin: release o=packages.dotdeb.org\nPin-Priority: 100"
dest=/etc/apt/preferences dest: /etc/apt/preferences
when: ansible_distribution_release == 'jessie' and dotdeb
when: ansible_distribution_release == 'jessie' and dotdeb | default(false)
- block:
- name: APT | Install apt-transport-https
apt:
pkg: apt-transport-https
update_cache: yes
cache_valid_time: 3600
- name: APT_KEY | Install GPG key
apt_key:
url: 'https://packages.sury.org/php/apt.gpg'
- name: APT_REPOSITORY | Add APT repository
apt_repository:
repo: 'deb https://packages.sury.org/php {{ ansible_distribution_release }} main'
when: sury | default(false)
- name: APT | Install needed packages - name: APT | Install needed packages
apt: pkg={{ item }} update_cache=yes cache_valid_time=3600 state=present apt:
pkg: "{{ item }}"
update_cache: yes
cache_valid_time: 3600
state: present
with_items: with_items:
- cron
- curl - curl
- fcgiwrap - fcgiwrap
- jq
- nghttp2 - nghttp2
- strace - strace
- vim - vim
- unzip
- name: APT | Install PHP5.6 - name: APT | Install daemonize from Stretch
apt: pkg={{ item }} update_cache=yes cache_valid_time=3600 state=present apt:
with_items: deb: http://ftp.us.debian.org/debian/pool/main/d/daemonize/daemonize_1.7.7-1+b1_amd64.deb
- php5-fpm
- php5-sqlite
when: nginx_php56
- name: APT | Install PHP7 - name: APT | Install PHP
apt: pkg={{ item }} update_cache=yes cache_valid_time=3600 state=present apt:
with_items: pkg: "{{ item.version | php_fpm_package }}"
- php7.0-fpm update_cache: yes
- php7.0-sqlite3 cache_valid_time: 3600
when: nginx_php70 state: present
with_items: "{{ nginx_php }}"
register: apt_php
- name: SERVICE | Force start services - name: SERVICE | Force start fcgiwrap
service: name={{ item.name }} state=started service:
register: sf name: "fcgiwrap"
with_items: state: started
- { name: 'php5-fpm', cond: "{{ nginx_php56 }}" }
- { name: 'php7.0-fpm', cond: "{{ nginx_php70 }}" } # Bypasses Ansible 2.4 issue (cannot use service module)... With service module... php is not really started!
- { name: 'fcgiwrap', cond: true } - name: COMMAND | Force start PHP
when: "{{ item.cond }}" command: "service {{ item.version | php_fpm_service }} start"
with_items: "{{ nginx_php }}"
when: apt_php.changed
- name: GET_URL | Download ngrok
get_url:
url: "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip"
dest: "/tmp/ngrok.zip"
- name: UNARCHIVE | Uncompress ngrok
unarchive:
src: "/tmp/ngrok.zip"
dest: "/tmp"
remote_src: yes
- name: SHELL | Check if ngrok is started
shell: ps aux | grep -q [n]grok
register: psngrok
changed_when: false
failed_when: false
- block:
- name: SHELL | Start ngrok
shell: daemonize /tmp/ngrok http 8888 -bind-tls=false
- name: WAIT_FOR | ngrok started
wait_for:
delay: 2
port: 4040
when: psngrok.rc > 0
- name: SHELL | Get ngrok public address
shell: curl 'http://127.0.0.1:4040/api/tunnels/command_line' | jq '.public_url' | grep -oE '[[:alnum:]]+\.ngrok\.io'
register: ngrok
changed_when: false

View File

@@ -4,13 +4,16 @@
set_fact: set_fact:
nginx_pkgng_package: 'nginx-devel' nginx_pkgng_package: 'nginx-devel'
nginx_user: 'www' nginx_user: 'www'
nginx_php70: false nginx_php:
nginx_php56_sockets: - version: '5.6'
- host: '127.0.0.1' sockets:
port: 9000 - host: '127.0.0.1'
port: 9000
- name: PKGNG | Install needed packages - name: PKGNG | Install needed packages
pkgng: pkg={{ item }} state=present pkgng:
pkg: "{{ item }}"
state: present
with_items: with_items:
- php56 - php56
- curl - curl
@@ -18,7 +21,10 @@
- nghttp2 - nghttp2
- name: SERVICE | Force start services - name: SERVICE | Force start services
service: name={{ item }} state=started enabled=yes service:
name: "{{ item }}"
state: started
enabled: yes
register: sf register: sf
with_items: with_items:
- php-fpm - php-fpm

View File

@@ -2,25 +2,34 @@
- hosts: all - hosts: all
pre_tasks: pre_tasks:
- debug: var=dotdeb
- debug: var=nginx_php56
- debug: var=nginx_php70
- debug: var=nginx_backports
- name: INCLUDE | Pre_tasks related to OS version - name: INCLUDE | Pre_tasks related to OS version
include: "includes/pre_{{ ansible_distribution }}.yml" include: "includes/pre_{{ ansible_distribution }}.yml"
- name: FILE | Create an internal SSL dir - name: FILE | Create an internal SSL dir
file: path={{ int_ansible_ssl_dir }} state=directory file:
path: "{{ int_ansible_ssl_dir }}"
state: directory
- name: COPY | Deploy test certificate - name: COPY | Deploy test certificate
copy: src=file/test.crt dest={{ int_ansible_ssl_dir }}/test.crt copy:
src: "file/test.crt"
dest: "{{ int_ansible_ssl_dir }}/test.crt"
- name: COPY | Deploy test key - name: COPY | Deploy test key
copy: src=file/test.key dest={{ int_ansible_ssl_dir }}/test.key copy:
src: "file/test.key"
dest: "{{ int_ansible_ssl_dir }}/test.key"
- name: LINEINFILE | Add all hosts in /etc/hosts
lineinfile:
line: "127.0.2.1\t{% for s in nginx_sites %}{% if s.name is string %}{{ s.name }}{% else %}{% for n in s.name %}{{ n }} {% endfor %}{% endif %} {% if s.redirect_from is defined %}{% for rf in s.redirect_from %}{{ rf }} {% endfor %}{% endif %}{% endfor %}"
regexp: '^127\.0\.2'
dest: "/etc/hosts"
unsafe_writes: yes
vars: vars:
# Internal vars # Internal vars
int_ansible_ssl_dir: '/etc/ansible-ssl' int_ansible_ssl_dir: '/etc/ansible-ssl'
# Role vars # Role vars
nginx_worker_processes: 1 # Ansible+FreeBSD can't detect CPU number nginx_worker_processes: 1 # Ansible+FreeBSD can't detect CPU number
nginx_apt_package: 'nginx-extras' nginx_apt_package: 'nginx-extras'
nginx_dyn_modules: ['http_geoip'] nginx_module_packages: ['libnginx-mod-http-headers-more-filter']
nginx_upstreams: nginx_upstreams:
- name: 'test' - name: 'test'
servers: servers:
@@ -53,7 +62,12 @@
description: 'Please login!' description: 'Please login!'
users: [] users: []
state: 'absent' state: 'absent'
nginx_acmesh: true
nginx_acmesh_test: true
nginx_ssl_pairs: nginx_ssl_pairs:
- name: '{{ ngrok.stdout }}'
acme: true
acme_port: 8888
- name: 'test-ssl-predeployed.local' - name: 'test-ssl-predeployed.local'
dest_key: "{{ int_ansible_ssl_dir }}/test.key" dest_key: "{{ int_ansible_ssl_dir }}/test.key"
dest_cert: "{{ int_ansible_ssl_dir }}/test.crt" dest_cert: "{{ int_ansible_ssl_dir }}/test.crt"
@@ -115,9 +129,9 @@
- ' DZ no;' - ' DZ no;'
- ' TN no;' - ' TN no;'
- '}' - '}'
nginx_default_vhost: 'first-test' nginx_default_site: 'first-test'
nginx_default_vhost_ssl: 'test-ssl-predeployed.local' nginx_default_site_ssl: 'test-ssl-predeployed.local'
nginx_vhosts: nginx_sites:
- name: - name:
- 'test.local' - 'test.local'
- 'test-alias.local' - 'test-alias.local'
@@ -170,7 +184,7 @@
- '/b' - '/b'
- '/c' - '/c'
- name: 'test-php.local' - name: 'test-php.local'
php_version: "{{ '7.0' if nginx_php70 else '5.6' }}" php_version: "{{ nginx_php.1.version if nginx_php.1 is defined else nginx_php.0.version }}"
upstream_params: upstream_params:
- 'fastcgi_param FOO bar;' - 'fastcgi_param FOO bar;'
redirect_from: redirect_from:
@@ -180,6 +194,8 @@
use_access_log: true use_access_log: true
- name: 'test-php-index.local' - name: 'test-php-index.local'
template: '_php_index' template: '_php_index'
- name: 'test-php-index2.local'
template: '_php_index2'
- name: 'test-proxy.local' - name: 'test-proxy.local'
listen: listen:
- 8080 - 8080
@@ -228,7 +244,13 @@
https_proxy_protocol_port: [20443] https_proxy_protocol_port: [20443]
template: '_base' template: '_base'
ssl_name: 'test-ssl.local' ssl_name: 'test-ssl.local'
nginx_dh_length: 2048 - name: '{{ ngrok.stdout }}'
proto: ['http', 'https']
template: '_base'
ssl_name: '{{ ngrok.stdout }}'
headers:
'X-acme': '1'
nginx_dh_length: 1024
roles: roles:
- ../../ - ../../
post_tasks: post_tasks:
@@ -237,117 +259,174 @@
# -------------------------------- # --------------------------------
- name: INCLUDE | Post_tasks related to OS version - name: INCLUDE | Post_tasks related to OS version
include: "includes/post_{{ ansible_distribution }}.yml" include: "includes/post_{{ ansible_distribution }}.yml"
# -------------------------------- # --------------------------------
# Deploy index files # Deploy index files
# -------------------------------- # --------------------------------
- name: -- Add PHP file -- - name: -- Add PHP file --
copy: dest="{{ nginx_root }}/{{ item }}/public/index.php" content="<?php phpinfo();" copy:
with_items: ['test-php.local', 'test-php-index.local'] dest: "{{ nginx_root }}/{{ item }}/public/index.php"
content: "<?php phpinfo();"
with_items:
- 'test-php.local'
- 'test-php-index.local'
- 'test-php-index2.local'
- name: -- Add HTML file -- - name: -- Add HTML file --
copy: dest="{{ item }}/index.html" content="Index HTML test OK\n" copy:
with_items: ['{{ nginx_root }}/first-test/public', '/var/tmp', '{{ nginx_root }}/test-htpasswd-all.local/public', '{{ nginx_root }}/test-ssl.local/public', '{{ nginx_root }}/test-ssl-predeployed.local/public', '{{ nginx_root }}/test-ssl-proxy-protocol.local/public'] dest: "{{ item }}/index.html"
content: "Index HTML test OK\n"
with_items:
- '{{ nginx_root }}/first-test/public'
- '/var/tmp'
- '{{ nginx_root }}/test-htpasswd-all.local/public'
- '{{ nginx_root }}/test-ssl.local/public'
- '{{ nginx_root }}/test-ssl-predeployed.local/public'
- '{{ nginx_root }}/test-ssl-proxy-protocol.local/public'
- '{{ nginx_root }}/{{ ngrok.stdout }}/public'
- name: -- Create directory -- - name: -- Create directory --
file: path={{ nginx_root }}/test-htpasswd.local/public/hello state=directory file:
path: "{{ nginx_root }}/test-htpasswd.local/public/hello"
state: directory
- name: -- Add HTML file hello -- - name: -- Add HTML file hello --
copy: dest="{{ nginx_root }}/test-htpasswd.local/public/hello/index.html" content="hello\n" copy:
dest: "{{ nginx_root }}/test-htpasswd.local/public/hello/index.html"
content: "hello\n"
# -------------------------------- # --------------------------------
# Test custom facts # Test custom facts
# -------------------------------- # --------------------------------
- name: -- CHECK FACTS -- - name: -- CHECK FACTS --
assert: assert:
that: "'{{ ansible_local.nginx.fact_nginx_vhosts[0].name[0] }}' == 'test.local'" that: "'{{ ansible_local.nginx.fact_nginx_sites[0].name[0] }}' == 'test.local'"
# -------------------------------- # --------------------------------
# Simple vhosts tests # Simple sites tests
# -------------------------------- # --------------------------------
- name: -- VERIFY VHOSTS -- - name: -- VERIFY SITES --
command: "curl -H 'Host: {{ item.name if item.name is string else item.name[0] }}' http://127.0.0.1{% if item.listen is defined %}:{{ item.listen[0] }}{% endif %}/" uri:
with_items: "{{ nginx_vhosts }}" url: "http://{{ item | nginx_site_name }}{% if item.listen is defined %}:{{ item.listen[0] }}{% endif %}/"
status_code: '200,301,302,401,403'
follow_redirects: none
with_items: "{{ nginx_sites }}"
when: item.state is undefined or item.state != "absent" when: item.state is undefined or item.state != "absent"
changed_when: false changed_when: false
- name: -- VERIFY FORBIDDEN -- - name: -- VERIFY FORBIDDEN --
command: "curl -H 'Host: test-php-index.local' http://127.0.0.1/phpinfo.php" uri:
register: f url: "http://test-php-index.local/phpinfo.php"
failed_when: f.stdout.find('403 Forbidden') == -1 status_code: 403
changed_when: false
- name: -- VERIFY REDIRECT VHOSTS -- - name: -- VERIFY REDIRECT SITES --
command: "curl -H 'Host: {{ item.redirect_from[0] }}' http://127.0.0.1/" uri:
with_items: "{{ nginx_vhosts }}" url: "http://{{ item.redirect_from[0] }}/"
status_code: 301
follow_redirects: none
with_items: "{{ nginx_sites }}"
when: item.redirect_from is defined and (item.state is undefined or item.state != "absent") when: item.redirect_from is defined and (item.state is undefined or item.state != "absent")
changed_when: false changed_when: false
register: r
failed_when: r.stdout.find('301 Moved Permanently') == -1
# -------------------------------- # --------------------------------
# PHP # PHP
# -------------------------------- # --------------------------------
- name: -- VERIFY PHP5 VHOSTS (implicit default) -- - name: -- VERIFY PHP SITES --
command: "curl -H 'Host: {{ item }}' http://127.0.0.1/" uri:
url: "http://{{ item.name}}/"
return_content: yes
register: p register: p
changed_when: false with_items: "{{ nginx_sites }}"
failed_when: p.stdout.find('PHP Version 5') == -1 when: >
with_items: ['test-php-index.local'] item.template is defined and
when: nginx_php56 (item.template == '_php' or item.template == '_php_index' or item.template == '_php_index2')
failed_when: p.content.find('PHP Version ' + item.php_version if 'php_version' in item else nginx_php.0.version) == -1
- name: -- VERIFY PHP7 VHOSTS -- - name: -- VERIFY INDEX2 --
command: "curl -H 'Host: {{ item }}' http://127.0.0.1/" uri:
register: p url: "http://test-php-index2.local/lorem.php?ipsum=sit&dolor=amet"
changed_when: false return_content: yes
failed_when: p.stdout.find('PHP Version 7') == -1 register: p2
with_items: ['test-php.local'] failed_when: p2.content.find('PHP Version') == -1
when: nginx_php70
# -------------------------------- # --------------------------------
# Basic Auth # Basic Auth
# -------------------------------- # --------------------------------
- name: -- VERIFY AUTH BASIC NONE -- - name: -- VERIFY AUTH BASIC NONE --
command: "curl -H 'Host: test-htpasswd.local' http://127.0.0.1/hello/" uri:
changed_when: false url: "http://test-htpasswd.local/hello/"
register: authnone status_code: 401
failed_when: authnone.stdout.find('401 Authorization Required') == -1
- name: -- VERIFY AUTH BASIC FAIL -- - name: -- VERIFY AUTH BASIC FAIL --
command: "curl -u fail:fail -H 'Host: test-htpasswd.local' http://127.0.0.1/hello/" uri:
changed_when: false url: "http://test-htpasswd.local/hello/"
register: authfail status_code: 401
failed_when: authfail.stdout.find('401 Authorization Required') == -1 user: "fail"
password: "fail"
force_basic_auth: yes
- name: -- VERIFY AUTH BASIC OK -- - name: -- VERIFY AUTH BASIC OK --
command: "curl -u hanx:qwerty -H 'Host: test-htpasswd.local' http://127.0.0.1/hello/" uri:
changed_when: false url: "http://test-htpasswd.local/hello/"
register: authok user: "hanx"
failed_when: authok.stdout.find('hello') == -1 password: "qwerty"
force_basic_auth: yes
- name: -- VERIFY AUTH BASIC FAIL GLOBAL -- - name: -- VERIFY AUTH BASIC FAIL GLOBAL --
command: "curl -u fail:fail -H 'Host: test-htpasswd-all.local' http://127.0.0.1/" uri:
changed_when: false url: "http://test-htpasswd-all.local/"
register: authgfail status_code: 401
failed_when: authgfail.stdout.find('401 Authorization Required') == -1 user: "fail"
- name: -- VERIFY AUTH BASIC OK -- password: "fail"
command: "curl -u hanx:qwerty -H 'Host: test-htpasswd-all.local' http://127.0.0.1/" force_basic_auth: yes
changed_when: false
register: authgok - name: -- VERIFY AUTH BASIC OK GLOBAL --
failed_when: authgok.stdout.find('401 Authorization Required') != -1 uri:
url: "http://test-htpasswd-all.local/"
user: "hanx"
password: "qwerty"
force_basic_auth: yes
# -------------------------------- # --------------------------------
# BackupPC # BackupPC
# -------------------------------- # --------------------------------
- name: -- VERIFY BACKUPPC -- - name: -- VERIFY BACKUPPC --
command: "curl -u hanx:qwerty -H 'Host: backuppc.local' http://127.0.0.1/" uri:
changed_when: false url: "http://backuppc.local/"
user: "hanx"
password: "qwerty"
force_basic_auth: yes
return_content: yes
register: authbpc register: authbpc
failed_when: authbpc.stdout.find('BackupPC Server Status') == -1
when: ansible_distribution != 'FreeBSD' when: ansible_distribution != 'FreeBSD'
failed_when: authbpc.content.find('BackupPC Server Status') == -1
# -------------------------------- # --------------------------------
# Nagios # Nagios (not avaiblable on Debian >= 9)
# -------------------------------- # --------------------------------
- name: -- VERIFY NAGIOS3 PHP -- - block:
command: "curl -u nagiosadmin:nagios -H 'Host: nagios3.local' http://127.0.0.1/side.php"
changed_when: false - name: -- VERIFY NAGIOS3 PHP --
register: nagios_php uri:
failed_when: nagios_php.stdout.find('Nagios Core') == -1 url: "http://nagios3.local/side.php"
- name: -- VERIFY NAGIOS3 CGI -- user: "nagiosadmin"
command: "curl -u nagiosadmin:nagios -H 'Host: nagios3.local' http://127.0.0.1/cgi-bin{% if ansible_distribution == 'Debian' %}/nagios3{% endif %}/summary.cgi" password: "nagios"
changed_when: false force_basic_auth: yes
register: nagios_cgi return_content: yes
failed_when: nagios_cgi.stdout.find('Nagios Event Summary') == -1 register: nagios_php
failed_when: nagios_php.content.find('Nagios Core') == -1
- name: -- VERIFY NAGIOS3 CGI --
uri:
url: "http://nagios3.local/cgi-bin{% if ansible_distribution == 'Debian' %}/nagios3{% endif %}/summary.cgi"
user: "nagiosadmin"
password: "nagios"
force_basic_auth: yes
return_content: yes
register: nagios_cgi
failed_when: nagios_cgi.content.find('Nagios Event Summary') == -1
when: ansible_distribution_major_version | version_compare('9', 'lt')
# -------------------------------- # --------------------------------
# Owncloud # Owncloud
@@ -374,18 +453,26 @@
# SSL # SSL
# -------------------------------- # --------------------------------
- name: -- VERIFY SSL -- - name: -- VERIFY SSL --
command: "curl --insecure -H 'Host: {{ item }}' https://127.0.0.1/" uri:
changed_when: false url: "https://{{ item }}/"
return_content: yes
validate_certs: no
register: sslok register: sslok
failed_when: sslok.stdout.find('Index HTML test OK') == -1 failed_when: sslok.content.find('Index HTML test OK') == -1
with_items: with_items:
- 'test-ssl-predeployed.local' - 'test-ssl-predeployed.local'
- 'test-ssl.local' - 'test-ssl.local'
- '{{ ngrok.stdout }}'
- name: -- VERIFY SSL REDIRECT -- - name: -- VERIFY SSL REDIRECT --
command: "curl -v -H 'Host: {{ item.name }}' http://127.0.0.1/" uri:
changed_when: false url: "http://{{ item.name }}/"
validate_certs: no
status_code: 301
return_content: yes
follow_redirects: none
register: sslredirok register: sslredirok
failed_when: "'< Location: https://{{ item.name }}{{ ':' + item.port if item.port is defined else '' }}/' not in sslredirok.stderr" failed_when: '"https://%s%s" % (item.name, ":" + item.port if item.port is defined else "") not in sslredirok.location'
with_items: with_items:
- name: 'test-ssl-redirect.local' - name: 'test-ssl-redirect.local'
- name: 'test-ssl-redirect-many.local' - name: 'test-ssl-redirect-many.local'
@@ -394,39 +481,50 @@
port: '8443' port: '8443'
# -------------------------------- # --------------------------------
# Default vhosts # Default sites
# -------------------------------- # --------------------------------
- name: -- VERIFY DEFAULT VHOST -- - name: -- VERIFY DEFAULT SITE --
command: "curl -v http://127.0.0.1/" uri:
changed_when: false url: 'http://127.0.0.1/'
return_content: yes
register: vdefault register: vdefault
failed_when: > failed_when: >
vdefault.stdout.find('Index HTML test OK') == -1 or vdefault.content.find('Index HTML test OK') == -1 or
vdefault.stderr.find('X-ansible-default') == -1 vdefault.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SSL VHOST --
command: "curl --insecure -v https://127.0.0.1/" - name: -- VERIFY DEFAULT SITE + STUB STATUS--
changed_when: false uri:
register: defaultssl url: 'http://127.0.0.1/status'
failed_when: > return_content: yes
defaultssl.stdout.find('Index HTML test OK') == -1 or
defaultssl.stderr.find('X-ansible-default') == -1
- name: -- VERIFY NOT DEFAULT VHOST --
command: "curl -v -H 'Host: test-php.local' http://127.0.0.1/"
changed_when: false
register: vphp
failed_when: vphp.stderr.find('X-ansible-default') != -1
- name: -- VERIFY NOT DEFAULT SSL VHOST --
command: "curl --insecure -v -H 'Host: test-ssl.local' https://127.0.0.1/"
changed_when: false
register: notdefaultssl
failed_when: notdefaultssl.stderr.find('X-ansible-default') != -1
- name: -- VERIFY DEFAULT VHOST + STUB_STATUS --
command: "curl -v http://127.0.0.1/status"
changed_when: false
register: vdefault_status register: vdefault_status
failed_when: > failed_when: >
vdefault_status.stderr.find('X-ansible-default') == -1 or vdefault_status.content.find('Active connections') == -1 or
vdefault_status.stdout.find('Active connections') == -1 vdefault_status.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SSL SITE --
uri:
url: 'https://127.0.0.1/'
return_content: yes
validate_certs: no
register: vdefault
failed_when: >
vdefault.content.find('Index HTML test OK') == -1 or
vdefault.x_ansible_default is not defined
- name: -- VERIFY NOT DEFAULT SITE --
uri:
url: 'http://test-php.local/'
return_content: yes
register: vphp
failed_when: vphp.x_ansible_default is defined
- name: -- VERIFY NOT DEFAULT SSL SITE --
uri:
url: 'https://test-ssl.local/'
return_content: yes
validate_certs: no
register: notdefaultssl
failed_when: notdefaultssl.x_ansible_default is defined
# -------------------------------- # --------------------------------
# Check HTTP2 # Check HTTP2

View File

@@ -1,25 +0,0 @@
#!/bin/sh
# Thanks to https://servercheck.in/blog/testing-ansible-roles-travis-ci-github
DIR=$( dirname $0 )
PLAYBOOK="$DIR/test.yml"
set -ev
ANSIBLE_VARS="{ nginx_php56: $NGINX_PHP56, nginx_php70: $NGINX_PHP70, nginx_backports: $NGINX_BACKPORTS, dotdeb: $DOTDEB }"
echo $ANSIBLE_VARS
# Check syntax
ansible-playbook -i localhost, -c local --syntax-check -vv $PLAYBOOK
# Check role
ansible-playbook -i localhost, -c local -e "$ANSIBLE_VARS" --sudo -vv $PLAYBOOK
# Check indempotence
ansible-playbook -i localhost, -c local -e "$ANSIBLE_VARS" --sudo -vv $PLAYBOOK \
| grep -q 'changed=0.*failed=0' \
&& (echo 'Idempotence test: pass' && exit 0) \
|| (echo 'Idempotence test: fail' && exit 1)

View File

@@ -2,7 +2,7 @@ nginx_events_use: 'epoll'
nginx_pid: '/run/nginx.pid' nginx_pid: '/run/nginx.pid'
nginx_etc_dir: '/etc/nginx' nginx_etc_dir: '/etc/nginx'
# Specific vhosts # Specific sites
nginx_nagios_root: '/usr/share/nagios3/htdocs' nginx_nagios_root: '/usr/share/nagios3/htdocs'
nginx_nagios_stylesheets: '/etc/nagios3/stylesheets' nginx_nagios_stylesheets: '/etc/nagios3/stylesheets'
nginx_fcgiwrap_sock: '/var/run/fcgiwrap.socket' nginx_fcgiwrap_sock: '/var/run/fcgiwrap.socket'

View File

@@ -2,6 +2,6 @@ nginx_events_use: 'kqueue'
nginx_pid: '/var/run/nginx.pid' nginx_pid: '/var/run/nginx.pid'
nginx_etc_dir: '/usr/local/etc/nginx' nginx_etc_dir: '/usr/local/etc/nginx'
# Specific vhosts # Specific sites
nginx_nagios_root: '/usr/local/www/nagios' nginx_nagios_root: '/usr/local/www/nagios'
nginx_fcgiwrap_sock: '/var/run/fcgiwrap/fcgiwrap.sock' nginx_fcgiwrap_sock: '/var/run/fcgiwrap/fcgiwrap.sock'

View File

@@ -44,5 +44,4 @@ nginx_servers_default_headers:
'X-Content-Type-Options': 'nosniff always' 'X-Content-Type-Options': 'nosniff always'
'X-XSS-Protection': '1; mode=block' 'X-XSS-Protection': '1; mode=block'
nginx_upstream_php56: 'php56' nginx_acmesh_bin: "{{ nginx_acmesh_dir }}/acme.sh"
nginx_upstream_php70: 'php70'