Now that our app is live and available through a custom domain, itās time to take a crucial step toward production readiness: securing it with SSL encryption.
š” Why SSL Matters
SSL (Secure Sockets Layer) ensures that any data transferred between your users and your server is encrypted and private. Without it, all communicationālike login credentials, form submissions, and API trafficāis transmitted in plain text and can be intercepted.
Youāll also notice modern browsers showing scary “Not Secure” warnings on HTTP-only websites. Google even considers HTTPS a ranking factor for SEO.
š What Is Letās Encrypt and Certbot?
- Letās Encrypt is a free, automated, and open Certificate Authority that issues SSL certificates.
- Certbot is a tool that automates the process of:
- Requesting a certificate
- Installing it with Nginx
- Renewing it automatically via cron
Best of all? It’s free and easy to integrate with Ansible.
š¦ Step 1: Create the Certbot Role
Letās start by creating a new Ansible role to install and configure SSL with Certbot:
cd ansible
mkdir -p roles/certbot/tasks
āļø Step 2: Configure the Role
Create roles/certbot/tasks/main.yml
and add the following:
---
- name: Install certbot
apt:
name:
- certbot
- python3-certbot-nginx
state: present
force: yes
update_cache: yes
- name: Register certbot
shell: |
certbot -n register --agree-tos --email {{ email }}
touch /etc/letsencrypt/.registered
args:
creates: /etc/letsencrypt/.registered
- name: Setup cronjob for renewal
cron:
name: certbot-renewal
job: "/bin/bash -lc '/usr/bin/certbot -q renew'"
minute: "0"
hour: "14"
user: "{{ username }}"
- name: 'Get certificate'
command: '/usr/bin/certbot -n --nginx certonly -d {{ hostname }} -d www.{{ hostname }}'
args:
creates: '/etc/letsencrypt/live/{{ hostname }}'
ignore_errors: true
š§ Breaking it Down
- Certbot installation: Installs the necessary Certbot packages for Nginx.
- Certbot registration: Registers an account with Letās Encrypt using your email (required).
- Cronjob setup: Ensures your certificate is automatically renewed daily.
- SSL certificate request: Requests a certificate for both
yourdomain.com
andwww.yourdomain.com
.
We use
certonly
so Certbot gets the cert but doesnāt modify the Nginx config (we do that manually via template).
š Step 3: Add the Role
In main.yml
, include the role:
...
roles:
...
- role: roles/certbot
And in your vars.yml
, add your email address:
email: <your email>
Then run the playbook:
play main.yml
š§Ŗ Verifying Certbot Setup
SSH onto the server and check:
- Certificate files:
ls /etc/letsencrypt/live/{{ hostname }}
You should see files like:
fullchain.pem
privkey.pem
cert.pem
- Dry-run renewal:
sudo certbot renew --dry-run
š Step 4: Update Nginx to Use SSL
Open your Nginx template at roles/app-nginx/templates/app.nginx.j2
and update it like so:
# Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name {{ hostname }};
return 301 https://$host$request_uri;
}
# Serve app over HTTPS
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ hostname }};
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ hostname }}/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://unix:/run/{{ service_name }}/gunicorn.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
š Nginx Breakdown
- The first server block redirects HTTP to HTTPS.
- The second block:
- Listens on port 443
- Uses the Letās Encrypt cert and private key
- Proxies traffic to Gunicorn (like before)
š Step 5: Run the Playbook Again
Apply the changes:
play main.yml
When itās done, test your HTTPS endpoint:
curl https://<domain>/todos
You should now see the expected JSON response from your Flask APIāthis time encrypted and secure ā
ā Summary
In this article, we:
- Installed and configured Certbot to obtain a free SSL certificate
- Set up automated renewal via cron
- Updated Nginx to redirect HTTP to HTTPS and use your new certificate
- Validated everything with a secure
curl
request
You now have a fully encrypted Flask API running behind HTTPSāhuge win for security and professionalism.
š Next Upā¦
In the final part of the series, weāll use Terraform to configure monitoring and alerts so we can track the health of our droplet.
See you there! š
Leave a Reply