Last active
August 17, 2021 15:21
-
-
Save srkiNZ84/9c2cc9a363ca759e09733cc4d739109b to your computer and use it in GitHub Desktop.
Bash script to automate the renewal of LetsEncrypt certificates using DNS authentication with Route53 and then updating the load balancers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/bash | |
# pre-requisites: | |
# apt install python3-pip awscli | |
# pip3 install certbot certbot-dns-route53 awscli | |
# mkdir .certbot/{config,work,logs} | |
# IAM policy attached to EC2 instance with: | |
# - route53:ListHostedZones | |
# - route53:GetChange | |
# - route53:ChangeResourceRecordSets | |
# - acm:ListCertificates | |
# - acm:ImportCertificate | |
# - acm:AddTagsToCertificate | |
# - elasticloadbalancing:SetLoadBalancerListenerSSLCertificate | |
# USAGE ./update_certificates.sh -d DOMAINTOGETCERTFOR -l LOADBALANCERTOUPDATE | |
# e.g. ./update_certificates.sh -d *.example.com -l production-public-lb | |
while getopts d:l: option | |
do | |
case "${option}" | |
in | |
d) DOMAIN=${OPTARG};; | |
l) LOADBALANCER=${OPTARG};; | |
esac | |
done | |
if [ -z "$DOMAIN" ] || [ -z "$LOADBALANCER" ]; | |
then | |
echo "Error: Domain or LoadBalancer variable not set. Exiting" | |
echo "USAGE ./update_certificates.sh -d DOMAINTOGETCERTFOR -l LOADBALANCERTOUPDATE" | |
echo " e.g. ./update_certificates.sh -d *.example.com -l production-public-lb" | |
exit 1 | |
fi | |
echo "$(date) Getting certificate for domain - $DOMAIN, and updating load balancer - $LOADBALANCER" | |
SHORTDOMAIN=$DOMAIN | |
if [[ "$DOMAIN" == *"*"* ]] | |
then | |
echo "Wildcard domain supplied - $DOMAIN" | |
SHORTDOMAIN=$(echo $DOMAIN | cut -d'.' -f2-) | |
echo "Without wildcard is $SHORTDOMAIN" | |
fi | |
# Get the certificates | |
.local/bin/certbot certonly \ | |
--config-dir .certbot/config \ | |
--work-dir .certbot/work \ | |
--logs-dir .certbot/logs \ | |
-n --agree-tos \ | |
--email [email protected] \ | |
--dns-route53 -d $DOMAIN \ | |
MD5SUM_CERT=$(md5sum .certbot/config/live/$SHORTDOMAIN/cert.pem | cut -d' ' -f1) | |
MD5SUM_KEY=$(md5sum .certbot/config/live/$SHORTDOMAIN/privkey.pem | cut -d' ' -f1) | |
TIMENOW=$(date +%s) | |
echo "Checking if certificate is already in AWS Certificate Manager..." | |
for acmCertificate in $(/home/ubuntu/.local/bin/aws acm list-certificates | jq -r .CertificateSummaryList[].CertificateArn) | |
do | |
echo "Checking certificate with ARN: $acmCertificate" | |
ACM_CERT_MD5SUM=$(/home/ubuntu/.local/bin/aws acm list-tags-for-certificate --certificate-arn $acmCertificate | jq -r '.Tags[] | select(.Key | contains("Md5SumCert")) | .Value') | |
if [[ "$MD5SUM_CERT" == "$ACM_CERT_MD5SUM" ]] | |
then | |
echo "$(date) Found certificate with matching hash! No need to import." | |
CERTIFICATE_ARN=$acmCertificate | |
break | |
fi | |
done | |
if [ -z "$CERTIFICATE_ARN" ] | |
then | |
echo "No matches found. Importing certificate to AWS Certificate Manager..." | |
CERTIFICATE_ARN=$(/home/ubuntu/.local/bin/aws acm import-certificate \ | |
--certificate file://.certbot/config/live/$SHORTDOMAIN/cert.pem \ | |
--private-key file://.certbot/config/live/$SHORTDOMAIN/privkey.pem \ | |
--certificate-chain file://.certbot/config/live/$SHORTDOMAIN/chain.pem \ | |
--tags Key=Name,Value=tj_co_wld_$TIMENOW Key=Md5SumCert,Value=$MD5SUM_CERT Key=Md5SumKey,Value=$MD5SUM_KEY \ | |
| jq -r .CertificateArn) | |
fi | |
ELB_NAME=$LOADBALANCER | |
echo "$(date) Updating SSL certificate of $ELB_NAME load balancter to be $CERTIFICATE_ARN" | |
# Switch LoadBalancers to use the new certificate | |
/home/ubuntu/.local/bin/aws elb set-load-balancer-listener-ssl-certificate \ | |
--load-balancer-name $ELB_NAME \ | |
--load-balancer-port 443 \ | |
--ssl-certificate-id $CERTIFICATE_ARN |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment