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

Joel Wembo
10 min readJul 9, 2024

--

In this comprehensive guide, we walk you through the process of securing your Apache2 web server hosted on an Azure Virtual Machine using Let’s Encrypt SSL certificates using ansible, terraform and manual process. From setting up your server to installing Certbot with Snap, this step-by-step tutorial ensures your website benefits from enhanced security and automated certificate renewal. Perfect for developers and system administrators looking to safeguard their websites with minimal hassle.

Preface

As the internet continues to evolve, ensuring the security and integrity of web communications has become paramount. SSL certificates play a critical role in protecting data transmission, providing a secure channel between users and servers. Let’s Encrypt, a free, automated, and open Certificate Authority, simplifies the process of obtaining and managing SSL certificates. This guide is designed for those using Apache2 on Azure Virtual Machines, offering clear instructions on how to implement Let’s Encrypt SSL certificates. Whether you’re new to server management or looking to streamline your security practices, this tutorial will help you achieve a secure web environment efficiently.

Step-by-Step Guide to Installing Let’s Encrypt SSL on Apache2 in Azure VM

Preface
Step-by-Step Guide to Installing Let’s Encrypt SSL on Apache2 in Azure VM
Introduction
Step 1 : Connect to VM
Step 2 : Install Apache2
Step 3 : create your website in apache2
Step 4 : Create a Virtual Host Configuration File
Step 5: Enable the New Virtual Host Configuration
Step 6 : Install Certbot in Lunix machine
Step 7: Obtain the SSL Certificate
Step 8 : Verify the Certificate Installation
Automating the process of setting up Let’s Encrypt SSL certificates on Apache2 in an Azure VM using Ansible and Terraform
Conclusion
· About me

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. Instance Provisioning: We used Terraform

2. Apache2 and Certbot Installation:

  • Connect to VM: Use your private key to establish an SSH connection to your Azure VM.
  • Update Packages: Update the package lists and installed software on your Ubuntu instance.
  • Install Apache2: Install the Apache 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.

Step 1 : Connect to VM

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

Here is the partial terraform code :

resource "azurerm_linux_virtual_machine" "prodxcloud-azure-lab-7" {
name = "prodxcloud-lab-7"
resource_group_name = var.resourcegroup
location = var.location
size = var.size
admin_username = var.admin_username
admin_password = var.admin_password
disable_password_authentication = false
network_interface_ids = [
azurerm_network_interface.prodxcloud-nic.id,
]

admin_ssh_key {
username = var.admin_username
public_key = file("${path.module}/id_rsa.pub")
}

source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-focal"
sku = "20_04-lts"
version = "latest"
}

os_disk {
storage_account_type = "Standard_LRS"
caching = "ReadWrite"
}

depends_on = [ azurerm_resource_group.resource_group ]

tags = {
environment = "prodxcloud VM ubuntu Lab 7"
}

}

resource "azurerm_network_security_group" "prodxcloud-sg-1" {
name = "prodxcloud-sg-1"
location = azurerm_resource_group.resource_group.location
resource_group_name = azurerm_resource_group.resource_group.name

security_rule {
name = "allow_all"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}

security_rule {
name = "allow_https"
priority = 1003
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}

IP : 20.28.57.57 ( Apache2 ) Domain name : prodxcloud.io

Point your domain name to your IP address using domain name registrar

## Check DNS
dig a prodxcloud.io
## check net-tools
apt install net-tools
ifconfig | grep 20.28.57.57

Step 2 : Install Apache2

sudo apt install apache2 -y
sudo systemctl enable apache2
sudo systemctl start apache2
sudo systemctl status apache2

Check it in your browser

Step 3 : create your website in apache2

clone or ftp your website folder to the server (any path)

mkdir -p /var/www/prodxcloud.io/html
cp * -R /var/www/prodxcloud.io/html

Step 4 : Create a Virtual Host Configuration File

  1. Create a new virtual host configuration file for your domain:
- sudo vim /etc/apache2/sites-available/prodxcloud.io.conf

2. Add the following configuration to the file, adjusting as necessary for your setup:

<VirtualHost *:80>
ServerAdmin webmaster@prodxcloud.io
ServerName prodxcloud.io
ServerAlias www.prodxcloud.io
DocumentRoot /var/www/prodxcloud.io/html
<Directory /var/www/prodxcloud.io/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/prodxcloud.io_error.log
CustomLog ${APACHE_LOG_DIR}/prodxcloud.io_access.log combined
</VirtualHost>

Save it → !wq!

Step 5: Enable the New Virtual Host Configuration

- Disable the default virtual host:

sudo a2dissite 000-default.conf

- Enable your new virtual host:

sudo a2ensite prodxcloud.io.conf

- Reload Apache to apply the changes:

sudo systemctl reload apache2
the website still not yet secure

Step 6 : Install Certbot in Lunix machine

sudo apt install snapd ( Not required)
sudo systemctl enable - now snapd ( not required if already installed)
sudo snap install core
sudo snap refresh core
sudo snap install - classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Step 7: Obtain the SSL Certificate

Run Certbot to obtain and install the SSL certificate for Apache:

sudo certbot - apache

Follow the interactive prompts to configure the SSL certificate for your domain:

Enter your email address.

Agree to the terms of service.

Choose whether to share your email address with the Electronic Frontier Foundation (EFF).

Select the domain(s) for which you want to enable HTTPS.

Step 8 : Verify the Certificate Installation

Check that the SSL certificate is correctly installed and configured:

sudo apache2ctl configtest

Automating the process of setting up Let’s Encrypt SSL certificates on Apache2 in an Azure VM

Automating the process of setting up Let’s Encrypt SSL certificates on Apache2 in an Azure VM using Ansible involves creating a playbook that includes tasks for installing Apache2, configuring your virtual host, installing Certbot via Snap, and obtaining and configuring the SSL certificate.

Here is a step-by-step guide with an example Ansible playbook:

Install Ansible

Create an inventory file (hosts.ini) to define your Azure VM:

[webservers]
your_vm_ip_address ansible_user=username ansible_ssh_private_key_file=~/.ssh/id_rsa

Create the Ansible Playbook

Create an Ansible playbook (setup_ssl.yml):

---
- name: Set up Apache2 and Let's Encrypt SSL on Azure VM
hosts: webservers
become: yes

tasks:
- name: Update APT package list
apt:
update_cache: yes

- name: Install Apache2
apt:
name: apache2
state: present

- name: Create website directory
file:
path: /var/www/prodxcloud.io/html
state: directory
owner: www-data
group: www-data
mode: '0755'

- name: Copy website files
copy:
src: /path/to/local/website/files/
dest: /var/www/prodxcloud.io/html/
owner: www-data
group: www-data
mode: '0755'

- name: Create virtual host configuration
copy:
dest: /etc/apache2/sites-available/prodxcloud.io.conf
content: |
<VirtualHost *:80>
ServerAdmin webmaster@prodxcloud.io
ServerName prodxcloud.io
ServerAlias www.prodxcloud.io
DocumentRoot /var/www/prodxcloud.io/html

<Directory /var/www/prodxcloud.io/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

ErrorLog ${APACHE_LOG_DIR}/prodxcloud.io_error.log
CustomLog ${APACHE_LOG_DIR}/prodxcloud.io_access.log combined
</VirtualHost>

- name: Disable default virtual host
command: a2dissite 000-default.conf

- name: Enable new virtual host
command: a2ensite prodxcloud.io.conf

- name: Reload Apache
service:
name: apache2
state: reloaded

- name: Install Snapd
apt:
name: snapd
state: present

- name: Ensure Snapd is started
systemd:
name: snapd
enabled: yes
state: started

- name: Install Certbot
snap:
name: certbot
classic: yes

- name: Create symbolic link for Certbot
file:
src: /snap/bin/certbot
dest: /usr/bin/certbot
state: link

- name: Obtain SSL certificate
command: certbot --apache --non-interactive --agree-tos --email your_email@domain.com -d prodxcloud.io -d www.prodxcloud.io
register: certbot_output
ignore_errors: yes

- name: Verify SSL certificate installation
command: apache2ctl configtest
register: apache2ctl_output
failed_when: "'Syntax OK' not in apache2ctl_output.stdout"

- name: Restart Apache
service:
name: apache2
state: restarted

- name: Set up automatic renewal for Certbot
cron:
name: "Certbot Renew Cron Job"
special_time: daily
job: "certbot renew --quiet --no-self-upgrade"

Run the Ansible playbook to automate the setup process:

ansible-playbook -i hosts.ini setup_ssl.yml

Upcoming next :

🚀 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 Apache2 and Certbot, obtaining the certificate, and configuring Apache2 for HTTPS. While some variations might exist for Azure VMs, following these steps will establish a secure connection for your website.

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:

--

--

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