Compare commits

...

320 Commits

Author SHA1 Message Date
Emilien Mantel a5325d7d54 🔥 Drop Ubuntu 18.04 support and hack CI 2023-05-31 12:10:40 +02:00
Emilien Mantel c61fb86cc0 💚 Allow CI job Ubuntu 20.04 to fail 2023-05-31 12:10:40 +02:00
Emilien Mantel c2e0fc241f ✏️ Fix doc typo 2023-05-31 12:10:40 +02:00
Emilien Mantel 1debe40739 💚 Fix Ubuntu 20.04 build
- Prevent segfault on nginx-extra package
2023-05-31 12:10:40 +02:00
Emilien Mantel c9e1aa2848 Skip checks for Ubuntu 18.04
Curl does not manage proxy protocol...
2023-05-31 12:10:40 +02:00
Emilien Mantel 0fd16bdd1e 🚀 Manage Ubuntu 2023-05-31 12:10:40 +02:00
Emilien Mantel 424160f9d4 🐛 Fix load vars for Debian based OS 2023-05-31 12:10:40 +02:00
Emilien Mantel 6abee22d23 Add missing collection dependencies 2023-05-31 12:10:40 +02:00
Emilien Mantel 3b3f1cb3e0 🔥 Remove useless code 2023-05-31 12:10:40 +02:00
Emilien Mantel 955857ac4f 📝 Add github action badge 2023-05-31 12:10:40 +02:00
Emilien Mantel 170046480a 🔥 Remove TravisCI 2023-05-31 12:10:40 +02:00
Emilien Mantel c8344201a8 Add Debian 12 and CI 2023-05-31 12:10:40 +02:00
Emilien Mantel c552dd3642 🚀 Add core options 2023-05-31 12:10:40 +02:00
Emilien Mantel d262ddd79e 🚨 Fix linter 2023-05-31 12:10:40 +02:00
Emilien Mantel 257437731a 🔒 Modernize TLS helpers 2023-05-31 12:10:40 +02:00
Emilien Mantel 3b69a4f700 🙈 Ignore pycharm files 2023-05-31 12:10:40 +02:00
Emilien Mantel 9f727adcb5 Fix linter 2022-11-25 10:11:19 +01:00
Emilien Mantel 55e075ac2b Drop Debian Stretch support 2021-09-10 17:05:53 +02:00
Emilien Mantel 26543001f3 Quickfix on invalid FQDN 2021-09-10 16:44:08 +02:00
Emilien Mantel 815e39162a Fix passlib install
- Do not break idempotence on Debian Stretch
- Python 2 must not be used now...
2021-09-10 16:43:32 +02:00
Emilien Mantel 7135bc68e7 Code refactoring on tests 2021-09-10 16:25:01 +02:00
Emilien Mantel 0622f8ab87 Some changes on acme.sh install process
- Remove useless git directory
- Force use letsencrypt as default CA
2021-09-10 16:02:24 +02:00
Emilien Mantel 8de557346e Some code refactoring on install process 2021-09-10 15:52:29 +02:00
Emilien Mantel 297dc1f669 Fix ansible lint 2021-09-03 12:19:32 +02:00
Emilien Mantel 5e2f988beb Merge branch 'master' into debian_11 2021-09-03 12:08:30 +02:00
Emilien Mantel 6aea2bcb5f Migrate to new TravisCI version 2021-09-01 12:05:07 +02:00
Emilien Mantel 8c6c4dc813 Fix Ansible Lint 2021-09-01 11:58:39 +02:00
Emilien Mantel a2780d3d95 Fix Ansible Lint 2021-09-01 11:45:44 +02:00
Emilien Mantel 6c7e0c2a47 Fix yaml lint 2021-09-01 11:21:12 +02:00
Emilien Mantel bdddb06fcc Add Debian Bullseye (11) support 2021-09-01 11:07:54 +02:00
Emilien Mantel 6e5fce00e7 Drop Backuppc support 2021-09-01 11:06:02 +02:00
Emilien Mantel 8268eb266a Fix no_log call crashes on Ansible 2.11 2021-09-01 11:02:45 +02:00
Emilien Mantel 8b73a835c6 Fix ngrok task to get hostname 2021-09-01 11:02:12 +02:00
Emilien Mantel 40ebe61c57 Add doc for custom site templates 2020-08-24 09:08:57 +02:00
Emilien Mantel 0f8688f290 Travis: don't install ansible buggy versions 2020-08-24 09:08:57 +02:00
Emilien Mantel 204e95725e Manage custom templates for sites
Issue #12 related
2020-08-24 09:08:57 +02:00
Emilien Mantel da08953a27 Drop Backuppc support 2020-08-24 09:08:57 +02:00
Emilien Mantel 4c63efa588 Compat python3 2020-05-18 16:10:42 +02:00
Emilien Mantel 3e228d0812 Typofix 2020-02-04 13:08:48 +01:00
Emilien Mantel 1e7a0fc855 Change HSTS header per site or globally 2020-02-04 13:06:26 +01:00
Emilien Mantel 93b90c748f Fix redirect_ssl cannot be a default_site 2020-02-04 11:31:21 +01:00
Emilien Mantel d8f6088362 Fix SSL with multiple names 2020-02-04 11:07:21 +01:00
Emilien Mantel 8c3b1c7f13 Compat with python3 2020-01-01 22:56:08 +01:00
Emilien Mantel 5cdd1a8b37 Skip tests on proxy protocol on Debian Stretch 2019-12-31 13:16:42 +01:00
Emilien Mantel 0363a37e06 Changeis for proxy_protocol and apply default values 2019-12-31 13:07:13 +01:00
Emilien Mantel a1e76453cf DH length 4096 -> 2048 2019-12-31 12:46:02 +01:00
Emilien Mantel 729173c46c Better SSL management
- Use filter plugins
- Acme: can use proxy protocol
- Acme: uses all sites name
- Acme: add more tests while crashing
2019-12-31 12:43:43 +01:00
Emilien Mantel 2f8ce00067 Add tests on proxy protocol 2019-12-30 17:43:18 +01:00
Emilien Mantel 9b286f9b96 Fix some issues:
- "main_name" is name/name[0] not filename
- improve some tests
- better proxy protocol handling (not necessary to declare ports twice)
2019-12-30 17:28:34 +01:00
Emilien Mantel 4a2478a4fb [WIP] Working on FreeBSD tests
Replace ngrok by serveo.net?
2019-12-29 18:18:24 +01:00
Emilien Mantel a9a72dd25f Drop PHP version support (useless) + fix some bugs 2019-12-29 16:29:18 +01:00
Emilien Mantel 2a612a55b9 Ajout symfony template 2019-12-26 17:55:07 +01:00
Emilien Mantel 1280a441ee Fix tests on Sury 2019-12-26 17:35:00 +01:00
Emilien Mantel 21edb6b584 Fix install role 2019-12-26 17:23:36 +01:00
Emilien Mantel c524b97b0f Use upstream config from HanXHX.php role 2019-12-26 17:16:13 +01:00
Emilien Mantel 993310641a Fix "always" management in add_header directive 2019-08-20 10:35:51 +02:00
Emilien Mantel f5885c5c55 Cache fonts 2019-08-07 21:11:00 +02:00
Emilien Mantel bb5e00d6f5 Don't remove acme.sh keys if acme.sh fails 2019-05-03 14:16:23 +02:00
Emilien Mantel cf010e4a4b Reload nginx with acme.sh
Sometimes fu****** systemd don't want you to restart nginx in a loop. I
t crashes the role.
2019-04-30 16:45:14 +02:00
Emilien M 39d3f5f06a
Fix lints warnings (#40)
* Add new filter plugins related to SSL
* Ignore lint on few tasks
2019-04-26 13:29:06 +02:00
Emilien M 247f849b86
Remove obsolete code (php 5.6 support) (#41)
Closes #39
2019-04-26 13:28:04 +02:00
Emilien Mantel a03a656b18 Prevent crash on Docker+Buster 2019-04-25 16:14:43 +02:00
Emilien Mantel 1239219d90 Add buster to travis 2019-04-25 14:37:15 +02:00
Emilien Mantel 4f94fc2211 acme.sh fixes
- fix acme.sh home directory
- Clean crash when acme.sh fails (EXPERIMENTAL)
2019-04-25 13:59:19 +02:00
Emilien M e89a154bb5
Support Debian Buster (#37) 2019-04-23 09:28:00 +02:00
Emilien Mantel c9bda9e95a Force Python2.7 on travis 2019-04-19 14:38:47 +02:00
Emilien Mantel 4efc975770 Remove obsolete doc 2019-04-10 10:01:32 +02:00
Emilien M 20d04015c1
Remove newlines+tab on server_name. Bypass acme.sh limitations (#38) 2019-03-20 19:37:55 +01:00
Emilien Mantel 98b0de9265 Fix tests 2019-02-21 18:32:38 +01:00
Emilien Mantel 95706359c8 Fix "override_try_files" 2019-02-20 17:08:56 +01:00
Emilien Mantel 1437619475 Manages locations before "/" 2019-02-20 15:13:25 +01:00
Emilien Mantel 7959182bf8 Remove legacy code 2019-02-20 15:06:59 +01:00
Emilien Mantel 5ed17149e5 Drop Jessie support 2019-02-13 14:40:03 +01:00
Emilien Mantel 91ca31e676 This role only works with Ansible 2.6+ 2019-02-12 18:18:03 +01:00
Emilien Mantel a021888728 Change DH file if length updated 2019-02-12 18:07:04 +01:00
Emilien Mantel c12113921c Fixes some warnings 2019-02-12 18:04:24 +01:00
Emilien Mantel 74b48fca2c Update crypto helpers
Fixes #36
2019-02-12 18:03:52 +01:00
Emilien Mantel 3642df1d5f Some fixes 2019-02-08 16:59:01 +01:00
Emilien Mantel c399bf35b5 Compat with modern ansible versions 2019-02-05 11:05:04 +01:00
Emilien M 8218e5c972
Fix deprecations (#35)
* Drop Nagios support
* Fix start PHP-FPM on Docker
* Fix deprecations on Ansible 2.7

- with_ -> loop
- fix filters as test
- test version_compare -> version
- set min_version to 2.5
2019-01-24 11:05:46 +01:00
Emilien Mantel 87c1c68949 Add Ansible 2.5 + 2.6 to travis 2018-10-03 14:09:20 +02:00
Emilien Mantel 817929beca Add self-signed cert feature 2018-04-20 09:32:46 +02:00
Emilien Mantel 678dff9a1a Tune vimrc (mouse is boring on stretch) 2018-04-20 09:20:39 +02:00
Emilien Mantel 3da65983bd Fix acme create 2018-03-22 20:35:51 +01:00
Emilien Mantel 3fb8f092fb Fake site + force IPv6 2018-03-22 20:30:10 +01:00
Emilien Mantel 19a85ca381 Autoconfigure ipv6 on fakesite 2018-03-22 19:48:41 +01:00
Emilien Mantel 2bab49221a Autoconfigure IPv6 on each server 2018-03-22 19:47:30 +01:00
Emilien Mantel 6e877c070e Configure nginx restart with acme.sh 2018-03-22 19:03:33 +01:00
Emilien Mantel c165f88126 Manage multiple names with acme.sh 2018-03-22 18:43:44 +01:00
Emilien Mantel 59dd3997de Acme uses light fake sites 2018-03-22 18:39:10 +01:00
Emilien Mantel ae6dc88bc4 Delete current site when playing with acme.sh 2018-03-22 17:49:02 +01:00
Emilien Mantel 6719b415ab Fix playbook crash whith acme and multiple domain 2018-03-22 17:47:53 +01:00
Emilien Mantel fd21603a4d Fix FreeBSD version for galaxy 2018-03-18 12:37:27 +01:00
Emilien Mantel f52be2bbf3 Add FreeBSD in meta/main.yml 2018-03-17 14:52:14 +01:00
Emilien Mantel a4aeec0a94 Drop check legacy nginx version 2018-03-17 14:08:48 +01:00
Emilien Mantel 713a2241de Drop owncloud code 2018-03-17 14:04:48 +01:00
Emilien Mantel 6cae501266 Drop fastcgi_params supprort 2018-03-17 14:02:08 +01:00
Emilien Mantel dd7834e8ce Fix daemonize lock file (ngrok)
It overwrited ngrok binary on Debian
2018-03-17 14:01:07 +01:00
Emilien Mantel cb031c4014 Force shell for FreeBSD 2018-03-17 14:00:01 +01:00
Emilien Mantel db97fe84f8 Add doc for FreeBSD 2018-03-17 12:54:57 +01:00
Emilien Mantel c9629e385f Working on FreeBSD 11/12 2018-03-17 12:24:19 +01:00
Emilien Mantel 5843d695b3 Manage FreeBSD 11 2018-03-16 21:56:15 +01:00
Emilien Mantel 8c7d581131 Fix php upstream with TCP socket 2018-03-16 18:53:53 +01:00
Emilien Mantel 0b85d81991 Better redirect management
Fixes renew with letsencrypt (always redirect and never handle
challenge)
2018-03-15 18:30:01 +01:00
Emilien Mantel 7fe08beb9a Enable TLSv1.3 on nginx v1.13.0 2018-03-15 18:13:13 +01:00
Emilien Mantel 33ef161623 Ansible 2.4 must not fail now 2018-03-15 18:07:36 +01:00
Emilien Mantel c2685732a4 Manages Ansible 2.4+ with Docker
Closes #30
2018-03-15 18:06:38 +01:00
Emilien Mantel 737dfbeb30 Add debug mode 2018-03-15 16:10:37 +01:00
Emilien Mantel def13392a7 Add Ansible 2.5 on travis 2018-03-15 12:56:12 +01:00
Emilien Mantel 6897f66344 redirect_from manages now https sites 2018-03-15 12:54:12 +01:00
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
Emilien Mantel a60e81cc1f fix redirect https : show port only if not 443 2017-04-13 15:16:53 +02:00
Emilien Mantel f1af8991fd Bug fix : redirect https with many names
On a multiple name vhost with redirect_https, redirection is done with
the origin name not the main name.
2017-04-13 14:21:14 +02:00
Emilien Mantel fcb59fd331 no_log when deleting htpasswd files 2017-03-14 11:21:35 +01:00
Emilien Mantel 2aa9e8b6b9 load modules uses pattern *.conf 2017-03-13 10:19:07 +01:00
Emilien Mantel 7892626fc0 Load module from {{nginx_dir}}/etc/modules-enabled 2017-03-13 09:53:29 +01:00
Emilien Mantel ae167d3317 Disabling htpasswd by setting false 2017-03-08 11:10:14 +01:00
Emilien Mantel d8f241f79c Fix headers quotes on nagios 2017-02-09 12:30:13 +01:00
Emilien Mantel 0e33d1b372 Auto quote headers values 2017-02-09 12:03:14 +01:00
Emilien Mantel 2cd559b87a Fix X-XSS-Protection with quotes 2017-02-09 11:59:33 +01:00
Emilien Mantel d550f1bab1 Read-only var: nginx_servers_default_headers 2017-02-08 16:16:19 +01:00
Emilien Mantel 021ca4e173 Auto add "X-XSS-Protection" header to servers 2017-02-08 15:59:02 +01:00
Emilien Mantel 38a8354754 Bind proxy_protocol on port 2017-01-03 12:07:31 +01:00
Emilien Mantel 1b06fe273f Add html file to test-ssl-proxy-protocol.local 2017-01-03 11:32:45 +01:00
Emilien Mantel 684c794566 Manage proxy protocol 2017-01-03 11:16:28 +01:00
Emilien Mantel f2cfae31b1 Update APT cache should not "change" 2016-12-08 17:34:59 +01:00
Emilien Mantel 481bcd34b1 no_log while creating SSL directories 2016-12-08 09:19:12 +01:00
Emilien Mantel 875c7cfb2e Async task: generate dh 2016-12-07 07:48:32 +01:00
Emilien Mantel 8caddedc68 Deploy custom facts with nginx_vhosts 2016-11-29 14:32:27 +01:00
Emilien Mantel 4a3aed6974 no_log on task : Deploy SSL certs 2016-11-29 09:35:53 +01:00
Emilien Mantel 8ccc9f521f Secure files permission 2016-11-25 11:33:20 +01:00
Emilien Mantel 5b0977567c New feature: provide location order (#24 related) 2016-11-23 11:44:04 +01:00
E Mantel de71e1bdcc Better display for server_name 2016-11-16 20:51:03 +01:00
Emilien Mantel 19cdab5ba4 default vhost on HTTPS redirect 2016-11-15 17:15:39 +01:00
Emilien Mantel 999f226838 Delete useless test 2016-11-07 17:40:00 +01:00
Emilien Mantel 40f67fc103 Vhost ssl_name name is now optionnal 2016-11-07 17:22:14 +01:00
Emilien Mantel 6b1366298f no_log on sensitive data 2016-11-02 14:48:49 +01:00
Emilien Mantel 817d56fb81 Fix redirect https on non standard port 2016-11-02 14:25:27 +01:00
Emilien Mantel e08401acf8 vhost redirect_from accepts string 2016-11-02 14:23:55 +01:00
Emilien Mantel 0bda544a2f Revert "nginx -t has no side effect"
This reverts commit 2641777abe.
2016-11-02 14:21:32 +01:00
Emilien Mantel 2641777abe nginx -t has no side effect 2016-10-27 17:48:57 +02:00
Emilien Mantel 60a368f3e1 Manage many configurations 2016-10-13 11:11:07 +02:00
Emilien Mantel 41a5575627 Dynamic modules starts at version 1.9.11 2016-10-12 18:16:53 +02:00
Emilien Mantel 42bb4a3e2b Dynamic module management (closes #23) 2016-10-12 18:13:59 +02:00
Emilien Mantel ef3440a015 Bug fix: vhost with absent state is not deleted in sites-enabled 2016-10-10 14:35:46 +02:00
Emilien Mantel eb704da8d8 README improvement pour vhost.filename 2016-10-07 11:01:00 +02:00
Emilien Mantel 64a9ab7c68 Better display in _base.j2 with many server_name 2016-10-07 10:57:26 +02:00
Emilien Mantel c4ee6eb1a2 vhost.filename used by log and directories creation 2016-10-07 10:50:05 +02:00
Emilien Mantel 8789bd2c9c Add some security rules for wordpress 2016-09-03 12:43:28 +02:00
Emilien Mantel a2e6e98436 Add new feature: nginx_fastcgi_fix_realpath 2016-08-30 17:14:34 +02:00
E Mantel fc44b704cf Merge pull request #22 from HanXHX/vhost_state
Vhost state
2016-08-30 12:28:44 +02:00
Emilien Mantel cf662acdd7 Fix condition when creating vhosts 2016-08-30 11:18:14 +02:00
Emilien Mantel 34c8d1926f Vhost state (closes #19) 2016-08-30 11:06:38 +02:00
Emilien Mantel 634d88874f Backward compatibility with nginx_php variable 2016-08-30 10:52:28 +02:00
Emilien Mantel 5e254331c4 manage php upstream version (styles) on vhost 2016-08-26 12:14:54 +02:00
Emilien Mantel 3ab8e0391c Disable tests for owncloud (fix later) 2016-08-25 18:19:07 +02:00
Emilien Mantel aac33b7376 better vhost for owncloud 2016-08-11 13:03:56 +02:00
Emilien Mantel 88c6c5a043 Manages PHP minor versions 2016-08-11 11:30:26 +02:00
Emilien Mantel a9ad41b40f Fix more block for owncloud 2016-08-11 11:09:43 +02:00
Emilien Mantel d26b2b9a49 Fix owncloud root 2016-08-11 10:59:44 +02:00
Emilien Mantel b17acac4c4 Tests packages on Debian 2016-08-11 10:48:12 +02:00
Emilien Mantel c160640c7f Force latest version of openssl when uses nginx from backports 2016-08-11 10:36:50 +02:00
Emilien Mantel 887219f86c Force install OpenSSL from backports when nginx uses backports 2016-08-11 10:25:45 +02:00
Emilien Mantel 76c02abf47 Fix owncloud js (from php) and add tests 2016-08-11 09:38:09 +02:00
Emilien Mantel 26c93c9315 Add owncloud and prevent nginx from dotdeb 2016-08-10 21:29:03 +02:00
Emilien Mantel 8fb3829860 Drop Wheezy support in IC 2016-08-09 16:12:54 +02:00
Emilien Mantel e4b5bb2a32 Support many php versions (php7) + drop wheezy support 2016-08-09 16:02:09 +02:00
Emilien Mantel af3930a58a New feature: upstream state (remove upstream if needed) 2016-05-11 17:21:52 +02:00
Emilien Mantel 4dcb5f44c6 Don't need any inventory file for tests 2016-03-23 17:27:59 +01:00
Emilien Mantel 1204dbacd1 [FreeBSD] Enable nginx service 2016-03-15 23:12:17 +01:00
Emilien Mantel 3087154335 [FreeBSD] restart nginx on vhost config changed 2016-03-15 23:00:55 +01:00
Emilien Mantel 72edbe8656 [FreeBSD] Force create log dir 2016-03-15 22:49:19 +01:00
E Mantel 66b2ac238c README: Change URL in galaxy 2016-03-15 19:48:00 +01:00
Emilien Mantel d49e41652c Update cipher list (from https://cipherli.st/) 2016-03-15 17:59:48 +01:00
Emilien Mantel 9b19231d8b use headers instead of more 2016-03-15 17:15:46 +01:00
Emilien Mantel 80d1d82acc Fix handler (didn't reload service after nginx -t) 2016-03-15 17:15:11 +01:00
Emilien Mantel 5445d66172 Add a wrapper: test configuration before reloading (better debugging) 2016-03-15 15:57:46 +01:00
Emilien Mantel 9a5afd09fa Force X-Frame-Options SAMEORIGIN for Nagios (closes #17) 2016-03-15 15:46:49 +01:00
Emilien Mantel 96e406c791 always directive managed for add_header option 2016-03-15 15:30:22 +01:00
Emilien Mantel 02994af5ee Default headers with always directive 2016-03-15 15:01:58 +01:00
Emilien Mantel ee79ec9845 SSL helper can be disabled 2016-03-15 12:16:57 +01:00
Emilien Mantel 2ba906be2e Add custom headers in vhost (moved from ssl helpers) 2016-03-15 10:51:14 +01:00
Emilien Mantel d223f8b144 Add a check for HTTPS redirect 2016-03-15 09:22:01 +01:00
Emilien Mantel 8f837de390 Avoid double / in redirect_https 2016-03-15 09:08:52 +01:00
Emilien Mantel aa4bc8d6a7 Move to new galaxy version 2016-03-14 19:39:11 +01:00
Emilien Mantel 2fcf7fa701 Delete useless files 2016-03-14 19:37:25 +01:00
Emilien Mantel 91686fc266 doc minor fix 2016-03-14 19:27:51 +01:00
Emilien Mantel 5e493c15ac Fix deprecation warning 2016-03-14 19:21:47 +01:00
Emilien Mantel 97aeda5678 New feature: redirect_https (HTTP -> HTTPS) 2016-03-14 19:20:08 +01:00
Emilien Mantel 3666b29184 nghttp2 only on Debian Jessie+ 2016-03-09 15:03:41 +01:00
Emilien Mantel 9b5f136510 Fix trailing whitespaces 2016-03-09 11:20:19 +01:00
Emilien Mantel 7cc44bc009 Fix regression (merge?): filename for vhosts 2016-03-09 11:15:37 +01:00
Emilien Mantel 078c3420e1 Fix Vagrantfile (debian is not freebsd)... uh? :) 2016-03-09 10:28:06 +01:00
Emilien Mantel 2cfda9a930 Fix check HTTP2 on FreeBSD (multi-OS code) 2016-03-08 19:37:39 +01:00
E Mantel 29a40fc0a8 Merge pull request #14 from HanXHX/freebsd
Freebsd support
2016-03-08 18:59:38 +01:00
Emilien Mantel 33f34a0550 Manage FreeBSD nginx package name 2016-03-07 12:08:34 +01:00
Emilien Mantel 8fc6f7117e Doc fixes 2016-03-07 12:05:58 +01:00
Emilien Mantel 972555ce22 Minor fixes 2016-03-07 11:59:26 +01:00
Emilien Mantel 2f0672359d I support now FreeBSD! 2016-03-05 18:43:49 +01:00
Emilien Mantel cdc152afbe Nagios OK on FreeBSD 2016-03-05 18:34:04 +01:00
Emilien Mantel 729b621ccb Fix check htpasswd in location (replace echo test) 2016-03-05 17:31:21 +01:00
Emilien Mantel c13cb0d770 PHP works on FreeBSD 2016-03-05 17:26:05 +01:00
Emilien Mantel 8edd69547d [WIP] split pre/post tasks related to OS version 2016-03-05 15:46:54 +01:00
Emilien Mantel 791832f6d1 Config seems ok 2016-03-05 15:36:25 +01:00
Emilien Mantel e00313bb36 [WIP] FreeBSD install ok 2016-03-05 15:07:39 +01:00
Emilien Mantel 44a5c31b12 Typofix 2016-03-05 12:12:09 +01:00
Emilien Mantel 232e63dffe Add travis webhook to galaxy 2016-03-05 12:06:08 +01:00
Emilien Mantel fe68e17663 Logging must be set to false to be disabled 2016-03-05 12:00:07 +01:00
Emilien Mantel ac61b3df0a Add new galaxy tags 2016-03-05 11:40:43 +01:00
Emilien Mantel 1071881ac2 Merge branch 'master' of https://github.com/HanXHX/ansible-nginx
Conflicts:
	tasks/vhost.yml
2016-03-05 11:39:29 +01:00
Emilien Mantel e139ab3e35 Fix deprecation warnings 2016-03-05 11:37:37 +01:00
Emilien Mantel 1f82e7adfe Add HTTP2 check 2016-03-05 11:30:48 +01:00
Emilien Mantel e43a958b03 Gitignore *.retry 2016-03-05 11:06:34 +01:00
Emilien Mantel 47c24a2eb3 Fix HTTP2 syntax error 2016-03-05 10:59:20 +01:00
Emilien Mantel 82c44be932 Use official debian box and DHCP 2016-03-05 10:46:46 +01:00
Emilien Mantel 781008dfff Each vhost can have his own filename 2016-03-04 16:38:40 +01:00
Emilien Mantel 26a50945c5 Split apt update cache (fix install when cache is outdated) 2016-02-09 18:36:48 +01:00
Emilien Mantel 4dc28d9471 Delete useless tasks 2016-02-09 17:17:44 +01:00
Emilien Mantel 3231e58bc0 Test stub status on default http vhost 2016-02-09 16:57:13 +01:00
Emilien Mantel d4f9b6f710 Fix default var nginx_custom_http 2016-01-26 11:19:51 +01:00
Emilien Mantel d049be0d81 Remove duplicate link 2016-01-25 17:02:17 +01:00
Emilien Mantel 863dc6ca76 In tests, dh = 1024bits (speedup tests) 2016-01-22 10:06:35 +01:00
Emilien Mantel 1338e4dee6 Fix indent 2016-01-22 09:52:15 +01:00
Emilien Mantel dd97e5ec79 Apps vhosts should without root and created dirs 2016-01-22 09:46:43 +01:00
Emilien Mantel 7f56db76e0 Simplify proxy template 2016-01-22 09:36:52 +01:00
Emilien Mantel 51a1105dff Check PHP (should fix travis) 2016-01-21 17:54:24 +01:00
Emilien Mantel 0a8f21b0b7 Min ansible version is now 2.0 (closes #10) 2016-01-21 17:10:36 +01:00
Emilien Mantel 75d815b4a4 Revert "Bypass htpasswd module bug (state=absent on missing file)"
This reverts commit f8d138828b.
2016-01-21 17:09:54 +01:00
Emilien Mantel 520eed50c3 Manage default vhost. Closes #11 2016-01-21 17:08:01 +01:00
Emilien Mantel c36c4824b7 Cleanup tests 2016-01-21 15:34:18 +01:00
Emilien Mantel c357658c25 Fix Nagios vhost and better tests 2016-01-21 15:16:21 +01:00
Emilien Mantel be349ec686 new vhost: nagios3 (without css) 2016-01-15 15:48:18 +01:00
Emilien Mantel 287d154532 SSL strapling on Nginx >= 1.3.7 2016-01-15 12:13:15 +01:00
Emilien Mantel 11c98ab145 SSL with existing keys 2016-01-12 17:26:30 +01:00
Emilien Mantel ef5a7bf756 Closes #9 2016-01-12 15:10:43 +01:00
Emilien Mantel 2f6f2d4362 Fix variable check 2016-01-12 15:01:01 +01:00
Emilien Mantel 53b9dc078e Minor changes on doc 2016-01-12 14:48:53 +01:00
Emilien Mantel ccba868390 Improve checks SSL/TLS + vhost 2016-01-12 14:40:09 +01:00
Emilien Mantel 9b6523a0b1 Doc split + SSL + minor changes 2016-01-12 12:14:36 +01:00
Emilien Mantel 883948f081 Better dh management 2016-01-12 11:16:41 +01:00
Emilien Mantel ad9c0fa979 Fix main name in vhosts 2016-01-12 09:27:53 +01:00
Emilien Mantel 8a30223bb9 Fix upstream (php is optional) 2016-01-11 23:55:33 +01:00
Emilien Mantel 49f11751e6 Refactoring + SSL support 2016-01-11 18:20:42 +01:00
Emilien Mantel f64e1f1106 New feature: install nginx from backports 2016-01-11 15:18:21 +01:00
Emilien Mantel d463b690ec Force start backuppc 2015-12-23 22:37:37 +01:00
Emilien Mantel 7c9c7ab474 Try fix travis with fcgiwrap (down?) 2015-12-23 18:03:17 +01:00
Emilien Mantel c703a4fba8 Support BackupPC 2015-12-23 17:39:06 +01:00
Emilien Mantel e0bb5e2752 Add feature: new custom instructions 2015-12-09 17:06:59 +01:00
Emilien Mantel 05cb864c7c Use more vars instead of a bug dirty dict 2015-12-09 16:46:50 +01:00
Emilien Mantel f8d138828b Bypass htpasswd module bug (state=absent on missing file) 2015-12-04 08:54:59 +01:00
Emilien Mantel 1d86ed9a40 Add htpasswd doc 2015-12-03 17:24:58 +01:00
Emilien Mantel f9127f9a40 Manage auth basic on all vhost 2015-12-03 17:09:29 +01:00
Emilien Mantel 88d1c7fdb7 Use macro for auth_basic 2015-12-03 16:59:37 +01:00
Emilien Mantel c0f2d694e7 Meilleure gestion des dossiers et htpasswd par location 2015-12-03 16:32:08 +01:00
Emilien Mantel 0d65cd3c5c Add redirect_to_code in vhost 2015-12-01 16:40:34 +01:00
Emilien Mantel 9779555ac8 Few minor changes 2015-12-01 16:35:56 +01:00
Emilien Mantel 17905edf30 Begin Stretch support 2015-12-01 16:26:16 +01:00
Emilien Mantel f2c6ec6c57 Travis badge on master branch 2015-12-01 15:52:10 +01:00
Emilien Mantel 80e3cae22e New feature on vhosts: "redirect_to" 2015-12-01 15:46:57 +01:00
Emilien Mantel 3fdc16578c Improve file deletions 2015-11-30 14:41:35 +01:00
Emilien Mantel 1d56fc249d Deleted vhost don't need a template 2015-11-30 12:16:17 +01:00
Emilien Mantel bfe4a315f9 Vhost dir 2015-11-05 15:38:18 +01:00
Emilien Mantel 9fcba824f5 Create root directory 2015-11-04 09:16:59 +01:00
Emilien Mantel d1dbdb83d4 Fix idempotence 2015-11-03 15:09:14 +01:00
Emilien Mantel bee0cb9a66 Remove template validation 2015-11-03 14:54:35 +01:00
Emilien Mantel 6be44c7da8 Many minor changes 2015-11-03 14:45:01 +01:00
Emilien Mantel a0a6e35a3a Only reload nginx 2015-11-03 14:38:47 +01:00
Emilien Mantel f57ab08594 location / can be overwrited 2015-11-03 14:31:50 +01:00
Emilien Mantel d26a6f26f5 shell module is not necessary 2015-11-02 17:44:09 +01:00
Emilien Mantel 97c3d2e169 Fix and improve tests/vhosts + php_index vhost 2015-11-02 16:30:46 +01:00
Emilien Mantel c2644d4e5d update readme 2015-10-22 15:46:21 +02:00
Emilien Mantel 70529e223d nginx_vhosts[x].name now accepts list or string 2015-10-22 10:25:30 +02:00
91 changed files with 3282 additions and 495 deletions

4
.ansible-lint 100644
View File

@ -0,0 +1,4 @@
---
enable_list:
- fqcn-builtins

43
.github/workflows/ci.yml vendored 100644
View File

@ -0,0 +1,43 @@
---
name: ci
'on':
pull_request:
push:
branches:
- master
jobs:
yaml-lint:
name: YAML Lint
runs-on: ubuntu-latest
steps:
- name: Fetch code
uses: actions/checkout@v3
- name: Set up Python 3.
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install test dependencies.
run: pip3 install yamllint
- name: Lint code.
run: |
yamllint .
ansible-lint:
name: Ansible Lint
runs-on: ubuntu-latest
steps:
- name: Fetch code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Run ansible-lint
uses: ansible/ansible-lint-action@v6.15.0

17
.github/workflows/galaxy.yml vendored 100644
View File

@ -0,0 +1,17 @@
---
name: Deploy on Ansible Galaxy
'on':
- push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: galaxy
uses: robertdebock/galaxy-action@1.2.0
with:
galaxy_api_key: ${{ secrets.galaxy_api_key }}

43
.github/workflows/molecule.yml vendored 100644
View File

@ -0,0 +1,43 @@
---
name: Molecule
'on':
pull_request:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
scenario:
- debian-10
- debian-11
- debian-12
- ubuntu-22.04
allowed-to-fail:
- false
include:
- scenario: ubuntu-20.04
allowed-to-fail: true
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: "${{ github.repository }}"
- name: Molecule
uses: gofrolist/molecule-action@v2.3.19
with:
molecule_options: --base-config molecule/_shared/base.yml
molecule_args: --scenario-name ${{ matrix.scenario }}
molecule_working_dir: "HanXHX/ansible-nginx"
continue-on-error: ${{ matrix.allowed-to-fail }}
- name: Fake command
run: echo "End of job"

4
.gitignore vendored
View File

@ -1,2 +1,6 @@
.vagrant*
*.swp
*.retry
*.pyc
/tests/hanxhx.php
/.idea

View File

@ -1,13 +0,0 @@
env:
- PLATFORM=debian-wheezy
- PLATFORM=debian-jessie
sudo: required
language: python
services:
- docker
script:
- docker build -f tests/$PLATFORM.Dockerfile -t test-$PLATFORM . && docker run --name $PLATFORM test-$PLATFORM

6
.yamllint.yml 100644
View File

@ -0,0 +1,6 @@
---
extends: default
rules:
line-length: disable

203
README.md
View File

@ -1,141 +1,162 @@
Nginx for Debian Ansible role
=============================
Nginx for Debian/FreeBSD Ansible role
=====================================
[![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-HanXHX.nginx-blue.svg)](https://galaxy.ansible.com/list#/roles/4399) [![Build Status](https://travis-ci.org/HanXHX/ansible-nginx.svg)](https://travis-ci.org/HanXHX/ansible-nginx)
[![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-HanXHX.nginx-blue.svg)](https://galaxy.ansible.com/HanXHX/nginx/) ![GitHub Workflow Status (master branch)](https://img.shields.io/github/actions/workflow/status/hanxhx/ansible-nginx/molecule.yml?branch=master)
Install and configure Nginx on Debian.
Install and configure Nginx on Debian/FreeBSD.
This role is not production ready. SSL management wille come later.
Features:
- SSL/TLS "hardened" support
- Manage basic auth on site / location
- Proxy + Upstream
- Fast PHP configuration
- Preconfigured site templates (should work on many app)
- Auto-configure HTTP2 on SSL/TLS sites
- Manage dynamic modules (install and loading)
- Deploy custom facts.d with sites config
- Can listen with proxy protocol
- Generate certificates with acme.sh (let's encrypt) -- *EXPERIMENTAL*
Supported OS:
| OS | Working | Stable (active support) |
|----------------------|---------|------------------------------------------------------------------------------------------------------|
| Debian Jessie (8) | Yes | Check latest supported version ([1.5.0](https://github.com/HanXHX/ansible-nginx/releases/tag/1.5.0)) |
| Debian Stretch (9) | Yes | Check latest supported version ([1.9.0](https://github.com/HanXHX/ansible-nginx/releases/tag/1.9.0)) |
| Debian Buster (10) | Yes | Yes |
| Debian Bullseye (11) | Yes | Yes |
| Debian Bookworm (12) | Yes | Not yet :) |
| FreeBSD 11 | NA | No |
| FreeBSD 12 | NA | No |
| Ubuntu 20.04 | Yes | Yes |
| Ubuntu 22.04 | Yes | Yes |
Requirements
------------
None.
- Ansible >=2.11
- If you set true to `nginx_backports`, you must install backports repository before lauching this role.
Role Variables
--------------
- `nginx_apt_package`: APT nginx package (try: apt-cache search ^nginx)
- `nginx_root`: root directory where you want to have your files
- `nginx_log_dir`: log directory (if you change it, don't forget to change logrotate config)
- `nginx_ssl_dir`: directory where you install your SSL/TLS keys
- `nginx_resolver`: list of DNS resolver (default: OpenDNS)
- `nginx_error_log_level`: default log level
- `nginx_dh_length`: DH key length (default is 2048)
### Packaging
### PHP
Debian:
- `nginx_php`: boolean if you need to preconfigure PHP (default: false)
- `nginx_php_sockets`: list of //sockets//
- `nginx_apt_package`: APT nginx package (try: apt-cache search ^nginx)
- `nginx_backports`: Install nginx from backport repository (bool)
You should see [Nginx upstream module doc](http://nginx.org/en/docs/http/ngx_http_upstream_module.html).
FreeBSD:
Socket:
- `unix_socket`
- `host`
- `port`
- `weight`
- `max_fails`
- `fail_timeout`
- `nginx_pkgng_package`: PKGNG nginx package (should be "nginx" or "nginx-devel")
### Shared
- `nginx_root`: root directory where you want to have your files
- `nginx_log_dir`: log directory (if you change it, don't forget to change logrotate config)
- `nginx_resolver`: list of DNS resolver (default: OpenDNS)
- `nginx_error_log_level`: default log level
- `nginx_auto_config_httpv2`: boolean, auto configure HTTP2 where possible
- `nginx_fastcgi_fix_realpath`: boolean, use realpath for fastcgi (fix problems with symlinks and PHP opcache)
- `nginx_default_hsts`: string, default header sent for HSTS
### Nginx Configuration
- `nginx_user`
- `nginx_worker_processes`
- `nginx_events`: key/value in events block
- `nginx_http`: key/value in http block
- `nginx_user`
- `nginx_worker_processes`
- `nginx_pid`: daemon pid file
- `nginx_events_*`: all variables in events block
- `nginx_http_*`: all variables in http block
- `nginx_custom_core`: instructions list (for core, will put data in `/etc/nginx/nginx.conf`)
- `nginx_custom_http`: instructions list (will put data in `/etc/nginx/conf.d/custom.conf`)
- `nginx_module_packages`: package list module to install (Debian)
- `nginx_load_modules`: module list to load (full path), should be used only on FreeBSD
### Vhost management
### Misc
You can see many examples in: [tests/test.yml](tests/test.yml).
- `nginx_debug_role`: set _true_ if you need to see output of no\_log tasks
- `nginx_vhosts`: List of dict. A vhost has few keys. See bellow.
About modules
-------------
#### Common
Last updates from Debian backports loads modules from /etc/nginx/modules-enabled directory. Disabling/Enabling is not supported anymore. Please wait further update.
- `name`: (M) List of domain used. The first occurence is the most important!
- `template`: (M) template used to create vhost
- `enable`: (O) Enable the vhost (default is true)
- `delete`: (O) Delete the vhost (default is false)
- `redirect_from`: (O) Domain list to redirect to the first `name`. You can use this key to redirect non-www to www
- `location`: (O) Add new custom locations (it does not overwrite!)
- `more`: (O) Add more custom infos.
- `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
- `manage_local_content`: (O) Boolean. Set to false if you don't want to manage local content (images, css...). This option is useless if you use proxy `template`
Fine configuration
------------------
(O) : Optional
(M) : Mandatory
[Site configuration](doc/site.md)
#### Templates
[PHP configuration](doc/php.md)
- `base`: static template
- `php`: PHP base template. Can work with many frameworks/tools.
- `wordpress`
- `dokuwiki`
- `proxy`
[Upstream Configuration](doc/upstream.md)
Templates works as parent-child.
[SSL/TLS Configuration](doc/ssl.md)
#### About proxy template
[Basic Auth](doc/auth.md)
Proxy template allow you to use Nginx as reverse proxy. Usefull when you have application serveur such as Redmine, Jenkins...
[FreeBSD](doc/freebsd.md)
You have many key added to vhost key:
[acme.sh](doc/acme.md)
- `upstream_name`: (O) upstream name used to pass proxy
- `proxy_params`: (M) list of raw params passed to the vhost
Note
----
(O) : Optional
(M) : Mandatory
### Upstream management
- `nginx_upstreams`: List of dict. An upstream has few keys. See bellow.
Note: Few params are unavailable on old Nginx version. But this role don't put it if your version is too old!
#### Upstream params
- `name`: upstream name. Can be use in vhost with *proxy_pass http://upstream_name*
- `params`: list of param (hash, zone...)
- `servers`: each upstream MUST have at least 1 server
#### Server params
You must set a `path`. For example: *192.168.0.50:8080* or *unix:/tmp/my.sock*.
All this params are optional. You should see [Nginx upstream doc](http://nginx.org/en/docs/http/ngx_http_upstream_module.html).
- `weight`
- `max`fails`
- `fail`timeout`
- `backup`
- `down`
- `route`
- `slow`start`
- Active support for Debian/Ubuntu.
- FreeBSD support is experimental. I only test (for the moment) 10.2 (but it can work on other versions).
Dependencies
------------
None
See: [requirements.yml](requirements.yml).
If you need to dev this role locally on Vagrant
------------------------------------------------
Before use vagrant, run once:
```commandline
ansible-galaxy install -p ./tests/ HanXHX.php,master
```
If you need to dev this role locally with molecule
--------------------------------------------------
Check available scenarios in [molecule](molecule) directory.
With `debian-12` scenario:
```commandline
molecule -v -c molecule/_shared/base.yml verify -s debian-12
```
Example Playbook
----------------
- hosts: servers
roles:
- { role: HanXHX.nginx }
See [tests/test.yml](tests/test.yml).
License
-------
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
------------------
- You can find many other roles in my GitHub "lab": https://github.com/HanXHX/my-ansible-playbooks
- All issues, pull-request are welcome :)
- Twitter: [@hanxhx_](https://twitter.com/hanxhx_)

82
Vagrantfile vendored
View File

@ -5,27 +5,83 @@
Vagrant.configure("2") do |config|
vms = [
[ "debian-wheezy", "deb/wheezy-amd64" , "192.168.33.27" ],
[ "debian-jessie", "deb/jessie-amd64", "192.168.33.28" ]
vms_debian = [
{ :name => "debian-buster", :box => "debian/buster64", :vars => {} },
{ :name => "debian-bullseye", :box => "debian/bullseye64", :vars => {} }
]
config.vm.provider "virtualbox" do |v|
v.cpus = 1
v.memory = 256
end
vms_freebsd = [
{ :name => "freebsd-11", :box => "freebsd/FreeBSD-11.3-STABLE", :vars => {} },
{ :name => "freebsd-12", :box => "freebsd/FreeBSD-12.1-STABLE", :vars => {} }
]
vms.each do |vm|
config.vm.define vm[0] do |m|
m.vm.box = vm[1]
m.vm.network "private_network", ip: vm[2]
conts = [
{ :name => "docker-debian-buster", :docker => "hanxhx/vagrant-ansible:debian10", :vars => {} },
{ :name => "docker-debian-bullseye", :docker => "hanxhx/vagrant-ansible:debian11", :vars => {} },
]
config.vm.network "private_network", type: "dhcp"
config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
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
if opts[:name].include? "bullseye"
m.vm.provision "shell", inline: "[ -f '/root/first_provision' ] || (apt-get update -qq && apt-get -y dist-upgrade && touch /root/first_provision)"
end
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.groups = { "test" => [ vm[0] ] }
ansible.verbose = 'vv'
ansible.sudo = true
ansible.become = true
ansible.extra_vars = opts[:vars].merge({ "nginx_debug_role": true, is_docker: true })
end
end
end
vms_debian.each do |opts|
config.vm.define opts[:name] do |m|
m.vm.box = opts[:box]
m.vm.provider "virtualbox" do |v|
v.cpus = 1
v.memory = 256
end
if opts[:name].include? "bullseye"
m.vm.provision "shell", inline: "[ -f '/root/first_provision' ] || (apt-get update -qq && apt-get -y dist-upgrade && touch /root/first_provision)"
end
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.verbose = 'vv'
ansible.become = true
ansible.extra_vars = opts[:vars].merge({ "nginx_debug_role": true })
end
end
end
vms_freebsd.each do |opts|
config.vm.base_mac = "080027D14C66"
config.vm.define opts[:name] do |m|
m.vm.box = opts[:box]
m.vm.provider "virtualbox" do |v, override|
override.ssh.shell = "csh"
v.cpus = 2
v.memory = 512
end
m.vm.provision "shell", inline: "[ -e /usr/local/bin/bash ] || pkg install -y python bash"
m.vm.provision "ansible" do |ansible|
ansible.playbook = "tests/test.yml"
ansible.verbose = 'vv'
ansible.become = true
ansible.extra_vars = opts[:vars].merge({ "nginx_debug_role": true, "ansible_python_interpreter": '/usr/local/bin/python' })
end
end
end
end

View File

@ -1,29 +1,39 @@
---
# Debian
nginx_apt_package: nginx-full
nginx_backports: false
# FreeBSD
nginx_pkgng_package: nginx
#
# Nginx shared variables
#
nginx_root: "/srv/www"
nginx_log_dir: '/var/log/nginx'
nginx_ssl_dir: '/etc/nginx/ssl'
nginx_resolver:
hosts: ['208.67.222.222', '208.67.220.220'] # OpenDNS
valid: '300'
timeout: '5'
nginx_error_log_level: 'warn' # http://nginx.org/en/docs/ngx_core_module.html#error_log
nginx_dh_length: 2048
nginx_resolver_hosts: ['8.8.8.8', '8.8.4.4']
nginx_resolver_valid: '300s'
nginx_resolver_timeout: '5s'
nginx_error_log_level: 'warn' # http://nginx.org/en/docs/ngx_core_module.html#error_log
nginx_auto_config_httpv2: true
nginx_default_site: null
nginx_default_site_ssl: null
nginx_fastcgi_fix_realpath: true
nginx_default_hsts: 'max-age=63072000; includeSubDomains'
#
# Nginx directories
#
nginx_htpasswd_dir: '{{ nginx_etc_dir }}/htpasswd'
nginx_ssl_dir: '{{ nginx_etc_dir }}/ssl'
nginx_helper_dir: '{{ nginx_etc_dir }}/helper'
#
# Load upstream
#
# PHP
nginx_php: false
nginx_php_sockets:
- unix_socket: "/var/run/php5-fpm.sock"
nginx_php: []
#
# Nginx configuration
@ -31,43 +41,105 @@ nginx_php_sockets:
nginx_user: 'www-data'
nginx_worker_processes: '{{ ansible_processor_vcpus }}'
nginx_events:
worker_connections: '512'
multi_accept: 'on'
use: 'epoll'
#
# Nginx events
#
nginx_events_worker_connections: '512'
nginx_events_multi_accept: 'on'
#
# Nginx HTTP
#
nginx_http:
access_log: 'off'
error_log: 'off'
client_body_buffer_size: '1M'
client_header_buffer_size: '1M'
client_max_body_size: '10M'
large_client_header_buffers: '8 8k'
client_body_timeout: '60'
client_header_timeout: '60'
keepalive_timeout: '30 30'
send_timeout: '120'
ignore_invalid_headers: 'on'
keepalive_requests: '100'
recursive_error_pages: 'on'
sendfile: 'on'
server_name_in_redirect: 'off'
server_tokens: 'off'
tcp_nodelay: 'on'
tcp_nopush: 'on'
reset_timedout_connection: 'on'
gzip: 'on'
gzip_buffers: '16 8k'
gzip_comp_level: '9'
gzip_http_version: '1.0'
gzip_min_length: '0'
gzip_types: 'text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml'
gzip_vary: 'on'
gzip_disable: '"msie6"'
# etag: 'off'
nginx_http_types_hash_max_size: 2048
nginx_http_default_type: 'application/octet-stream'
nginx_http_access_log: 'off'
nginx_http_error_log: 'off'
nginx_http_client_body_buffer_size: '1M'
nginx_http_client_header_buffer_size: '1M'
nginx_http_client_max_body_size: '10M'
nginx_http_large_client_header_buffers: '8 8k'
nginx_http_client_body_timeout: '60'
nginx_http_client_header_timeout: '60'
nginx_http_keepalive_timeout: '30 30'
nginx_http_send_timeout: '120'
nginx_http_ignore_invalid_headers: 'on'
nginx_http_keepalive_requests: '100'
nginx_http_recursive_error_pages: 'on'
nginx_http_sendfile: 'on'
nginx_http_server_name_in_redirect: 'off'
nginx_http_server_tokens: 'off'
nginx_http_tcp_nodelay: 'on'
nginx_http_tcp_nopush: 'on'
nginx_http_reset_timedout_connection: 'on'
nginx_http_gzip: 'on'
nginx_http_gzip_buffers: '16 8k'
nginx_http_gzip_comp_level: '9'
nginx_http_gzip_http_version: '1.0'
nginx_http_gzip_min_length: '0'
nginx_http_gzip_types: 'text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml'
nginx_http_gzip_vary: 'on'
nginx_http_gzip_disable: '"msie6"'
nginx_vhosts: []
#
# Custom global configuration
#
nginx_custom_http: []
nginx_custom_core: []
#
# Nginx default
#
nginx_default_listen:
- '80'
- '[::]:80'
nginx_default_listen_ssl:
- '443'
- '[::]:443'
nginx_default_listen_proxy_protocol: []
nginx_default_listen_proxy_protocol_ssl: []
#
# Sites
#
nginx_sites: []
#
# Upstreams
#
nginx_upstreams: []
#
# htpasswd
#
nginx_htpasswd: []
#
# SSL pairs
#
nginx_ssl_pairs: []
#
# Dynamic modules
#
nginx_module_packages: []
nginx_load_modules: []
#
# Diffie-Hellman
#
nginx_dh: null
nginx_dh_path: '{{ nginx_ssl_dir }}/dhparam.pem'
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
#
# Debug
#
nginx_debug_role: false

15
doc/acme.md 100644
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

41
doc/auth.md 100644
View File

@ -0,0 +1,41 @@
Auth Basic management
=====================
Description
-----------
Auth basic is managed in a separate list. Each auth file can be shared between locations or sites.
Each htpasswd has few keys:
- `name`: (M) used to create file and as pointee
- `description`: (M) Used for the message box :)
- `users`: each users is composed with 3 keys: `name` (M), `password` (M) and `state` (O) present/absent (default: present)
- `state`: (O) present or absent. Default: present
`nginx_htpasswd` should be placed in a vault file.
Example
-------
```yaml
nginx_sites:
# htpasswd on all site
- name: test.local
htpasswd: 'hello'
template: '_base'
# htpasswd only in /hello
- name: test-location.local
template: '_base'
location:
'/hello':
- htpasswd: 'hello'
nginx_htpasswd:
- name: 'hello'
description: 'Please login!'
users:
- name: 'bob'
password: 'my_pass'
```

12
doc/freebsd.md 100644
View File

@ -0,0 +1,12 @@
Freebsd
=======
Limitations
-----------
Due to Ansible + FreeBSD limitations (`ansible_processor_vcpus`), You must explicitely set `nginx_worker_processes`.
About modules
-------------
Dynamic modules must be set with full path (see `nginx_load_modules` path).

22
doc/php.md 100644
View File

@ -0,0 +1,22 @@
PHP
===
`nginx_php`:
- `upstream_name` (M)
- `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).
Each socket have:
- `unix`
XOR
- `host` (M)
- `port` (M)
- `weight` (O)
- `max_fails` (O)
- `fail_timeout` (O)

141
doc/site.md 100644
View File

@ -0,0 +1,141 @@
Site management
===============
You can see many examples in: [tests/test.yml](../tests/test.yml).
`nginx_sites`: List of dict. A site has few keys. See bellow.
Common
------
- `name`: (M) Domain or list of domain used.
- `state`: (O) Site status. Can be "present" (default), "absent" and "disabled".
- `filename`: (O) Specify filename in `/etc/nginx/sites-*`. Do NOT specify default (reserved keyword). It will be used for log filenames and directories creation.
(O): Optional
(M): Mandatory
(D): Depends other keys...
You can use 2 config (at the same time time):
- pre-built: Some configuration are templated (Wordpress, Symfony...), auto create root dir, perform an "A+" on ssllabs for https... etc
- custom: Push your own site config template. Usefull when you have a complex configuration.
Pre-built site config
---------------------
# Keys
- `template`: (M) template used to create site. Optional if you set `state`=`absent` or using `redirect_to`.
- `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).
- `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).
- `redirect_to_code`: Redirect code (default: 302)
- `redirect_https`: (O) Boolean. Redirect HTTP to HTTPS. If "true", you _MUST_ set `proto` to `['https']`.
- `location`: (O) Add new custom locations (it does not overwrite!)
- `location_order`: (O) Due to non preditive `location` order, you can provide the good order (see test-location.local in [tests/test.yml](../tests/test.yml)).
- `location_before`: (O) Add new custom locations before generated location by template
- `location_order_before`: (O) Manages location order for `location_before`
- `more`: (O) Add more custom infos.
- `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
- `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 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.
- `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".
- `listen_proxy_protocol` (O) Enable proxy protocol on http port.
- `listen_proxy_protocol_ssl` (O) Enable proxy protocol on https port.
- `hsts` (O) overwrite default header for hsts
### Templates
- `_base`: static template
- `_dokuwiki`
- `_redirect`: should not be called explicitly
- `_phalcon`: Phalcon PHP Framework
- `_php`: PHP base template. Can work with many frameworks/tools
- `_php_index`: Same as above. But you can only run index.php
- `_proxy`
- `_wordpress`
Templates works as parent-child.
### About proxy template
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 site key:
- `upstream_name`: (O) upstream name used to pass proxy
- `proxy_params`: (M) list of raw params passed to the site
(O) : Optional
### Default sites
You can manage default site by setting domain name to these variables.
- `nginx_default_site`
- `nginx_default_site_ssl`
*IT WORKS ONLY WITH PRE-BUIT SITES*
### Example
```yaml
- nginx_sites:
- name: 'mywebsite.com'
template: '_wordpress'
headers:
x-ansibled: '1'
manage_local_content: false
```
Custom site config
------------------
### Keys
- `custom_template`: (M) template path used
You can add some extra infos if needed.
### Example:
```yaml
- nginx_sites:
- name: 'mycustom-website.com'
custom_template: 'my/template_dir/the-template.conf.j2'
allow_admin: '192.168.0.0/24'
```
In `my/template_dir/the-template.conf.j2`:
```
#
# {{ ansible_managed }} - {{ item.name }}
#
server {
listen 8080 http2 proxy_protocol;
server_name {{ item.name }};
index index.html;
root /var/www/{{ item.name }};
location / {
try_files $uri $uri/ =404;
}
location /admin {
allow {{ item.allow_admin }};
deny all;
}
}
```

96
doc/ssl.md 100644
View File

@ -0,0 +1,96 @@
SSL/TLS Management
==================
You can put all this variables in a separated vault file.
Variables
---------
- `nginx_dh`: DH content
- `nginx_dh_length`: DH key length (default is 2048)
- `nginx_dh_path`: file location
- `nginx_ssl_dir`: directory where you install your SSL/TLS keys
- `nginx_ssl_pairs`
Cert/Key pairs
--------------
Each pair must have a `name`.
Note: `name` is used to deploy key/cert. With defaults values dans `name` = "foo", key is -> /etc/nginx/ssl/foo/foo.key
### Content mode
Key/Cert content is stored in variable. Useful with vault.
- `key`: content of the private key
- `cert`: content of the public key
### Remote file
You can use these variables if you use another task/role to manages your certificates.
- `dest_cert`: remote path where certificate is located
- `dest_key`: remote path where key is located
### Self signed
Create a self-signed pair and deploy it. Do not use this feature in production.
- `self_signed`: set true to use this feature
- `force`: optional feature (default: false), force regen pair (not idempotent)
### Acme
Uses acme.sh to create free certificates. It uses HTTP-01 challenge. Use this feature for standalone servers.
- `acme`: set true to use this feature. It uses `name` (can be a string or string list).
Have a look to [acme configuration](acme.md configuration).
Tips
----
- 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
--------------
If you do not specify any dh param, this role auto generates it.
Example
-------
```yaml
nginx_sites;
- name: 'test-ssl.local'
proto: ['http', 'https']
template: '_base'
ssl_name: 'mysuperkey'
- name: 'test-ssl2.local'
proto: ['http', 'https']
template: '_base'
- name: 'test-ssl3.local'
proto: ['http', 'https']
template: '_base'
- name: 'test-self-signed.local'
proto: ['http', 'https']
template: '_base'
ssl_name: 'this.is.self.signed'
nginx_ssl_pairs:
- name: mysuperkey
key: |
-----BEGIN RSA PRIVATE KEY-----
....(snip)....
-----END RSA PRIVATE KEY-----
cert: |
-----BEGIN CERTIFICATE-----
....(snip)....
-----END CERTIFICATE-----
- name: test-ssl2.local
acme: true
- name: this.is.self.signed
self_signed: true
force: false
```

41
doc/upstream.md 100644
View File

@ -0,0 +1,41 @@
Upstream management
===================
`nginx_upstreams`: List of dict. An upstream has few keys. See bellow.
Upstream params
---------------
- `name`: upstream name. Can be use in site with *proxy_pass http://upstream_name*
- `params`: list of param (hash, zone...)
- `servers`: each upstream MUST have at least 1 server
- `state`: Optional. Can be 'absent' or 'present'
Server params
-------------
You must set a `path`. For example: *192.168.0.50:8080* or *unix:/tmp/my.sock*.
All this params are optional. You should see [Nginx upstream doc](http://nginx.org/en/docs/http/ngx_http_upstream_module.html).
- `weight`
- `max_fails`
- `fail_timeout`
- `backup`
- `down`
- `route`
- `slow_start`
Example
-------
```yaml
nginx_upstreams:
- name: 'proxy_apache'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
state: 'present'
```

View File

@ -1 +0,0 @@
<h1>HTML works</h1>

View File

@ -1,3 +0,0 @@
<?php
echo "<h1>PHP works!</h1>";

View File

@ -0,0 +1,68 @@
def nginx_site_filename(site):
if 'filename' in site:
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']
def nginx_ssl_dir(pair, ssl_dir):
return ssl_dir + '/' + nginx_site_filename(pair)
def nginx_key_path(pair, ssl_dir):
if 'dest_key' in pair:
return pair['dest_key']
else:
return nginx_ssl_dir(pair, ssl_dir) + '/' + nginx_site_filename(pair) + '.key'
def nginx_cert_path(pair, ssl_dir):
if 'dest_cert' in pair:
return pair['dest_cert']
else:
return nginx_ssl_dir(pair, ssl_dir) + '/' + nginx_site_filename(pair) + '.crt'
def nginx_all_site_names(site):
all_sites = []
if isinstance(site['name'], list):
all_sites = all_sites + site['name']
else:
all_sites.append(site['name'])
if 'redirect_from' in site:
if isinstance(site['redirect_from'], list):
all_sites = all_sites + site['redirect_from']
else:
all_sites.append(site['redirect_from'])
return all_sites
def nginx_search_by_ssl_name(sites, ssl_name):
if isinstance(ssl_name, list):
comp_ssl_name = ssl_name[0]
else:
comp_ssl_name = ssl_name
res = None
for site in sites:
if 'ssl_name' in site and site['ssl_name'] == comp_ssl_name:
res = site
break
return res
class FilterModule(object):
''' Nginx module '''
def filters(self):
return {
'nginx_site_filename': nginx_site_filename,
'nginx_site_name': nginx_site_name,
'nginx_ssl_dir': nginx_ssl_dir,
'nginx_key_path': nginx_key_path,
'nginx_cert_path': nginx_cert_path,
'nginx_all_site_names': nginx_all_site_names,
'nginx_search_by_ssl_name': nginx_search_by_ssl_name
}

View File

@ -0,0 +1,10 @@
def php_default_upstream_socket(php_version):
return '/run/php/php%s-fpm.sock' % php_version
class FilterModule(object):
''' PHP module '''
def filters(self):
return {
'php_default_upstream_socket': php_default_upstream_socket,
}

View File

@ -1,6 +1,14 @@
---
- name: restart nginx
action: service name=nginx state=restarted enabled=yes
- name: reload nginx
action: service name=nginx state=reloaded enabled=yes
- name: Reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
- name: Setup
ansible.builtin.setup:

View File

@ -1,16 +1,37 @@
---
galaxy_info:
author: Emilien Mantel
description: Nginx for Debian
company:
license: GPLv2
min_ansible_version: 1.2
namespace: hanxhx
role_name: nginx
description: Nginx for Debian / FreeBSD
company: TripleStack
license: GPLv2
min_ansible_version: '2.11'
platforms:
- name: Debian
versions:
- wheezy
- jessie
categories:
- web
- name: Debian
versions:
- buster
- bullseye
- bookworm
- name: Ubuntu
versions:
- focal
- jammy
- name: FreeBSD
versions:
- '11.0'
- '11.1'
- '12.0'
galaxy_tags:
- web
- debian
- proxy
- http
- http2
- https
- ssl
- tls
- nginx
- cdn
dependencies: []

View File

@ -0,0 +1,19 @@
# Molecule managed
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
{% if item.env is defined %}
{% for var, value in item.env.items() %}
{% if value %}
ENV {{ var }} {{ value }}
{% endif %}
{% endfor %}
{% endif %}
RUN apt-get update && \
apt-get install -y python3 sudo bash ca-certificates iproute2 python-apt-common \
&& apt-get clean

View File

@ -0,0 +1,39 @@
---
scenario:
test_sequence:
- dependency
- syntax
- create
- prepare
- converge
- idempotence
- verify
- destroy
dependency:
name: galaxy
options:
requirements-file: ./molecule/_shared/requirements.yml
role-file: ./molecule/_shared/requirements.yml
driver:
name: docker
role_name_check: 1
provisioner:
name: ansible
env:
ANSIBLE_FILTER_PLUGINS: "../../filter_plugins"
config_options:
defaults:
deprecation_warnings: false
callback_whitelist: timer,profile_tasks
fact_caching: jsonfile
fact_caching_connection: ./cache
forks: 100
connection:
pipelining: true
playbooks:
converge: ../_shared/converge.yml
prepare: ../_shared/prepare.yml
verify: ../_shared/verify.yml
verifier:
name: ansible

View File

@ -0,0 +1,20 @@
---
- name: Converge
hosts: all
gather_facts: true
vars_files:
- vars/misc.yml
vars:
nginx_debug_role: true
tasks:
- name: SHELL | Get ngrok public address
ansible.builtin.shell: set -o pipefail && curl 'http://127.0.0.1:4040/api/tunnels/command_line' 2> /dev/null | jq -r '.public_url' | cut -d '/' -f 3
args:
executable: /bin/bash
register: ngrok
changed_when: false
- name: Include role
ansible.builtin.include_role:
name: "hanxhx.nginx"

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDHTCCAgWgAwIBAgIJAJzUwbFlhyxIMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNV
BAMMGnRlc3Qtc3NsLXByZWRlcGxveWVkLmxvY2FsMB4XDTE2MDExMjE2MDUxNVoX
DTI2MDEwOTE2MDUxNVowJTEjMCEGA1UEAwwadGVzdC1zc2wtcHJlZGVwbG95ZWQu
bG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDm4q94vffiU89G
GO7rjDfr3C32tH9sM5sXqJT+7N5BLYLF0iSRIvy33MtwFu//TV3f+8nLlQuHYVVk
L6NEvaL8lh+nRexCQ/y+aXMh7lMhuwPXGgPR1LXsTqyDXbmV9c7k/Kwx5qHAcOb9
d9YzmcOSO4M9v3WMl/4Zw2J7zNYruypxNBgFEwFx3NJ3AztACMYoVOIR5mS8ARX6
xea4ddii1F41Vch+eiCGP9VZwDhEujhjy9PXvdBtYNwggM6d82Df9wwaFyIW5DU4
PhpgAngvE2keY0GLy/LaXa6LAW+TCfPMRT2RtDuvqWr+useWF+O3n81TZqM/G7LV
9iPxkkRNAgMBAAGjUDBOMB0GA1UdDgQWBBSzXW5UY02/S0xrrobZCVOhas6VeDAf
BgNVHSMEGDAWgBSzXW5UY02/S0xrrobZCVOhas6VeDAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4IBAQC0+Tr0w9aG4f3LG3+WRGKfMopKICNEkA7JrPrvVUq8
7UgtdrpOUZAL5AKxVVo1rHDdoL/VpjdqHdhyPzaSUl8hppCFsWmdQh4wLKGoyvcN
AqSGpXTeLSoFJ357F2OIQpXm2lfT2fVGebwyCNFkwpp7klFnmOusSl2/v5Y5cz+A
WvWrDg3jsNglx3mNLVcjbOSnen2PsZSmcVo27D0el6oDju8jjstyJ+Dvu0WP+CDL
s/VolFdbei7d4r2dj86OZ/BCZurltyc0wI3NMOdUuA7q4f1MPTRu7qr/ua5ItK92
Avc+Gjn/Y/aIhzKpPicJQDK6FzxjfhCc8xtk0EjB4IpP
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDm4q94vffiU89G
GO7rjDfr3C32tH9sM5sXqJT+7N5BLYLF0iSRIvy33MtwFu//TV3f+8nLlQuHYVVk
L6NEvaL8lh+nRexCQ/y+aXMh7lMhuwPXGgPR1LXsTqyDXbmV9c7k/Kwx5qHAcOb9
d9YzmcOSO4M9v3WMl/4Zw2J7zNYruypxNBgFEwFx3NJ3AztACMYoVOIR5mS8ARX6
xea4ddii1F41Vch+eiCGP9VZwDhEujhjy9PXvdBtYNwggM6d82Df9wwaFyIW5DU4
PhpgAngvE2keY0GLy/LaXa6LAW+TCfPMRT2RtDuvqWr+useWF+O3n81TZqM/G7LV
9iPxkkRNAgMBAAECggEAEEeZkczrRpUcP1gQuKEZbFMJFqUhevKkk+V6JAN1pGje
GK65j1ZFNX2nBo9Hetvsq5doYidvOat+RuMpAvbQIDlBoBzJDN8YWiC7UoAocm9q
VOdrr4btEO13MogQRuefH/xE8/vMGfKcBvFFNDw6UvxJQ7hVRIWPECf7sLj/vPOC
OpMKghxcabQqidMPKyyHVPhQjuIvqW/SqBFpD+Ul0Ja1QGdx+p+/EwVmXnei6Kr8
/ypULreHqIlBLD6McfFehxDV0m5U7qXb5xK3zdUurIhZixKLjbdRrorNInfEvlOh
vDy+hsF5GSzvn9dRrMAy/QcRPpXU47VNYZ5BfdCBTQKBgQD8VCbdpG5siXSlIjZd
xypgK1ttp8udTPWC1trnAc+Ku9O+cGmvABxYJA1iR/GDpSfMxglB7OhSecywKrr+
S7Yjs9e/dyBmvF7U15JJaGp+db2Ct64z7MvqkwSJ5a0qrrZJRFetDdqdH9FPvURs
B147jbKsPiGcljjXbZlOBHJH9wKBgQDqPqoA3VqYOmvR7Ei8/skY2EOpFpOhSNko
ARFwUsDNHRk677URH97TCHq5UrwubfCeIcIptXHrMfaTsfq8vPLPykReIMRaknxf
DULJPHSoeBLrCAZmaWF1JVyYhrLhHNAzQ3u7a/kYIJm87FEZy3Ml6FSZmIGbRBqx
zqZYKoHs2wKBgQD469tbk7cLg556uYGAidYYAS20w29uwlkAtgxFD9g6OIjuud7I
MQfFO+uoJOjwwaC9ti+zxY56roVq1PybmP0Zw3T3AQIJ15KFzhQWLte/4U8PATzt
JJEV2+sCTn3COZDCPpVvttcPYjAOxdwV5j7j6Sl2GeT2oIt6mjg+asyCiQKBgQDk
LPxu8TBRfv8OMqs8Jrf/EpL9/7b48bxOwpOZJZMXelPcXCm1r6TfTrA1HAmg9Ijh
kKLQ/CUm5Ll7b3B+L1Qa4r2sLyD11SF/eaxn2BMPFD/hYCTT160ObsF+9h8DN4z7
kq3RiMDRJth69nuds9fLwj++ipcdhr62G0VgNq/u5wKBgCz/I5J3tPNjrU9YampR
0gNnUkUfJWbiVMsG9uwL9l0L/ZzQHvELJ523QXQ0v/e/szHCyoX319u8HEQlC0Jw
Twlj81HDZzruDUB/mcH6Ee3zHKOmmF6ma+CgoYJJElKW89MUttPdmkH2J1QqLz+7
EGREwqjr8/wm22DzKNiyDXJ0
-----END PRIVATE KEY-----

View File

@ -0,0 +1,15 @@
---
- name: Prepare
hosts: all
gather_facts: true
vars_files:
- vars/misc.yml
tasks:
- name: INCLUDE_TASKS | Pre tasks related to OS
ansible.builtin.include_tasks: "../../tests/includes/pre_{{ ansible_os_family }}.yml"
- name: INCLUDE_TASKS | Pre_tasks common
ansible.builtin.include_tasks: "../../tests/includes/pre_common.yml"

View File

@ -0,0 +1,7 @@
---
roles:
- name: hanxhx.php
collections:
- community.general

View File

@ -0,0 +1,16 @@
# {{ ansible_managed }} - custom template
server {
listen 80;
listen 8888 http2;
listen 9999 http2 proxy_protocol;
server_name {{ item.name }};
index index.html index.htm;
root {{ item.root }};
location / {
try_files $uri $uri/ =404;
}
}

View File

@ -0,0 +1,259 @@
---
# Force SysVinit, since systemd won't work in a Docker container
ansible_service_mgr: "sysvinit"
# ----------------------------------------
# Copied from {role_dir}/tests/group_vars/all.yml
# ----------------------------------------
# Internal vars
int_ansible_ssl_dir: '/etc/ansible-ssl'
# Role vars
nginx_worker_processes: 1 # Ansible+FreeBSD can't detect CPU number
nginx_apt_package: 'nginx-extras'
nginx_module_packages: ['libnginx-mod-http-headers-more-filter']
nginx_custom_core:
- 'worker_rlimit_nofile 4242;'
nginx_upstreams:
- name: 'test'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
- name: 'test-absent'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
state: 'absent'
nginx_htpasswd:
- name: 'hello'
description: 'Please login!'
users:
- name: 'hx'
password: 'asdfg'
state: 'absent'
- name: 'hanx'
password: 'qwerty'
- name: 'deleteme'
description: 'Please login!'
users: []
state: 'absent'
nginx_acmesh: true
nginx_acmesh_test: true
nginx_ssl_pairs:
- name: '{{ ngrok.stdout }}'
acme: true
- name: 'test-ssl-selfsigned.local'
self_signed: true
force: false
- name:
- 'test-ssl-predeployed.local'
- 'test-multiple-name.local' # Hack: tests for acme with multiple name, without using acme
dest_key: "{{ int_ansible_ssl_dir }}/test.key"
dest_cert: "{{ int_ansible_ssl_dir }}/test.crt"
- name: 'test-ssl.local'
key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvavrJWFp3Al2VwRgKx+4Y2mbRRvoxvyd2pyN0xMJ/tCJscaG
8s60v6WZ9FcCOeMkSI2DXsk4z7pbQdQn0h2GDr/5MOJkPAVWSWEN46tpaLZ3v0zp
88ZIbnEk1G0PsdFuW/pnLsakPlAMrl1VArFsV6YsatLt30UIYYcRO97StkoOehCx
A5w+XqtfHZeQZ0/DS81633gwYUcMuSTUFZ60r7ge1/m77DTSKg3rTVk5sebP8cjS
+aWHvxP/GyvvDsT+3gjRJx2/5O3JkfH0zaOsaU2Avj0PR0c5rhynrNO/l1k+GJJB
cbBrM+yA8Ofzp4oXUrCfaIq3RuL3Pd+khcKsiwIDAQABAoIBAQCPpAMQ7BUfbosQ
m1+5SOx7XR8Z12kSSX3CcY12rJSFRakB2TeZ6rE38lIFmV82N67iw0kaH4nGx3sU
/3aoyXMc+IXfX5RJYEFYkQfTw5ywkH9fgQAsfZ2dBlK+DVo1cEYDoj9CTW1VQ4pX
Ape+0l8agd5hiBxdWgpe0ctbbARnx584viLiA/iPBDNxKi9zEYw+WP7hSj5QWahr
a09tubcC4L6tjvv8CoZTRSKfCW64vWRDvE6vmA+zJN9Arc1WTYzF1KO1Gybwf8h7
stJb191smAgGDFhKo0j58ncyAnrS1k4mapm86QQhlfIA6DKvvC0qm3KdQns5b7HM
PyzW0hwBAoGBAO2mTVTOsziom9vtBwM0nRMMEgynR2X3EKMJz2mjcCf66f1F+aQ5
DvQFM2V8S2s1nGnPh8NKKZ8DxW1NKuR4qx82zeAXpUs9ibHxOnw4YRC485zqc2Wt
fSO1OEDYeKyzWP1nGGtCntYUXzJnWn/wz0mBGKzLKTuLwyFIKx1b7bybAoGBAMxR
N+lT57rX6d4GUqcgNOuWMZ/D8egnE5+hsoiFnHOisRLOgUgBBSy4rwAZx+rdHYT+
RO11L1PLYEzyvnO0f13R+N7aqKwNXDSzZGA+jb4pjkVidIC2smG/JYKJH5Z+kakw
mwMKP0wdRZJsCaMgScHmWJS8d6Ox/XJJoWrTWTbRAoGAWJlEgVaiaIArwz1F/QLz
gHNik0cWDkSi9jWlFxwwpycbbypUXM5M7dq2g6JoN6sACk6trbgLdlYgl5RKZm06
VuPGs0H9hOSHXkix5jfasDJT2G9r4D9ixRo9w6cwriobBjYWW3612tgzeYYgrkwn
655uhZUkZSfA8rqGIGbyZfsCgYAf5WH8G+wmIATTc1s92epJCOZwUY+XNVp75itP
4sPczX4lOHW4PuiG5cH0GxI5mRE9rNAn3c5on2xGNvMCbyAfDmNyruH8Eg3d8E9w
MvO/xw79x/P2EA9i8QszCKMUxGeK6RqZ6+SbxkoRJKqQe77n9UTI228179hoGhSH
77ySsQKBgQC8SSZn6a8PpSIIFXB9WCFMwfGFYbUz0wvpaeZP8GKx3BEzMeJqSUaJ
hrQgpwQXkueeamlCQcvV3AUCoBRWTYRLDrWiUIXuIgikDWBFp6TBvTnVRI7iktly
fNED7jXOSjJqnFmdkZlAI5V8dM++mVYVykJD6jcaVRQvxqFLrhSaRg==
-----END RSA PRIVATE KEY-----
cert: |
-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIJALKJfbk5vuieMA0GCSqGSIb3DQEBBQUAMBkxFzAVBgNV
BAMMDnRlc3Qtc3NsLmxvY2FsMB4XDTE2MDExMTE2NDI0NFoXDTI2MDEwODE2NDI0
NFowGTEXMBUGA1UEAwwOdGVzdC1zc2wubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQC9q+slYWncCXZXBGArH7hjaZtFG+jG/J3anI3TEwn+0Imx
xobyzrS/pZn0VwI54yRIjYNeyTjPultB1CfSHYYOv/kw4mQ8BVZJYQ3jq2lotne/
TOnzxkhucSTUbQ+x0W5b+mcuxqQ+UAyuXVUCsWxXpixq0u3fRQhhhxE73tK2Sg56
ELEDnD5eq18dl5BnT8NLzXrfeDBhRwy5JNQVnrSvuB7X+bvsNNIqDetNWTmx5s/x
yNL5pYe/E/8bK+8OxP7eCNEnHb/k7cmR8fTNo6xpTYC+PQ9HRzmuHKes07+XWT4Y
kkFxsGsz7IDw5/OnihdSsJ9oirdG4vc936SFwqyLAgMBAAGjUDBOMB0GA1UdDgQW
BBRaSF1L+ivPhmIVGQjtviBqZWDS9DAfBgNVHSMEGDAWgBRaSF1L+ivPhmIVGQjt
viBqZWDS9DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCjrgB9+Zuq
Rx7T2mRUl4jf75dLabuBQD0ePALTtvNyBSghhzSr90mE7GlFOYAv0JsmEa3R1LVF
wLPIdrIhNHpt7hN0PkhUlfgmxBnRSCfhpiq4xxsDVFM7ehtDz4+dv1LUDMXo07+E
f24g9aqmypiFzHisUQrYIhtQmHxRpKyGp6kDAW9qNxg6k/Um00aHdYfuD9ER4ksR
f8Hto7f+vssKxCRY2OZXqq13PxEwC5+hgAUkTdrycA/moXFuHJi3lCnCND7sSzvG
tXBggOusyFZFC4bs2m+V+Z+RN+tK2c/c0nq5HR8MV5HwIm4Z8GoT2/0BfJ00cgWL
lVz0gDBfdH8f
-----END CERTIFICATE-----
nginx_custom_http:
- 'add_header X-ansible 1;'
- 'geoip_country {% if ansible_os_family == "Debian" %}/usr/share/GeoIP/GeoIP.dat{% else %}/usr/local/share/GeoIP/GeoIP.dat{% endif %};'
- 'map $geoip_country_code $allowed_country {'
- ' default yes;'
- ' MA no;'
- ' DZ no;'
- ' TN no;'
- '}'
nginx_default_site: 'test.local'
nginx_default_site_ssl: 'test-ssl-predeployed.local'
nginx_sites:
- name:
- 'test.local'
- 'test-alias.local'
- 'test2-alias.local'
template: '_base'
filename: 'first-test'
override_try_files: '$uri/ $uri =404'
headers:
'X-Frame-Options': 'deny always'
'X-ansible-default': '1'
manage_local_content: false
use_error_log: true
more:
- 'autoindex off;'
location:
'/test':
- 'return 403;'
'/gunther':
- 'return 404;'
'/status':
- 'stub_status on;'
- 'access_log off;'
- 'allow 127.0.0.1;'
- 'deny all;'
- name: 'test-htpasswd.local'
template: '_base'
location_before:
'/hello':
- htpasswd: 'hello'
location:
'/public':
- htpasswd: false
use_error_log: true
- name: 'test-htpasswd-all.local'
template: '_base'
htpasswd: 'hello'
- name: 'test-location.local'
template: '_base'
location_before:
'/b':
- 'alias /var/tmp;'
'/c':
- 'alias /var/tmp;'
location:
'/':
- 'alias /var/tmp;'
'/a':
- 'alias /var/tmp;'
location_order_before:
- '/b'
- '/c'
location_order:
- '/'
- '/a'
- name: 'test-php.local'
php_upstream: "manual"
upstream_params:
- 'fastcgi_param FOO bar;'
redirect_from:
- 'www.test-php.local'
template: '_php'
use_error_log: true
use_access_log: true
- name: 'test-php-index.local'
template: '_php_index'
php_upstream: 'hx_unix'
- name: 'test-php-index2.local'
template: '_php_index2'
php_upstream: 'hx_ip'
- name: 'test-proxy.local'
listen:
- 8080
template: '_proxy'
upstream_name: 'test'
headers:
'X-proxyfied': '1'
- name: 'deleted.local'
state: 'absent'
- name: 'redirect-to.local'
redirect_to: 'http://test.local'
- name: 'test-ssl.local'
proto: ['http', 'https']
template: '_base'
- name:
- 'test-ssl-selfsigned.local'
- 'www.test-ssl-selfsigned.local'
proto: ['http', 'https']
template: '_base'
hsts: 'max-age=1664;'
- name: 'test-ssl-predeployed.local'
proto: ['http', 'https']
template: '_base'
ssl_name: 'test-ssl-predeployed.local'
headers:
'X-ansible-default': '1'
ssl_template: false
- name: 'test-ssl-redirect.local'
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
- name:
- 'test-ssl-redirect-many.local'
- 'test-ssl-redirect-many2.local'
listen_ssl: [8443]
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
redirect_from:
- 'www.test-ssl-redirect-many.local'
- 'www.test-ssl-redirect-many2.local'
- name: 'test-ssl-proxy-protocol.local'
proto: ['http', 'https']
listen_proxy_protocol: [20080]
listen_proxy_protocol_ssl: [20443]
template: '_base'
ssl_name: 'test-ssl.local'
headers:
'X-Proxy-Protocol': '1'
- name: '{{ ngrok.stdout }}'
proto: ['http', 'https']
listen_proxy_protocol: [21080]
listen_proxy_protocol_ssl: [21443]
template: '_base'
ssl_name: '{{ ngrok.stdout }}'
headers:
'X-acme': '1'
- name: 'test-custom-template.local'
custom_template: 'templates/custom_template.conf.j2'
root: '/tmp/custom-template'
nginx_php: "{{ [{'upstream_name': 'manual', 'sockets': [{'host': '127.0.0.1', 'port': '9636'}]}] }}"
nginx_dh_length: 1024

View File

@ -0,0 +1,19 @@
---
- name: Verify
hosts: all
gather_facts: true
vars_files:
- vars/misc.yml
vars:
nginx_root: "/srv/www"
tasks:
- name: SHELL | Get ngrok public address
ansible.builtin.shell: set -o pipefail && curl 'http://127.0.0.1:4040/api/tunnels/command_line' 2> /dev/null | jq -r '.public_url' | cut -d '/' -f 3
args:
executable: /bin/bash
register: ngrok
changed_when: false
- name: INCLUDE_TASKS | Post_tasks common
ansible.builtin.include_tasks: "../../tests/includes/post_common.yml"

View File

@ -0,0 +1,13 @@
---
platforms:
- name: debian-10
image: dokken/debian-10
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

View File

@ -0,0 +1,13 @@
---
platforms:
- name: debian-11
image: dokken/debian-11
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

View File

@ -0,0 +1,13 @@
---
platforms:
- name: debian-12
image: dokken/debian-12
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

View File

View File

@ -0,0 +1,20 @@
---
platforms:
- name: ubuntu-20.04
image: dokken/ubuntu-20.04
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true
# Segfault on Ubuntu 20.04 with `nginx-extras` package...
provisioner:
inventory:
host_vars:
ubuntu-20.04:
nginx_apt_package: 'nginx-full'

View File

@ -0,0 +1,13 @@
---
platforms:
- name: ubuntu-22.04
image: dokken/ubuntu-22.04
command: /lib/systemd/systemd
dockerfile: ../_shared/Dockerfile.j2
capabilities:
- SYS_ADMIN
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true

4
requirements.yml 100644
View File

@ -0,0 +1,4 @@
---
collections:
- community.general

57
tasks/config.yml 100644
View File

@ -0,0 +1,57 @@
---
- name: TEMPLATE | Deploy nginx.conf
ansible.builtin.template:
src: "etc/nginx/nginx.conf.j2"
dest: "{{ nginx_etc_dir }}/nginx.conf"
mode: 0644
owner: root
group: root
notify: Reload nginx
- name: TEMPLATE | Deploy all helpers
ansible.builtin.template:
src: "{{ item }}"
dest: "{{ nginx_helper_dir }}/{{ item | basename | regex_replace('.j2$', '') }}"
mode: 0644
owner: root
group: root
with_fileglob: '../templates/etc/nginx/helper/*.j2'
notify: Reload nginx
- name: TEMPLATE | Deploy custom http configuration
ansible.builtin.template:
src: "etc/nginx/conf.d/custom.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/custom.conf"
mode: 0644
owner: root
group: root
notify: Reload nginx
- name: LINEINFILE | Fix path
ansible.builtin.lineinfile:
regexp: '{{ item.0.regexp }}'
line: '{{ item.0.line }}'
dest: '{{ item.1 }}'
loop: "{{ list_one | product(list_two) | list }}"
vars:
list_one:
- regexp: '^fastcgi_param SCRIPT_FILENAME'
line: 'fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;'
- regexp: '^fastcgi_param DOCUMENT_ROOT'
line: 'fastcgi_param DOCUMENT_ROOT $realpath_root;'
list_two:
- '{{ nginx_etc_dir }}/fastcgi.conf'
when: nginx_fastcgi_fix_realpath
- name: COPY | Add modules manually
ansible.builtin.copy:
content: |
{% for m in nginx_load_modules %}
load_module {{ m }};
{% endfor %}
dest: "{{ nginx_etc_dir }}/modules-enabled/000-modules.conf"
mode: 0644
owner: root
group: root
notify: Reload nginx

21
tasks/htpasswd.yml 100644
View File

@ -0,0 +1,21 @@
---
- name: FILE | Delete htpasswd file
ansible.builtin.file:
path: "{{ nginx_htpasswd_dir }}/{{ item.name }}"
state: absent
loop: "{{ nginx_htpasswd }}"
when: item.state is defined and item.state == 'absent'
no_log: "{{ not nginx_debug_role }}"
- name: HTPASSWD | Manage files
community.general.htpasswd:
name: "{{ item.1.name }}"
password: "{{ item.1.password }}"
path: "{{ nginx_htpasswd_dir }}/{{ item.0.name }}"
mode: 0644
owner: root
group: root
loop: "{{ nginx_htpasswd | subelements('users') }}"
when: item.0.state is not defined or item.0.state == 'present'
no_log: "{{ not nginx_debug_role }}"

View File

@ -0,0 +1,27 @@
---
- name: SET_FACT | Bypass https://github.com/ansible/ansible/issues/19874
ansible.builtin.set_fact:
ansible_distribution_release: 'buster'
when: ansible_facts.distribution_major_version == "buster/sid"
- name: APT | Update cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
changed_when: false
- name: APT | Install nginx and dependencies
ansible.builtin.apt:
pkg: "{{ nginx_apt_package }}"
default_release: "{{ ansible_distribution_release + '-backports' if (nginx_backports and ansible_distribution == 'Debian') else ansible_distribution_release }}"
- name: APT | Install nginx modules
ansible.builtin.apt:
pkg: "{{ nginx_module_packages }}"
state: present
- name: APT | Install passlib lib
ansible.builtin.apt:
pkg: "python3-passlib"
state: present

View File

@ -0,0 +1,59 @@
---
- name: PKGNG | Install nginx and related tools
community.general.pkgng:
name: "{{ item }}"
state: present
loop:
- acme.sh
- "{{ nginx_pkgng_package }}"
- py27-passlib
- curl
#
# Bypass https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=224166#c1
#
- name: Bypass https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=224166#c1
when: true
block:
- name: COMMAND | Create /usr/local/etc/fdfs/http.conf
ansible.builtin.command: touch /usr/local/etc/fdfs/http.conf
args:
creates: /usr/local/etc/fdfs/http.conf
notify: Restart nginx
- name: LINEINFILE | Tune fdfs
ansible.builtin.lineinfile:
regexp: ^load_fdfs_parameters_from_tracker
line: load_fdfs_parameters_from_tracker=false
path: /usr/local/etc/fdfs/mod_fastdfs.conf
notify: Restart nginx
- name: META | Flush handlers (Restart nginx when fdfs is tuned)
ansible.builtin.meta: flush_handlers
- name: FILE | Create configuration dir (like Debian)
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/{{ item }}"
state: directory
mode: 0755
owner: root
group: root
loop:
- conf.d
- sites-available
- sites-enabled
- name: FILE | Create log directory
ansible.builtin.file:
path: "{{ nginx_log_dir }}"
owner: "{{ nginx_user }}"
group: wheel
mode: 0755
state: directory
- name: SERVICE | Enable nginx
ansible.builtin.service:
name: nginx
enabled: true

View File

@ -0,0 +1,36 @@
---
- name: STAT | Check acme.sh is installed
ansible.builtin.stat:
path: "{{ nginx_acmesh_dir }}"
register: acme
- name: Install acme.sh if needed
when: not acme.stat.exists
block:
- name: APT | Install git
ansible.builtin.apt:
pkg: git
- name: GIT | Get acme.sh
ansible.builtin.git:
repo: 'https://github.com/Neilpang/acme.sh.git'
dest: '{{ nginx_acmesh_git_dir }}'
update: false
version: master
- name: COMMAND | Install acme.sh
ansible.builtin.command: ./acme.sh --install --home "{{ nginx_acmesh_dir }}"
args:
chdir: "{{ nginx_acmesh_git_dir }}"
creates: "{{ nginx_acmesh_dir }}"
- name: COMMAND | Force acme.sh to use letsencrypt (instead of zerossl)
ansible.builtin.command: '{{ nginx_acmesh_dir }}/acme.sh --set-default-ca --server letsencrypt --home "{{ nginx_acmesh_dir }}"'
changed_when: true
- name: FILE | Remove temp acme.sh dir
ansible.builtin.file:
path: '{{ nginx_acmesh_git_dir }}'
state: absent

View File

@ -0,0 +1,8 @@
---
- name: INCLUDE_TASKS | Install
ansible.builtin.include_tasks: "{{ ansible_os_family }}.yml"
- name: IMPORT_TASKS | acme
ansible.builtin.import_tasks: "acme.yml"
when: nginx_acmesh

View File

@ -1,40 +1,30 @@
---
- name: APT | Install nginx
apt: pkg={{ nginx_apt_package }} state=latest update_cache=yes cache_valid_time=3600
- name: INCLUDE_VARS | Related to OS
ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
tags: ['nginx::site', 'nginx::ssl']
- name: SHELL | Get Nginx version
shell: nginx -v 2>&1 | sed -r 's#.*/##;' | cut -d ' ' -f 1
register: nginx_version
changed_when: false
- name: INCLUDE_TASKS | Install
ansible.builtin.import_tasks: "install/main.yml"
tags: ['nginx::site', 'nginx::ssl']
- name: TEMPLATE | Deploy nginx.conf
template: src=etc/nginx/nginx.conf.j2 dest=/etc/nginx/nginx.conf validate= "nginx -t"
notify: restart nginx
- name: IMPORT_TASKS| Prepare
ansible.builtin.import_tasks: prepare.yml
tags: ['nginx::site', 'nginx::ssl']
- name: FILE | Create /etc/nginx/helpers
file: dest=/etc/nginx/helpers owner=root mode=0755 state=directory
- name: IMPORT_TASKS| Install
ansible.builtin.import_tasks: config.yml
- name: FILE | Create /etc/nginx/ssl
file: dest=/etc/nginx/ssl owner=root mode=0755 state=directory
- name: IMPORT_TASKS| Upstream configuration
ansible.builtin.import_tasks: upstream.yml
#- name: COMMAND | Creates DH file
# command: openssl dhparam -out {{ nginx_dh_path }} {{ nginx_dh_length }}
# args:
# creates: "{{ nginx_dh_path }}"
- name: IMPORT_TASKS| htpasswd configuration
ansible.builtin.import_tasks: htpasswd.yml
- name: TEMPLATE | Deploy all helpers
template: src={{ item }} dest=/etc/nginx/helpers/{{ item | basename | regex_replace('\.j2$','') }}
with_fileglob: '../templates/etc/nginx/helpers/*.j2'
notify: reload nginx
- name: IMPORT_TASKS| SSL configuration
ansible.builtin.import_tasks: ssl/main.yml
tags: ['nginx::ssl']
- name: INCLUDE | Upstream configuration
include: upstream.yml
when: nginx_php
- name: INCLUDE | Vhosts configuration
include: vhost.yml
# TODO:
# - Python
# - Ruby (SHIT!)
- name: IMPORT_TASKS| Sites configuration
ansible.builtin.import_tasks: site.yml
tags: ['nginx::site']

47
tasks/prepare.yml 100644
View File

@ -0,0 +1,47 @@
---
- name: SHELL | Get Nginx version
ansible.builtin.shell: nginx -v 2>&1 | sed -r 's#.*/##;' | cut -d ' ' -f 1
args:
executable: /bin/sh
register: nginx_version
changed_when: false
check_mode: false
tags:
- skip_ansible_lint
- name: SHELL | Get module list
ansible.builtin.shell: |
nginx -V 2>&1 |
tr -- - '\n' |
grep -A 1 with |
grep _module |
sed -r 's/_module//g; s/\s+//g' |
sort
args:
executable: /bin/sh
register: shell_modules
changed_when: false
check_mode: false
tags:
- skip_ansible_lint
- name: SET_FACT | Save modules
ansible.builtin.set_fact:
nginx_modules: "{{ shell_modules.stdout_lines }}"
- name: FILE | Create folders
ansible.builtin.file:
dest: "{{ item.dir }}"
owner: "{{ item.owner }}"
mode: "{{ item.mode }}"
state: directory
loop: "{{ nginx_dirs }}"
- name: FILE | Create ansible facts dir
ansible.builtin.file:
path: /etc/ansible/facts.d
state: directory
mode: 0755
owner: root
group: root

125
tasks/site.yml 100644
View File

@ -0,0 +1,125 @@
---
- name: FAIL | Check filenames
ansible.builtin.fail:
msg: "Forbidden keyword default on site {{ item | nginx_site_name }}"
when: item.filename is defined and item.filename == 'default'
loop: "{{ nginx_sites }}"
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FAIL | Check HTTPS redir and proto
ansible.builtin.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)
loop: "{{ nginx_sites }}"
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Create root directory
ansible.builtin.file:
path: "{{ nginx_root }}"
state: directory
mode: 0755
owner: root
group: root
- name: FILE | Create root public folders (foreach nginx_sites)
ansible.builtin.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') }}"
loop: "{{ 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
ansible.builtin.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 }}"
mode: 0644
owner: root
group: root
notify: 'Reload nginx'
when: (item.state is not defined or item.state != 'absent') and item.custom_template is not defined
loop: "{{ nginx_sites }}"
loop_control:
label: "{{ item | nginx_site_name }}"
- name: TEMPLATE | Create sites with preconfigured template
ansible.builtin.template:
src: "{{ item.custom_template }}"
dest: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}"
mode: 0644
owner: root
group: root
notify: 'Reload nginx'
when: (item.state is not defined or item.state != 'absent') and item.custom_template is defined
loop: "{{ nginx_sites }}"
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Delete sites
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}"
state: absent
loop: "{{ nginx_sites | product(dirs) | list }}"
notify: 'Reload nginx'
when: item.0.state is defined and item.0.state == 'absent'
vars:
dirs: ['sites-available', 'sites-enabled']
loop_control:
label: "{{ nginx_etc_dir }}/{{ item.1 }}/{{ item.0 | nginx_site_filename }}"
- name: FILE | Enable sites
ansible.builtin.file:
src: "{{ nginx_etc_dir }}/sites-available/{{ item | nginx_site_filename }}"
dest: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_filename }}"
state: link
loop: "{{ nginx_sites }}"
notify: 'Reload nginx'
when: >
item.state is not defined or item.state == 'present'
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Disable sites
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_filename }}"
state: absent
loop: "{{ nginx_sites }}"
notify: 'Reload nginx'
when: item.state is defined and item.state == 'disabled'
loop_control:
label: "{{ item | nginx_site_name }}"
- name: FILE | Delete default site when explicitely defined
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/sites-enabled/default"
state: absent
notify: 'Reload nginx'
when: nginx_default_site is not none
- name: FILE | Auto set default site
ansible.builtin.file:
src: "{{ nginx_etc_dir }}/sites-available/default"
dest: "{{ nginx_etc_dir }}/sites-enabled/default"
state: link
notify: 'Reload nginx'
when: nginx_default_site is none
- name: TEMPLATE | Deploy facts
ansible.builtin.template:
src: etc/ansible/facts.d/nginx.fact.j2
dest: /etc/ansible/facts.d/nginx.fact
mode: 0644
notify: ['Setup']

103
tasks/ssl/acme.yml 100644
View File

@ -0,0 +1,103 @@
---
- name: SET_FACT | Assign default...
ansible.builtin.set_fact:
acme_create: []
- name: STAT | Check if certificates are already installed
ansible.builtin.stat:
path: "{{ item | nginx_cert_path(nginx_ssl_dir) }}"
loop: "{{ nginx_ssl_pairs }}"
when: item.acme is defined and item.acme
register: acme_installed_certs
- name: SET_FACT | Assign var with certificates to create
ansible.builtin.set_fact:
acme_create: "{{ acme_create | default([]) + [(item.item)] }}"
loop: "{{ acme_installed_certs.results }}"
when: item.skipped is not defined and (not item.stat.exists or item.stat.size == 0)
- name: BLOCK | Start acme
block:
- name: TEMPLATE | Create fake site
ansible.builtin.template:
src: "etc/nginx/conf.d/FAKESITE.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf"
mode: 0644
owner: root
group: root
loop: "{{ acme_create }}"
register: fake_site
notify: Restart nginx
- name: TEMPLATE | Create fake site
ansible.builtin.template:
src: "etc/nginx/conf.d/FAKESITE.conf.j2"
dest: "/tmp/FAKESITE_{{ item | nginx_site_name }}.conf"
mode: 0644
owner: root
group: root
loop: "{{ acme_create }}"
- name: FILE | Delete current site if needed # noqa: no-handler
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/sites-enabled/{{ item | nginx_site_name }}"
state: absent
loop: "{{ acme_create }}"
when: fake_site.changed
notify: Restart nginx
- name: META | Ensure nginx is restarted if needed
ansible.builtin.meta: flush_handlers
- name: COMMAND | Get certificates
ansible.builtin.command: |
{{ nginx_acmesh_bin }}
--home {{ nginx_acmesh_dir }}
--issue{% for s in nginx_sites | nginx_search_by_ssl_name(item.name) | nginx_all_site_names %} -d {{ s }}{% endfor %}
--nginx
{% if nginx_acmesh_test %}--test --log{% endif %}
args:
creates: "{{ nginx_acmesh_dir }}/{{ item | nginx_site_name }}/fullchain.cer"
loop: "{{ acme_create }}"
register: acme_get
failed_when: acme_get.rc != 0 and acme_get.rc != 2
no_log: "{{ not nginx_debug_role }}"
- name: FILE | Create SSL dir per site
ansible.builtin.file:
path: "{{ nginx_ssl_dir }}/{{ item | nginx_site_name }}"
loop: "{{ acme_create }}"
- name: COMMAND | Install certificates
ansible.builtin.command: |
{{ nginx_acmesh_bin }}
--home {{ nginx_acmesh_dir }}
--install-cert -d {{ nginx_sites | nginx_search_by_ssl_name(item | nginx_site_name) | nginx_site_name }}
--fullchain-file {{ item | nginx_cert_path(nginx_ssl_dir) }}
--key-file {{ item | nginx_key_path(nginx_ssl_dir) }}
--reloadcmd "service nginx reload"
args:
creates: "{{ item | nginx_cert_path(nginx_ssl_dir) }}"
loop: "{{ nginx_ssl_pairs }}"
when: item.acme is defined and item.acme
notify: Restart nginx
rescue:
- name: FAIL | Explicit
ansible.builtin.fail:
msg: "Something is bad... Auto crash!"
always:
- name: FILE | Delete fake sites
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/conf.d/FAKESITE_{{ item | nginx_site_name }}.conf"
state: absent
loop: "{{ acme_create }}"
notify: Restart nginx
- name: META | Flush handlers
ansible.builtin.meta: flush_handlers

View File

@ -0,0 +1,8 @@
---
- name: IMPORT_TASKS | standard.yml
ansible.builtin.import_tasks: standard.yml
- name: IMPORT_TASKS | acme.yml
ansible.builtin.import_tasks: acme.yml
when: nginx_acmesh

View File

@ -0,0 +1,86 @@
---
- name: Generate DH if needed
when: nginx_dh is not string
block:
- name: STAT | Get info about DH file
ansible.builtin.stat:
path: "{{ nginx_dh_path }}"
get_checksum: false
register: stat_dh_file
- name: SHELL | Get info about DH file
ansible.builtin.shell: |
set -o pipefail &&
openssl dhparam -in {{ nginx_dh_path }} -text -noout 2>&1 | awk '/DH Parameters/ { print substr($3, 2) }'
args:
executable: /bin/bash
changed_when: false
register: dh_info
when: stat_dh_file.stat.exists
- name: COMMAND | Generate DH file # noqa: no-changed-when
ansible.builtin.command: openssl dhparam -out {{ nginx_dh_path }} {{ nginx_dh_length }}
when: not stat_dh_file.stat.exists or (dh_info.stdout | int != nginx_dh_length | int)
notify: Restart nginx
- name: COPY | Deploy DH file from vars
ansible.builtin.copy:
content: "{{ nginx_dh }}"
dest: "{{ nginx_dh_path }}"
owner: root
group: root
mode: 0640
when: nginx_dh is string
notify: Restart nginx
- name: FILE | Create SSL directories
ansible.builtin.file:
path: "{{ item | nginx_ssl_dir(nginx_ssl_dir) }}"
state: directory
owner: root
group: root
mode: 0750
loop: "{{ nginx_ssl_pairs }}"
when: item.dest_key is not defined or item.dest_cert is not defined
no_log: "{{ not nginx_debug_role }}"
- name: COPY | Deploy SSL keys
ansible.builtin.copy:
content: "{{ item.key }}"
dest: "{{ item | nginx_key_path(nginx_ssl_dir) }}"
owner: root
group: root
mode: 0640
loop: "{{ nginx_ssl_pairs }}"
when: item.key is defined
notify: Restart nginx
no_log: "{{ not nginx_debug_role }}"
- name: COPY | Deploy SSL certs
ansible.builtin.copy:
content: "{{ item.cert }}"
dest: "{{ item | nginx_cert_path(nginx_ssl_dir) }}"
owner: root
group: root
mode: 0644
loop: "{{ nginx_ssl_pairs }}"
when: item.cert is defined
notify: Restart nginx
no_log: "{{ not nginx_debug_role }}"
- name: COMMAND | Create self-signed certificates
ansible.builtin.command: |
openssl req
-new -newkey rsa:2048 -sha256 -days 3650 -nodes -x509
-subj '/CN={{ item | nginx_site_name }}'
-keyout {{ item | nginx_key_path(nginx_ssl_dir) }}
-out {{ item | nginx_cert_path(nginx_ssl_dir) }}
args:
chdir: "{{ item | nginx_ssl_dir(nginx_ssl_dir) }}"
creates: "{{ '/tmp/dummy' if item.force is defined and item.force else item | nginx_cert_path(nginx_ssl_dir) }}"
loop: "{{ nginx_ssl_pairs }}"
when: item.self_signed is defined
notify: Restart nginx
no_log: "{{ not nginx_debug_role }}"

View File

@ -1,10 +1,29 @@
---
- name: TEMPLATE | Deploy PHP upstream to Nginx
template: src=etc/nginx/upstream/php.conf.j2 dest=/etc/nginx/conf.d/php.conf
notify: reload nginx
ansible.builtin.template:
src: "etc/nginx/conf.d/php.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/php.conf"
mode: 0644
owner: root
group: root
notify: Reload nginx
- name: TEMPLATE | Deploy other upstreams
template: src=etc/nginx/upstream/upstream.conf.j2 dest=/etc/nginx/conf.d/upstream-{{ item.name }}.conf
with_items: nginx_upstreams
notify: reload nginx
ansible.builtin.template:
src: "etc/nginx/conf.d/_upstream.conf.j2"
dest: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf"
mode: 0644
owner: root
group: root
loop: "{{ nginx_upstreams }}"
when: item.state is not defined or item.state == 'present'
notify: Reload nginx
- name: FILE | Delete other upstreams
ansible.builtin.file:
path: "{{ nginx_etc_dir }}/conf.d/upstream-{{ item.name }}.conf"
state: absent
loop: "{{ nginx_upstreams }}"
when: item.state is defined and item.state == 'absent'
notify: Reload nginx

View File

@ -1,65 +0,0 @@
---
- name: FILE | Create root folders (foreach nginx_vhosts)
file: >
path={{ nginx_root }}/{{ item.name[0] }}/public
state=directory
owner={{ item.owner | default('www-data') }}
group={{ item.group | default('www-data') }}
mode={{ item.mode | default('0755') }}
with_items: nginx_vhosts
when: item.root is not defined and item.template != '_proxy'
- name: TEMPLATE | Create vhosts
template: >
src=etc/nginx/sites-available/{{ item.template }}.j2
dest=/etc/nginx/sites-available/{{ item.name[0] }}
with_items: nginx_vhosts
notify: reload nginx
when: item.delete is not defined or not item.delete
#- name: COPY | Add index.html / index.php
# copy: src={{ item }} dest={{ nginx_root }}/{{ item.name }}/public/{{ item }} owner=www-data group=www-data mode=0666
# with_fileglob: "web/*"
- name: FILE | Delete vhosts
file: dest=/etc/nginx/sites-enabled/{{ item.name[0] }} state=absent
file: dest=/etc/nginx/sites-available/{{ item.name[0] }} state=absent
with_items: nginx_vhosts
notify: reload nginx
when: item.delete is defined and item.delete
- name: FILE | Enable vhosts
file: >
src=/etc/nginx/sites-available/{{ item.name[0] }}
dest=/etc/nginx/sites-enabled/{{ item.name[0] }}
state=link
with_items: nginx_vhosts
notify: reload nginx
when: >
((item.enable is not defined) or
(item.enable is defined and item.enable)) and
(item.delete is not defined or not item.delete)
- name: FILE | Disable vhosts
file: dest=/etc/nginx/sites-enabled/{{ item.name[0] }} state=absent
with_items: nginx_vhosts
notify: reload nginx
when: item.enable is defined and not item.enable
#- name: FILE | Create ssl dir per vhost (if needed)
# file: dest=/etc/nginx/ssl/{{ item.name }} owner=root mode=0750 state=directory
# with_items: nginx_vhosts
# when: item.ssl.use is defined and item.ssl.use
# TODO...
#- name: COPY | Deploy SSL keys if needed
# copy: src=keys/{{ item.name }}/{{ item.name }}.crt dest=/etc/nginx/ssl/{{ item.name }} mode=660
# copy: src=keys/{{ item.name }}/{{ item.name }}.key dest=/etc/nginx/ssl/{{ item.name }} mode=660
# with_items: nginx_vhosts
# when: item.ssl.use and not generatekey
# TODO:
# - deploy defaults files (index.html/index.php) allready in files/
# - work with role "ssl_autosign"

View File

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

View File

@ -0,0 +1,18 @@
{% set site = nginx_sites | nginx_search_by_ssl_name(item.name) %}
{% set __listen = item.listen | default(nginx_default_listen) %}
{% set __listen_proxy_protocol = item.listen_proxy_protocol | default(nginx_default_listen_proxy_protocol) %}
server {
{% for port in __listen %}
listen {{ port }};
{% endfor %}
{% for port in __listen_proxy_protocol %}
listen {{ port }} proxy_protocol;
{% endfor %}
server_name {{ site | nginx_all_site_names | join(" ") }};
location / {
return 503;
}
}

View File

@ -1,5 +1,5 @@
{%- macro s(key, value, is_bool, min_version) %}
{% if nginx_version.stdout | version_compare(min_version, 'ge') %}
{% if nginx_version.stdout is version(min_version, 'ge') %}
{% if is_bool and value %} {{ key }}{% elif not is_bool %} {{ key }}={{ value }}{% endif %}
{% endif %}
{%- endmacro -%}

View File

@ -0,0 +1,7 @@
#
# {{ ansible_managed }}
#
{% for i in nginx_custom_http %}
{{ i }}
{% endfor %}

View File

@ -0,0 +1,29 @@
#
# {{ ansible_managed }}
#
{% for php in nginx_php %}
upstream {{ php.upstream_name }} {
{% for sock in php.sockets | default([]) %}
{% if sock.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 }} weight={{ sock.weight | default('1') }};
{% endif %}
{% endfor %}
}
{% endfor %}
{% if ansible_local.hanxhx_php.fpm_pool is defined%}
# -------------------------------------------------------
# Auto-detected PHP config for HanXHX.php ansible role
# -------------------------------------------------------
{% for php in ansible_local.hanxhx_php.fpm_pool %}
upstream {{ php.name }} {
server {% if php.listen.startswith('/') %}unix:{{ php.listen }}{% else %}{{ php.listen }}{% endif %};
}
{% endfor %}
{% endif %}
# vim:filetype=nginx

View File

@ -0,0 +1,23 @@
#
# {{ ansible_managed }}
# See: https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=intermediate&openssl=1.1.1n&hsts=false&guideline=5.7
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
ssl_dhparam {{ nginx_dh_path }};
# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# Replace with the IP address of your resolver
resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }};
# vim:filetype=nginx

View File

@ -0,0 +1,21 @@
#
# {{ ansible_managed }}
# See: https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=modern&openssl=1.1.1n&hsts=false&guideline=5.7
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# modern configuration
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# Replace with the IP address of your resolver
resolver {{ nginx_resolver_hosts | join(' ') }} valid={{ nginx_resolver_valid }};
resolver_timeout {{ nginx_resolver_timeout }};
# vim:filetype=nginx

View File

@ -1,18 +0,0 @@
#
# {{ ansible_managed }}
#
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_stapling on;
ssl_stapling_verify on;
resolver {{ nginx_resolver.hosts | default(['208.67.222.222', '208.67.220.220']) | join(' ') }} valid={{ nginx_resolver.valid}}s;
resolver_timeout {{ nginx_resolver.timeout }}s;
# vim:filetype=nginx

View File

@ -1,18 +0,0 @@
#
# {{ ansible_managed }}
#
ssl_ciphers "AES256+EECDH:AES256+EDH";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_stapling on;
ssl_stapling_verify on;
resolver {{ nginx_resolver.hosts | default(['208.67.222.222', '208.67.220.220']) | join(' ') }} valid={{ nginx_resolver.valid}}s;
resolver_timeout {{ nginx_resolver.timeout }}s;
# vim:filetype=nginx

View File

@ -4,27 +4,53 @@
user {{ nginx_user }};
worker_processes {{ nginx_worker_processes }};
pid /run/nginx.pid;
pid {{ nginx_pid }};
{% for i in nginx_custom_core %}
{{ i }}
{% endfor %}
include {{ nginx_etc_dir }}/modules-enabled/*.conf;
events {
{% for key, value in nginx_events.iteritems() %}
{{ "\t%-30s %s" | format(key, value) }};
{% endfor %}
worker_connections {{ nginx_events_worker_connections }};
multi_accept {{ nginx_events_multi_accept }};
use {{ nginx_events_use }};
}
http {
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
types_hash_max_size {{ nginx_http_types_hash_max_size }};
include {{ nginx_etc_dir }}/mime.types;
# From Ansible
{% for key, value in nginx_http.iteritems() %}
{{ "\t%-30s %s" | format(key, value) }};
{% endfor %}
# /From Ansible
default_type {{ nginx_http_default_type }};
access_log {{ nginx_http_access_log }};
error_log {{ nginx_http_error_log }};
client_body_buffer_size {{ nginx_http_client_body_buffer_size }};
client_header_buffer_size {{ nginx_http_client_header_buffer_size }};
client_max_body_size {{ nginx_http_client_max_body_size }};
large_client_header_buffers {{ nginx_http_large_client_header_buffers }};
client_body_timeout {{ nginx_http_client_body_timeout }};
client_header_timeout {{ nginx_http_client_header_timeout }};
keepalive_timeout {{ nginx_http_keepalive_timeout }};
send_timeout {{ nginx_http_send_timeout }};
ignore_invalid_headers {{ nginx_http_ignore_invalid_headers }};
keepalive_requests {{ nginx_http_keepalive_requests }};
recursive_error_pages {{ nginx_http_recursive_error_pages }};
sendfile {{ nginx_http_sendfile }};
server_name_in_redirect {{ nginx_http_server_name_in_redirect }};
server_tokens {{ nginx_http_server_tokens }};
tcp_nodelay {{ nginx_http_tcp_nodelay }};
tcp_nopush {{ nginx_http_tcp_nopush }};
reset_timedout_connection {{ nginx_http_reset_timedout_connection }};
gzip {{ nginx_http_gzip }};
gzip_buffers {{ nginx_http_gzip_buffers }};
gzip_comp_level {{ nginx_http_gzip_comp_level }};
gzip_http_version {{ nginx_http_gzip_http_version }};
gzip_min_length {{ nginx_http_gzip_min_length }};
gzip_types {{ nginx_http_gzip_types }};
gzip_vary {{ nginx_http_gzip_vary }};
gzip_disable {{ nginx_http_gzip_disable }};
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
include {{ nginx_etc_dir }}/conf.d/*.conf;
include {{ nginx_etc_dir }}/sites-enabled/*;
}
# vim:filetype=nginx

View File

@ -1,6 +1,68 @@
{% set __listen = item.listen | default(['80']) %}
{% set __listen_ssl = item.listen_ssl | default(['443']) %}
{% set __proto = item.proto | default(['http']) %}
{% set __main_name = item | nginx_site_name %}
{% set __listen = item.listen | default(nginx_default_listen) %}
{% set __listen_ssl = item.listen_ssl | default(nginx_default_listen_ssl) %}
{% set __listen_proxy_protocol = item.listen_proxy_protocol | default(nginx_default_listen_proxy_protocol) %}
{% set __listen_proxy_protocol_ssl = item.listen_proxy_protocol_ssl | default(nginx_default_listen_proxy_protocol_ssl) %}
{% set __location = item.location | default({}) %}
{% set __location_before = item.location_before | default({}) %}
{% set __headers = item.headers | default(nginx_servers_default_headers) %}
{% set __ssl_name = item.ssl_name | default(__main_name) %}
{% set __location_order = item.location_order | default(__location.keys()) %}
{% set __location_order_before = item.location_order_before | default(__location_before.keys()) %}
{% set __http2 = nginx_auto_config_httpv2 and 'http_v2' in nginx_modules %}
{% macro listen_http() %}
{% endmacro %}
{% macro server_name(name) %}
{% if name is string %}{{ name }}{% else %}{{ name | join(" ") }}{% endif %}
{% endmacro %}
{% macro locations(list, order) %}
{% if order | length > 0 %}
# --> Custom locations
{% for location in order %}
location {{ location }} {
{% set opts = list[location] %}
{% for opt in opts %}
{% if opt.htpasswd is defined %}
{{ htpasswd(opt.htpasswd, 2) }}
{% else %}
{{ opt }}
{% endif %}
{% endfor %}
}
{% endfor %}
# <-- Custom locations
{% endif %}
{% endmacro %}
{% macro htpasswd(htpasswd_name, indent=1) -%}
{%- if htpasswd_name != false %}
{%- for ht in nginx_htpasswd if ht.name == htpasswd_name %}
{{ "\t" * indent }}auth_basic "{{ ht.description }}";
{{ "\t" * indent }}auth_basic_user_file {{ nginx_htpasswd_dir }}/{{ ht.name }};
{%- endfor %}
{%- endif %}
{%- endmacro %}
{% macro ssl(ssl_name) %}
{% for sn in nginx_ssl_pairs if (sn.name is defined and (sn | nginx_site_name) == ssl_name) %}
ssl_certificate {{ sn | nginx_cert_path(nginx_ssl_dir) }};
ssl_certificate_key {{ sn | nginx_key_path(nginx_ssl_dir) }};
{% endfor %}
{%- endmacro %}
{% macro httpsredirect(name) %}
server {
{% for port in __listen %}
listen {{ port }};
{% endfor %}
{% for port in __listen_proxy_protocol %}
listen {{ port }} proxy_protocol;
{% endfor %}
server_name {{ server_name(name) }};
location / {
return 301 https://{{ name }}{% if '443' not in __listen_ssl and 443 not in __listen_ssl %}:{{ __listen_ssl[0] }}{% endif %}$request_uri;
}
}
{% endmacro %}
#
# {{ ansible_managed }}
#
@ -9,89 +71,123 @@
# HTTP
#
server {
{% if 'http' in __proto %}
{% for port in __listen %}
listen {{ port }};
listen {{ port }}{% if nginx_default_site == __main_name %} default_server{% endif %};
{% endfor %}
server_name {{ item.name | join(' ') }};
{% for port in __listen_proxy_protocol %}
listen {{ port }}{% if nginx_default_site == __main_name %} default_server{% endif %} proxy_protocol;
{% endfor %}
{% endif %}
{% if 'https' in __proto %}
{% for port in __listen_ssl %}
listen {{ port }}{% if nginx_default_site_ssl == __main_name %} default_server{% endif %} ssl{% if __http2 %} http2{% endif %};
{% endfor %}
{% for port in __listen_proxy_protocol_ssl %}
listen {{ port }}{% if nginx_default_site_ssl == __main_name %} default_server{% endif %} ssl{% if __http2 %} http2{% endif %} proxy_protocol;
{% endfor %}
{{ ssl(__ssl_name) }}
{% if item.ssl_template is not defined or item.ssl_template != false %}
include {{ nginx_helper_dir + '/ssl-' + item.ssl_template | default('strong') }};
add_header Strict-Transport-Security "{{ item.hsts | default(nginx_default_hsts) }}" always;
{% endif %}
{% endif %}
server_name {{ server_name(item.name) }};
{% block root %}
{% if item.root is defined %}
root {{ item.root }};
{% else %}
root {{ nginx_root }}/{{ item.name[0] }}/public;
root {{ nginx_root }}/{{ item | nginx_site_filename }}/public;
{% endif %}
{% endblock %}
{% block template_index %}
index {{ item.index | default('index.html index.htm') }};
{% endblock %}
{% block template_more %}
{% if item.more is defined and item.more is iterable %}
{% for line in item.more %}
{{ line }}
{% endfor %}
{% endif %}
{% endblock %}
{% if item.htpasswd is defined %}
{{ htpasswd(item.htpasswd, 1) }}
{% endif %}
{% block template_headers %}
# --> Custom headers
{% for key, value in __headers.items() %}
add_header {{ key }} "{{ value | regex_replace('\s+always$', '') }}"{% if value | regex_search('\s+always$') %} always{% endif %};
{% endfor %}
# <-- Custom headers
{% endblock %}
{{ locations(__location_before, __location_order_before) }}
{% if not '/' in __location %}
location / {
{% block template_try_files %}
try_files {{ override_try_files | default('$uri $uri/ =404') }};
try_files {{ item.override_try_files | default('$uri $uri/ =404') }};
{% endblock %}
}
{% endif %}
{% block template_upstream_location %}
{% endblock %}
{% block template_custom_location %}
{% endblock %}
{{ locations(__location, __location_order) }}
{% block template_local_content %}
{% if item.manage_local_content is not defined or item.manage_local_content %}
location ~ /\.ht {
deny all;
}
{% block template_local_content %}
{% if item.manage_local_content is not defined or item.manage_local_content %}
location = /favicon.ico {
expires 30d;
access_log off;
log_not_found off;
}
location ~* \.(txt|js|css|png|jpe?g|gif|ico|svg)$ {
location ~* \.(txt|js|css|png|jpe?g|gif|ico|svg|(o|t)tf|woff2?|eot)$ {
expires 30d;
log_not_found off;
}
{% endif %}
{% endblock %}
{% if __location is iterable and __location | length > 0 %}
# --> Custom locations
{% for location, opts in __location.iteritems() %}
location {{ location }} {
{% for opt in opts %}
{{ opt }}
{% endfor %}
}
{% endfor %} # <-- Custom locations
{% endif %}
{% if item.use_access_log is defined and item.use_access_log %}
access_log {{ nginx_log_dir }}/{{ item.name[0] }}_access.log combined;
{% if item.use_access_log is defined %}
{% if item.use_access_log %}
access_log {{ nginx_log_dir }}/{{ __main_name }}_access.log combined;
{% else %}
access_log off;
{% endif %}
{% if item.use_error_log is defined and item.use_error_log %}
error_log {{ nginx_log_dir }}/{{ item.name[0] }}_error.log {{ nginx_error_log_level }};
{% endif %}
{% if item.use_error_log is defined %}
{% if item.use_error_log %}
error_log {{ nginx_log_dir }}/{{ __main_name }}_error.log {{ nginx_error_log_level }};
{% else %}
error_log off;
{% endif %}
{% endif %}
}
{#
ssl on;
ssl_certificate {{ nginx_ssl_dir }}/{{ item.name }}/{{ item.name }}.crt;
ssl_certificate_key {{ nginx_ssl_dir }}/{{ item.name }}/{{ item.name }}.key;
include /etc/nginx/helpers/ssl-{{ item.ssl.template | default('strong') }};
#}
# HTTPS
#server {
#}
{% if item.redirect_https is defined and item.redirect_https %}
#
# Redirect HTTP to HTTPS
#
{% if item.name is string %}
{{ httpsredirect(item.name) }}
{% else %}
{% for i in item.name %}
{{ httpsredirect(i) }}
{% endfor %}
{% endif %}
{% endif %}
{% if item.redirect_from is defined and item.redirect_from is iterable %}
#
@ -101,9 +197,36 @@ server {
{% for port in __listen %}
listen {{ port }};
{% endfor %}
server_name {{ item.redirect_from | join(' ') }};
return 301 $scheme://{{ item.name[0] }}$request_uri;
{% for port in __listen_proxy_protocol %}
listen {{ port }} proxy_protocol;
{% endfor %}
server_name {{ server_name(item.redirect_from) }};
location / {
return 301 $scheme://{{ __main_name }}$request_uri;
}
}
{% if 'https' in __proto %}
server {
{% for port in __listen_ssl %}
listen {{ port }} ssl{% if __http2 %} http2{% endif %};
{% endfor %}
{% for port in __listen_proxy_protocol_ssl %}
listen {{ port }} ssl{% if __http2 %} http2{% endif %} proxy_protocol;
{% endfor %}
{{ ssl(__ssl_name) }}
{% if item.ssl_template is not defined or item.ssl_template != false %}
include {{ nginx_helper_dir + '/ssl-' + item.ssl_template | default('strong') }};
add_header Strict-Transport-Security "{{ item.hsts | default(nginx_default_hsts) }}" always;
{% endif %}
server_name {{ server_name(item.redirect_from) }};
location / {
return 301 https://{{ __main_name }}{% if '443' not in __listen_ssl and 443 not in __listen_ssl %}:{{ __listen_ssl[0] }}{% endif %}$request_uri;
}
}
{% endif %}
{% endif %}
# vim:filetype=nginx

View File

@ -1,25 +1,22 @@
{% extends "_base.j2" %}
{% block template_index %}
index {{ item.index | default('index.html index.htm index.php') }};
{% endblock %}
{% block template_try_files %}
try_files {{ override_try_files | default('$uri $uri/ /index.php') }};
try_files {{ item.override_try_files | default('$uri $uri/ =404') }};
{% endblock %}
{% block template_upstream_location %}
location ~ \.php$ {
fastcgi_pass php;
fastcgi_pass {{ item.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

@ -0,0 +1,20 @@
{% extends "_php.j2" %}
{% block template_upstream_location %}
location = /index.php {
fastcgi_pass {{ item.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 %}
include fastcgi.conf;
}
{% endblock %}
{% block template_custom_location %}
location ~ \.(php\d?|phtml)$ {
return 403;
}
{% endblock %}

View File

@ -0,0 +1,18 @@
{% extends "_php.j2" %}
{% block template_try_files %}
try_files {{ item.override_try_files | default('$uri $uri/ /index.php') }};
{% endblock %}
{% block template_upstream_location %}
location = /index.php {
fastcgi_pass {{ item.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 %}
include fastcgi.conf;
}
{% endblock %}

View File

@ -1,16 +1,14 @@
{% extends "_base.j2" %}
{% block template_try_files %}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://{{ item.upstream_name }};
proxy_read_timeout 90;
{#proxy_redirect http://{{ upstream.name }} https://jenkins.domain.tld;#}
{% block root %}
{% if item.root is defined %}
root {{ item.root }};
{% endif %}
{% endblock %}
{% block template_try_files %}
include {{ nginx_etc_dir }}/proxy_params;
proxy_pass http://{{ item.upstream_name }};
{% if item.proxy_params is defined and item.proxy_params is iterable %}
{% for param in item.proxy_params %}
{{ param }}

View File

@ -0,0 +1,14 @@
{% extends "_base.j2" %}
{% block root %}
{% endblock %}
{% block template_index %}
{% endblock %}
{% block template_try_files %}
return {{ item.redirect_to_code | default('302') }} {{ item.redirect_to }}$request_uri;
{% endblock %}
{% block template_local_content %}
{% endblock %}

View File

@ -0,0 +1,27 @@
{% extends "_php.j2" %}
{% block template_try_files %}
try_files $uri /index.php$is_args$args;
{% endblock %}
{% block template_upstream_location %}
location /bundles {
try_files $uri =404;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass {{ item.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 %}
include fastcgi.conf;
internal;
}
location ~ \.php$ {
return 404;
}
{% endblock %}

View File

@ -3,3 +3,9 @@
{% block template_try_files %}
try_files $uri $uri/ /index.php?$args;
{% endblock %}
{% block template_custom_location %}
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
{% endblock %}

View File

@ -1,15 +0,0 @@
#
# {{ ansible_managed }}
#
upstream php {
{% for item in nginx_php_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 %}
}
# vim:filetype=nginx

View File

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

View File

@ -1,6 +0,0 @@
FROM williamyeh/ansible:debian7-onbuild
RUN apt-get update
CMD ["sh", "tests/test.sh"]
EXPOSE 6379

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDHTCCAgWgAwIBAgIJAJzUwbFlhyxIMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNV
BAMMGnRlc3Qtc3NsLXByZWRlcGxveWVkLmxvY2FsMB4XDTE2MDExMjE2MDUxNVoX
DTI2MDEwOTE2MDUxNVowJTEjMCEGA1UEAwwadGVzdC1zc2wtcHJlZGVwbG95ZWQu
bG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDm4q94vffiU89G
GO7rjDfr3C32tH9sM5sXqJT+7N5BLYLF0iSRIvy33MtwFu//TV3f+8nLlQuHYVVk
L6NEvaL8lh+nRexCQ/y+aXMh7lMhuwPXGgPR1LXsTqyDXbmV9c7k/Kwx5qHAcOb9
d9YzmcOSO4M9v3WMl/4Zw2J7zNYruypxNBgFEwFx3NJ3AztACMYoVOIR5mS8ARX6
xea4ddii1F41Vch+eiCGP9VZwDhEujhjy9PXvdBtYNwggM6d82Df9wwaFyIW5DU4
PhpgAngvE2keY0GLy/LaXa6LAW+TCfPMRT2RtDuvqWr+useWF+O3n81TZqM/G7LV
9iPxkkRNAgMBAAGjUDBOMB0GA1UdDgQWBBSzXW5UY02/S0xrrobZCVOhas6VeDAf
BgNVHSMEGDAWgBSzXW5UY02/S0xrrobZCVOhas6VeDAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4IBAQC0+Tr0w9aG4f3LG3+WRGKfMopKICNEkA7JrPrvVUq8
7UgtdrpOUZAL5AKxVVo1rHDdoL/VpjdqHdhyPzaSUl8hppCFsWmdQh4wLKGoyvcN
AqSGpXTeLSoFJ357F2OIQpXm2lfT2fVGebwyCNFkwpp7klFnmOusSl2/v5Y5cz+A
WvWrDg3jsNglx3mNLVcjbOSnen2PsZSmcVo27D0el6oDju8jjstyJ+Dvu0WP+CDL
s/VolFdbei7d4r2dj86OZ/BCZurltyc0wI3NMOdUuA7q4f1MPTRu7qr/ua5ItK92
Avc+Gjn/Y/aIhzKpPicJQDK6FzxjfhCc8xtk0EjB4IpP
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDm4q94vffiU89G
GO7rjDfr3C32tH9sM5sXqJT+7N5BLYLF0iSRIvy33MtwFu//TV3f+8nLlQuHYVVk
L6NEvaL8lh+nRexCQ/y+aXMh7lMhuwPXGgPR1LXsTqyDXbmV9c7k/Kwx5qHAcOb9
d9YzmcOSO4M9v3WMl/4Zw2J7zNYruypxNBgFEwFx3NJ3AztACMYoVOIR5mS8ARX6
xea4ddii1F41Vch+eiCGP9VZwDhEujhjy9PXvdBtYNwggM6d82Df9wwaFyIW5DU4
PhpgAngvE2keY0GLy/LaXa6LAW+TCfPMRT2RtDuvqWr+useWF+O3n81TZqM/G7LV
9iPxkkRNAgMBAAECggEAEEeZkczrRpUcP1gQuKEZbFMJFqUhevKkk+V6JAN1pGje
GK65j1ZFNX2nBo9Hetvsq5doYidvOat+RuMpAvbQIDlBoBzJDN8YWiC7UoAocm9q
VOdrr4btEO13MogQRuefH/xE8/vMGfKcBvFFNDw6UvxJQ7hVRIWPECf7sLj/vPOC
OpMKghxcabQqidMPKyyHVPhQjuIvqW/SqBFpD+Ul0Ja1QGdx+p+/EwVmXnei6Kr8
/ypULreHqIlBLD6McfFehxDV0m5U7qXb5xK3zdUurIhZixKLjbdRrorNInfEvlOh
vDy+hsF5GSzvn9dRrMAy/QcRPpXU47VNYZ5BfdCBTQKBgQD8VCbdpG5siXSlIjZd
xypgK1ttp8udTPWC1trnAc+Ku9O+cGmvABxYJA1iR/GDpSfMxglB7OhSecywKrr+
S7Yjs9e/dyBmvF7U15JJaGp+db2Ct64z7MvqkwSJ5a0qrrZJRFetDdqdH9FPvURs
B147jbKsPiGcljjXbZlOBHJH9wKBgQDqPqoA3VqYOmvR7Ei8/skY2EOpFpOhSNko
ARFwUsDNHRk677URH97TCHq5UrwubfCeIcIptXHrMfaTsfq8vPLPykReIMRaknxf
DULJPHSoeBLrCAZmaWF1JVyYhrLhHNAzQ3u7a/kYIJm87FEZy3Ml6FSZmIGbRBqx
zqZYKoHs2wKBgQD469tbk7cLg556uYGAidYYAS20w29uwlkAtgxFD9g6OIjuud7I
MQfFO+uoJOjwwaC9ti+zxY56roVq1PybmP0Zw3T3AQIJ15KFzhQWLte/4U8PATzt
JJEV2+sCTn3COZDCPpVvttcPYjAOxdwV5j7j6Sl2GeT2oIt6mjg+asyCiQKBgQDk
LPxu8TBRfv8OMqs8Jrf/EpL9/7b48bxOwpOZJZMXelPcXCm1r6TfTrA1HAmg9Ijh
kKLQ/CUm5Ll7b3B+L1Qa4r2sLyD11SF/eaxn2BMPFD/hYCTT160ObsF+9h8DN4z7
kq3RiMDRJth69nuds9fLwj++ipcdhr62G0VgNq/u5wKBgCz/I5J3tPNjrU9YampR
0gNnUkUfJWbiVMsG9uwL9l0L/ZzQHvELJ523QXQ0v/e/szHCyoX319u8HEQlC0Jw
Twlj81HDZzruDUB/mcH6Ee3zHKOmmF6ma+CgoYJJElKW89MUttPdmkH2J1QqLz+7
EGREwqjr8/wm22DzKNiyDXJ0
-----END PRIVATE KEY-----

View File

@ -0,0 +1,252 @@
---
# Internal vars
int_ansible_ssl_dir: '/etc/ansible-ssl'
# Role vars
nginx_worker_processes: 1 # Ansible+FreeBSD can't detect CPU number
nginx_apt_package: 'nginx-extras'
nginx_module_packages: ['libnginx-mod-http-headers-more-filter']
nginx_custom_core:
- 'worker_rlimit_nofile 4242;'
nginx_upstreams:
- name: 'test'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
- name: 'test-absent'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
state: 'absent'
nginx_htpasswd:
- name: 'hello'
description: 'Please login!'
users:
- name: 'hx'
password: 'asdfg'
state: 'absent'
- name: 'hanx'
password: 'qwerty'
- name: 'deleteme'
description: 'Please login!'
users: []
state: 'absent'
nginx_acmesh: true
nginx_acmesh_test: true
nginx_ssl_pairs:
- name: '{{ ngrok.stdout }}'
acme: true
- name: 'test-ssl-selfsigned.local'
self_signed: true
force: false
- name:
- 'test-ssl-predeployed.local'
- 'test-multiple-name.local' # Hack: tests for acme with multiple name, without using acme
dest_key: "{{ int_ansible_ssl_dir }}/test.key"
dest_cert: "{{ int_ansible_ssl_dir }}/test.crt"
- name: 'test-ssl.local'
key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvavrJWFp3Al2VwRgKx+4Y2mbRRvoxvyd2pyN0xMJ/tCJscaG
8s60v6WZ9FcCOeMkSI2DXsk4z7pbQdQn0h2GDr/5MOJkPAVWSWEN46tpaLZ3v0zp
88ZIbnEk1G0PsdFuW/pnLsakPlAMrl1VArFsV6YsatLt30UIYYcRO97StkoOehCx
A5w+XqtfHZeQZ0/DS81633gwYUcMuSTUFZ60r7ge1/m77DTSKg3rTVk5sebP8cjS
+aWHvxP/GyvvDsT+3gjRJx2/5O3JkfH0zaOsaU2Avj0PR0c5rhynrNO/l1k+GJJB
cbBrM+yA8Ofzp4oXUrCfaIq3RuL3Pd+khcKsiwIDAQABAoIBAQCPpAMQ7BUfbosQ
m1+5SOx7XR8Z12kSSX3CcY12rJSFRakB2TeZ6rE38lIFmV82N67iw0kaH4nGx3sU
/3aoyXMc+IXfX5RJYEFYkQfTw5ywkH9fgQAsfZ2dBlK+DVo1cEYDoj9CTW1VQ4pX
Ape+0l8agd5hiBxdWgpe0ctbbARnx584viLiA/iPBDNxKi9zEYw+WP7hSj5QWahr
a09tubcC4L6tjvv8CoZTRSKfCW64vWRDvE6vmA+zJN9Arc1WTYzF1KO1Gybwf8h7
stJb191smAgGDFhKo0j58ncyAnrS1k4mapm86QQhlfIA6DKvvC0qm3KdQns5b7HM
PyzW0hwBAoGBAO2mTVTOsziom9vtBwM0nRMMEgynR2X3EKMJz2mjcCf66f1F+aQ5
DvQFM2V8S2s1nGnPh8NKKZ8DxW1NKuR4qx82zeAXpUs9ibHxOnw4YRC485zqc2Wt
fSO1OEDYeKyzWP1nGGtCntYUXzJnWn/wz0mBGKzLKTuLwyFIKx1b7bybAoGBAMxR
N+lT57rX6d4GUqcgNOuWMZ/D8egnE5+hsoiFnHOisRLOgUgBBSy4rwAZx+rdHYT+
RO11L1PLYEzyvnO0f13R+N7aqKwNXDSzZGA+jb4pjkVidIC2smG/JYKJH5Z+kakw
mwMKP0wdRZJsCaMgScHmWJS8d6Ox/XJJoWrTWTbRAoGAWJlEgVaiaIArwz1F/QLz
gHNik0cWDkSi9jWlFxwwpycbbypUXM5M7dq2g6JoN6sACk6trbgLdlYgl5RKZm06
VuPGs0H9hOSHXkix5jfasDJT2G9r4D9ixRo9w6cwriobBjYWW3612tgzeYYgrkwn
655uhZUkZSfA8rqGIGbyZfsCgYAf5WH8G+wmIATTc1s92epJCOZwUY+XNVp75itP
4sPczX4lOHW4PuiG5cH0GxI5mRE9rNAn3c5on2xGNvMCbyAfDmNyruH8Eg3d8E9w
MvO/xw79x/P2EA9i8QszCKMUxGeK6RqZ6+SbxkoRJKqQe77n9UTI228179hoGhSH
77ySsQKBgQC8SSZn6a8PpSIIFXB9WCFMwfGFYbUz0wvpaeZP8GKx3BEzMeJqSUaJ
hrQgpwQXkueeamlCQcvV3AUCoBRWTYRLDrWiUIXuIgikDWBFp6TBvTnVRI7iktly
fNED7jXOSjJqnFmdkZlAI5V8dM++mVYVykJD6jcaVRQvxqFLrhSaRg==
-----END RSA PRIVATE KEY-----
cert: |
-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIJALKJfbk5vuieMA0GCSqGSIb3DQEBBQUAMBkxFzAVBgNV
BAMMDnRlc3Qtc3NsLmxvY2FsMB4XDTE2MDExMTE2NDI0NFoXDTI2MDEwODE2NDI0
NFowGTEXMBUGA1UEAwwOdGVzdC1zc2wubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQC9q+slYWncCXZXBGArH7hjaZtFG+jG/J3anI3TEwn+0Imx
xobyzrS/pZn0VwI54yRIjYNeyTjPultB1CfSHYYOv/kw4mQ8BVZJYQ3jq2lotne/
TOnzxkhucSTUbQ+x0W5b+mcuxqQ+UAyuXVUCsWxXpixq0u3fRQhhhxE73tK2Sg56
ELEDnD5eq18dl5BnT8NLzXrfeDBhRwy5JNQVnrSvuB7X+bvsNNIqDetNWTmx5s/x
yNL5pYe/E/8bK+8OxP7eCNEnHb/k7cmR8fTNo6xpTYC+PQ9HRzmuHKes07+XWT4Y
kkFxsGsz7IDw5/OnihdSsJ9oirdG4vc936SFwqyLAgMBAAGjUDBOMB0GA1UdDgQW
BBRaSF1L+ivPhmIVGQjtviBqZWDS9DAfBgNVHSMEGDAWgBRaSF1L+ivPhmIVGQjt
viBqZWDS9DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCjrgB9+Zuq
Rx7T2mRUl4jf75dLabuBQD0ePALTtvNyBSghhzSr90mE7GlFOYAv0JsmEa3R1LVF
wLPIdrIhNHpt7hN0PkhUlfgmxBnRSCfhpiq4xxsDVFM7ehtDz4+dv1LUDMXo07+E
f24g9aqmypiFzHisUQrYIhtQmHxRpKyGp6kDAW9qNxg6k/Um00aHdYfuD9ER4ksR
f8Hto7f+vssKxCRY2OZXqq13PxEwC5+hgAUkTdrycA/moXFuHJi3lCnCND7sSzvG
tXBggOusyFZFC4bs2m+V+Z+RN+tK2c/c0nq5HR8MV5HwIm4Z8GoT2/0BfJ00cgWL
lVz0gDBfdH8f
-----END CERTIFICATE-----
nginx_custom_http:
- 'add_header X-ansible 1;'
- 'geoip_country {% if ansible_os_family == "Debian" %}/usr/share/GeoIP/GeoIP.dat{% else %}/usr/local/share/GeoIP/GeoIP.dat{% endif %};'
- 'map $geoip_country_code $allowed_country {'
- ' default yes;'
- ' MA no;'
- ' DZ no;'
- ' TN no;'
- '}'
nginx_default_site: 'test.local'
nginx_default_site_ssl: 'test-ssl-predeployed.local'
nginx_sites:
- name:
- 'test.local'
- 'test-alias.local'
- 'test2-alias.local'
template: '_base'
filename: 'first-test'
override_try_files: '$uri/ $uri =404'
headers:
'X-Frame-Options': 'deny always'
'X-ansible-default': '1'
manage_local_content: false
use_error_log: true
more:
- 'autoindex off;'
location:
'/test':
- 'return 403;'
'/gunther':
- 'return 404;'
'/status':
- 'stub_status on;'
- 'access_log off;'
- 'allow 127.0.0.1;'
- 'deny all;'
- name: 'test-htpasswd.local'
template: '_base'
location_before:
'/hello':
- htpasswd: 'hello'
location:
'/public':
- htpasswd: false
use_error_log: true
- name: 'test-htpasswd-all.local'
template: '_base'
htpasswd: 'hello'
- name: 'test-location.local'
template: '_base'
location_before:
'/b':
- 'alias /var/tmp;'
'/c':
- 'alias /var/tmp;'
location:
'/':
- 'alias /var/tmp;'
'/a':
- 'alias /var/tmp;'
location_order_before:
- '/b'
- '/c'
location_order:
- '/'
- '/a'
- name: 'test-php.local'
php_upstream: "manual"
upstream_params:
- 'fastcgi_param FOO bar;'
redirect_from:
- 'www.test-php.local'
template: '_php'
use_error_log: true
use_access_log: true
- name: 'test-php-index.local'
template: '_php_index'
php_upstream: 'hx_unix'
- name: 'test-php-index2.local'
template: '_php_index2'
php_upstream: 'hx_ip'
- name: 'test-proxy.local'
listen:
- 8080
template: '_proxy'
upstream_name: 'test'
headers:
'X-proxyfied': '1'
- name: 'deleted.local'
state: 'absent'
- name: 'redirect-to.local'
redirect_to: 'http://test.local'
- name: 'test-ssl.local'
proto: ['http', 'https']
template: '_base'
- name:
- 'test-ssl-selfsigned.local'
- 'www.test-ssl-selfsigned.local'
proto: ['http', 'https']
template: '_base'
hsts: 'max-age=1664;'
- name: 'test-ssl-predeployed.local'
proto: ['http', 'https']
template: '_base'
ssl_name: 'test-ssl-predeployed.local'
headers:
'X-ansible-default': '1'
ssl_template: false
- name: 'test-ssl-redirect.local'
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
- name:
- 'test-ssl-redirect-many.local'
- 'test-ssl-redirect-many2.local'
listen_ssl: [8443]
proto: ['https']
template: '_base'
ssl_name: 'test-ssl.local'
redirect_https: true
redirect_from:
- 'www.test-ssl-redirect-many.local'
- 'www.test-ssl-redirect-many2.local'
- name: 'test-ssl-proxy-protocol.local'
proto: ['http', 'https']
listen_proxy_protocol: [20080]
listen_proxy_protocol_ssl: [20443]
template: '_base'
ssl_name: 'test-ssl.local'
headers:
'X-Proxy-Protocol': '1'
- name: '{{ ngrok.stdout }}'
proto: ['http', 'https']
listen_proxy_protocol: [21080]
listen_proxy_protocol_ssl: [21443]
template: '_base'
ssl_name: '{{ ngrok.stdout }}'
headers:
'X-acme': '1'
- name: 'test-custom-template.local'
custom_template: 'templates/custom_template.conf.j2'
root: '/tmp/custom-template'
nginx_php: "{{ [{'upstream_name': 'manual', 'sockets': [{'host': '127.0.0.1', 'port': '9636'}]}] }}"
nginx_dh_length: 1024

View File

@ -0,0 +1 @@
---

View File

@ -0,0 +1 @@
---

View File

@ -0,0 +1,262 @@
---
# --------------------------------
# Deploy index files
# --------------------------------
- name: -- Add PHP file --
ansible.builtin.copy:
dest: "{{ nginx_root }}/{{ item }}/public/index.php"
content: "<?php phpinfo();"
mode: 0644
owner: root
group: root
loop:
- 'test-php.local'
- 'test-php-index.local'
- 'test-php-index2.local'
- name: -- Add Directories --
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: 0755
loop:
- "{{ nginx_root }}/test-htpasswd.local/public/hello"
- "/tmp/custom-template"
- name: -- Add HTML file --
ansible.builtin.copy:
dest: "{{ item }}/index.html"
content: "Index HTML test OK\n"
mode: 0644
owner: root
group: root
loop:
- '{{ nginx_root }}/first-test/public'
- '/var/tmp'
- '{{ nginx_root }}/test-htpasswd-all.local/public'
- '{{ nginx_root }}/test-ssl.local/public'
- '{{ nginx_root }}/test-ssl-selfsigned.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 --
ansible.builtin.file:
path: "{{ nginx_root }}/test-htpasswd.local/public/hello"
state: directory
mode: 0755
owner: root
group: root
- name: -- Add HTML file hello --
ansible.builtin.copy:
dest: "{{ nginx_root }}/test-htpasswd.local/public/hello/index.html"
content: "hello\n"
mode: 0644
owner: root
group: root
# --------------------------------
# Test custom facts
# --------------------------------
- name: -- CHECK FACTS --
ansible.builtin.assert:
that: "'{{ ansible_local.nginx.fact_nginx_sites[0].name[0] }}' == 'test.local'"
# --------------------------------
# Simple sites tests
# --------------------------------
- name: -- VERIFY SITES --
ansible.builtin.uri:
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
loop: "{{ nginx_sites }}"
when: item.state is undefined or item.state != "absent"
changed_when: false
- name: -- VERIFY FORBIDDEN --
ansible.builtin.uri:
url: "http://test-php-index.local/phpinfo.php"
status_code: 403
- name: -- VERIFY REDIRECT SITES --
ansible.builtin.uri:
url: "http://{{ item.redirect_from[0] }}/"
status_code: 301
follow_redirects: none
loop: "{{ nginx_sites }}"
when: item.redirect_from is defined and (item.state is undefined or item.state != "absent") and (item.proto is not defined or 'https' not in item.proto)
changed_when: false
- name: -- VERIFY REDIRECT HTTPS SITES --
ansible.builtin.uri:
url: "https://{{ item.redirect_from[0] }}:{{ item.listen_ssl[0] | default(443) }}/"
status_code: 301
follow_redirects: none
validate_certs: false
loop: "{{ nginx_sites }}"
when: item.redirect_from is defined and (item.state is undefined or item.state != "absent") and item.proto is defined and 'https' in item.proto
changed_when: false
# --------------------------------
# PHP
# --------------------------------
- name: -- VERIFY PHP SITES --
ansible.builtin.uri:
url: "http://{{ item.name }}/"
return_content: true
register: p
loop: "{{ nginx_sites }}"
when: >
item.template is defined and
(item.template == '_php' or item.template == '_php_index' or item.template == '_php_index2')
failed_when: p.content.find('PHP Version') == -1
- name: -- VERIFY INDEX2 --
ansible.builtin.uri:
url: "http://test-php-index2.local/lorem.php?ipsum=sit&dolor=amet"
return_content: true
register: p2
failed_when: p2.content.find('PHP Version') == -1
# --------------------------------
# Basic Auth
# --------------------------------
- name: -- VERIFY AUTH BASIC NONE --
ansible.builtin.uri:
url: "http://test-htpasswd.local/hello/"
status_code: 401
- name: -- VERIFY AUTH BASIC FAIL --
ansible.builtin.uri:
url: "http://test-htpasswd.local/hello/"
status_code: 401
user: "fail"
password: "fail"
force_basic_auth: true
- name: -- VERIFY AUTH BASIC OK --
ansible.builtin.uri:
url: "http://test-htpasswd.local/hello/"
user: "hanx"
password: "qwerty"
force_basic_auth: true
- name: -- VERIFY AUTH BASIC FAIL GLOBAL --
ansible.builtin.uri:
url: "http://test-htpasswd-all.local/"
status_code: 401
user: "fail"
password: "fail"
force_basic_auth: true
- name: -- VERIFY AUTH BASIC OK GLOBAL --
ansible.builtin.uri:
url: "http://test-htpasswd-all.local/"
user: "hanx"
password: "qwerty"
force_basic_auth: true
# --------------------------------
# SSL
# --------------------------------
- name: -- VERIFY SSL --
ansible.builtin.uri:
url: "https://{{ item }}/"
return_content: true
validate_certs: false
register: sslok
failed_when: sslok.content.find('Index HTML test OK') == -1
loop:
- 'test-ssl-predeployed.local'
- 'test-ssl-selfsigned.local'
- 'test-ssl.local'
- '{{ ngrok.stdout }}'
- name: -- VERIFY SSL REDIRECT --
ansible.builtin.uri:
url: "http://{{ item.name }}/"
validate_certs: false
status_code: 301
return_content: true
follow_redirects: none
register: sslredirok
failed_when: '"https://%s%s" % (item.name, ":" + item.port if item.port is defined else "") not in sslredirok.location'
loop:
- name: 'test-ssl-redirect.local'
- name: 'test-ssl-redirect-many.local'
port: '8443'
- name: 'test-ssl-redirect-many2.local'
port: '8443'
# --------------------------------
# Default sites
# --------------------------------
- name: -- VERIFY DEFAULT SITE --
ansible.builtin.uri:
url: 'http://127.0.0.1/'
return_content: true
register: vdefault
failed_when: >
vdefault.content.find('Index HTML test OK') == -1 or
vdefault.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SITE + STUB STATUS--
ansible.builtin.uri:
url: 'http://127.0.0.1/status'
return_content: true
register: vdefault_status
failed_when: >
vdefault_status.content.find('Active connections') == -1 or
vdefault_status.x_ansible_default is not defined
- name: -- VERIFY DEFAULT SSL SITE --
ansible.builtin.uri:
url: 'https://127.0.0.1/'
return_content: true
validate_certs: false
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 --
ansible.builtin.uri:
url: 'http://test-php.local/'
return_content: true
register: vphp
failed_when: vphp.x_ansible_default is defined
- name: -- VERIFY NOT DEFAULT SSL SITE --
ansible.builtin.uri:
url: 'https://test-ssl.local/'
return_content: true
validate_certs: false
register: notdefaultssl
failed_when: notdefaultssl.x_ansible_default is defined
# --------------------------------
# Check Proxy protocol
# --------------------------------
- name: SHELL | Check HTTP proxy protocol
ansible.builtin.shell: set -o pipefail && curl -I --haproxy-protocol http://test-ssl-proxy-protocol.local:20080 | grep -qi 'X-Proxy-Protocol'
args:
executable: /bin/bash
changed_when: false
- name: SHELL | Check HTTPS proxy protocol
ansible.builtin.shell: set -o pipefail && curl -I --haproxy-protocol -k https://test-ssl-proxy-protocol.local:20443 | grep -qi 'X-Proxy-Protocol'
args:
executable: /bin/bash
changed_when: false
# --------------------------------
# Check HTTP2
# --------------------------------
- name: SHELL | Check HTTP2
ansible.builtin.shell: set -o pipefail && nghttp -nv https://localhost 2> /dev/null | grep -q h2
args:
executable: /bin/bash
changed_when: false

View File

@ -0,0 +1,82 @@
---
- name: APT_REPOSITORY | Install backports
ansible.builtin.apt_repository:
repo: 'deb http://httpredir.debian.org/debian {{ ansible_distribution_release }}-backports main'
state: present
when: nginx_backports is defined and nginx_backports
- name: APT | Install needed packages
ansible.builtin.apt:
pkg: "{{ packages }}"
update_cache: true
cache_valid_time: 3600
state: present
vars:
packages:
- cron
- curl
- daemonize
- jq
- nghttp2
- strace
- vim
- unzip
- name: APT | Install PHP
ansible.builtin.apt:
pkg: "{{ pkgs }}"
update_cache: true
cache_valid_time: 3600
state: present
vars:
pkgs:
- php-cli
- php-fpm
- name: SHELL | Get current PHP version
ansible.builtin.shell: php --version | awk '/^PHP/ { print $2 }' | grep -o -E '^.{3}'
changed_when: false
register: cur_php_version
# Bypasses Ansible+Docker issue. With service module... php is not really started!
- name: COMMAND | Force start PHP
ansible.builtin.command: "service php{{ cur_php_version.stdout }}-fpm start"
args:
creates: "/run/php/php{{ cur_php_version.stdout }}-fpm.pid"
- name: GET_URL | Download ngrok
ansible.builtin.get_url:
url: "https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz"
dest: "/tmp/ngrok.zip"
- name: UNARCHIVE | Uncompress ngrok
ansible.builtin.unarchive:
src: "/tmp/ngrok.zip"
dest: "/tmp"
remote_src: true
- name: SET_FACT | ngrok_path
ansible.builtin.set_fact:
ngrok_path: '/tmp/ngrok'
- name: USER | Create PHP User foo
ansible.builtin.user:
name: foo
system: true
- name: INCLUDE_ROLE | hanxhx.php # TODO: repair vagrant
ansible.builtin.include_role:
name: "hanxhx.php"
vars:
php_version: "{{ cur_php_version.stdout }}"
php_autoremove_default_pool: false
php_fpm_poold:
- name: 'hx_unix'
user: 'foo'
php_value:
display_errors: 'Off'
php_admin_value:
memory_limit: '98M'
- name: 'hx_ip'
listen: '127.0.0.1:9636'

View File

@ -0,0 +1,66 @@
---
- name: SET_FACT | FreeBSD web user
set_fact:
nginx_pkgng_package: 'nginx-full'
nginx_user: 'www'
nginx_php:
- upstream_name: 'manual'
sockets:
- host: '127.0.0.1'
port: 9000
- upstream_name: 'hx_unix'
sockets:
- host: '127.0.0.1'
port: 9000
- upstream_name: 'hx_ip'
sockets:
- host: '127.0.0.1'
port: 9000
ngrok_path: '/usr/local/bin/ngrok'
- name: PKGNG | Install needed packages
pkgng:
pkg: "{{ packages }}"
state: present
vars:
packages:
- bash
- curl
- daemonize
- fcgiwrap
- jq
- nghttp2
- php74
- vim
- name: SERVICE | Force start services
service:
name: "{{ item }}"
state: started
enabled: true
register: sf
loop:
- php-fpm
- name: STAT | Check ports
stat:
path: /usr/ports
register: ports
- block:
- name: COMMAND | Get ports
command: portsnap fetch --interactive
- name: COMMAND | Extract ports
command: portsnap extract
no_log: true
when: not ports.stat.exists
- name: SHELL | Install ngrok
shell: make install clean DISABLE_LICENSES=yes
args:
chdir: /usr/ports/security/ngrok
creates: "{{ ngrok_path }}"

View File

@ -0,0 +1,59 @@
---
- name: COMMAND | Start ngrok
ansible.builtin.command: daemonize -l /tmp/ngrok.lock {{ ngrok_path }} http 80 --scheme http
failed_when: false
changed_when: ngrok.stderr.find("Can't lock the lock file") == -1
register: ngrok
- name: WAIT_FOR | ngrok started # noqa: no-handler
ansible.builtin.wait_for:
delay: 2
port: 4040
when: ngrok.changed
- name: SHELL | Get ngrok public address
ansible.builtin.shell: set -o pipefail && curl 'http://127.0.0.1:4040/api/tunnels/command_line' 2> /dev/null | jq -r '.public_url' | cut -d '/' -f 3
args:
executable: /bin/bash
register: ngrok
changed_when: false
- name: FILE | Create an internal SSL dir
ansible.builtin.file:
path: "{{ int_ansible_ssl_dir }}"
state: directory
mode: 0750
owner: root
group: root
- name: COPY | Deploy test cert/key
ansible.builtin.copy:
src: "file/{{ item }}"
dest: "{{ int_ansible_ssl_dir }}/{{ item }}"
mode: 0640
owner: root
group: root
loop:
- 'test.key'
- 'test.crt'
- name: COPY | Add all hosts in /etc/hosts
ansible.builtin.copy:
content: |
127.0.0.1 localhost
{% for s in nginx_sites %}
{% if s.name is string %}
127.0.0.1 {{ s.name }}
{% else %}
127.0.0.1 {% for n in s.name %}{{ n }} {% endfor %}
{% endif %}
{% if s.redirect_from is defined %}
127.0.0.1 {% for rf in s.redirect_from %}{{ rf }} {% endfor %}
{% endif %}
{% endfor %}
dest: "/etc/hosts"
mode: 0644
owner: root
group: root
unsafe_writes: true

View File

@ -1 +0,0 @@
localhost

View File

@ -0,0 +1,16 @@
# {{ ansible_managed }} - custom template
server {
listen 80;
listen 8888 http2;
listen 9999 http2 proxy_protocol;
server_name {{ item.name }};
index index.html index.htm;
root {{ item.root }};
location / {
try_files $uri $uri/ =404;
}
}

View File

@ -1,21 +0,0 @@
#!/bin/sh
# Thanks to https://servercheck.in/blog/testing-ansible-roles-travis-ci-github
DIR=$( dirname $0 )
INVENTORY_FILE="$DIR/inventory"
PLAYBOOK="$DIR/test.yml"
set -ev
# Check syntax
ansible-playbook -i $INVENTORY_FILE -c local --syntax-check -vv $PLAYBOOK
# Check role
ansible-playbook -i $INVENTORY_FILE -c local --sudo -vv $PLAYBOOK
# Check indempotence
ansible-playbook -i $INVENTORY_FILE -c local --sudo -vv $PLAYBOOK \
| grep -q 'changed=0.*failed=0' \
&& (echo 'Idempotence test: pass' && exit 0) \
|| (echo 'Idempotence test: fail' && exit 1)

View File

@ -1,66 +1,20 @@
---
- hosts: all
- name: Launch tests # noqa: role-name[path]
hosts: all
pre_tasks:
- apt: pkg={{ item }} update_cache=yes cache_valid_time=3600 state=present
with_items:
- php5-fpm
- curl
vars:
nginx_php: true
nginx_upstreams:
- name: 'test'
servers:
- path: '127.0.0.1:80'
max_conns: 150
weight: 10
down: false
nginx_vhosts:
- name:
- 'test.local'
- 'test-alias.local'
- 'test2-alias.local'
template: '_base'
override_try_files: '$uri $uri index.htm index.html'
manage_local_content: false
more:
- 'autoindex off;'
location:
'/test':
- 'return 403;'
'/gunther':
- 'return 404;'
- name:
- 'test-php.local'
upstream_params:
- 'fastcgi_param FOO bar;'
redirect_from:
- 'www.test-php.local'
template: '_php'
- name:
- 'test-proxy.local'
listen:
- 8080
template: '_proxy'
upstream_name: 'test'
- name:
- 'deleted.local'
template: '_base'
delete: true
- name: INCLUDE_TASKS | Pre_tasks related to OS version
ansible.builtin.include_tasks: "includes/pre_{{ ansible_os_family }}.yml"
- name: IMPORT_TASKS | Pre_tasks common
ansible.builtin.import_tasks: "includes/pre_common.yml"
roles:
- ../../
post_tasks:
- name: -- Add PHP file --
copy: dest="{{ nginx_root }}/test-php.local/public/index.php" content="<?php phpinfo();"
- name: -- Add HTML file --
copy: dest="{{ nginx_root }}/test.local/public/index.html" content="Index HTML test OK\n"
- name: -- VERIFY VHOSTS --
shell: "curl -H 'Host: {{ item.name[0] }}' http://127.0.0.1{% if item.listen is defined and item.listen is iterable %}:{{ item.listen[0] }}{% endif %}/"
with_items: nginx_vhosts
when: item.delete is undefined or not item.delete
changed_when: false
- name: -- VERIFY REDIRECT VHOSTS --
shell: "curl -H 'Host: {{ item.redirect_from[0] }}' http://127.0.0.1/"
with_items: nginx_vhosts
when: item.redirect_from is defined and (item.delete is undefined or not item.delete)
changed_when: false
- name: INCLUDE_TASKS | Post_tasks related to OS version
ansible.builtin.include_tasks: "includes/post_{{ ansible_os_family }}.yml"
- name: IMPORT_TASKS | Post_tasks common
ansible.builtin.import_tasks: "includes/post_common.yml"

5
vars/Debian.yml 100644
View File

@ -0,0 +1,5 @@
---
nginx_events_use: 'epoll'
nginx_pid: '/run/nginx.pid'
nginx_etc_dir: '/etc/nginx'

7
vars/FreeBSD.yml 100644
View File

@ -0,0 +1,7 @@
---
nginx_events_use: 'kqueue'
nginx_pid: '/var/run/nginx.pid'
nginx_etc_dir: '/usr/local/etc/nginx'
nginx_acmesh_bin: '/usr/local/sbin/acme.sh'

View File

@ -1,4 +1,4 @@
nginx_dh_path: /etc/nginx/ssl/dhparams.pem
---
nginx_upstream_server_params:
- key: 'weight'
@ -23,3 +23,30 @@ nginx_upstream_server_params:
# - key: 'resolve'
# is_bool: true
# min_version: '1.5.12'
nginx_dirs:
- dir: "{{ nginx_htpasswd_dir }}"
mode: "0750"
owner: "{{ nginx_user }}"
- dir: "{{ nginx_ssl_dir }}"
mode: "0750"
owner: "root"
- dir: "{{ nginx_helper_dir }}"
mode: "0755"
owner: "root"
- dir: "{{ nginx_etc_dir }}/modules-available"
mode: "0755"
owner: "root"
- dir: "{{ nginx_etc_dir }}/modules-enabled"
mode: "0755"
owner: "root"
nginx_templates_no_dir:
- '_proxy'
nginx_servers_default_headers:
'X-Frame-Options': 'DENY always'
'X-Content-Type-Options': 'nosniff always'
'X-XSS-Protection': '1; mode=block always'
nginx_acmesh_bin: "{{ nginx_acmesh_dir }}/acme.sh"