Tuesday, October 6, 2015

Today, me and a colleague from StarterSquad spent some time puzzling out the deploy of a group of microservices on Vagrant. The environment was Apache + mod_wsgi + Flask. In the "real-life", these services more or less happily run each on their own AWS EBS instance. For the simplicity of the local development, we wanted to provision them all on a Vagrant instance instead. (We use an Ansible-based tool called Prudentia to orchestrate deployment on different platforms with relative ease, but as a first step, the priority was to just make it all run there with a single command.)

The problem we encountered in the end was that some services seemed to ignore environment variables set with SetEnv in Apache configuration. That was strange because on AWS, the environment variables were set separately for every EBS instance and they seemed to be picked up. (These variables were used in from_envvars Flask directive to replace the defaults).

Then came a learning moment for me (I did not work much with Apache / mod_wsgi / Python before) that the Python applications started with mod_wsgi are supposed to read their environment variables from a dictionary when they start. One can eventually add them to the OS environment with code like that:

def application(environ, start_response):
    for key in environ:
        os.environ[key] = environ[key]
    from my_module import app
    return app(environ, start_response)

However, not all of already existing microservices of our client were using that technique, and yet they seemed to have the right environment variables anyway.

As it appears, on AWS Elastic BeanStack the configuration variables are the system environment, and not Apache environment variables! It would be good if EBS documentation more clearly stated that difference.