├── .ansible-lint
├── .clog.toml
├── .editorconfig
├── .gitignore
├── .travis.yml
├── .vscode
├── extensions.json
└── settings.json
├── CHANGELOG.md
├── LICENSE
├── Makefile
├── README.md
├── defaults
└── main.yml
├── files
└── etc
│ └── nginx
│ └── rules
│ ├── cache_busting.conf
│ ├── cors_ajax.conf
│ ├── cors_web_fonts.conf
│ ├── expires.conf
│ ├── gzip.conf
│ ├── gzip_static.conf
│ ├── no_transform.conf
│ ├── security.conf
│ └── ssl.conf
├── handlers
└── main.yml
├── meta
├── main.yml
└── readme.yml
├── tasks
├── config.yml
├── install.yml
├── main.yml
├── manage.yml
└── service.yml
├── templates
└── etc
│ └── nginx
│ ├── nginx.conf.j2
│ └── sites-available
│ ├── site-body.j2
│ ├── site-redirect.j2
│ └── site.j2
└── tests
└── main.yml
/.ansible-lint:
--------------------------------------------------------------------------------
1 | exclude_paths:
2 | - ./meta/readme.yml
3 |
--------------------------------------------------------------------------------
/.clog.toml:
--------------------------------------------------------------------------------
1 | [clog]
2 | changelog = "CHANGELOG.md"
3 | repository = "https://github.com/weareinteractive/ansible-nginx"
4 | from-latest-tag = true
5 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 | # Change these settings to your own preference
9 | indent_size = 2
10 | indent_style = space
11 |
12 | # We recommend you to keep these unchanged
13 | charset = utf-8
14 | end_of_line = lf
15 | insert_final_newline = true
16 | trim_trailing_whitespace = true
17 |
18 | [Makefile]
19 | indent_style = tab
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | *.retry
3 | .DS_Store
4 | .vagrant
5 | .vscode/*
6 | !.vscode/settings.json
7 | !.vscode/extensions.json
8 | .idea
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | sudo: required
3 | language: python
4 | services:
5 | - docker
6 | env:
7 | global:
8 | - role: weareinteractive.nginx
9 | matrix:
10 | - distribution: Ubuntu
11 | distribution_version: "18.04"
12 | init: /lib/systemd/systemd
13 | run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
14 | # Skipping due to: AttributeError: 'module' object has no attribute 'SSL_ST_INIT'
15 | #- distribution: Ubuntu
16 | # distribution_version: "16.04"
17 | # init: /lib/systemd/systemd
18 | # run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
19 | - distribution: Debian
20 | distribution_version: "9"
21 | init: /lib/systemd/systemd
22 | run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
23 | - distribution: Debian
24 | distribution_version: "8"
25 | init: /lib/systemd/systemd
26 | run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
27 |
28 | before_install:
29 | - sudo apt-get update
30 | - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
31 | - docker pull ansiblecheck/ansiblecheck:"${distribution,,}"-"${distribution_version}"
32 |
33 | script:
34 | - container_id=$(mktemp)
35 | # Start The Built Container In The Background
36 | - 'docker run --detach --volume="${PWD}":/etc/ansible/roles/${role}:ro ${run_opts} ansiblecheck/ansiblecheck:"${distribution,,}"-"${distribution_version}" "${init}" > "${container_id}"'
37 |
38 | # Install dependencies
39 | - 'docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-galaxy install -c weareinteractive.apt weareinteractive.openssl weareinteractive.htpasswd'
40 |
41 | # Ansible syntax check.
42 | - 'docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/${role}/tests/main.yml --syntax-check'
43 |
44 | # Test role.
45 | - 'docker exec "$(cat ${container_id})" env ANSIBLE_FORCE_COLOR=1 ansible-playbook /etc/ansible/roles/${role}/tests/main.yml'
46 |
47 | # Test Idempotence
48 | - idempotence=$(mktemp)
49 | - docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/${role}/tests/main.yml | tee -a ${idempotence}
50 | - >
51 | tail ${idempotence}
52 | | grep -q 'changed=0.*failed=0'
53 | && (echo 'Idempotence test: pass' && exit 0)
54 | || (echo 'Idempotence test: fail' && exit 1)
55 |
56 | notifications:
57 | webhooks: https://galaxy.ansible.com/api/v1/notifications/
58 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "vscoss.vscode-ansible"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "*.yml": "ansible"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ### 2.0.1 (2020-05-04)
3 |
4 |
5 |
6 |
7 |
8 | ## 2.0.0 (2020-05-04)
9 |
10 |
11 | #### Features
12 |
13 | * move files to fit conventions ([fc20b264](https://github.com/weareinteractive/ansible-nginx/commit/fc20b2640014d08192c8b0000e5898de4969bf7b))
14 |
15 | #### Breaking changes
16 |
17 | In order to upgrade from 1.x to 2.x you need to:
18 |
19 | * add extensions to `nginx_sites[].ssl.key_name` and `nginx_sites[].ssl.cert_name` i.e. `server.key`
20 | * in case of custom rules, change the location from `files/etc-nginx-rules` to `files/etc/nginx/rules`
21 |
22 |
23 | ## 1.5.0 (2019-10-18)
24 |
25 |
26 | #### Features
27 |
28 | * rename role ([95bb2d51](https://github.com/weareinteractive/ansible-nginx/commit/95bb2d51398f6e61c6330d2378a38e29438569c3))
29 | * ensure config folders ([e27ebc86](https://github.com/weareinteractive/ansible-nginx/commit/e27ebc86c522fff78c088b84ca6e411ec93854e4))
30 | * add depencies ([299f3844](https://github.com/weareinteractive/ansible-nginx/commit/299f38446f76359ca85d75db91cb7adcaca22f2e))
31 | * ensure sites-enabled folder ([731d3546](https://github.com/weareinteractive/ansible-nginx/commit/731d354692b6c98af0412a8e97b89888cbb46dc2))
32 | * bump ansible min version ([67b2c245](https://github.com/weareinteractive/ansible-nginx/commit/67b2c245f3f4594595fb281b9352295daa861e9a))
33 | * update apt repository ([95a17572](https://github.com/weareinteractive/ansible-nginx/commit/95a17572b23145f68ee9376d4604093d967ad7af))
34 | * use import_tasks ([0f2ad490](https://github.com/weareinteractive/ansible-nginx/commit/0f2ad4906914081ac244c707f7b3b221382edd79))
35 |
36 | #### Bug Fixes
37 |
38 | * add apt key ([fe5c5ca6](https://github.com/weareinteractive/ansible-nginx/commit/fe5c5ca66aaa7d6dc6e64be7f67b22636fd99637))
39 |
40 |
41 |
42 |
43 | ## 1.4.0 (2016-08-15)
44 |
45 |
46 | #### Features
47 |
48 | * readd restart handler ([6cb85d7d](https://github.com/weareinteractive/ansible-nginx/commit/6cb85d7d08d206a5d35fef833ac6974228a62dc7))
49 | * use reload instead of restart ([8dd51d3f](https://github.com/weareinteractive/ansible-nginx/commit/8dd51d3fe4dfbf5a6b843562d5f4995810dd121f))
50 |
51 |
52 |
53 |
54 | ## 1.3.0 (2016-07-27)
55 |
56 |
57 | #### Features
58 |
59 | * update syntax for ansible 2.0 ([669ceaf9](https://github.com/weareinteractive/ansible-nginx/commit/669ceaf9cdf3bef2d4b4d71bab0db75d6fa89019))
60 | * add CHANGELOG ([34ed15ac](https://github.com/weareinteractive/ansible-nginx/commit/34ed15ac8998e491c8f79a1311ddca518f5c0899))
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) We Are Interactive
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PWD=$(shell pwd)
2 | ROLE_NAME=weareinteractive.nginx
3 | ROLE_PATH=/etc/ansible/roles/$(ROLE_NAME)
4 | TEST_VERSION=ansible --version
5 | TEST_DEPS=ansible-galaxy install -c weareinteractive.apt weareinteractive.openssl weareinteractive.htpasswd
6 | TEST_SYNTAX=ansible-playbook -v -i 'localhost,' -c local $(ROLE_PATH)/tests/main.yml --syntax-check
7 | TEST_PLAYBOOK=ansible-playbook -vvvv -i 'localhost,' -c local $(ROLE_PATH)/tests/main.yml
8 | TEST_IDEMPOTENT=$(TEST_PLAYBOOK) | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1)
9 | TEST_CMD=$(TEST_DEPS); $(TEST_VERSION); $(TEST_SYNTAX); $(TEST_PLAYBOOK); $(TEST_IDEMPOTENT)
10 |
11 | docs:
12 | ansible-role docgen
13 |
14 | lint:
15 | ansible-lint .
16 |
17 | ubuntu%: TEST_DEPS+=\
18 | && apt-get update \
19 | && apt-get install -y python-setuptools python-openssl python-pip
20 |
21 | ubuntu18.04: dist=ubuntu-18.04
22 | ubuntu18.04: .run
23 |
24 | ubuntu16.04: dist=ubuntu-16.04
25 | ubuntu16.04: .run
26 |
27 | debian%: TEST_DEPS+=\
28 | && apt-get update
29 |
30 | debian9: dist=debian-9
31 | debian9: .run
32 |
33 | debian8: dist=debian-8
34 | debian8: .run
35 |
36 | .run:
37 | @echo "RUN:"
38 | @echo " docker run -it --rm -v $(PWD):$(ROLE_PATH) ansiblecheck/ansiblecheck:$(dist) /bin/bash"
39 | @echo " $(TEST_CMD)"
40 | @docker run -it --rm -v $(PWD):$(ROLE_PATH) ansiblecheck/ansiblecheck:$(dist) /bin/bash -c "$(TEST_CMD)"
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ansible weareinteractive.nginx role
2 |
3 | [](https://travis-ci.org/weareinteractive/ansible-nginx)
4 | [](https://galaxy.ansible.com/weareinteractive/nginx)
5 | [](https://github.com/weareinteractive/ansible-nginx)
6 | [](https://github.com/weareinteractive/ansible-nginx)
7 |
8 | > `weareinteractive.nginx` is an [Ansible](http://www.ansible.com) role which:
9 | >
10 | > * installs nginx
11 | > * configures nginx
12 | > * creates sites
13 | > * enables/disables sites
14 | > * optionally removes default host
15 | > * adds rules
16 | > * configures service
17 |
18 | **Note:**
19 |
20 | > Since Ansible Galaxy supports [organization](https://www.ansible.com/blog/ansible-galaxy-2-release) now, this role has moved from `franklinkim.nginx` to `weareinteractive.nginx`!
21 |
22 | ## Installation
23 |
24 | Using `ansible-galaxy`:
25 |
26 | ```shell
27 | $ ansible-galaxy install weareinteractive.nginx
28 | ```
29 |
30 | Using `requirements.yml`:
31 |
32 | ```yaml
33 | - src: weareinteractive.nginx
34 | ```
35 |
36 | Using `git`:
37 |
38 | ```shell
39 | $ git clone https://github.com/weareinteractive/ansible-nginx.git weareinteractive.nginx
40 | ```
41 |
42 | ## Dependencies
43 |
44 | * Ansible >= 2.4
45 | ## Related (see example)
46 |
47 | * [weareinteractive.openssl](https://github.com/weareinteractive/ansible-openssl)
48 | * [weareinteractive.htpasswd](https://github.com/weareinteractive/ansible-htpasswd)
49 |
50 | ## Variables
51 |
52 | Here is a list of all the default variables for this role, which are also available in `defaults/main.yml`.
53 |
54 | ```yaml
55 | ---
56 |
57 | # nginx_sites:
58 | # - id: foo (required)
59 | # name: foo.com (required)
60 | # ip: '*'
61 | # port: 80
62 | # state: present
63 | # add_webroot: no
64 | # template: path/to/template.j2
65 | # aliases: []
66 | # redirects: []
67 | # ssl:
68 | # port: 443
69 | # key_name: mykey.key
70 | # key_path: path/to/key
71 | # cert_name: mycert.crt
72 | # cert_path: path/to/cert
73 | # rules: []
74 | # auth:
75 | # name: foo
76 | # file: foo
77 | # append: ''
78 | #
79 |
80 | # dependencies packages to install package
81 | nginx_dependencies:
82 | - ca-certificates
83 | - gnupg2
84 | # apt repository
85 | nginx_repo: "deb http://nginx.org/packages/{{ ansible_distribution|lower }}/ {{ ansible_distribution_release }} nginx"
86 | # apt repository key
87 | nginx_repo_key: ABF5BD827BD9BF62
88 | # package name (version)
89 | nginx_package: nginx
90 | # run as a less privileged user for security reasons.
91 | nginx_user: www-data
92 | # number or auto
93 | nginx_worker_processes: 1
94 | nginx_worker_connections: 1024
95 | # default settings
96 | nginx_sendfile: 'on'
97 | nginx_tcp_nopush: 'on'
98 | nginx_tcp_nodelay: 'on'
99 | nginx_keepalive_timeout: 15
100 | nginx_types_hash_max_size: 2048
101 | nginx_server_names_hash_bucket_size: 128
102 | nginx_server_tokens: 'off'
103 | # remove default site
104 | nginx_remove_default: no
105 | # start on boot
106 | nginx_service_enabled: yes
107 | # current state: started, stopped
108 | nginx_service_state: started
109 | # enabled/disabled sites
110 | nginx_sites: []
111 | # add rules
112 | nginx_add_rules: yes
113 |
114 | ```
115 |
116 | ## Handlers
117 |
118 | These are the handlers that are defined in `handlers/main.yml`.
119 |
120 | ```yaml
121 | ---
122 |
123 | - name: restart nginx
124 | service: name=nginx state=restarted
125 | when: nginx_service_state != 'stopped'
126 |
127 | - name: reload nginx
128 | service: name=nginx state=reloaded
129 | when: nginx_service_state != 'stopped'
130 |
131 | ```
132 |
133 | ## Rules
134 |
135 | If `nginx_add_rules` is `yes`, it will copy some configuration rules to `/etc/nginx/rules`:
136 |
137 | * cache_busting.conf
138 | * cors_web_fonts.conf
139 | * gzip.conf
140 | * no_transform.conf
141 | * ssl.conf
142 | * cors_ajax.con
143 | * expires.conf
144 | * gzip_static.conf
145 | * security.conf
146 |
147 | ## Usage
148 |
149 | This is an example playbook:
150 |
151 | ```yaml
152 | ---
153 |
154 | - hosts: all
155 | become: yes
156 | roles:
157 | - weareinteractive.apt
158 | - weareinteractive.openssl
159 | - weareinteractive.htpasswd
160 | - weareinteractive.nginx
161 | vars:
162 | htpasswd:
163 | - name: foobar
164 | users:
165 | - { name: foobar, password: foobar }
166 | openssl_generate_csr: yes
167 | openssl_self_signed:
168 | - name: fooboar.local
169 | subject:
170 | C: DE
171 | ST: Bavaria
172 | L: Munich
173 | O: Foo Bar Inc
174 | CN: foobar.local
175 | emailAddress: null@foobar.local
176 | nginx_sites:
177 | - id: foobar
178 | add_webroot: yes
179 | name: foobar.local
180 | ssl:
181 | key_name: foobar.local.key
182 | cert_name: foobar.local.crt
183 | rules:
184 | - gzip
185 | - security
186 | auth:
187 | name: Foo Bar
188 | file: foobar
189 | nginx_worker_processes: 1
190 | nginx_remove_default: yes
191 | # do not start service as we're running in docker
192 | nginx_service_state: stopped
193 | nginx_service_enabled: no
194 |
195 | ```
196 |
197 |
198 | ## Testing
199 |
200 | ```shell
201 | $ git clone https://github.com/weareinteractive/ansible-nginx.git
202 | $ cd ansible-nginx
203 | $ make test
204 | ```
205 |
206 | ## Contributing
207 | In lieu of a formal style guide, take care to maintain the existing coding style. Add unit tests and examples for any new or changed functionality.
208 |
209 | 1. Fork it
210 | 2. Create your feature branch (`git checkout -b my-new-feature`)
211 | 3. Commit your changes (`git commit -am 'Add some feature'`)
212 | 4. Push to the branch (`git push origin my-new-feature`)
213 | 5. Create new Pull Request
214 |
215 | *Note: To update the `README.md` file please install and run `ansible-role`:*
216 |
217 | ```shell
218 | $ gem install ansible-role
219 | $ ansible-role docgen
220 | ```
221 |
222 | ## License
223 | Copyright (c) We Are Interactive under the MIT license.
224 |
--------------------------------------------------------------------------------
/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # nginx_sites:
4 | # - id: foo (required)
5 | # name: foo.com (required)
6 | # ip: '*'
7 | # port: 80
8 | # state: present
9 | # add_webroot: no
10 | # template: path/to/template.j2
11 | # aliases: []
12 | # redirects: []
13 | # ssl:
14 | # port: 443
15 | # key_name: mykey.key
16 | # key_path: path/to/key
17 | # cert_name: mycert.crt
18 | # cert_path: path/to/cert
19 | # rules: []
20 | # auth:
21 | # name: foo
22 | # file: foo
23 | # append: ''
24 | #
25 |
26 | # dependencies packages to install package
27 | nginx_dependencies:
28 | - ca-certificates
29 | - gnupg2
30 | # apt repository
31 | nginx_repo: "deb http://nginx.org/packages/{{ ansible_distribution|lower }}/ {{ ansible_distribution_release }} nginx"
32 | # apt repository key
33 | nginx_repo_key: ABF5BD827BD9BF62
34 | # package name (version)
35 | nginx_package: nginx
36 | # run as a less privileged user for security reasons.
37 | nginx_user: www-data
38 | # number or auto
39 | nginx_worker_processes: 1
40 | nginx_worker_connections: 1024
41 | # default settings
42 | nginx_sendfile: 'on'
43 | nginx_tcp_nopush: 'on'
44 | nginx_tcp_nodelay: 'on'
45 | nginx_keepalive_timeout: 15
46 | nginx_types_hash_max_size: 2048
47 | nginx_server_names_hash_bucket_size: 128
48 | nginx_server_tokens: 'off'
49 | # remove default site
50 | nginx_remove_default: no
51 | # start on boot
52 | nginx_service_enabled: yes
53 | # current state: started, stopped
54 | nginx_service_state: started
55 | # enabled/disabled sites
56 | nginx_sites: []
57 | # add rules
58 | nginx_add_rules: yes
59 |
--------------------------------------------------------------------------------
/files/etc/nginx/rules/cache_busting.conf:
--------------------------------------------------------------------------------
1 | # Built-in filename-based cache busting
2 |
3 | # https://github.com/h5bp/html5-boilerplate/blob/5370479476dceae7cc3ea105946536d6bc0ee468/.htaccess#L403
4 | # This will route all requests for /css/style.20120716.css to /css/style.css
5 | # Read also this: github.com/h5bp/html5-boilerplate/wiki/cachebusting
6 | # This is not included by default, because it'd be better if you use the build
7 | # script to manage the file names.
8 | location ~* (.+)\.(?:\d+)\.(js|css|png|jpg|jpeg|gif)$ {
9 | try_files $uri $1.$2;
10 | }
11 |
--------------------------------------------------------------------------------
/files/etc/nginx/rules/cors_ajax.conf:
--------------------------------------------------------------------------------
1 | # Cross domain AJAX requests
2 | add_header "Access-Control-Allow-Origin" "*";
3 |
--------------------------------------------------------------------------------
/files/etc/nginx/rules/cors_web_fonts.conf:
--------------------------------------------------------------------------------
1 | # Cross domain webfont access
2 | location ~* \.(?:ttf|ttc|otf|eot|woff)$ {
3 | add_header "Access-Control-Allow-Origin" "*";
4 |
5 | # Also, set cache rules for webfonts.
6 | #
7 | # See http://wiki.nginx.org/HttpCoreModule#location
8 | # And https://github.com/h5bp/server-configs/issues/85
9 | # And https://github.com/h5bp/server-configs/issues/86
10 | expires 1M;
11 | access_log off;
12 | add_header Cache-Control "public";
13 | }
14 |
--------------------------------------------------------------------------------
/files/etc/nginx/rules/expires.conf:
--------------------------------------------------------------------------------
1 | # Expire rules for static content
2 |
3 | # No default expire rule. This config mirrors that of apache as outlined in the
4 | # html5-boilerplate .htaccess file. However, nginx applies rules by location,
5 | # the apache rules are defined by type. A concequence of this difference is that
6 | # if you use no file extension in the url and serve html, with apache you get an
7 | # expire time of 0s, with nginx you'd get an expire header of one month in the
8 | # future (if the default expire rule is 1 month). Therefore, do not use a
9 | # default expire rule with nginx unless your site is completely static
10 |
11 | # cache.appcache, your document html and data
12 | location ~* \.(?:manifest|appcache|html?|xml|json)$ {
13 | expires -1;
14 | access_log /var/log/nginx/static.log;
15 | }
16 |
17 | # Feed
18 | location ~* \.(?:rss|atom)$ {
19 | expires 1h;
20 | add_header Cache-Control "public";
21 | }
22 |
23 | # Media: images, icons, video, audio, HTC
24 | location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
25 | expires 1M;
26 | access_log off;
27 | add_header Cache-Control "public";
28 | }
29 |
30 | # CSS and Javascript
31 | location ~* \.(?:css|js)$ {
32 | expires 1y;
33 | access_log off;
34 | add_header Cache-Control "public";
35 | }
36 |
37 | # WebFonts
38 | # If you are NOT using cross-domain-fonts.conf, uncomment the following directive
39 | # location ~* \.(?:ttf|ttc|otf|eot|woff)$ {
40 | # expires 1M;
41 | # access_log off;
42 | # add_header Cache-Control "public";
43 | # }
44 |
--------------------------------------------------------------------------------
/files/etc/nginx/rules/gzip.conf:
--------------------------------------------------------------------------------
1 | # Enable compression both for HTTP/1.0 and HTTP/1.1 (required for CloudFront).
2 | gzip_http_version 1.0;
3 |
4 | # Compression level (1-9).
5 | # 5 is a perfect compromise between size and cpu usage, offering about
6 | # 75% reduction for most ascii files (almost identical to level 9).
7 | gzip_comp_level 5;
8 |
9 | # Don't compress anything that's already small and unlikely to shrink much
10 | # if at all (the default is 20 bytes, which is bad as that usually leads to
11 | # larger files after gzipping).
12 | gzip_min_length 256;
13 |
14 | # Compress data even for clients that are connecting to us via proxies,
15 | # identified by the "Via" header (required for CloudFront).
16 | gzip_proxied any;
17 |
18 | # Tell proxies to cache both the gzipped and regular version of a resource
19 | # whenever the client's Accept-Encoding capabilities header varies;
20 | # Avoids the issue where a non-gzip capable client (which is extremely rare
21 | # today) would display gibberish if their proxy gave them the gzipped version.
22 | gzip_vary on;
23 |
24 | # Compress all output labeled with one of the following MIME-types.
25 | gzip_types
26 | application/atom+xml
27 | application/javascript
28 | application/json
29 | application/rss+xml
30 | application/vnd.ms-fontobject
31 | application/x-font-ttf
32 | application/x-web-app-manifest+json
33 | application/xhtml+xml
34 | application/xml
35 | font/opentype
36 | image/svg+xml
37 | image/x-icon
38 | text/css
39 | text/plain
40 | text/x-component;
41 | # text/html is always compressed by HttpGzipModule
--------------------------------------------------------------------------------
/files/etc/nginx/rules/gzip_static.conf:
--------------------------------------------------------------------------------
1 | # This should be turned on if you are going to have pre-compressed copies (.gz) of
2 | # static files available. If not it should be left off as it will cause extra I/O
3 | # for the check. It is best if you enable this in a location{} block for
4 | # a specific directory, or on an individual server{} level.
5 | gzip_static on;
--------------------------------------------------------------------------------
/files/etc/nginx/rules/no_transform.conf:
--------------------------------------------------------------------------------
1 | # Prevent mobile network providers from modifying your site
2 | add_header "Cache-Control" "no-transform";
3 |
--------------------------------------------------------------------------------
/files/etc/nginx/rules/security.conf:
--------------------------------------------------------------------------------
1 | # Block access to hidden files and directories.
2 | # This includes directories used by version control systems such as Git and SVN.
3 | location ~* (?:^|/)\. {
4 | deny all;
5 | access_log off;
6 | log_not_found off;
7 | }
8 |
9 | # Block access to backup and source files.
10 | # These files may be left by some text editors and can pose a great security
11 | # danger when anyone has access to them.
12 | location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
13 | deny all;
14 | access_log off;
15 | log_not_found off;
16 | }
17 |
--------------------------------------------------------------------------------
/files/etc/nginx/rules/ssl.conf:
--------------------------------------------------------------------------------
1 | # Protect against the BEAST attack by preferring RC4-SHA when using SSLv3 and TLS protocols.
2 | # Note that TLSv1.1 and TLSv1.2 are immune to the beast attack but only work with OpenSSL v1.0.1 and higher and has limited client support.
3 | ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
4 | ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
5 | ssl_prefer_server_ciphers on;
6 |
7 | # Optimize SSL by caching session parameters for 10 minutes. This cuts down on the number of expensive SSL handshakes.
8 | # The handshake is the most CPU-intensive operation, and by default it is re-negotiated on every new/parallel connection.
9 | # By enabling a cache (of type "shared between all Nginx workers"), we tell the client to re-use the already negotiated state.
10 | # Further optimization can be achieved by raising keepalive_timeout, but that shouldn't be done unless you serve primarily HTTPS.
11 | ssl_session_cache shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
12 | ssl_session_timeout 10m;
--------------------------------------------------------------------------------
/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: restart nginx
4 | service: name=nginx state=restarted
5 | when: nginx_service_state != 'stopped'
6 |
7 | - name: reload nginx
8 | service: name=nginx state=reloaded
9 | when: nginx_service_state != 'stopped'
10 |
--------------------------------------------------------------------------------
/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | author: franklin
4 | company: We Are Interactive
5 | description: Installs and configures nginx
6 | min_ansible_version: 2.4
7 | license: MIT
8 | # Optionally specify the branch Galaxy will use when accessing the GitHub
9 | # repo for this role. During role install, if no tags are available,
10 | # Galaxy will use this branch. During import Galaxy will access files on
11 | # this branch. If travis integration is cofigured, only notification for this
12 | # branch will be accepted. Otherwise, in all cases, the repo's default branch
13 | # (usually master) will be used.
14 | github_branch: master
15 | #
16 | # Below are all platforms currently available. Just uncomment
17 | # the ones that apply to your role. If you don't see your
18 | # platform on this list, let us know and we'll get it added!
19 | #
20 | platforms:
21 | #- name: EL
22 | # versions:
23 | # - all
24 | # - 5
25 | # - 6
26 | # - 7
27 | #- name: GenericUNIX
28 | # versions:
29 | # - all
30 | # - any
31 | #- name: Solaris
32 | # versions:
33 | # - all
34 | # - 10
35 | # - 11.0
36 | # - 11.1
37 | # - 11.2
38 | # - 11.3
39 | #- name: Fedora
40 | # versions:
41 | # - all
42 | # - 16
43 | # - 17
44 | # - 18
45 | # - 19
46 | # - 20
47 | # - 21
48 | # - 22
49 | # - 23
50 | #- name: Windows
51 | # versions:
52 | # - all
53 | # - 2012R2
54 | #- name: SmartOS
55 | # versions:
56 | # - all
57 | # - any
58 | #- name: opensuse
59 | # versions:
60 | # - all
61 | # - 12.1
62 | # - 12.2
63 | # - 12.3
64 | # - 13.1
65 | # - 13.2
66 | #- name: Amazon
67 | # versions:
68 | # - all
69 | # - 2013.03
70 | # - 2013.09
71 | #- name: GenericBSD
72 | # versions:
73 | # - all
74 | # - any
75 | #- name: FreeBSD
76 | # versions:
77 | # - all
78 | # - 10.0
79 | # - 10.1
80 | # - 10.2
81 | # - 8.0
82 | # - 8.1
83 | # - 8.2
84 | # - 8.3
85 | # - 8.4
86 | # - 9.0
87 | # - 9.1
88 | # - 9.1
89 | # - 9.2
90 | # - 9.3
91 | - name: Ubuntu
92 | versions:
93 | - all
94 | # - lucid
95 | # - maverick
96 | # - natty
97 | # - oneiric
98 | # - precise
99 | # - quantal
100 | # - raring
101 | # - saucy
102 | # - trusty
103 | # - utopic
104 | # - vivid
105 | # - wily
106 | #- name: SLES
107 | # versions:
108 | # - all
109 | # - 10SP3
110 | # - 10SP4
111 | # - 11
112 | # - 11SP1
113 | # - 11SP2
114 | # - 11SP3
115 | #- name: GenericLinux
116 | # versions:
117 | # - all
118 | # - any
119 | - name: Debian
120 | versions:
121 | - all
122 | # - etch
123 | # - jessie
124 | # - lenny
125 | # - squeeze
126 | # - wheezy categories:
127 | #
128 | # List tags for your role here, one per line. A tag is
129 | # a keyword that describes and categorizes the role.
130 | # Users find roles by searching for tags. Be sure to
131 | # remove the '[]' above if you add tags to this list.
132 | #
133 | # NOTE: A tag is limited to a single word comprised of
134 | # alphanumeric characters. Maximum 20 tags per role.
135 | galaxy_tags:
136 | - web
137 | - nginx
138 | # List your role dependencies here, one per line. Only
139 | # dependencies available via galaxy should be listed here.
140 | # Be sure to remove the '[]' above if you add dependencies
141 | # to this list.
142 | dependencies: []
143 |
--------------------------------------------------------------------------------
/meta/readme.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | galaxy_name: weareinteractive.nginx
4 | github_user: weareinteractive
5 | github_name: ansible-nginx
6 | badges: |
7 | [](https://travis-ci.org/weareinteractive/ansible-nginx)
8 | [](https://galaxy.ansible.com/weareinteractive/nginx)
9 | [](https://github.com/weareinteractive/ansible-nginx)
10 | [](https://github.com/weareinteractive/ansible-nginx)
11 | description: |
12 | > * installs nginx
13 | > * configures nginx
14 | > * creates sites
15 | > * enables/disables sites
16 | > * optionally removes default host
17 | > * adds rules
18 | > * configures service
19 |
20 | **Note:**
21 |
22 | > Since Ansible Galaxy supports [organization](https://www.ansible.com/blog/ansible-galaxy-2-release) now, this role has moved from `franklinkim.nginx` to `weareinteractive.nginx`!
23 | after_dependencies: |
24 | ## Related (see example)
25 |
26 | * [weareinteractive.openssl](https://github.com/weareinteractive/ansible-openssl)
27 | * [weareinteractive.htpasswd](https://github.com/weareinteractive/ansible-htpasswd)
28 | after_handlers: |
29 | ## Rules
30 |
31 | If `nginx_add_rules` is `yes`, it will copy some configuration rules to `/etc/nginx/rules`:
32 |
33 | * cache_busting.conf
34 | * cors_web_fonts.conf
35 | * gzip.conf
36 | * no_transform.conf
37 | * ssl.conf
38 | * cors_ajax.con
39 | * expires.conf
40 | * gzip_static.conf
41 | * security.conf
42 |
--------------------------------------------------------------------------------
/tasks/config.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Configuring nginx
4 | template:
5 | src: etc/nginx/nginx.conf.j2
6 | dest: /etc/nginx/nginx.conf
7 | owner: root
8 | group: root
9 | mode: "0644"
10 | notify: reload nginx
11 |
12 | - name: Ensure folders
13 | file:
14 | path: "{{ item }}"
15 | state: directory
16 | group: root
17 | owner: root
18 | mode: "0644"
19 | with_items:
20 | - /etc/nginx/sites-enabled
21 | - /etc/nginx/sites-available
22 |
23 | - name: Disabling default site
24 | file:
25 | path: /etc/nginx/sites-enabled/default
26 | state: absent
27 | when: nginx_remove_default
28 | notify: reload nginx
29 |
30 | - name: Removing default host
31 | file:
32 | path: "{{ item }}"
33 | state: absent
34 | with_items:
35 | - /etc/nginx/sites-available/default
36 | - /var/www/html
37 | when: nginx_remove_default
38 |
39 | - name: Adding rules
40 | copy:
41 | src: etc/nginx/rules/
42 | dest: /etc/nginx/rules/
43 | owner: root
44 | group: root
45 | mode: "0644"
46 | when: nginx_add_rules
47 |
--------------------------------------------------------------------------------
/tasks/install.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Installing dependencies
4 | apt:
5 | pkg: "{{ nginx_dependencies }}"
6 | state: present
7 |
8 | - name: Importing APT key
9 | apt_key:
10 | id: "{{ nginx_repo_key }}"
11 | keyserver: keyserver.ubuntu.com
12 | state: present
13 |
14 | - name: Adding APT repository
15 | apt_repository:
16 | repo: "{{ nginx_repo }}"
17 | update_cache: yes
18 |
19 | - name: Installing packages
20 | package:
21 | name: "{{ nginx_package }}"
22 | state: present
23 |
--------------------------------------------------------------------------------
/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - import_tasks: install.yml
4 | tags:
5 | - web
6 | - nginx
7 | - install
8 | - nginx-install
9 |
10 | - import_tasks: config.yml
11 | tags:
12 | - web
13 | - nginx
14 | - config
15 | - nginx-config
16 |
17 | - import_tasks: manage.yml
18 | when: nginx_sites | length
19 | tags:
20 | - web
21 | - nginx
22 | - manage
23 | - nginx-manage
24 |
25 | - import_tasks: service.yml
26 | tags:
27 | - web
28 | - nginx
29 | - service
30 | - nginx-service
31 |
--------------------------------------------------------------------------------
/tasks/manage.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Creating webroots
4 | file:
5 | dest: "/var/www/{{ item.id }}/htdocs"
6 | state: directory
7 | when: item.add_webroot is defined and item.add_webroot
8 | with_items: "{{ nginx_sites }}"
9 |
10 | - name: Configuring sites
11 | template:
12 | src: "{{ item.template|default('etc/nginx/sites-available/site.j2') }}"
13 | dest: "/etc/nginx/sites-available/{{ item.id }}"
14 | owner: root
15 | group: root
16 | mode: "0644"
17 | with_items: "{{ nginx_sites }}"
18 | notify: reload nginx
19 |
20 | - name: Enabling sites
21 | file:
22 | src: "/etc/nginx/sites-available/{{ item.id }}"
23 | dest: "/etc/nginx/sites-enabled/{{ item.id }}"
24 | state: link
25 | when: item.state is not defined or item.state == 'present'
26 | with_items: "{{ nginx_sites }}"
27 | notify: reload nginx
28 |
29 | - name: Disabling sites
30 | file:
31 | src: "/etc/nginx/sites-available/{{ item.id }}"
32 | dest: "/etc/nginx/sites-enabled/{{ item.id }}"
33 | state: absent
34 | when: item.state is defined and item.state == 'absent'
35 | with_items: "{{ nginx_sites }}"
36 | notify: restart nginx
37 |
--------------------------------------------------------------------------------
/tasks/service.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Configuring service
4 | service:
5 | name: nginx
6 | state: "{{ nginx_service_state }}"
7 | enabled: "{{ nginx_service_enabled }}"
8 |
--------------------------------------------------------------------------------
/templates/etc/nginx/nginx.conf.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | # Run as a less privileged user for security reasons.
4 | user {{ nginx_user }};
5 |
6 | # How many worker threads to run;
7 | # "auto" sets it to the number of CPU cores available in the system, and
8 | # offers the best performance. Don't set it higher than the number of CPU
9 | # cores if changing this parameter.
10 |
11 | # The maximum number of connections for Nginx is calculated by:
12 | # max_clients = worker_processes * worker_connections
13 | worker_processes {{ nginx_worker_processes }};
14 | pid /run/nginx.pid;
15 |
16 | events {
17 | # When you need > 8000 * cpu_cores connections, you start optimizing your OS,
18 | # and this is probably the point at which you hire people who are smarter than
19 | # you, as this is *a lot* of requests.
20 | worker_connections {{ nginx_worker_connections }};
21 | # multi_accept on;
22 | }
23 |
24 | http {
25 |
26 | ##
27 | # Basic Settings
28 | ##
29 |
30 | sendfile {{ nginx_sendfile }};
31 | tcp_nopush {{ nginx_tcp_nopush }};
32 | tcp_nodelay {{ nginx_tcp_nodelay }};
33 | keepalive_timeout {{ nginx_keepalive_timeout }};
34 | types_hash_max_size {{ nginx_types_hash_max_size }};
35 | server_tokens {{ nginx_server_tokens }};
36 |
37 | server_names_hash_bucket_size {{ nginx_server_names_hash_bucket_size }};
38 | # server_name_in_redirect off;
39 |
40 | include /etc/nginx/mime.types;
41 | default_type application/octet-stream;
42 |
43 | ##
44 | # Logging Settings
45 | ##
46 |
47 | access_log /var/log/nginx/access.log;
48 | error_log /var/log/nginx/error.log;
49 |
50 | ##
51 | # Gzip Settings
52 | ##
53 |
54 | gzip on;
55 | gzip_disable "msie6";
56 |
57 | gzip_vary on;
58 | gzip_proxied any;
59 | gzip_comp_level 6;
60 | gzip_buffers 16 8k;
61 | gzip_min_length 10;
62 | gzip_http_version 1.1;
63 | gzip_types
64 | text/plain
65 | text/css
66 | application/json
67 | application/x-javascript
68 | application/javascript
69 | text/xml
70 | application/xml
71 | application/xml+rss
72 | text/javascript
73 | image/png
74 | image/gif
75 | image/jpeg;
76 |
77 | ##
78 | # nginx-naxsi config
79 | ##
80 | # Uncomment it if you installed nginx-naxsi
81 | ##
82 |
83 | #include /etc/nginx/naxsi_core.rules;
84 |
85 | ##
86 | # nginx-passenger config
87 | ##
88 | # Uncomment it if you installed nginx-passenger
89 | ##
90 |
91 | #passenger_root /usr;
92 | #passenger_ruby /usr/bin/ruby;
93 | ##
94 | # Virtual Host Configs
95 | ##
96 |
97 | include /etc/nginx/conf.d/*.conf;
98 | include /etc/nginx/sites-enabled/*;
99 | }
100 |
--------------------------------------------------------------------------------
/templates/etc/nginx/sites-available/site-body.j2:
--------------------------------------------------------------------------------
1 | server {
2 | server_name {{ item.name }}{% for value in item.aliases|default([]) %} {{ value }}{% endfor %};
3 | root /var/www/{{ item.id }}/htdocs;
4 |
5 | # --- listen ----------------------------------------------------------------
6 |
7 | listen {{ item.ip|default('*') }}:{{item.port|default(80)}};
8 | {% if item.ssl is defined %}
9 | listen {{ item.ip|default('*') }}:{{item.ssl.port|default(443)}} ssl;
10 | {% endif %}
11 |
12 | {% if item.ssl is defined %}
13 | # --- ssl -------------------------------------------------------------------
14 | include rules/ssl.conf;
15 |
16 | ssl_certificate {{ item.ssl.cert_path|default(openssl_certs_path) }}/{{ item.ssl.cert_name|default('server.crt') }};
17 | ssl_certificate_key {{ item.ssl.key_path|default(openssl_keys_path) }}/{{ item.ssl.key_name|default('server.key') }};
18 | {% endif %}
19 |
20 | {% if item.rules is defined %}
21 | # --- rule ------------------------------------------------------------------
22 | {% for value in item.rules %}
23 | include rules/{{ value }}.conf;
24 | {% endfor %}
25 | {% endif %}
26 |
27 | {% if item.auth is defined %}
28 | # --- auth ------------------------------------------------------------------
29 |
30 | auth_basic "{{ item.auth.name|default(item.id) }}";
31 | auth_basic_user_file /etc/htpasswd/{{ item.auth.file|default(item.id) }};
32 | {% endif %}
33 |
34 | # --- locations -------------------------------------------------------------
35 |
36 | location / {
37 | try_files $uri $uri/ =404;
38 | }
39 |
40 | # --- logging ---------------------------------------------------------------
41 |
42 | error_log /var/log/nginx/error-{{ item.id }}.log;
43 | access_log /var/log/nginx/access-{{ item.id }}.log;
44 |
45 | {% if item.append is defined %}
46 | # --- appended --------------------------------------------------------------
47 |
48 | {{ item.append }}
49 | {% endif %}
50 | }
51 |
--------------------------------------------------------------------------------
/templates/etc/nginx/sites-available/site-redirect.j2:
--------------------------------------------------------------------------------
1 | {% for value in item.redirects|default([]) %}
2 | server {
3 | server_name {{ value }};
4 | listen {{ item.ip|default('*') }}:{{item.port|default(80)}};
5 | {% if item.ssl is defined %}
6 | listen {{ item.ip|default('*') }}:{{item.ssl.port|default(443)}} ssl;
7 | {% endif %}
8 |
9 | {% if item.ssl is defined %}
10 | # --- ssl -------------------------------------------------------------------
11 |
12 | include rules/ssl.conf;
13 |
14 | ssl_certificate {{ item.ssl.cert_path|default(openssl_certs_path) }}/{{ item.ssl.cert_name|default('server.crt') }};
15 | ssl_certificate_key {{ item.ssl.key_path|default(openssl_keys_path) }}/{{ item.ssl.key_name|default('server.key') }};
16 | {% endif %}
17 |
18 | # --- redirects --------------------------------------------------------------
19 |
20 | rewrite ^/(.*)$ $scheme://{{ item.name }}/$1 permanent;
21 | }
22 | {% endfor %}
23 |
--------------------------------------------------------------------------------
/templates/etc/nginx/sites-available/site.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | {% include "etc/nginx/sites-available/site-redirect.j2" %}
4 |
5 | {% include "etc/nginx/sites-available/site-body.j2" %}
6 |
--------------------------------------------------------------------------------
/tests/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - hosts: all
4 | become: yes
5 | roles:
6 | - weareinteractive.apt
7 | - weareinteractive.openssl
8 | - weareinteractive.htpasswd
9 | - weareinteractive.nginx
10 | vars:
11 | htpasswd:
12 | - name: foobar
13 | users:
14 | - { name: foobar, password: foobar }
15 | openssl_generate_csr: yes
16 | openssl_self_signed:
17 | - name: fooboar.local
18 | subject:
19 | C: DE
20 | ST: Bavaria
21 | L: Munich
22 | O: Foo Bar Inc
23 | CN: foobar.local
24 | emailAddress: null@foobar.local
25 | nginx_sites:
26 | - id: foobar
27 | add_webroot: yes
28 | name: foobar.local
29 | ssl:
30 | key_name: foobar.local.key
31 | cert_name: foobar.local.crt
32 | rules:
33 | - gzip
34 | - security
35 | auth:
36 | name: Foo Bar
37 | file: foobar
38 | nginx_worker_processes: 1
39 | nginx_remove_default: yes
40 | # do not start service as we're running in docker
41 | nginx_service_state: stopped
42 | nginx_service_enabled: no
43 |
--------------------------------------------------------------------------------