A step-by-step guide for AWS EC2 provisioning using Terraform: Let’s Encrypt SSL Certificate in EC2 nginx server or Azure Virtual Machine ubuntu — Part 13 ( + Wildcard SSL )

Joel Wembo
11 min readJul 8, 2024

--

Let’s Encrypt SSL Certificate in EC2 nginx server or Azure VM ubuntu — Part 13. The document discusses securing a web server running on Ubuntu in either an Amazon EC2 instance or an Azure Virtual Machine with a free SSL certificate from Let’s Encrypt. We also added Wildcard SSL certification for subdomains.

prodxcloud ec2 instance running website secured using Let’s Encrypt SSL Certificate by joelwembo
prodxcloud ec2 instance running website secured using Let’s Encrypt SSL Certificate

Let’s Encrypt the SSL Certificate in EC2 nginx server or Azure VM Ubuntu Roadmap:

· Let’s Encrypt the SSL Certificate in EC2 nginx server or Azure VM Ubuntu Roadmap:
Introduction
Step 1: EC2 Provisioning
Step 2: nginx installation
Step 4: Add DNS Record Type A to your domain name pointing to your EC2 or Azure VM instance Public IP
Step 5: Install Certbot on Ubuntu ( Linux )
Step 6: Configure Nginx for Your Domain Name
Step 7: Nginx with Lets Encrypt ( certbot )
Step 8: Wildcard SSL
Conclusion
· About me
References

Introduction

SSL is the standard technology for securing an internet connection by encrypting data sent between a website and a browser (or between two servers). It prevents hackers from seeing or stealing any information transferred, including personal or financial data.

Installing Let’s Encrypt in the Ubuntu virtual machine. It will cover:

Let’s Encrypt is a global Certificate Authority (CA). We let people and organizations around the world obtain, renew, and manage SSL/TLS certificates. Our certificates can be used by websites to enable secure HTTPS connections. Let’s Encrypt offers Domain Validation (DV) certificates.

1. EC2 Provisioning:

  • Key Pair: Generate a key pair for SSH access to your EC2 instance. This involves creating a public and private key pair on your local machine. The private key will be used to connect securely to your instance.
  • Security Group: Create a security group in your AWS Management Console. This group defines inbound and outbound traffic rules for your EC2 instance. You’ll need to allow access through ports 22 (SSH) and 80 (HTTP) for initial setup and potentially 443 (HTTPS) for certificate validation.
  • Launch Instance: Launch an Ubuntu instance on EC2, selecting the appropriate Amazon Machine Image (AMI), instance type, and associating the previously created security group.

2. Nginx and Certbot Installation:

  • Connect to EC2: Use your private key to establish an SSH connection to your EC2 instance.
  • Update Packages: Update the package lists and installed software on your Ubuntu instance.
  • Install Nginx: Install the Nginx web server software using the package manager.
  • Install Certbot: Install Certbot, the tool to obtain Let’s Encrypt certificates, following the official installation guide for your specific Ubuntu version.

3. Obtain and Configure SSL Certificate:

  • Configure DNS Validation (Optional): Depending on the chosen Certbot method, you might need to configure a DNS record for your domain to validate ownership. This involves creating a specific record type (e.g., CNAME) in your domain name provider’s control panel.
  • Run Certbot: Use Certbot to obtain the SSL certificate for your domain name. The specific command will depend on the chosen validation method (standalone, DNS validation, etc.).
  • Configure Nginx for SSL: Update your Nginx configuration file to use the obtained SSL certificate and key for your website. This typically involves enabling HTTPS and specifying the certificate and key file paths.

4. Azure VM Specific Steps (Possible Variations): The document might also detail any variations required for setting up the environment and obtaining the certificate on an Azure VM. This could involve differences in security group configuration or using Azure-specific tools for DNS validation.

Step 1: EC2 Provisioning

For this demo, we have used both Github Actions and Terraform to provision our Ubuntu image. Please check Part 1 and Part 2 to learn how to get ready your ec2 instance or virtual machine.

Quick Note : Make sure you enable the ports 80 and 443 for securee HTTPS in your aws ec2 security group as follow :

Step 2: nginx installation

Here is the script to install nginx in Linux ( Ubuntu )

#!/bin/bash
# nginx installation in ubuntu server
sudo apt-get update
sudo apt-get install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx
echo '<!doctype html>
<html lang="en"><h1>EC2 running website</h1></br>
<h3>First Instance</h3>
</html>' | sudo tee /var/www/html/index.html

For the EC2 Amazon Linux 2, use the following commands:

# nginx installer for amazon lunix 2
# # Update package index
sudo yum update -y
# Install the Extra Packages for Enterprise Linux (EPEL) repository
sudo amazon-linux-extras install epel -y
# Install Nginx
sudo yum install -y nginx
# Start Nginx service
sudo systemctl start nginx
# Enable Nginx to start on boot
sudo systemctl enable nginx

For this demo, our IP address is 54.82.241.38 and our domain name is prodxcloud.io hosted in godaddy.com

Next, Check the installation

- sudo nginx -t 
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
- sudo systemctl status nginx

- The default.conf file for Nginx is typically located in the /etc/nginx/sites-available/ directory on Ubuntu. Here's how you can check and edit this file:
cd /etc/nginx/sites-available/
sudo vim default

- The main nginx.conf file is typically located in the /etc/nginx/ directory on Ubuntu. Here’s how you can find and edit it:
cd /etc/nginx/
ls -l
sudo vim nginx.conf
or
vim /etc/nginx/nginx.conf

- On Ubuntu, the default web root directory for Nginx is typically located at /var/www/html. This is where you place your website files, such as HTML, CSS, JavaScript, and other assets.

Here's how you can navigate to the www directory and verify its contents:

cd /var/www/html
sudo vim index.html
* Reload after change : sudo systemctl reload nginx

Step 4: Add DNS Record Type A to your domain name pointing to your EC2 or Azure VM instance Public IP

https://ph.godaddy.com/help/add-an-a-record-19238

Check DNS (if you are using Cloudflare enable full strict by ssl/tsl>overview>full_strict)

dig prodxcloud.io
dig www.prodxcloud.io

Test it :

Step 5: Install Certbot on Ubuntu ( Linux )

snap version
## If you don't have it
apt policy snapd and apt install snapd

update : ```sudo snap install core; sudo snap refresh core ```

Optional ( Remove certbot-auto and any Certbot OS packages sudo apt-get remove certbot)

Install Certbot:

sudo snap install - classic certbot

Create a symbolic link for the Certbot command:

sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot - version

Step 6: Configure Nginx for Your Domain Name

cd /etc/nginx/sites-available/
sudo vim /etc/nginx/sites-available/prodxcloud.io

add the following code:

server {
listen 80;

root /var/www/prodxcloud.io/html;
index index.html;

server_name prodxcloud.io www.prodxcloud.io;

location / {
try_files $uri $uri/ =404;
}
}

Next :

Create a folder for our website:

sudo mkdir -p /var/www/prodxcloud.io/html

Updated ownership and permissions :

sudo chown -R $USER:$USER /var/www/prodxcloud.io
sudo chmod -R 755 /var/www/prodxcloud.io

Create/upload the website

Option 1 : echo “<h1>Welcome to prodxcloud.io</h1>” | sudo tee /var/www/prodxcloud.io/index.html

Option 2: vi /var/www/prodxcloud.io/html/index.html

<html>
<head>
<title>prodxcloud.io new website working !!</title>
</head>
<body>
<h1>prodxcloud.io website with SSL certificate</h1>
</body>
</html>

- Enable the new configuration by creating a symlink to the sites-enabled directory:

sudo mkdir /etc/nginx/sites-available/ ( Already done )
sudo mkdir /etc/nginx/sites-enabled ( Already done )
sudo vi /etc/nginx/sites-available/prodxcloud.io
sudo ln -s /etc/nginx/sites-available/prodxcloud.io /etc/nginx/sites-enabled/

Reload and Test your nginx server again:

sudo nginx -t
sudo systemctl reload nginx or systemctl restart nginx

Add include statement

sudo vi /etc/nginx/nginx.conf

add this line at the bottom of HTML section include /etc/nginx/sites-enabled/*;

Step 7: Nginx with Lets Encrypt ( certbot )

sudo certbot --nginx --test-cert ( x1 staging)

Certbot Still in staging , we will have to request 1 more time

Check it using https://prodxcloud.io or https://www.prodxcloud.io

Let’s Encrypt SSL Certificate in EC2 nginx server or Azure VM ubuntu for https://prodxcloud.io by joel wembo
Let’s Encrypt SSL Certificate in EC2 nginx server or Azure VM ubuntu for https://prodxcloud.io
prodxcloud ec2 instance running website secured using Let’s Encrypt SSL Certificate by joelwembo

In the next blog post, we are going to write Wildcard SSL

Step 8: Wildcard SSL

To obtain a Wildcard SSL certificate for your domain *.prodxcloud.io, you can use Certbot with the DNS-01 challenge, which requires you to create a DNS TXT record. Here's how to do it:

  1. Run Certbot with the DNS-01 challenge:

sudo certbot certonly --manual --preferred-challenges dns -d *.prodxcloud.io -d prodxcloud.io

  • Certbot will provide you with a DNS TXT record that you need to add to your DNS provider’s settings.

2. Add the DNS TXT record:

  • Log in to your DNS provider’s management console.
  • Add a new TXT record with the name _acme-challenge.prodxcloud.io and the value provided by Certbot.
  • Wait for the DNS changes to propagate (this may take a few minutes).

3. After adding the DNS record, press Enter in the Certbot terminal to continue.

Certbot will then validate the DNS record and issue the Wildcard SSL certificate.

Navigate to the Nginx sites-available directory and Create or edit the configuration file for your domain:

sudo vim /etc/nginx/sites-available/prodxcloud.io
server {
listen 80;
listen [::]:80;
server_name prodxcloud.io *.prodxcloud.io;

root /var/www/prodxcloud.io;
index index.html;

location / {
try_files $uri $uri/ =404;
}

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/prodxcloud.io/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/prodxcloud.io/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
}

Test and Reload Nginx to apply the changes:

sudo nginx -t
sudo systemctl reload nginx

Verify SSL Certificate Renewal

Verify that Certbot’s automatic renewal is working

sudo certbot renew --dry-run

By following these steps, you can obtain and configure a Wildcard SSL certificate for your domain *.prodxcloud.io and ensure that your subdomains like api.prodxcloud.io and app.prodxcloud.io are covered. If you encounter any issues or need further assistance, feel free to ask!

🚀 A step-by-step guide for AWS EC2 provisioning using Terraform: Let’s Encrypt SSL on Apache2 servers in an Azure Virtual Machine using Ansible Playbook — Part 14

Conclusion

This guide empowers you to secure your Ubuntu web server on either an EC2 instance or an Azure VM using a free Let’s Encrypt SSL certificate. It walks you through provisioning your EC2 instance, installing Nginx and Certbot, obtaining the certificate, and configuring Nginx for HTTPS. While some variations might exist for Azure VMs, following these steps will establish a secure connection for your website.

echo | openssl s_client -servername www.prodxcloud.io -connect www.prodxcloud.io:443 | openssl x509 -noout -dates -subject -issuer
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/www.prodxcloud.io/fullchain.pem
Key is saved at: /etc/letsencrypt/live/www.prodxcloud.io/privkey.pem
This certificate expires on 2024-10-06.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

To enhance readability, this handbook is divided into chapters and split into parts. The first, part, “A step-by-step guide for AWS EC2 provisioning using Terraform: HA, ALB, VPC, and Route53 — Part 1”, and the second part “A step-by-step guide for AWS EC2 provisioning using Terraform: HA, CloudFront, WAF, and SSL Certificate — Part 2”, and “A step-by-step guide for AWS EC2 provisioning using Terraform: Cloud Cost Optimization, AWS EC2 Spot Instances — Part 3”, was covered in a separate article to keep the reading time manageable and ensure focused content. The next part or chapter will be published in the next post, upcoming in a few days, A step-by-step guide for AWS EC2 provisioning using Terraform: Azure and AWS VPN Site-to-site Connection for EC2 (multi-cloud) using Terraform — Part 15“ and so much more !!

Thank you for Reading !! 🙌🏻, don’t forget to subscribe and give it a CLAP 👏, and if you found this article useful contact me or feel free to sponsor me to produce more public content. see me in the next article.🤘

About me

I am Joel Wembo, AWS certified cloud Solutions architect, Back-end developer, and AWS Community Builder, I‘m based in the Philippines 🇵🇭; and currently working at prodxcloud as a DevOps & Cloud Architect. I bring a powerful combination of expertise in cloud architecture, DevOps practices, and a deep understanding of high availability (HA) principles. I leverage my knowledge to create robust, scalable cloud applications using open-source tools for efficient enterprise deployments.

I’m looking to collaborate on AWS CDK, AWS SAM, DevOps CI/CD, Serverless Framework, CloudFormation, Terraform, Kubernetes, TypeScript, GitHub Actions, PostgreSQL, and Django.”

For more information about the author ( Joel O. Wembo ) visit:

Links:

References

--

--

Joel Wembo

I am a Cloud Solutions Architect at prodxcloud. Expert in AWS, AWS CDK, EKS, Serverless Computing and Terraform. https://www.linkedin.com/in/joelotepawembo