Search code examples
amazon-web-servicesflaskurl-routingamazon-elastic-beanstalkwerkzeug

Why does AWS Elastic Beanstalk Python insert a 'static' rule ahead of all others in priority?


The 'static' routing rule for my Python application is behaving strangely in my AWS Elastic Beanstalk application (and nowhere else), appearing to override all other rules.

For example, using the two functions below, on both my development machines and test servers elsewhere and on AWS, routes list the static rule last, and match_route shows other non-static rules matching paths that begin with 'static/...'. And as expected, if I navigate to a page with a path that starts with static/... on my non-AWS machines, one of my other (non-static) rules is matched. However (only) on AWS-EB, the server's static rule is invoked for such paths!

Why and how is AWS-EB "inserting" this rule ahead of all others? How do I either disable this behavior on AWS, or replicate it in my non-AWS systems?


application.url_map.host_matching = True
# ...

def routes(verbose, wide):
    """List routes supported by the application"""
    for rule in sorted(app.url_map.iter_rules()):
        if verbose:
            fmt = "{:45s} {:30s} {:30s}" if wide else "{:35s} {:25s} {:25s}"
            line = fmt.format(rule, rule.endpoint, ','.join(rule.methods))
        else:
            fmt = "{:45s}" if wide else "{:35s}"
            line = fmt.format(rule)

        print(line)

def match_route(host, match):
    """Match a route for a given host"""
    if match is not None:
        urls = app.url_map.bind(host)
        try:
            m = urls.match(match, "GET")
            z = '{}({})'.format(m[0], ','.join(["{}='{}'".format(arg, m[1][arg]) for arg in m[1]] +
                                               ["host='{}'".format(host)]))
            return z
        except NotFound:
            return

Solution

  • This is a result of the Apache server configuration in /etc/httpd/conf.d/wsgi.conf which contains

    Alias /static/ /opt/python/current/app/static/
    

    If you delete or comment out that line, the server will no longer "intercept" paths that start with 'static'.

    Accomplishing this is, however, a bit trickier than one might guess, since the wigs.conf file gets (re)created after files are uploaded and commands are executed.

    One way around this is to modify the file with a post-deployment hook, being sure to restart the webserver afterwards:

    files:
      "/opt/elasticbeanstalk/hooks/appdeploy/post/remalias.sh" :
        mode: "00775"
        owner: root
        group: root
        content: |
          sed -i.backup -e 's/^Alias\s[/]static[/]\s[a-z/]*$//g' /etc/httpd/conf.d/wsgi.conf
          service httpd restart