Uno de los retos más frustrantes en el desarrollo de aplicaciones hoy en día es la paridad de entorno. Mientras que los últimos años han demostrado que las herramientas de virtualización y contenedorización como Vagrant y Docker (y la propia herramienta de estado de ActiveState) pueden asegurar que los sistemas operativos y las dependencias que alimentan la infraestructura de una aplicación son consistentes entre entornos, las dependencias externas son casi imposibles de replicar en un entorno que no sea de producción.
En un mundo en el que las dependencias de terceros se han entrelazado irreversiblemente con la lógica de negocio principal de casi todos los proyectos de software, se está volviendo cada vez más difícil mantener el desarrollo, la puesta en escena y los entornos de producción consistentes entre sí. Mientras que algunos productos con apariencia de auto-alojamiento – como Minio a Amazon S3 – alivian el dolor de la gestión de múltiples despliegues de un solo servicio, hace poco para aliviar el desafío de la gestión de la configuración a través de los entornos.
Cuando la producción, la puesta en escena, el desarrollo, la máquina local de Bob, y el entorno QE todos requieren un despliegue diferente de un servicio determinado, pasando los archivos de configuración de ida y vuelta, o confiar en complejas condiciones para determinar qué despliegue de un entorno determinado debe hablar, se vuelve cada vez más impracticable. La necesidad de flexibilidad también pone de manifiesto la dificultad de estas soluciones en un entorno a gran escala. ¿Qué pasa si, por ejemplo, la máquina local de Bob necesita hablar temporalmente con un servicio que está reservado para el entorno de puesta en escena?
Variables de entorno en Python
La configuración entre entornos es un dolor, pero afortunadamente los problemas descritos anteriormente se han vuelto lo suficientemente comunes en los últimos años que están casi resueltos. Gracias al apoyo de la comunidad de código abierto, y la evangelización de las mejores prácticas como la Aplicación de 12 Factores, ha habido un cambio en los últimos años de la gestión de la configuración de la aplicación basada en archivos a la gestión de la configuración basada en variables de entorno.
Disponibles en todos los principales sistemas operativos, las variables de entorno son – tal como su nombre indica – variables que se implementan en el nivel de entorno para definir la forma en que las aplicaciones que se ejecutan por debajo deben comportarse. En términos más sencillos, son variables agnósticas a la aplicación que se gestionan fuera del contexto de un proceso determinado. La principal ventaja de utilizar variables de entorno es que esto permite a los desarrolladores definir cómo debe ejecutarse una aplicación sin cambiar una línea de código.
Por ejemplo, si la máquina local de Bob necesita hablar con el servicio CDN que está reservado para el entorno de Staging, puede cambiar la variable de entorno CDN_URL
para reflejar lo que se define en Staging sin tener que tocar ningún código gestionado. Más importante aún, esto permite a Bob definir servicios simulados o internos para su uso con pruebas unitarias y de integración, todo ello sin tener que escribir una sola línea de código adicional.
Definición de Variables de Entorno
Aunque el acto de definir variables de entorno es generalmente dependiente del sistema operativo, la gran mayoría de los lenguajes de programación han abstraído estas diferencias mediante el uso de paquetes de desarrollo como el proyecto dotenv de Python. Por ejemplo, en lugar de tener que definir una variable de entorno API_USER
a nivel del sistema operativo, un archivo .env
gitignado localmente puede mantener las variables de entorno en todos los entornos de desarrollo. Esto permite a los desarrolladores utilizar un archivo de configuración gestionado localmente para establecer las variables de entorno, mientras que al mismo tiempo permite la configuración a través de «verdaderas» variables de entorno en entornos que no son de desarrollo.
Como ejemplo, aquí está un simple archivo .env
que un desarrollador puede utilizar en su entorno local:
APP_ENVIRONMENT=localAPP_NAME=localhostQUEUE_DRIVER=syncAPI_USER=bob
Por otro lado, el entorno de producción puede definir sus variables de entorno dentro de un Dockerfile, ambos son métodos válidos para mantener las variables de entorno.
Recuperación de variables de entorno
Independientemente de cómo se definan las variables de entorno, siempre se pueden recuperar en Python utilizando el método os.getenv()
:
import os# Get environment variablesUSER = os.getenv('API_USER')
Tenga en cuenta que, en el caso de que la variable de entorno no esté definida, el valor será por defecto None
.
Cómo empezar con los secretos
Ahora bien, aunque las variables de entorno son una excelente solución para gestionar configuraciones dispares entre entornos, no son una bala de plata. En el clima de desarrollo de hoy en día, la seguridad debe ser una prioridad, y los datos sensibles deben mantenerse de forma segura.
Desgraciadamente, las variables de entorno por sí solas no son seguras. Mientras que hacen un gran trabajo de almacenamiento de datos de configuración, la forma en que definimos los datos más sensibles como las contraseñas, claves de la API, y las claves de cifrado debe requerir más cuidado. Aquí es donde entran en juego los secretos. Encriptados en reposo, los secretos sólo deben ser recuperados en un único tiempo de ejecución, según sea necesario, para reducir las probabilidades de una violación de datos. De esta manera, incluso si su proveedor de alojamiento se ve comprometido, puede estar seguro de que sus secretos sensibles están bien cerrados.
Creación de &Gestión de secretos con la herramienta de estado
Entonces, ¿cómo creamos y gestionamos los secretos? Mientras que hay un número de diferentes maneras de abordar este problema, la Herramienta de Estado de ActiveState es una excelente solución para el lenguaje Python. Similar a virtualenv
o pipenv
, la Herramienta de Estado es una interfaz de gestión de entornos virtuales que evitará la contaminación cruzada de instalaciones y configuraciones de Python entre proyectos. Lo que la diferencia de otras herramientas de gestión de entornos virtuales es su integración con la plataforma ActiveState, lo que permite una interfaz central para gestionar las configuraciones del entorno y, sí, los secretos.
Antes de que podamos aprovechar las capacidades de gestión de secretos de la Herramienta de Estado, primero tenemos que utilizar la Herramienta de Estado para configurar un entorno virtual dentro del directorio de nuestro proyecto. Para ello, primero identifica el proyecto ActiveState con el que vas a trabajar (para este tutorial, puedes utilizar mi proyecto zachflower/envs-vs-secrets-demo
siempre que tengas una cuenta gratuita de la Plataforma ActiveState, o puedes crear la tuya propia). A continuación, ejecuta el comando state activate
para tu proyecto determinado:
$ state activate zachflower/envs-vs-secrets-demo Where would you like to checkout zachflower/envs-vs-secrets-demo? /home/zach/Projects/miscellaneous/activestate-variables/zachflower/envs-vs-secrets-demoActivating state: zachflower/envs-vs-secrets-demoThe State Tool is currently in beta, we are actively changing and adding features based on developer feedback.Downloading required artifactsDownloading 1 / 1 Installing 0 / 1 0 %You are now in an 'activated state', this will give you a virtual environment to work in that doesn't affect the rest of your system.Your 'activated state' allows you to define scripts, events and constants via the activestate.yaml file at the root of your project directory.To expand your language and/or package selection, or to define client-side encrypted secrets, please visit https://platform.activestate.com/zachflower/envs-vs-secrets-demo.To try out scripts with client-side encrypted secrets we've created a simple script for you in your activestate.yaml, try it out by running 'helloWorld'
Como puedes ver, el comando activar configura el entorno virtual tal y como está definido en tu proyecto ActiveState. En el caso de que el proyecto aún no haya sido configurado, se sembrará un proyecto simple con parámetros por defecto para proporcionarle un ejemplo de cómo debe ir todo junto. Esta configuración se almacena en un archivo en la raíz del directorio de su proyecto llamado activestate.yaml
.
Archivo de configuración para secretos &Más
El archivo activestate.yaml
define un tiempo de ejecución de desarrollo bajo el cual se ejecutará su aplicación. Por ejemplo, el predeterminado define una simple secuencia de comandos que utiliza un secreto, así como algunos oyentes de eventos que realizan acciones cada vez que se produce un evento definido:
project: https://platform.activestate.com/zachflower/envs-vs-secrets-demoscripts:# This script uses a secret. Note that you can define your own secrets at# https://platform.activestate.com/zachflower/envs-vs-secrets-demo/scripts - name: helloWorld value: echo ${secrets.user.world}events: # This is the ACTIVATE event, it will run whenever a new virtual environment is created (eg. by running `state activate`) # On Linux and macOS this will be ran as part of your shell's rc file, so you can use it to set up aliases, functions, environment variables, etc. - name: ACTIVATE constraints: os: macos,linux value: | echo "You are now in an 'activated state', this will give you a virtual environment to work in that doesn't affect the rest of your system." echo "" echo "Your 'activated state' allows you to define scripts, events and constants via the activestate.yaml file at the root of your project directory." echo "" echo "To expand your language and/or package selection, or to define client-side encrypted secrets, please visit https://platform.activestate.com/zachflower/envs-vs-secrets-demo." echo "" echo "To try out scripts with client-side encrypted secrets we've created a simple script for you in your activestate.yaml, try it out by running 'helloWorld'"
Aunque no hay nada particularmente innovador aquí, el poder potencial de este archivo debe ser inmediatamente obvio. Por ejemplo, la siguiente secuencia de comandos proporciona un ejemplo básico de cómo utilizar los secretos en el archivo de configuración:
scripts:# This script uses a secret. Note that you can define your own secrets at# https://platform.activestate.com/zachflower/envs-vs-secrets-demo/scripts - name: helloWorld value: echo ${secrets.user.world}
Cuando se ejecuta el comando helloWorld
(desde un estado activado), se hará eco del valor del secreto user.world
y, en el caso de que el secreto aún no esté definido, pedirá un valor:
$ helloWorldThe action you are taking uses a secret that has not been given a value yet.Name: worldDescription: - (This secret has no description, you can set one via the web dashboard)Scope: user (Only you can access the value) Please enter a value for secret "world": ******
Usando Secretos
Aunque el ejemplo es relativamente simplista, el verdadero valor de los secretos proviene de los eventos de activación. En lugar de recuperar un valor secreto dentro del contexto de un script, las variables de entorno pueden ser definidas usando secretos recuperados sin exponer nunca esos secretos fuera de este entorno seguro:
project: https://platform.activestate.com/zachflower/envs-vs-secrets-demo?commitID=5fd1c161-c5a4-480c-8aba-29d8ab361b42events: - name: ACTIVATE constraints: os: macos,linux value: | export WORLD=${secrets.user.world}
Ahora, si el secreto user.world
está definido, entonces la variable de entorno WORLD
estará definida y podrá ser recuperada como cualquier otra variable de entorno:
$ echo $WORLDworld!
Sin embargo, si no está definida, entonces se le pedirá al usuario que la defina al activar el entorno virtual de ActiveState:
The action you are taking uses a secret that has not been given a value yet.Name: helloDescription: - (This secret has no description, you can set one via the web dashboard)Scope: user (Only you can access the value) Please enter a value for secret "world": ******
Muy bien, ¿verdad?
Llevándolo más lejos
La gestión de la configuración en el desarrollo de aplicaciones es, en su mayor parte, un tema resuelto, pero la gestión de los secretos no lo es todavía. El número de proyectos que han comprobado los datos sensibles en un repositorio de control de versiones es asombroso, y es algo que incluso empresas muy respetadas han hecho, pero a través del uso de la higiene de seguridad adecuada y productos como la Herramienta de Estado de ActiveState, mantener los datos de configuración sensibles seguros y protegidos es cada vez más fácil.
- Pruébalo por ti mismo creando una cuenta gratuita de la Plataforma ActiveState y descargando la Herramienta de Estado para simplificar la gestión de secretos.
- También puede ver nuestro webinar sobre Cómo Gestionar Secretos Compartidos usando la Herramienta de Estado
Blogs Relacionados:
El Secreto para Gestionar Secretos Compartidos
Los Desarrolladores pueden Compartir Secretos Rápida y Fácilmente sin Sacrificar la Seguridad