Skip to content

Instantly share code, notes, and snippets.

@slenky
Created March 28, 2018 10:21
Show Gist options
  • Save slenky/24373f4deec4bf8744421fb7e4f897c6 to your computer and use it in GitHub Desktop.
Save slenky/24373f4deec4bf8744421fb7e4f897c6 to your computer and use it in GitHub Desktop.
AWS Elastic Beanstalk -- Let's Encrypt for load-balanced environments
files:
"/home/ec2-user/set_env.sh":
mode: "000755"
owner: root
group: root
content: |
instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
region=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk -F\" '{print $4}')
ebenvname=$(aws --output text ec2 describe-tags --region $region --filters "Name=resource-id,Values=${instance_id}" "Name=key,Values=elasticbeanstalk:environment-name" | awk '{print $5}')
elbname=$(aws elasticbeanstalk describe-environment-resources --region $region --environment-name $ebenvname | jq -r '.EnvironmentResources.LoadBalancers[0].Name')
sgname=$(aws elb describe-load-balancers --region $region --load-balancer-name $elbname | jq -r '.LoadBalancerDescriptions[0].SourceSecurityGroup.GroupName')
echo "export LB_NAME=$elbname" > /etc/environment
echo "export AWS_DEFAULT_REGION=$region" >> /etc/environment
echo "export SG_NAME=$sgname" >> /etc/environment
"/home/ec2-user/execute_letsencrypt.sh":
mode: "000755"
owner: root
group: root
content: |
. /etc/environment
FIND_VALID_CERT=$(aws acm list-certificates --certificate-statuses ISSUED | grep "$CERTDOMAIN" -B 1)
if [[ ! -z $FIND_VALID_CERT ]]; then
NEW_CERT_ARN=$(echo "$FIND_VALID_CERT" | grep CertificateArn | awk '{print $2}' | tr -d ,\")
else
CERT_FILE="/etc/letsencrypt/live/$CERTDOMAIN/fullchain.pem"
while( ! curl -s $CERTDOMAIN > /dev/null ); do sleep 5; done
./certbot-auto certonly --debug --non-interactive --email [email protected] --agree-tos --webroot --webroot-path /usr/share/nginx/html --domains ${CERTDOMAIN} --keep-until-expiring
CERT_RES=$(aws acm import-certificate \
--certificate file:///etc/letsencrypt/live/$CERTDOMAIN/cert.pem \
--private-key file:///etc/letsencrypt/live/$CERTDOMAIN/privkey.pem \
--certificate-chain file:///etc/letsencrypt/live/$CERTDOMAIN/chain.pem \
--output json
)
echo $CERT_RES
NEW_CERT_ARN=$(echo $CERT_RES | python -c 'import json,sys;obj=json.load(sys.stdin);print(obj["CertificateArn"])')
fi
aws ec2 authorize-security-group-ingress --group-name $SG_NAME --protocol tcp --port 443 --cidr 0.0.0.0/0
aws elb create-load-balancer-listeners --load-balancer-name "$LB_NAME" \
--listeners "Protocol=HTTPS,LoadBalancerPort=443,InstanceProtocol=HTTP,InstancePort=80,SSLCertificateId=${NEW_CERT_ARN}" || \
aws elb set-load-balancer-listener-ssl-certificate \
--load-balancer-name $LB_NAME \
--load-balancer-port 443 \
--ssl-certificate-id $NEW_CERT_ARN
exit 0
"/home/ec2-user/disable_health.sh":
mode: "000755"
owner: root
group: root
content: |
. /etc/environment
aws elb configure-health-check \
--load-balancer-name $LB_NAME \
--health-check Target=HTTP:80/,Interval=10,UnhealthyThreshold=5,HealthyThreshold=3,Timeout=5 && \
sleep 15
"/home/ec2-user/enable_health.sh":
mode: "000755"
owner: root
group: root
content: |
. /etc/environment
aws elb configure-health-check \
--load-balancer-name $LB_NAME \
--health-check Target=HTTP:80/health,Interval=10,UnhealthyThreshold=5,HealthyThreshold=3,Timeout=5
container_commands:
10installcertbot:
command: "sudo wget https://dl.eff.org/certbot-auto;chmod a+x certbot-auto"
20fixyum:
command: "yum install -y jq"
21getloadbalance:
command: "/bin/bash /home/ec2-user/set_env.sh"
22runnginx:
command: "service nginx start"
23disablehealth:
command: "/bin/bash /home/ec2-user/disable_health.sh"
30getcertwebrootmode:
command: "/bin/bash /home/ec2-user/execute_letsencrypt.sh"
40link:
command: "sudo ln -sf /etc/letsencrypt/live/${CERTDOMAIN} /etc/letsencrypt/live/ebcert"
test: "[[ -f /etc/letsencrypt/live/${CERTDOMAIN} ]]"
50enablehealth:
command: "/bin/bash /home/ec2-user/enable_health.sh"
1. Set the CERTDOMAIN env variable for your environment
2. Check the /home/ec2-user/enable_health.sh file - I'm switching to /health cause it used with Spring app.
3. Upload everything to .ebextensions folder inside your project.
Keep in mind that AWS Certificate Manager has limited to 100 certificates at all and 200 certificate uploads per year.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment