{"id":23637026,"url":"https://github.com/ansibleguy/infra_nginx","last_synced_at":"2025-08-31T12:30:29.775Z","repository":{"id":53920652,"uuid":"413969223","full_name":"ansibleguy/infra_nginx","owner":"ansibleguy","description":"Ansible Role to provision Nginx sites","archived":false,"fork":false,"pushed_at":"2024-09-06T16:32:58.000Z","size":183,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"latest","last_synced_at":"2024-09-06T19:46:16.234Z","etag":null,"topics":["ansible","ansible-role","automation","certbot","certificates","iac","infrastructure-as-code","nginx","webserver"],"latest_commit_sha":null,"homepage":"","language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ansibleguy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"ansible0guy","github":"ansibleguy"}},"created_at":"2021-10-05T20:27:27.000Z","updated_at":"2024-09-06T16:33:02.000Z","dependencies_parsed_at":"2024-06-23T13:24:47.731Z","dependency_job_id":"de64f85f-7f9a-427d-be7c-0b4584dd0229","html_url":"https://github.com/ansibleguy/infra_nginx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nginx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nginx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nginx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nginx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ansibleguy","download_url":"https://codeload.github.com/ansibleguy/infra_nginx/tar.gz/refs/heads/latest","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231590686,"owners_count":18396934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-role","automation","certbot","certificates","iac","infrastructure-as-code","nginx","webserver"],"created_at":"2024-12-28T06:17:26.730Z","updated_at":"2025-08-31T12:30:29.691Z","avatar_url":"https://github.com/ansibleguy.png","language":"Jinja","funding_links":["https://ko-fi.com/ansible0guy","https://github.com/sponsors/ansibleguy"],"categories":[],"sub_categories":[],"readme":"[![Nginx](https://nginx.org/nginx.png)](https://nginx.org)\n\n# Ansible Role - Nginx Webserver\n\nAnsible Role to deploy one or multiple NGINX sites on a linux server.\n\n\n[![Lint](https://github.com/ansibleguy/infra_nginx/actions/workflows/lint.yml/badge.svg)](https://github.com/ansibleguy/infra_nginx/actions/workflows/lint.yml)\n[![Ansible Galaxy](https://badges.ansibleguy.net/galaxy.badge.svg)](https://galaxy.ansible.com/ui/standalone/roles/ansibleguy/infra_nginx)\n\n**Molecule Integration-Tests**:\n\n* Status: [![Molecule Test Status](https://badges.ansibleguy.net/infra_nginx.molecule.svg)](https://github.com/ansibleguy/_meta_cicd/blob/latest/templates/usr/local/bin/cicd/molecule.sh.j2) |\n[![Functional-Tests](https://github.com/ansibleguy/infra_nginx/actions/workflows/integration_test_result.yml/badge.svg)](https://github.com/ansibleguy/infra_nginx/actions/workflows/integration_test_result.yml)\n* Logs: [API](https://ci.ansibleguy.net/api/job/ansible-test-molecule-infra_nginx/logs?token=2b7bba30-9a37-4b57-be8a-99e23016ce70\u0026lines=1000) | [Short](https://badges.ansibleguy.net/log/molecule_infra_nginx_test_short.log) | [Full](https://badges.ansibleguy.net/log/molecule_infra_nginx_test.log)\n\nInternal CI: [Tester Role](https://github.com/ansibleguy/_meta_cicd) | [Jobs API](https://github.com/O-X-L/github-self-hosted-jobs-systemd)\n\n**Tested:**\n* Debian 11\n* Debian 12\n\n----\n\n## Install\n\n```bash\n# latest\nansible-galaxy role install git+https://github.com/ansibleguy/infra_nginx\n\n# from galaxy\nansible-galaxy install infra_nginx\n\n# or to custom role-path\nansible-galaxy install infra_nginx --roles-path ./roles\n\n# install dependencies\nansible-galaxy install -r requirements.yml\n\n# if you want to use basic-auth: install python dependencies\npython3 -m pip install -r requirements.txt\n```\n\n----\n\n## Usage\n\n### Config\n\nDefine the nginx dictionary as needed!\n\n```yaml\nnginx:\n  config:\n    client_max_body_size: '500m'\n    ssl_session_timeout: '15m'\n  \n  sites:\n    some_proxy:\n      mode: 'proxy'\n      domain: 'some.guy.net'\n      aliases:\n        - 'service.guy.net'\n\n      port_ssl: 8443\n      port_plain: 8080\n      proxy:  # default proxy-target is localhost\n        port: 50000  # target port\n        \n        cache:  # upstream content-caching\n          enable: true\n\n      ssl:\n        mode: 'existing'  # pre-existing certificates to be copied to the target server\n\n      security:\n        # very basic filtering of bad bots based on user-agent matching\n        block_script_bots: true\n        block_bad_crawler_bots: true\n\n    guys_statics:\n      mode: 'server'\n      domain: 'static.guy.net'\n      serve:\n        path: '/var/www/static'\n\n      ssl:\n        mode: 'snakeoil'\n      \n      config:  # add settings as key-value pairs\n        LimitRequestFields: 10\n      config_additions:  # add a list of custom lines of config\n        - 'location = /favicon.ico {alias /var/not_www/site_guys_statics/favicon.ico;}'\n\n    git_stuff:\n      mode: 'redirect'\n      redirect:\n        target: 'https://github.com/ansibleguy'\n\n      ssl:\n        mode: 'letsencrypt'\n      letsencrypt:\n        email: 'nginx@template.ansibleguy.net'\n\n      security:\n        restrict_methods: false\n\n    fileshare:\n      mode: 'server'\n      domain: 'files.guy.net'\n      serve:\n        path: '/var/www/files'\n\n      basic_auth:\n        enable: true\n        provider: 'file'\n        file:\n          users:\n            some_user: 'some_password'\n```\n\n### Execution\n\nRun the playbook:\n```bash\nansible-playbook -K -D -i inventory/hosts.yml playbook.yml\n```\n\nTo only process a specific site: (_and safe time_)\n```bash\nansible-playbook -K -D -i inventory/hosts.yml playbook.yml -e only_site=SITE_NAME\n# note: multiple comma-separated sites should also work\n```\n\n\nThere are also some useful **tags** available:\n* base =\u003e only configure basics; sites will not be touched\n* sites\n* config =\u003e only update site config (_excluding certificates_)\n* certs\n* letsencrypt\n* auth\n* only_certs (can be used as skip-tag)\n\nTo debug errors - you can set the 'debug' variable at runtime:\n```bash\nansible-playbook -K -D -i inventory/hosts.yml playbook.yml -e debug=yes\n```\n\n----\n\n## Functionality\n\n* **Package installation**\n  * Ansible dependencies (_minimal_)\n  * Nginx\n\n\n* **Configuration**\n  * Support for multiple sites/servers\n  * Three **config-modes**:\n    * proxy (_default_)\n    * serve\n    * redirect\n  * Support for specific configurations using the 'config' and 'config_additions' parameters\n  * Option to filter 'locations' by GeoIP =\u003e COMING SOON (:\n\n  * **Default config**:\n    * Disabled: \u003cTLS1.2, unsecure ciphers, autoindex, servertokens\n    * Security headers: HSTS, X-Frame, Referrer-Policy, Content-Type nosniff, X-Domain-Policy, XXS-Protection\n    * Limits to prevent DDoS\n    * Using a Self-Signed certificate\n    * HTTP2 enabled with fallback to HTTP1.1\n    * IPv6 support enabled\n\n\n  * **SSL modes** (_for more info see: [CERT ROLE](https://github.com/ansibleguy/infra_nginx)_)\n    * **selfsigned** =\u003e Generate self-signed ones\n    * **ca** =\u003e Generate a minimal Certificate Authority and certificate signed by it\n    * **letsencrypt** =\u003e Uses the LetsEncrypt certbot\n    * **existing** =\u003e Copy certificate files or use existing ones\n\n\n  * **Default opt-ins**:\n    * restricting methods to POST/GET/HEAD\n    * status-page listener on localhost\n    * Logging to syslog\n    * http2\n\n\n  * **Default opt-outs**:\n    * proxy-mode caching\n    * Blocking of Known Script-Bots\n    * Blocking of known Bad-Crawler-Bots\n\n## Info\n\n* **Note:** this role currently only supports debian-based systems\n\n\n* **Note:** Most of the role's functionality can be opted in or out.\n\n  For all available options - see the default-config located in the main/site defaults-file!\n\n\n* **Info:** Many variables can be set either on 'global' or 'per-site' scope.\n\n  Site config is always overruling the global one.\n\n\n* **Note:** This role expects that the site's unencrypted 'server' will only redirect to its encrypted connection.\n\n\n* **Note:** If you want all domain-names to get 'caught' by a site/server you need to add an underline '_' as alias or domain!\u003cbr\u003e\nThis will also be done automatically if no domain is supplied.\n\n\n* **Warning:** Not every setting/variable you provide will be checked for validity. Bad config might break the role!\n\n\n* **Info:** To disable default settings and headers =\u003e just set their value to: '' (_empty string_)\n\n\n* **Info:** If you are filtering web-requests via GeoIP filter using your firewall =\u003e LetsEncrypt will work with only opening port 80 to the world.\n\n  Requests other than '.well-known/acme-challenge/' are just redirected to 443.\n\n\n* **Info:** For LetsEncrypt renewal to work, you must allow outgoing connections to:\n\n  80/tcp, 443/tcp+udp to acme-v02.api.letsencrypt.org, staging-v02.api.letsencrypt.org (_debug mode_) and r3.o.lencr.org\n\n\n* **Info:** This role also supports configuring basic-auth.\n\n  For advanced use-cases you might want to set [auth_request](http://nginx.org/en/docs/http/ngx_http_auth_request_module.html) in `site.config_additions_root` that can be used to implement OAuth-Proxies and so on.\n\n\n* **Info:** You can set the `plain_only` flag to disable HTTPS. This might be nice-to-have if you are behind another proxy server.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fansibleguy%2Finfra_nginx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fansibleguy%2Finfra_nginx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fansibleguy%2Finfra_nginx/lists"}