I have a Python application that is deployed using Helm and Kubernetes. I want to take hard-coded variables out of main.py and make them configurable in Helm. The trouble is if I pull them out of main.py then I lose the ability to run my code with python3 main.py
. Then I lose the ability to test and iterate quickly because I need to maintain two separate systems for every parameter in 3-4 places.
main.py
Before Extracting Hard-Coded Variables:HOST = "http://host"
PORT = 1234
if __name__ == '__main__':
connect_to_server(HOST, PORT)
host: "http://host"
port: "1234"
Using string for environment variable integer as per Helm docs.
env:
- name: HOST
value: {{ required "host is required!" .Values.host | quote }}
- name: PORT
value: {{ required "port is required!" .Values.port | quote }}
main.py
After Extracting Hard-Coded Variables::if __name__ == '__main__':
try:
HOST = os.environ['HOST']
PORT = int(os.environ['PORT'])
connect_to_server(HOST, PORT)
except IndexError as e:
print("Unable to run app! No env vars defined outside Helm!")
raise e
If I leave this setup above as is it will not run when I execute python main.py
. If I want to get this to run using plain old python3 main.py
then I need to set up an entirely separate and parallel system to manage my environment variables locally. This is less than ideal and feels like an uber-pain to manage. I want to be able to continue to test things quickly locally without adding a bunch of try/catch exceptions for environment variables throughout the application. I know I can import env vars all sorts of ways, but I don't want to maintain two different systems with the same info. How can I add env vars in Helm Charts while still being nimble in my Python application locally? Is there a way to import my local values.yaml
and set them as environment variables with the same name as in cronjob.yaml (i.e., HOST)? Or is there another solution I am not aware of for this use-case?
One option you could take is to continue to allow the environment variables, but provide a default in the case that the environment variable is not set. You can do this easily with the get()
method:
if __name__ == '__main__':
HOST = os.environ.get('HOST', 'http://host')
PORT = int(os.environ.get('PORT', '1234'))
connect_to_server(HOST, PORT)