Skip to content

Instantly share code, notes, and snippets.

@tony-gutierrez
Last active March 7, 2024 11:29
Show Gist options
  • Save tony-gutierrez/198988c34e020af0192bab543d35a62a to your computer and use it in GitHub Desktop.
Save tony-gutierrez/198988c34e020af0192bab543d35a62a to your computer and use it in GitHub Desktop.
AWS Elastic Beanstalk .ebextensions config for single instance free SSL using letsencrypt certbot and nginx. http://bluefletch.com/blog/domain-agnostic-letsencrypt-ssl-config-for-elastic-beanstalk-single-instances/
# Dont forget to set the env variable "certdomain", and either fill in your email below or use an env variable for that too.
# Also note that this config is using the LetsEncrypt staging server, remove the flag when ready!
Resources:
sslSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
CidrIp: 0.0.0.0/0
files:
# The Nginx config forces https, and is meant as an example only.
/etc/nginx/conf.d/000_http_redirect_custom.conf:
mode: "000644"
owner: root
group: root
content: |
server {
listen 8080;
return 301 https://$host$request_uri;
}
# The Nginx config forces https, and is meant as an example only.
/etc/nginx/conf.d/https_custom.pre:
mode: "000644"
owner: root
group: root
content: |
# HTTPS server
server {
listen 443 default ssl;
server_name localhost;
error_page 497 https://$host$request_uri;
ssl_certificate /etc/letsencrypt/live/ebcert/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ebcert/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_prefer_server_ciphers on;
if ($ssl_protocol = "") {
rewrite ^ https://$host$request_uri? permanent;
}
location ~ ^/(lib/|img/) {
root /var/app/current/public;
access_log off;
}
location / {
proxy_pass http://nodejs;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
packages:
yum:
epel-release: []
container_commands:
10_installcertbot:
command: "wget https://dl.eff.org/certbot-auto;chmod a+x certbot-auto"
20_getcert:
command: "sudo ./certbot-auto certonly --debug --non-interactive --email XXX@XXX.com --agree-tos --standalone --domains ${certdomain} --keep-until-expiring --pre-hook \"service nginx stop\" --staging"
30_link:
command: "ln -sf /etc/letsencrypt/live/${certdomain} /etc/letsencrypt/live/ebcert"
40_config:
command: "mv /etc/nginx/conf.d/https_custom.pre /etc/nginx/conf.d/https_custom.conf"
@hein-j
Copy link

hein-j commented Mar 21, 2021

@vahiwe I can't thank you enough. Worked perfectly.

@garyng2000
Copy link

for those who is interested, i have created a simple template(for python and nodejs). the EB portion is generic and can be used for other framework(.NET etc.)

https://github.com/garyng2000/flaskweb

@olayinkasf
Copy link

Anyone with a working example of using acme.sh?

@TheArhaam
Copy link

If I'm not mistaken, this is all it takes now:

.ebextensions
|_ 00_epel.config
|_ 01_AWS_Single_LetsEncrypt.config

00_epel.config

commands:
  add_epel_repo:
    command: "sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
    test: "[ ! -e /tmp/add_epel_repo_run_once ] && touch /tmp/add_epel_repo_run_once || exit 0"
    ignoreErrors: true

01_AWS_Single_LetsEncrypt.config

Resources:
  sslSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] }
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
      CidrIp: 0.0.0.0/0

packages:
  yum:
    epel-release: []

container_commands:
  01_certbot_install:
    command: "sudo yum install certbot python-certbot-nginx"
  02_certbot_generate_certs:
    command: "sudo certbot --agree-tos --non-interactive --domains ${CERT_DOMAINS} --email ${CERT_EMAIL} --nginx"
  03_certbot_auto_renew:
    command: "sudo certbot renew --dry-run"

@lucas-coelho
Copy link

This will not work, because container_commands runs before Elastic Beanstalk deploys and runs your application and the proxy server. So, the /etc/nginx/nginx.conf will be overridden.
The structure that works for me is shown below:

|-- .platform
|   -- hooks
|       -- postdeploy
|           -- ssl_setup_certbot.sh
|-- .ebextensions
|   -- ssl.config

The content of ssl_setup_certbot.sh:

#!/usr/bin/env bash

echo "Installing CERTBOT.."
CERT_DOMAIN=`/opt/elasticbeanstalk/bin/get-config environment -k CERT_DOMAIN`
CERT_EMAIL=`/opt/elasticbeanstalk/bin/get-config environment -k CERT_EMAIL`
sudo yum -y install certbot python-certbot-nginx
sudo certbot --agree-tos --non-interactive --domains ${CERT_DOMAIN} --email ${CERT_EMAIL} --nginx
sudo certbot renew --dry-run
echo "CERTBOT installed!"

The content of ssl.config:

Resources:
  sslSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] }
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
      CidrIp: 0.0.0.0/0

packages:
  yum:
    epel-release: []

files:
  "/etc/cron.d/certbot_renew":
    mode: "000644"
    owner: root
    group: root
    content: |
      0 */12 * * * root /usr/bin/certbot -q renew --nginx
 
commands:
  add_epel_repo:
    command: "sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
    test: "[ ! -e /tmp/add_epel_repo_run_once ] && touch /tmp/add_epel_repo_run_once || exit 0"
    ignoreErrors: true
    
   

CERT_DOMAIN and CERT_EMAIL is environment variable included in the eb environment.

@TheArhaam
Copy link

Thanks @lucas-coelho, I'll test that out
I pretty much got exhausted and switched to CodeDeploy 😅

@anhnq-hblab
Copy link

Hi @lucas-coelho.
I'm trying this your config in code but not run https.
can you tell me what config am i missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment