Install LE and route53 plugin

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx python3-certbot-dns-route53

Create AWS Role and policy for automating DNS TXT entries
Create a config file to authenticate certbot against AWS Route53 for modifying DNS TXT records against *.domain.tld .

/root/.aws/credentials

[letsencrypt]
aws_access_key_id={AWS_Access_ID}
aws_secret_access_key={AWS_Secret_Key}

Restrict non-root users and groups from accessing the file.

sudo chmod 640 /root/.aws/credentials

Create an AWS IAM account : aws.route53.letsencrypt

Create AWS policy assigned to aws.route53.letsencrypt

{
    "Version": "2012-10-17",
      
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:ListHostedZones",
                "route53:GetChange"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect" : "Allow",
            "Action" : [
                "route53:ChangeResourceRecordSets"
            ],
            "Resource" : [
                "arn:aws:route53:::hostedzone/{ZONE_ID}"
            ]
        }
    ]
}

Request new wildcard TLS cert for subdomans
Request a new wildcard certificate using certbot. We do not want certbot to automatically 'install' the certificate as we will create a custom NGINX config anyway.

sudo certbot certonly --dns-route53 -n -d *.domain.tld --server https://acme-v02.api.letsencrypt.org/directory

Create cron job for Lets Encrypt
Schedule a cron job for Lets Encrypt to auto-renew the subdomain wildcard TLS certificate using certbot-auto. Pick a random hour and minute.

0 */12 * * * root certbot -q renew --renew-hook 'service nginx reload' >> /var/log/letsencrypt/renew.log

Configure reverse proxy and enforce HTTPS
Configure NGINX as a reverse proxy to listen on port 443 only; redirect insecure HTTP to HTTPS