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"
@HausCloud
Copy link

@panagath Were you able to figure it out?

@sinmarcus3
Copy link

Hey @HausCloud, I used your solution in your Gist and it deployed successfully with no errors. But https doesn't seem to work. The http version works fine though. Is there a step after deployment that I'm missing?

@mstarcevic
Copy link

mstarcevic commented Sep 17, 2020

@sinmarcus3 I got it working just last week. Let me go back over my notes later today and I'll let you know what exactly I did.

@mstarcevic
Copy link

mstarcevic commented Sep 17, 2020

@sinmarcus3 Details as promised:

  1. Make sure that you are running on Amazon Linux 2.
  2. Make sure you do the eb labs download.
  3. Put the .platform folder at the same level as the .elasticbeanstalk folder.
  4. In .platform/hooks/postdeploy/00_ssl_setup_certbost.sh script, set the following variables manually:
    CERTBOT_NAME
    CERTBOT_EMAIL
    CERTBOT_DOMAINS
    ***Note the original version of the script had these coming through as environment variables but the in the revised script, you set them manually.
  5. In the .ebextensions folder, have the two config files as follows (you can call them what you want):

single_instance.config
option_settings:
- namespace: aws:elasticbeanstalk:environment
option_name: EnvironmentType
value: SingleInstance

https.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

  1. Make sure that you deploy the .platform and .ebextensions folders, both at the top level of your zip.
  2. Run eb deploy

@sinmarcus3
Copy link

Thanks @mstarcevic. It seemed to deploy fine with no errors or issues. The logs even suggest the certificate was successfully enabled:
Congratulations! You have successfully enabled...
The http site works fine but the https still doesn't respond and refuses to connect with the following error: ERR_CONNECTION_REFUSED

@mstarcevic
Copy link

mstarcevic commented Sep 17, 2020

@sinmarcus3 I can't remember anything else that I may have had to do, either in eb or on the AWS console side of things. My domain names are registered through Route 53 and I know I did a bit of stuffing around with Alias records and such. But I'm pretty sure that I also got it going with the environment URL directly. How are you checking? Postman?

Did you include the eb environment URL in the domain names CERTBOT variable? And what format did you use, assuming you did...

@mstarcevic
Copy link

mstarcevic commented Sep 17, 2020

I think that I included IP addresses somewhere along the line but no longer. However, you did remind me of one other thing... In the corresponding EC2 instance in the incoming rules, I have a provision for port 443. I think that I had to put that in... in any case, it's there...
ie port 443, TCP, 0.0.0.0/0 (for the security group tied in with the eb). That's to go with ports 80 and 22...

@HausCloud
Copy link

@sinmarcus3 Can you curl localhost:80 and localhost:443? Check your config. You may have a load balancer attached.

@sinmarcus3
Copy link

@HausCloud It failed with connection refused on port 443. Have checked the config and there's no load balancer is attached.

@jhaist
Copy link

jhaist commented Sep 18, 2020

@sinmarcus3 I am having the exact same issue as you. I can see that the SSL certificate was successfully enabled, but I am also getting connection refused on port 443.

@sinmarcus3
Copy link

@HausCloud I just stepped through it with a fresh sample app. The problem occurs when I input multiple domains in 00_ssl_setup_certbot.sh, i.e., CERTBOT_DOMAINS = "somedomain.ap-southeast-2.elasticbeanstalk.com,somedomain.co.nz,www.somedomain.co.nz". The code says the certificate is successfully installed and the http site will work, but the https version of the site will return a connection refused error.

@mstarcevic
Copy link

@sinmarcus3 I'm inputting 2 domains and it still works.

@HausCloud
Copy link

@sinmarcus3 Want to set up a zoom call? Let's see if we can debug it.

@jhaist
Copy link

jhaist commented Sep 18, 2020

When I SSH into my EC2 console and run telnet <my_ip_address> 443, I am receiving connection refused. Any ideas?

@sinmarcus3
Copy link

sinmarcus3 commented Sep 18, 2020

@HausCloud I managed to get it to work by rebuilding the environment. I didn't make any other changes.

@EffyCoder
Copy link

@sinmarcus3 Want to set up a zoom call? Let's see if we can debug it.

HausCloud I tried setting up https using your code. But I found that nothing sort of happens even the logging things. I have set up domain for single instance in the said variable still it didn't work. I even tried it with fresh environment setup. But no luck.

@gavleavitt
Copy link

@sinmarcus3, @HausCloud and @jhaist I am having a similar issue, when I deploy my application HTTPS doesn't work while HTTP does. However, if I rebuild the environment then HTTPS and HTTPS redirect start working until I deploy again, which requires another rebuild.

@optimistiks
Copy link

optimistiks commented Oct 4, 2020

same issue as @gavleavitt, when I use the solution from @HausCloud https stops working after CodePipeline deploy phase, rebuilding environment helps. Tried some things like removing the hook script after first run, but no luck. (I have single domain)

@HausCloud
Copy link

HausCloud commented Oct 5, 2020

@EffyCoder @gavleavitt Can you post your EB setup so I can try to reproduce the issue?
@optimistiks Double check your config is a actually a single instance. See if the permissions_fix helps. Check your connected EC2 instance if the security settings are listening on 443. Otherwise, try a few curls in and out of the instance to debug.

@gskoljarev
Copy link

@HausCloud @optimistiks @gavleavitt @sinmarcus3. Had a similar issue, but I sorted it out - found that postdeploy script was filling /etc/nginx/nginx.conf with duplicate server_names_hash_bucket_size 192; entries, creating an invalid nginx configuration. Had to ssh into the instance (as root), run the postdeploy script manually and check the conf with nginx -t.

@gskoljarev
Copy link

gskoljarev commented Oct 8, 2020

I've modified the postdeploy script as following (also commented out the 'Prevent certificate installation if not clean sample app' part).

...
HTTP_STRING='^http\s*{$'
NAME_LIMIT='http {\nserver_names_hash_bucket_size 192;\n'
SERVER_NAMES_HASH='nserver_names_hash_bucket_size 192;'

# Prevent replace if not clean sample app

if ! grep -Fxq "SERVER_NAMES_HASH" /etc/nginx/nginx.conf; then
    # Increase size of string name for --domains (for default EB configs)
    
    if ! sed -i "s/$HTTP_STRING/$NAME_LIMIT/g" /etc/nginx/nginx.conf; then
        log_and_exit 'ERROR: Changing server name limit failed'
    fi
fi

# # Prevent certificate installation if not clean sample app

# CERT_REGEX="Certificate Name:\s+$CERTBOT_NAME"

# if certbot certificates | grep -Ew "$CERT_REGEX"; then
#     log_and_exit 'INFO: Certificate already installed.'
# fi

# Set up certificates
...

@morsanu
Copy link

morsanu commented Oct 16, 2020

I almost cried when I saw the lock icon as I spent 2 days running Linux commands. Just wanted to thank you for all the solutions in this thread.

@EffyCoder
Copy link

I followed the steps as described above and concerning the advice of @tbezemer.
The certificate is downloaded and installed, all steps from container_commands have been executed successfully, but the nginx does not use my custom configuration - in fact, the nginx configuration seems to be resetted to a standard configuration.
I checked this by connecting via SSH to the beanstalk-server. During deployment of my application I can see there for a short time my custom config file https_custom.conf in the folder /etc/nginx/conf.d, but a short time later it is gone...

Finally I discovered the solution for my problem - I had to modify the line 40_config as follows (50_restartnginx also seems not to be necessary, I could remove it without problem):

40_config:
    command: "mv /etc/nginx/conf.d/https_custom.pre /var/elasticbeanstalk/staging/nginx/conf.d/https_custom.conf"

Your comment saved me. I was struggling for month. Trying out various configurations. But had no luck.

@vahiwe
Copy link

vahiwe commented Nov 14, 2020

I tried using the container_commands to setup the nginx configuration files but i couldn't find the files after successful deployment. After carrying out some research, I was pointed to this AWS documentation on how to override nginx configuration files. My folder structure is shown below.

~/workspace/my-app/
|-- .platform
|   -- nginx
|       -- nginx.conf
|       -- conf.d
|           -- https_custom.conf
|-- .ebextensions
|   -- ssl.config

I also had issues with installing the epel using the yum package manager on Amazon Linux 2. So i tweaked the setup to use rpm to install epel.

Here is the content of my ssl.config:

# Dont forget to set the env variable "DOMAIN_LINK" and either fill in your email below or set the env variable "EMAIL_LINK" for that too.

--- 
Resources: 
  sslSecurityGroupIngress: 
    Properties: 
      CidrIp: 0.0.0.0/0
      FromPort: 443
      GroupId: 
        ? "Fn::GetAtt"
        : 
          - AWSEBSecurityGroup
          - GroupId
      IpProtocol: tcp
      ToPort: 443
    Type: "AWS::EC2::SecurityGroupIngress"

files: 
  /etc/cron.d/certbot_renew: 
    content: "@weekly root certbot renew\n"
    group: root
    mode: "000644"
    owner: root
    
container_commands:
  10_downloadepel: 
    command: "sudo wget -r --no-parent -A 'epel-release-*.rpm' https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/"
  20_installepel: 
    command: "sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm --force"
  30_enableepl: 
    command: "sudo yum-config-manager --enable epel*"
  40_installcertbot: 
    command: "sudo yum install -y certbot"
  50_getcert: 
    command: "sudo certbot certonly --debug --non-interactive --email ${EMAIL_LINK} --agree-tos --standalone --domains ${DOMAIN_LINK} --keep-until-expiring --pre-hook \"sudo service nginx stop\" --post-hook \"sudo service nginx start\""
  60_link: 
    command: "ln -sf /etc/letsencrypt/live/${DOMAIN_LINK} /etc/letsencrypt/live/ebcert"

Below is the content of nginx.conf:

#Elastic Beanstalk Nginx Configuration File

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    32137;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';

    include       conf.d/*.conf;

    map $http_upgrade $connection_upgrade {
        default     "upgrade";
    }

    server {
        listen        80 default_server;
        access_log    /var/log/nginx/access.log main;

        client_header_timeout 60;
        client_body_timeout   60;
        keepalive_timeout     60;
        gzip                  off;
        gzip_comp_level       4;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        # Include the Elastic Beanstalk generated locations
        include conf.d/elasticbeanstalk/*.conf;
    }
}

Below is the content of https_custom.conf:

upstream nodejs {
    server 127.0.0.1:3030;
    keepalive 256;
}
# HTTPS server
server {
    listen       443 default ssl;
    server_name  localhost;
    error_page 497 https://$host$request_uri;

    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
    set $year $1;
    set $month $2;
    set $day $3;
    set $hour $4;
    }

    access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
    
    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";
    }
}

Hopefully this helps.

@aivoric
Copy link

aivoric commented Nov 26, 2020

I am getting the following error:
"Your system is not supported by certbot-auto anymore.
Certbot cannot be installed.
"

It looks like certbot-auto was deprecated:
certbot/certbot@cac9d8f

Here is a discussion:
https://community.letsencrypt.org/t/your-system-is-not-supported-by-certbot-auto-anymore/135504/21

Any other ideas about how to get it to work?

Thank you.

@HausCloud
Copy link

I almost cried when I saw the lock icon as I spent 2 days running Linux commands. Just wanted to thank you for all the solutions in this thread.

@morsanu Happy to help.

@putuyoga
Copy link

putuyoga commented Dec 3, 2020

I am getting the following error:
"Your system is not supported by certbot-auto anymore.
Certbot cannot be installed.
"

It looks like certbot-auto was deprecated:
certbot/certbot@cac9d8f

Here is a discussion:
https://community.letsencrypt.org/t/your-system-is-not-supported-by-certbot-auto-anymore/135504/21

Any other ideas about how to get it to work?

Thank you.

You can install the original certbot, instead of certbot-auto

      wget -O epel.rpm –nv https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
      sudo yum install -y ./epel.rpm
      sudo yum install -y python2-certbot-apache.noarch

then replace ./certbot-auto command with certbot

@andylolu2
Copy link

Thank you so much @vahiwe, it worked flawlessly.

@vahiwe
Copy link

vahiwe commented Jan 9, 2021

Thank you so much @vahiwe, it worked flawlessly.

@andylolu2 you're welcome. You can reference an article I wrote on it here.

@zedy
Copy link

zedy commented Jan 13, 2021

@vahiwe I took the OP's post and combined it with your solution from (above) changed a few params to work with Apache and got this:

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:
    /etc/httpd/conf.d/ssl.pre:
        mode: "000644"
        owner: root
        group: root
        content: |
            LoadModule ssl_module modules/mod_ssl.so
            Listen 443

            <VirtualHost *:443>
                <Directory /opt/python/current/app/build/static>
                    Order deny,allow
                    Allow from all
                </Directory>
                
                SSLEngine on
                SSLCertificateFile "/etc/letsencrypt/live/${MY_DOMAIN}/fullchain.pem"
                SSLCertificateKeyFile "/etc/letsencrypt/live/${MY_DOMAIN}/privkey.pem"
                SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
                SSLProtocol All -SSLv2 -SSLv3
                SSLHonorCipherOrder On
                SSLSessionTickets Off
                
                Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
                Header always set X-Frame-Options DENY
                Header always set X-Content-Type-Options nosniff
                
                ProxyPass / http://localhost:80/ retry=0
                ProxyPassReverse / http://localhost:80/
                ProxyPreserveHost on
                RequestHeader set X-Forwarded-Proto "https" early
                # If you have pages that may take awhile to
                # respond, add a ProxyTimeout:
                # ProxyTimeout seconds
            </VirtualHost>
  
    /tmp/renew_cert_cron:
        mode: "000777"
        owner: root
        group: root
        content: |
            # renew Lets encrypt cert with certbot command
            0 1,13 * * * /tmp/certbot-auto renew

packages:
    yum:
        epel-release: []
        mod_ssl : []

container_commands:
    10_downloadepel:
        command: "sudo wget -r --no-parent -A 'epel-release-*.rpm' https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/"
    20_installepel:
        command: "sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm --force"
    30_enableepl:
        command: "sudo yum-config-manager --enable epel*"
    40_installcertbot:
        command: "sudo yum install -y certbot"
    50_getcert:
        command: "sudo certbot certonly --debug --non-interactive --email test@test.com --agree-tos --standalone --domains ${MY_DOMAIN} --keep-until-expiring --pre-hook \"sudo service httpd stop\" --post-hook \"sudo service httpd start\""
    60_link:
        command: "ln -sf /etc/letsencrypt/live/${MY_DOMAIN} /etc/letsencrypt/live/ebcert"

And it executes (all commends run) but https is still not working (http works fine, but https immediately returns 'Unable to connect') Any ideas? I've been stuck for 2 days now.

@vahiwe
Copy link

vahiwe commented Jan 13, 2021

@zedy I haven’t used Apache in any of my projects so might not really know what works and what doesn’t. But we can try connecting and solving it together.

@zedy
Copy link

zedy commented Jan 14, 2021

@vahiwe Thanks for the response. I figured it out. The ssl.pre from the files section of the code block doesn't get executed and is never created, so i created it manually. Working perfectly. Thanks again.

Created ssl.conf in /etc/httpd/conf.d/ (mod => 644, owner:group => root:root)

<VirtualHost *:443>
	<Directory /opt/python/current/app/build/static>
		Order deny,allow
		Allow from all
	</Directory>
	
	SSLEngine on
	SSLCertificateFile "/etc/letsencrypt/live/${MY_DOMAIN}/fullchain.pem"
	SSLCertificateKeyFile "/etc/letsencrypt/live/${MY_DOMAIN}/privkey.pem"
	SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
	SSLProtocol All -SSLv2 -SSLv3
	SSLHonorCipherOrder On
	SSLSessionTickets Off
	
	Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
	Header always set X-Frame-Options DENY
	Header always set X-Content-Type-Options nosniff
	
	ProxyPass / http://localhost:80/ retry=0
	ProxyPassReverse / http://localhost:80/
	ProxyPreserveHost on
	RequestHeader set X-Forwarded-Proto "https" early
	# If you have pages that may take awhile to
	# respond, add a ProxyTimeout:
	# ProxyTimeout seconds
</VirtualHost>

p.s. don't forget to restart sudo service httpd restart

@vahiwe
Copy link

vahiwe commented Jan 14, 2021

👍 @zedy. You can share for others who might have the same issue.

@caseypage
Copy link

Maybe this will help someone:

I updated my single web instance PHP Platform version and all my https stuff broke because of certbot-auto being deprecated. I'm just using the httpd config files that beanstalk uses by default.

I spent a while trying to get 'certbot' installed by all the different solutions above and elsewhere but kept running into errors/issues.

I was finally able to get it all working using this .ebextension config: https://gist.github.com/caseypage/3f59f29f1fb4d6590c9193340a38ea03

@rich5851
Copy link

rich5851 commented Feb 4, 2021

Maybe this will help someone:

I updated my single web instance PHP Platform version and all my https stuff broke because of certbot-auto being deprecated. I'm just using the httpd config files that beanstalk uses by default.

I spent a while trying to get 'certbot' installed by all the different solutions above and elsewhere but kept running into errors/issues.

I was finally able to get it all working using this .ebextension config: https://gist.github.com/caseypage/3f59f29f1fb4d6590c9193340a38ea03

Thank You! I also ran into issues because of certbot-auto being deprecated and tried different solutions. I was about to give up on this approach until I saw this comment.

@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