Search code examples
cloud-foundrysap-cloud-platform

Cloudfoundry VCAP_SERVICES variables are not supplied to container for django


I have a dockerized Django application that I want to deploy on SAP Cloud Platform via cloudfoundry cli utility. I have added couple of User Provided Services with their own set of credentials. For example, I added AWS S3 as a User Provided Service and provided credentials for the same.

Now those credentials are available as environment variable as

VCAP_SERVICES={"user-provided":[{
  "label": "user-provided",
  "name": "s3",
  "tags": [
  ],
  "instance_name": "s3",
  "binding_name": null,
  "credentials": {
    "aws_access_key": "****",
    "aws_secret_key": "****",
    "bucket": "****",
    "region": "****",
    "endpoint": "*****"
  },
  "syslog_drain_url": "",
  "volume_mounts": [
  ]
}]}

I have .env file where in I have variables defined, eg. AWS_ACCESS_KEY. Usually I pass string value to the variable which is then consumed by my app. But, given that I have configured it via User Provided Service mechanism and credentials are already there, I was wondering how do I get to access those credentials.


Solution

  • There are a few ways to extract service information in Python applications.

    1. You can do it programmatically using the cfenv library. You would simply integrate this library into the start-up of your application. This generally offers the most flexibility, but can sometimes be difficult to integrate with frameworks, depending on how frameworks expect the configuration to be feed in.

    2. You can generate environment variables or configuration files, from your example the .env file, on the fly. This can be done using a .profile script. A .profile script, if placed into the root of your application will execute prior to your application but inside the runtime container. This allows you to adjust the configuration of your application at just the last moment.

      A .profile script is just a shell script and in it, you can use tools like jq or sed to extract information from the VCAP_SERVICES environment variable and put that information elsewhere (possibly other environment variables or into a .env file).

      Because you are pushing a Python application, the .profile could also execute a Python script. The Python buildpack will run and guarantee that a Python runtime is available on the PATH for use by your .profile script. Thus you can do something like this, to execute a Python script.

      .profile script:

      python $HOME/.profile.py
      

      .profile.py script (made up this name, you can call it anything):

      #!/usr/bin/env python3
      print("Hello from python .profile script")
      

      You can even import Python libraries in your script that are included in your requirements.txt file from this script.