Ansible Playbook for Nginx Installation and Configuration
text
nginx-ssl-playbook/
├── inventory.ini
├── playbook.yml
├── templates/
│ ├── default-site.conf.j2
│ └── ssl-params.conf.j2
└── vars/
└── main.ymlStep 1: Create the Inventory File
Create an inventory file named inventory.ini:
ini
[webservers]
webserver ansible_host=your_server_ip ansible_user=root
[all:vars]
ansible_python_interpreter=/usr/bin/python3Step 2: Create Vars File
Create a vars file named vars/main.yml:
yaml
---
# Domain configuration
domain_name: "example.com"
domain_aliases:
- "www.example.com"
# Nginx configuration
nginx_root: "/var/www/html"
nginx_index_files: "index.html index.htm index.nginx-debian.html"
# SSL configuration
ssl_email: "your-email@example.com"
ssl_auto_redirect: true
# Custom website content (optional)
custom_website_content: "<html><head><title>My Website</title></head><body><h1>Hello, World!</h1></body></html>"Step 3: Create Template Files
Create a template file for the Nginx server block named templates/default-site.conf.j2:
jinja
server {
listen 80 default_server;
listen [::]:80 default_server;
root {{ nginx_root }};
index {{ nginx_index_files }};
server_name {{ domain_name }} {% for alias in domain_aliases %} {{ alias }}{% endfor %};
location / {
try_files $uri $uri/ =404;
}
}Create a template file for SSL parameters named templates/ssl-params.conf.j2:
jinja
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";Step 4: Create the Playbook
Create a playbook file named playbook.yml:
yaml
---
- hosts: webservers
become: yes
vars_files:
- vars/main.yml
tasks:
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Upgrade packages
apt:
upgrade: dist
- name: Install Nginx
apt:
name: nginx
state: present
notify: Start Nginx
- name: Allow HTTP and HTTPS through UFW
ufw:
rule: allow
name: "Nginx Full"
register: ufw_status
- name: Show UFW status
command: ufw status
register: ufw_status_result
changed_when: false
- name: Display UFW status
debug:
msg: "{{ ufw_status_result.stdout_lines }}"
- name: Configure Nginx default site
template:
src: templates/default-site.conf.j2
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: "0644"
notify: Reload Nginx
- name: Create custom website (optional)
copy:
content: "{{ custom_website_content }}"
dest: "{{ nginx_root }}/index.html"
owner: www-data
group: www-data
mode: "0644"
- name: Install Certbot
apt:
name:
- certbot
- python3-certbot-nginx
state: present
- name: Create SSL parameters file
template:
src: templates/ssl-params.conf.j2
dest: /etc/nginx/snippets/ssl-params.conf
owner: root
group: root
mode: "0644"
- name: Check if SSL certificate exists
stat:
path: /etc/letsencrypt/live/{{ domain_name }}/fullchain.pem
register: ssl_cert
- name: Get SSL certificate with Certbot
shell: >
certbot --nginx
-d {{ domain_name }}
{% for alias in domain_aliases %} -d {{ alias }}{% endfor %}
--non-interactive --agree-tos --email {{ ssl_email }}
{% if ssl_auto_redirect %}--redirect{% endif %}
when: not ssl_cert.stat.exists
notify: Reload Nginx
- name: Verify SSL certificate auto-renewal
command: certbot renew --dry-run
changed_when: false
- name: Update default site to include SSL params
lineinfile:
path: /etc/nginx/sites-available/default
regexp: "^ include snippets/ssl-params.conf;"
insertafter: ' listen \[\:\:\]\:443 ssl;'
line: " include snippets/ssl-params.conf;"
notify: Reload Nginx
handlers:
- name: Start Nginx
systemd:
name: nginx
state: started
enabled: yes
- name: Reload Nginx
systemd:
name: nginx
state: reloaded
- name: Test Nginx configuration
command: nginx -t
register: nginx_config_test
changed_when: false
notify: Reload Nginx if config OK
- name: Reload Nginx if config OK
systemd:
name: nginx
state: reloaded
when: nginx_config_test is successStep 5: Run the Playbook
- Update your inventory file with the correct server IP and user.
- Modify the variables in vars/main.yml to match your domain and preferences.
- Run the playbook with the following command:
bash
ansible-playbook -i inventory.ini playbook.ymlFeatures
This Ansible playbook automates the following tasks:
- Updates system packages
- Installs and configures Nginx
- Sets up proper firewall rules
- Creates a default website
- Installs and configures SSL with Certbot
- Implements additional security hardening
- Verifies auto-renewal of SSL certificates
- Includes thorough error checking and handlers
Customization
To use this playbook for different servers or domains:
- Modify the inventory.ini file to include your target servers
- Update the variables in vars/main.yml with domain names and other preferences
- Run the playbook again to apply the configuration to new servers
All templates and configurations are parameterized to make this playbook completely reusable across different environments.