Goal
Access credentials for Elasticsearch from within a Platform.sh application using Python.
Assumptions
- an active Platform.sh project
- properly configured
.platform/services.yaml
for the given service - SSH key configured on account if developing locally
- Elasticsearch installed if developing locally
- properly configured Elasticsearch relationship like so, in
.platform.app.yaml
:
relationships:
essearch: "searchelastic:elasticsearch"
If developing locally, remember to first open a tunnel to the project environment using the Platform CLI.
$ platform tunnel:open && export PLATFORM_RELATIONSHIPS="$(platform tunnel:info --encode)"
This will open an SSH tunnel to your current Platform.sh environment and expose a local environment variable that mimics the relationships array on Platform.sh. Check the Platform.sh documentation and How to develop locally on Platform.sh with a tethered connection for more information.
Problems
Platform.sh service credentials are made available to applications as the PLATFORM_RELATIONSHIPS
environment variable, which is a base64-encoded JSON string that has to be decoded before it can be used.
There are two primary options for accessing service credentials on Platform.sh that can be used within an application:
- Using the Platform.sh Config Reader library
- Accessing environment variables manually
Steps (Config Reader)
1. Install the library
Install the Platform.sh Configuration Reader library. See the documentation for minimum requirements.
$ pip install platformshconfig
2. Create a Config object
Creating a Config
object provides access to the Platform.sh environment.
from platformshconfig import Config
config = Config()
3. Read the credentials
# Get the credentials to connect to the Elasticsearch service.
credentials = config.credentials('essearch')
If the relationship is named something else, modify the credentials()
call accordingly.
Steps (Manual)
1. Load and decode the environment variable
import os, json, base64
relationships = json.loads(base64.b64decode(os.environ["PLATFORM_RELATIONSHIPS"]))
2. Get the credentials
credentials = relationships['essearch']
If the relationship is named something else, modify that line accordingly.
Use
In most cases, you will need only the scheme
, host
, and port
properties to connect to Elasticsearch. Pass those to your Elasticsearch library’s setup routine in your application. Most of the time the other values may be ignored.
In either case, credentials
is now a dictionary matching the relationship JSON object.
{
"username": null,
"scheme": "http",
"service": "searchelastic",
"fragment": null,
"ip": "169.254.101.149",
"hostname": "j2dkzht3gs2yr66fb2brhoj4zu.elasticsearch.service._.eu-3.platformsh.site",
"public": false,
"cluster": "rjify4yjcwxaa-master-7rqtwti",
"host": "essearch.internal",
"rel": "elasticsearch",
"query": [
],
"path": null,
"password": null,
"type": "elasticsearch:5.4",
"port": 9200
}
Conclusions
Using either the language-specific Platform.sh Configuration library or direct access methods for environment variables, an application can get Elasticsearch credentials in Python.
Platform.sh supports configuration libraries for multiple languages. The Python configuration library can be useful for inspecting the project environment:
# Checks whether the code is running in a build environment
config.inBuild()
# Checks whether the code is running in a runtime environment
config.inRuntime()
and for reading environment variables as attributes of config
:
# Available in Build and at Runtime
config.appDir
# Available at Runtime only
config.branch
config.smtpHost
The APIs for each language are written to be as consistent as possible, but seek out each library’s documentation for specific differences.