Hey Y’all. How have you been? Covid keep releasing updates and this never seems to end isn’t it ? ㋡Today I will be talking you through an Ansible script that I have written to set up a NGINX reverse proxy. You may wonder, wasn’t it the same thing that you wrote about last time? No! This time I have taken it a step further. This time we are looking at setting up a reverse proxy with caching and TLS. (With TLS certificate auto renewal enabled.)
Let’s jump right in to it. You can find the code here: https://github.com/ihsanizwer/AnsibleNginxReverseProxyWithCachingAndTLS.git
I know! the repo name is bit of a mouthful. But keep on reading. You’re in for a treat!
Where can I run it?
The script it self can be run on any master node having Ansible installed. But the targets(hosts/managed nodes) of this script must be running Ubuntu. It may work on other Debian derivatives. However, I haven’t tested it on other hosts. One more point: this only works for hosts with second level domains. For top level domains, we need to setup a challenge for certbot to work.
How to set it up?
There is a readme file in the repository. Please refer to it. It is important that you specify the correct hostnames in the inventory file. This is because the names in the inventory file will be used to set the hostnames of the hosts.
What’s the big deal?
Now you’ve reached the point where things get interesting. Firstly, note the serial
keyword in the playbook. The keyword ‘serial: 3
‘ ensures that only 3 hosts will be updated at a time. You can tweak it as you want. Anyways, the idea here is to enable rolling updates – meaning only 3 hosts will be in under maintenance at a time. Simultaneously, this results in lesser workload in the master node at a given time.
Next interesting thing is the use of Jinja2 templates. This means that everything takes shape during runtime. It takes shape based on variables and facts. I will show you a sample nginx template (before vs after) at the end of this blog post.
Setting up SSL/TLS and setting up auto-renewal. This is the next interesting item about the script. Certbot takes care of this. We just do the initial setup. In my sample configuration, I have allowed both http and https traffic. If you don’t want this and you only want to allow https traffic then you can use the config below. Note that the only difference is the “--redirect
” in place of “--no-redirect
“
gen_cert: "sudo certbot run -n --nginx --agree-tos -d {{ inventory_hostname }} -m {{ srv_adm_email }} --redirect"
Certbot installs cron for renewal. So there’s nothing to worry about certificate renewals.
Lastly, we have caching set up. This script allocates half of the main partition(we can choose whatever we want it to be) for caching. At this point the TTL for caching is set to be 4 hours. But, you can optimize it as per your requirement.
As promised earlier, here is a comparison of how the jinja2 template of the nginx config looks now. (refer below snippet)
proxy_cache_path "{{ cache_dir }}" keys_zone=cache1:10m max_size="1000m" inactive="{{ cache_ttl }}" use_temp_path=off;
server {
listen 80 default;
listen [::]:80 default;
server_name "{{ inventory_hostname }}";
location / {
proxy_pass "{{ proxy_pass }}";
proxy_cache cache1;
proxy_cache_valid 200 "{{ cache_ttl }}";
}
}
And this is how it will look after the script is run(on the managed node). (refer below snippet)
proxy_cache_path /nginx_cache keys_zone=cache1:10m max_size=10240m inactive=240m use_temp_path=off;
server {
listen 80 default;
listen [::]:80 default;
server_name rp-cache.eastus.cloudapp.azure.com;
location / {
proxy_pass http://myservtobecached.takeondevops.com:80;
proxy_cache cache1;
proxy_cache_valid 200 240m;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/rp-cache.eastus.cloudapp.azure.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/rp-cache.eastus.cloudapp.azure.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Do you want a simpler version of the above(vanilla NGINX reverse proxy)? Read this.