3

Problem

I am attempting to enable HTTPS on an EC2 instance in Elastic Beanstalk. I have a https-instance.config file in the .ebextensions directory which, among other things, stops and starts the httpd server. The original container commands are these (from the AWS docs here, and also mentioned in my question here:

container_commands:
  01killhttpd:
    command: "killall httpd"
  02waitforhttpddeath:
    command: "sleep 3"

However, I get the following error, detailed in the cfn-init.log:

2020-08-25 14:51:55,622 [INFO] -----------------------Starting build-----------------------
2020-08-25 14:51:55,631 [INFO] Running configSets: Infra-EmbeddedPostBuild
2020-08-25 14:51:55,634 [INFO] Running configSet Infra-EmbeddedPostBuild
2020-08-25 14:51:55,638 [INFO] Running config postbuild_0_tiny_app
2020-08-25 14:51:55,706 [ERROR] Command 01killhttpd (systemctl restart httpd.service) failed
2020-08-25 14:51:55,706 [ERROR] Error encountered during build of postbuild_0_tiny_app: Command 01killhttpd failed
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 542, in run_config
    CloudFormationCarpenter(config, self._auth_config).build(worklog)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 260, in build
    changes['commands'] = CommandTool().apply(self._config.commands)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/command_tool.py", line 117, in apply
    raise ToolError(u"Command %s failed" % name)
ToolError: Command 01killhttpd failed
2020-08-25 14:51:55,706 [ERROR] -----------------------BUILD FAILED!------------------------
2020-08-25 14:51:55,707 [ERROR] Unhandled exception during build: Command 01killhttpd failed
Traceback (most recent call last):
  File "/opt/aws/bin/cfn-init", line 171, in <module>
    worklog.build(metadata, configSets)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 129, in build
    Contractor(metadata).build(configSets, self)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 530, in build
    self.run_config(config, worklog)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 542, in run_config
    CloudFormationCarpenter(config, self._auth_config).build(worklog)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 260, in build
    changes['commands'] = CommandTool().apply(self._config.commands)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/command_tool.py", line 117, in apply
    raise ToolError(u"Command %s failed" % name)
ToolError: Command 01killhttpd failed

I have tried removing this restart from the https-instance.config, and it builds but cannot connect to HTTPS. I have also attempted to replace the above commands with others to restart the httpd server, but these have resulted in a nearly identical error as the one above:

container_commands:
  01restart:
    command: "systemctl restart httpd"

and

container_commands:
  01restartservice:
    command: "systemctl restart httpd.service"

Question

How do I restart the httpd server to allow for the HTTPS connection to my app?

Context

  • Amazon Linux 2
  • Flask app in a Python 3.7 environment
  • Using a single EC2 instance, so there is no load balancer
  • I only need this for development purposes

Here is the full https-instance.config I have from AWS:

packages:
  yum:
    mod_ssl : []
    
files:
  /etc/httpd/conf.d/ssl.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      LoadModule wsgi_module modules/mod_wsgi.so
      WSGIPythonHome /opt/python/run/baselinenv
      WSGISocketPrefix run/wsgi
      WSGIRestrictEmbedded On
      Listen 443
      <VirtualHost *:443>
        SSLEngine on
        SSLCertificateFile "/etc/pki/tls/certs/server.crt"
        SSLCertificateKeyFile "/etc/pki/tls/certs/server.key"
        
        Alias /static/ /opt/python/current/app/static/
        <Directory /opt/python/current/app/static>
        Order allow,deny
        Allow from all
        </Directory>
        
        WSGIScriptAlias / /opt/python/current/app/application.py
        
        <Directory /opt/python/current/app>
        Require all granted
        </Directory>
        
        WSGIDaemonProcess wsgi-ssl processes=1 threads=15 display-name=%{GROUP} \
          python-path=/opt/python/current/app \
          python-home=/opt/python/run/venv \
          home=/opt/python/current/app \
          user=wsgi \
          group=wsgi
        WSGIProcessGroup wsgi-ssl
        
      </VirtualHost>
      
  /etc/pki/tls/certs/server.crt:
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN CERTIFICATE-----
      MIID8zCCAtsCFGzyKrXOsCiyLHRPfBG75SlmQyXqMA0GCSqGSIb3DQEBCwUAMIG1
      ...
      PuulTMAZWNXHa0g+XbRTtOQDA8FA0vlA80B+rFUQESSo2Cw5JKXTaL9OpMMG/t9S
      qvv+vGuaIw==
      -----END CERTIFICATE-----

       
  /etc/pki/tls/certs/server.key:
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN RSA PRIVATE KEY-----
      MIIEogIBAAKCAQEA+OYzho7mXLUY6zTTqBIibsk2rfuJIO2xN2moIUNTqzJS8Yv6
      ...
      cSQsBzRR1Z5hl77Qa6gwiDx7rYswWtQt/8zsY8OUB3kg1SqriwI=
      -----END RSA PRIVATE KEY-----

container_commands:
  01restartservice:
    command: "systemctl restart httpd.service"
whoopscheckmate
  • 746
  • 8
  • 23

2 Answers2

3

The reason why your commands are failing is that on Amazon Linux 2 Python 3.7 environment there is no httpd (its physically installed, but not active). You can verify this by sshing into the instance and running:

sudo systemctl status httpd

Instead, there are nginx and gunicorn as wsgi. The link to the AWS docs you provided is for Amazon Linux 1, not 2.

Therefore, SSL certs and HTTPs should be setup using nginx config files in .platform/nginx/conf.d/ folder.

Marcin
  • 215,873
  • 14
  • 235
  • 294
  • 1
    Ok, interesting. I never would have known that from the AWS documentation--even here in their Linux 2 specific documentation (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html#ssl_enable), they talk about configuration in the '.platform/httpd/conf.d/' folder. I guess I don't know how the configuration would be different--not an expert on this--but that can be a separate question. I don't currenlty have ssh access. – whoopscheckmate Aug 26 '20 at 14:28
  • 2
    @whoopscheckmate Yes. Sadly AWS docs are messy now. Some deal with Amazon Linux 1, other parts talk about Amazon Linux 2 and its not clear when they do it. – Marcin Aug 26 '20 at 21:17
  • 1
    This answer makes sense, but I searched for a clear way to map the httpd configuration to the nginx configuration and didn't find anything. This is the documentation I see to enable https with nginx (https://www.techrepublic.com/article/how-to-enable-ssl-on-nginx/) but it doesn't seem right. My question is, is there a simple way to change the config file above to do the nginx setup? If so and you're up for helping, I can ask another question. If not, should I probably contact AWS on their forums? – whoopscheckmate Aug 27 '20 at 18:11
  • 1
    My one other idea was to change the wsgi to httpd somehow. Is this possible? – whoopscheckmate Aug 27 '20 at 18:13
  • @whoopscheckmate Not sure at the moment. Probably you could do it, but its not clear for me now how to do it. – Marcin Aug 27 '20 at 21:20
1

You can configure AWS Linux 2 to use Apache (httpd) though it is not the default.

You can either set it via the console when creating your environment or use the following in your config file:

option_settings:
  aws:elasticbeanstalk:environment:proxy:
    ProxyServer: apache

If you are using Apache, the command to restart it is:

sudo systemctl restart httpd

Also note that on AWS Linux 2, Apache is now just forwarding to localhost:8000, which is served by Gunicorn, rather than running the app via modwsgi.

See this answer for config files for self-signed certificates that work on AWS Linux 2.

Zags
  • 37,389
  • 14
  • 105
  • 140