Si has trabajado en cualquier forma de desarrollo de aplicaciones, seguro que ya has oído hablar del término «variables de entorno» Las variables de entorno se utilizan para almacenar los secretos de la aplicación y los datos de configuración, que son recuperados por tu aplicación en ejecución cuando se necesitan.

Las variables de entorno añaden dinamismo a tu base de código estático; puedes cambiar entre recursos internos/externos en función del valor de la variable de entorno que se pasa a tu aplicación.

Este artículo desglosará las variables de entorno para ti. Aprenderás algunas formas populares de crear y gestionar las variables de entorno y entenderás cuándo utilizarlas. Al final de este artículo, serás capaz de utilizar con eficacia y confianza las variables de entorno en tus aplicaciones.

Sin más preámbulos, ¡comencemos!

¿Qué Es Una Variable de Entorno?

Reiterando la explicación anterior, las variables de entorno son variables disponibles para tu programa/aplicación de forma dinámica durante el tiempo de ejecución. El valor de estas variables puede proceder de diversas fuentes: archivos de texto, gestores secretos de terceros, scripts de llamada, etc.

Lo importante aquí es el hecho de que el valor de estas variables de entorno no está codificado en tu programa. Son realmente dinámicas y pueden cambiarse en función del entorno en el que se ejecuta tu programa.

Tipos de Variables de Entorno

Hay tres tipos destacados de variables de entorno en un sistema informático basado en Windows, y cada uno de ellos tiene sus casos de uso. Vamos a discutirlas una por una.

1. Variables de entorno del sistema

Las variables de entorno del sistema residen en la raíz superior del sistema y son las mismas para todos los procesos que se ejecutan en un sistema bajo todos los perfiles de usuario del mismo. El administrador de tu sistema operativo/sistema suele establecerlas, y rara vez es necesario que juegues con ellas.

Uno de los usos más habituales de una variable de entorno del sistema es establecer una variable PATH para un paquete/biblioteca global que utilizarán todos los usuarios del sistema.

2. Variables de entorno de usuario

Las variables de entorno de usuario son aquellas que son locales a un perfil de usuario en los sistemas Windows. Estas variables se utilizan para almacenar información específica del usuario, como la ruta de acceso a una instalación local de bibliotecas que no deben ser utilizadas por todos los usuarios, valores específicos de programas instalados sólo para usuarios concretos, etc.

No necesitas que el administrador del sistema haga cambios en estas variables; puedes hacerlo tú mismo como usuario. Estas variables son útiles a la hora de implementar cambios locales en tu sistema sin afectar a otros usuarios.

3. Variables de entorno en tiempo de ejecución/proceso

Las variables de entorno en tiempo de ejecución se limitan únicamente al tiempo de ejecución o al proceso al que están asociadas. Suelen ser establecidas por el proceso padre que crea el nuevo proceso y van acompañadas de las variables de entorno del sistema y del usuario.

Puedes utilizar scripts de terminal para crear y almacenar estas variables sobre la marcha. Las variables de tiempo de ejecución no suelen ser permanentes, a menos que se hagan scripts, y tienes que definirlas cada vez que inicies un nuevo proceso.

Variables de entorno en sistemas basados en Unix

A diferencia de los sistemas Windows, los sistemas basados en Unix no tienen tres capas de tipos de variables de entorno. En estos sistemas, todo se almacena bajo un objeto var y puede ser accedido/modificado por el programa en ejecución.

Si necesitas establecer algunas variables de entorno como predeterminadas para que se carguen cada vez que se ejecute cualquier programa en tu sistema, tienes que definirlas en archivos como .~/bashrc o ~.profile que se cargan al arrancar el sistema.

Variables de entorno frente a pseudovariables de entorno

En los sistemas basados en Windows y DOS existe una línea separada de variables de entorno dinámicas, conocidas como pseudovariables de entorno. No se trata de pares de claves y valores asignados de forma estática, sino de referencias dinámicas que devuelven varios valores cuando se consultan.

Mientras que puedes asignar un valor a una variable de entorno manualmente utilizando el comando SET o su equivalente, no puedes asignar valores a las pseudovariables de entorno. Existe una lista fija de tales variables, y puedes utilizarlas en tu código para facilitar tu trabajo. Algunos casos de uso populares son %CD% para el directorio actual y %TIME% para la hora actual.

¿Por qué Debes Utilizar las Variables de Entorno?

Ahora que entiendes lo que es una variable de entorno y sus distintos tipos, es el momento de saber por qué deberías utilizarlas ampliamente en tus aplicaciones.

Separación de intereses

Una de las razones más importantes por las que deberías utilizar variables de entorno en tus aplicaciones es la adhesión a un principio de diseño popular y útil: la separación de intereses. Este principio de diseño establece que los programas informáticos deben dividirse en secciones distintas para gestionarlos de forma eficiente. Cada sección debe basarse en una de las preocupaciones principales del programa, y debe haber un acoplamiento mínimo entre dichas secciones.

Puedes considerar la configuración de la aplicación como una de esas preocupaciones, por lo que debe estar separada del programa principal. Una de las mejores formas de hacerlo es almacenarla en un archivo externo e inyectarla cuando sea necesario. Las variables de entorno te ayudan a aislar los datos críticos de configuración de la aplicación mediante archivos env o almacenes de variables remotas. De este modo, tus desarrolladores sólo reciben la información que necesitan.

Mantener conjuntos de configuración independientes entre entornos

Además de aislar las configuraciones de la aplicación de tu código fuente, también necesitas poder cambiar fácilmente entre conjuntos de datos de configuración. Si eliges codificar los valores de configuración de tu aplicación en tu código fuente, puede resultar casi imposible reemplazar esos valores en función de condiciones externas, como los entornos de despliegue.

El uso de variables de entorno te ayuda a desacoplar los datos de configuración de tu código y a estandarizar la forma en que se proporciona esta información a tu aplicación, lo que te permite modificar/cambiar la información que se proporciona sobre la marcha.

Asegurar los secretos

Los secretos de tu aplicación son información sensible. Si las personas equivocadas ponen sus manos en ellos, pueden acceder a la arquitectura interna de tu aplicación y a los recursos de terceros. Algunos ejemplos comunes son las claves de AWS y los detalles de las cuentas del sistema. El acceso no autorizado a estas claves puede conducir a la pérdida de dinero y datos de la aplicación. Los hackers pueden incluso llegar a impedir que tu aplicación funcione con normalidad.

Por tanto, es vital que protejas estos secretos. Dejarlos por ahí en tu código base puede hacer que todos tus desarrolladores tengan acceso a ellos. Si no sigues los métodos de ofuscación de código adecuados, tus aplicaciones pueden ser objeto de ingeniería inversa para recuperar las claves que se encuentran en tu código. Aislar estos secretos mediante variables de entorno puede evitar que se produzcan estos escenarios.

Ejemplos de Uso de las Variables de Entorno

Ahora que tienes una idea clara de cómo funcionan las variables de entorno y de cómo debes utilizarlas eficazmente, aquí tienes algunos escenarios comunes en los que puedes utilizar las variables de entorno:

  • Tipo de entorno: Las variables de entorno suelen utilizarse para almacenar el nombre del entorno en el que se está ejecutando la app. La lógica de la aplicación puede utilizar este valor para acceder al conjunto adecuado de recursos o para activar/desactivar determinadas funciones o secciones de la aplicación.
  • Nombre de dominio: El nombre de dominio de una aplicación puede variar en función de su entorno. Aislarlo también te ayuda a realizar fácilmente cambios en el nombre de dominio de tu aplicación sin tener que buscar sus apariciones en todo el código base.
  • URLs de la API: Cada entorno de tu aplicación puede tener APIs desplegadas en diferentes entornos también.
  • Claves privadas: Las claves de los servicios y recursos de pago deben estar aisladas del código fuente de la app para que no caigan accidentalmente en manos equivocadas.
  • Números de cuenta de servicio, etc.: Puedes variar otra información específica del sistema, como los números de cuenta de servicio, los llaveros, etc., en función del entorno de la app para la gestión y supervisión de los recursos.

¿Cómo Almacenar las Variables de Entorno?

Ahora que entiendes por qué son importantes las variables de entorno, es el momento de ver cómo puedes almacenarlas y acceder a ellas en tu aplicación. A continuación se comentan tres formas diferentes, aunque populares, de gestionar las variables de entorno en una aplicación.

Utilizar archivos .env

.env son sin duda la forma más fácil y popular de gestionar las variables de entorno. La idea es sencilla: almacenas tus variables de entorno en un archivo llamado .env en la raíz de tu proyecto. La aplicación busca las variables en este archivo y las carga para utilizarlas durante el tiempo de ejecución. Este es el aspecto de un archivo típico de .env:

VAR_UNO=SOME_KEY_HERE
VAR_DOS=SOME_OTHER_KEY_HERE

.env los archivos también te permiten definir conjuntos de variables de entorno y acceder a ellas en función del entorno de ejecución de tu aplicación o de otros factores. En lugar de guardar el archivo simplemente como .env, puedes hacer más de un archivo y guardarlos como .env.dev y .env.prod. Dentro de estos archivos, puedes definir los mismos conjuntos de variables pero con valores diferentes, según el entorno.

Plantilla de ejemplo

Cuando trabajes con archivos .env, no es recomendable añadirlos a tu sistema de control de versiones (más adelante se hablará de ello). Por lo tanto, debes definir un «.env.template» en tu proyecto para que los desarrolladores puedan seguir la plantilla y crear ellos mismos un archivo .env localmente.

Este es el aspecto que tendría un archivo .env.template:

VAR_UNO= # Your value here
VAR_DOS= # Your value here

No tiene que seguir ninguna convención, siempre que sea autoexplicativo para tu equipo de desarrollo. Para simplificar este proceso, también podrías utilizar paquetes como env-template.

Pros

Estas son algunas de las razones por las que deberías considerar el uso de archivos .env para gestionar las variables de entorno en tu aplicación.

Fácil de usar

Este método es el más sencillo en la línea de técnicas de gestión de variables de entorno. Todo lo que necesitas hacer es crear un archivo de texto plano que contenga tus secretos y almacenarlo en la raíz de tu proyecto.

Cambiar de entorno es tan sencillo como cambiar el propio archivo env. Puedes almacenar varios archivos con los nombres .env.dev, .env.prod, .env.uat, etc., y configurar tu código fuente para que acceda a estos archivos en función del entorno en el que se esté ejecutando.

Acceso local

Puedes configurar fácilmente los archivos .env en un entorno de desarrollo local. A diferencia de los gestores de variables nativos de la plataforma, no necesitas desplegar tu aplicación para aprovechar la funcionalidad de las variables de entorno. En comparación con los gestores de secretos, los archivos .env son más fáciles de configurar localmente, y no hay dependencia de la red para acceder a los secretos de tu aplicación.

Soporte de código abierto

Existen numerosos paquetes de código abierto que te ayudan a cargar y gestionar los secretos de las aplicaciones desde los archivos env. No necesitas depender de servicios de pago, ni tus opciones son limitadas en lo que respecta a la gestión de secretos de aplicación. Hay una amplia gama de bibliotecas de código abierto de terceros para ayudarte a gestionar tus archivos env. Algunos ejemplos populares/útiles son dotenv, env-template y cross-env.

Contras

He aquí algunas desventajas de los archivos env que debes conocer antes de utilizarlos en tus proyectos.

Formato

.env los archivos env almacenan los secretos de tu aplicación en forma de pares clave-valor. El formato habitual para almacenar las variables de entorno en un archivo .env es:

Key1=Value1

Tienes que ceñirte estrictamente a este formato para que tu aplicación pueda leer tus secretos de aplicación con éxito. Si cometes un pequeño error en algún lugar entre decenas o cientos de líneas de variables de entorno, es posible que no se analice todo el archivo, y tu programa arrojará errores inconexos en todo momento. El hecho de que haya un error de análisis en tu archivo .env puede que ni siquiera se destaque. Por eso debes tener cuidado al utilizar los archivos .env.

Propenso a la fuga accidental de secretos al compartir/almacenar

Como los archivos .env son archivos de texto plano, son vulnerables a la exposición accidental cuando se almacenan en un disco duro compartido o se envían a través de una red no segura. Por lo tanto, debes tener especial cuidado para que no se filtren los secretos de tu aplicación cuando los hayas almacenado utilizando archivos .env.

Utilizar el almacenamiento de variables nativo de la plataforma

Otra opción popular para almacenar variables de entorno es confiar en el almacenamiento de variables de tu plataforma de despliegue. La mayoría de los entornos de despliegue, como Heroku, AWS, Netlify, etc., ofrecen un espacio para que los usuarios suban secretos que luego se inyectan en el tiempo de ejecución de tu aplicación. Puedes consultar la documentación de tu plataforma de despliegue para saber si lo soporta y cómo empezar a utilizarlo.

Aquí tienes un rápido vistazo al gestor de variables de entorno de Netlify:

Screenshot of Netlify's environment variables manager showing an editable list of keys and values
Gestor de variables de entorno de Netlify.

Pros

He aquí por qué deberías considerar el uso de soluciones de almacenamiento de variables nativas de la plataforma.

Muy seguro

Dado que esta opción es gestionada íntegramente por tu plataforma de despliegue, es más segura que almacenar tus secretos en un archivo de texto plano. Puedes controlar quién tiene acceso al gestor de variables, y puedes estar seguro de que los secretos nunca se enviarán accidentalmente a tu VCS.

Fácil de actualizar

Actualizar las variables de entorno cuando se almacenan de forma independiente es más sencillo: no necesitas editar tu código fuente y hacer una nueva publicación para él. Simplemente puedes cambiar los valores en la plataforma y reconstruir tu proyecto. Éste recibirá los nuevos valores la próxima vez que se inicie.

También desaparecen los problemas de formato, ya que la mayoría de los gestores de despliegue específicos de la plataforma desgranan las claves a medida que las introduces. En casos como el de Netlify, consigues introducir los secretos de forma preformateada, eliminando las posibilidades de cometer un error de formato.

Permite la colaboración

Dado que todo tu equipo puede acceder a las plataformas de despliegue, puedes compartir fácilmente los secretos con las personas adecuadas sin tener que enviar archivos de texto por Internet. Puedes controlar quién tiene acceso al gestor de variables (en la mayoría de los casos) y utilizarlo como repositorio central para los secretos de tu aplicación.

Contras

Aunque los gestores de variables nativos de la plataforma parecen ser la solución que necesitas, hay algunas cuestiones que debes tener en cuenta antes de optar por ellos.

Dependientes de la plataforma

Como su nombre indica, son muy específicos de la plataforma que estés utilizando. En algunos casos, es posible que tu plataforma de despliegue no ofrezca este servicio. Cambiar tu plataforma de despliegue para tener acceso a dicho servicio podría no ser la mejor decisión.

No son uniformes

Al ser ofrecidos y gestionados completamente por la plataforma de despliegue, estos servicios pueden ser muy poco uniformes. Trasladar las variables de una plataforma a otra puede ser problemático. Ni siquiera puedes suponer que todas las plataformas de despliegue ofrezcan la posibilidad de importar/exportar variables de entorno. Aunque la mayoría lo hace, está totalmente en manos de la plataforma. Hay muchas posibilidades de que te encuentres con un bloqueo de proveedor a pequeña escala si tienes una larga lista de variables de entorno.

No hay soporte local

Aunque estos servicios son estupendos para acceder a las variables de entorno en los despliegues de tu aplicación, rara vez existe la posibilidad de que puedas utilizarlos mientras desarrollas tu aplicación localmente. En la mayoría de los casos, tendrás que recurrir a la gestión de archivos locales .env. Aunque cumple el objetivo, complica innecesariamente toda la configuración.

Utilizar gestores secretos

La tercera opción, que actualmente es bastante joven en sus fases de desarrollo, es utilizar gestores secretos dedicados. Los gestores de secretos son servicios de terceros que te permiten aislar completamente los secretos de tu aplicación de tu código fuente/implementación y obtenerlos cuando sea necesario a través de conexiones de red seguras.

Ventajas

Estas son algunas de las ventajas que ofrecen los gestores de secretos sobre otros métodos de gestión de secretos.

Alta seguridad

Como tus secretos se almacenan en un servicio completamente aislado, puedes estar seguro de que lo más probable es que nunca se filtren accidentalmente al compartirlos con tus colegas o a través de los commits del control de versiones. La plataforma de terceros se encarga de mantener tus secretos a salvo, y suelen tener acuerdos de nivel de servicio bastante estrictos en lo que respecta a la seguridad de los datos.

Incluso cuando se accede a los secretos desde dentro de tu aplicación, la mayoría de los gestores de secretos proporcionan su propio código cliente que puede obtener y permitir el acceso a los secretos de forma segura siempre que sea necesario.

Uniforme en todos los entornos

Como los secretos son ahora independientes de tu código base y de los entornos de despliegue, ahora puedes disfrutar de uniformidad en todos los entornos. No necesitas hacer arreglos especiales para la incorporación de nuevos desarrolladores o tomar medidas especiales antes de pasar tu aplicación a producción: la mayoría de estos aspectos se simplifican o son atendidos por tu gestor de secretos.

Contras

Aunque los gestores de secretos parecen ser la mejor solución posible para gestionar las variables de entorno, tienen su propia cuota de inconvenientes.

Coste

La gestión de las variables de entorno ha sido una actividad interna de los proyectos durante mucho tiempo. Incluso la mayoría de las plataformas de despliegue proporcionan esta función de forma gratuita, ya que no incurren en ningún coste adicional por ello.

Sin embargo, como los gestores secretos son servicios completamente independientes, tienen su propio coste de funcionamiento. Por tanto, los usuarios tienen que asumir este coste al utilizar estos servicios.

Etapas iniciales de la tecnología

Dado que la tecnología es bastante nueva, nunca se puede estar seguro de cómo va a ser adoptada por la industria en los próximos días. Aunque los gestores secretos son muy prometedores en términos de seguridad y facilidad de gestión, el factor coste y las preocupaciones sobre el manejo de datos podrían dar lugar a una adopción bastante lenta de la tecnología.

¿Cómo Trabajar con las Variables de Entorno?

Ahora que entiendes el concepto de variables de entorno y las formas disponibles de implementarlas en una aplicación, veamos cómo puedes trabajar con ellas a través del terminal y en aplicaciones basadas en Node.js.

Variables de entorno en el terminal

Como las variables de entorno son específicas de los procesos, puedes establecerlas y eliminarlas a través del terminal para que se transmitan a los procesos que tu terminal genera.

¿Cómo encontrar los valores de las variables?

Para ver la lista de variables de entorno en tu terminal, puedes ejecutar los siguientes comandos específicos de tu sistema operativo.

En Windows:

set

En Linux o MacOS:

env

Esto imprimirá una lista de todas las variables de entorno disponibles en tu terminal en funcionamiento.

Establecer nuevas variables

Para establecer nuevas variables a través del terminal, puedes ejecutar los siguientes comandos.

En Windows:

set "VAR_NAME=var_value"

En Linux o MacOS:

VAR_NAME=var_value

Borrar variables

Para eliminar una variable de entorno, debes ejecutar los siguientes comandos.

En Windows:

set "VAR_NAME="

En Linux o MacOS:

unset VAR_NAME

Ten en cuenta que los métodos comentados anteriormente sólo sirven para crear/borrar variables de entorno para la sesión actual del terminal.

Variables de entorno en Node.js

JavaScript es uno de los lenguajes de programación más populares actualmente. Se utiliza ampliamente en la construcción de aplicaciones tanto backend como front-end, lo que lo convierte en uno de los lenguajes de programación más versátiles.

Node.js es uno de los frameworks JS más utilizados para construir aplicaciones backend. Veamos cómo puedes manejar fácilmente las variables de entorno en las aplicaciones basadas en Node.js.

Acceder a las variables de entorno directamente

Node.js te proporciona una referencia a las variables de entorno de tu proceso actual a través de process.env. Puedes ver las variables de entorno disponibles imprimiendo este objeto en la consola.

Node.js app's output on the terminal showing a list of available environment variables.
Imprimiendo el objeto process.env.

Este objeto contendrá variables disponibles para el proceso Node en ejecución. Puedes añadirle nuevas variables declarándolas antes de ejecutar tu aplicación, de forma similar a esto:

VAR_UNO=SOMETHING node index.js
Node.js app's output on the terminal showing a list of available environment variables along with the new variable added on the top.
Imprimiendo el objeto process.env después de añadir una nueva variable.

Como puedes ver, la nueva variable se añade a tu objeto process.env. Sin embargo, no puedes acceder a ninguna variable definida en un archivo .env mediante este método. Para ello, debes utilizar un paquete como dotenv para cargar el archivo .env en tiempo de ejecución.

Uso del paquete dotenv para acceder a los archivos .env

El paquete dotenv te ayuda a cargar las variables de entorno almacenadas en los archivos .env en la raíz de tu proyecto. Su uso es sencillo, tienes que instalarlo ejecutando el siguiente comando:

npm i [email protected]

A continuación, tienes que añadir la siguiente línea de código al principio del código de tu aplicación para inicializar el paquete:

require('dotenv').config()

¡Ya está! Ahora los secretos que almacenes en un archivo .env en la raíz de tu proyecto se cargarán en tu objeto process.env en cuanto se inicie la aplicación. Veremos este método en acción más adelante en el siguiente tutorial.

Tutorial de Variable de Entorno

La mejor manera de entender un concepto técnico es verlo en acción. Aquí tienes un rápido tutorial para ayudarte a empezar con las variables de entorno y aprender su uso en detalle.

En la siguiente guía, demostraremos cómo utilizar las variables de entorno a través de las tres formas que hemos mencionado anteriormente: archivos.env, gestores de variables nativos de la plataforma y gestores secretos. Todas estas formas requerirán un paso común, que es configurar un proyecto básico de Node.js.

Primero: Crea un proyecto Node.js

Para empezar, asegúrate de que tienes Node.js instalado en tu sistema. Una vez que lo tengas configurado en tu sistema, tendrás acceso a npm (abreviatura de Node Package Manager). npm te ayuda a instalar paquetes de Node desde el registro global de npm a través de la línea de comandos. Será muy útil para instalar paquetes relacionados con nuestro proyecto de prueba.

A continuación, abre un terminal y crea un nuevo directorio. Inicializa un proyecto Node nuevo en él:

mkdir my-app
cd my-app
npm init

Mantén pulsado enter a través de las preguntas entrantes para aceptar las opciones por defecto. Una vez hecho esto, tu terminal tendrá un aspecto similar al siguiente

Terminal output showing the steps leading to the initialization of a fresh node app.
Creando un nuevo proyecto.

Ahora puedes abrir este proyecto con un IDE como Visual Studio Code o IntelliJ IDEA.

Crea un nuevo archivo en la raíz de la carpeta de tu proyecto y guárdalo con el nombre index.js. Este será el punto de partida de tu aplicación. A continuación, instala Express para crear y probar rápidamente servidores REST:

npm i express

Una vez que tengas instalado Express, pega el siguiente fragmento de código en tu archivo index.js:

const express = require("express")

const app = express()

app.get("/", (req, res) => {
   res.send("Hello world!")
})

app.listen(8080);

Este es un fragmento de inicio para un punto final básico de «Hola Mundo» utilizando Node.js y Express. Ejecuta lo siguiente en tu línea de comandos:

node index.js

Esto iniciará tu aplicación node + express. Si navegas a http://localhost:8080 en tu navegador web, recibirás una salida similar:

The text
¡Hola Mundo!.

Esto indica que has configurado tu aplicación correctamente. El siguiente paso es actualizar tu app para que utilice variables de entorno. Actualiza el código en index.js para que coincida con el siguiente fragmento:

const express = require("express")

const app = express()

app.get("/", (req, res) => {
  
   // the responseMessage object extracts its values from environment variables
   // If a value is not found, it instead stores the string "not found"
   const responseMessage = {
       environment: process.env.environment || "Not found",
       apiBaseUrl: process.env.apiBaseUrl || "Not found"
   }

   res.send(responseMessage)
})

app.listen(8080);

En lugar de enviar un mensaje «¡Hola mundo!» en la respuesta, ahora enviaremos un objeto JSON que contiene dos informaciones:

  • environment: Indica el entorno actual en el que está desplegada la app
  • apiBaseUrl: Lleva la URL base de una hipotética API. Cambiaremos el valor de esta URL en función del entorno en el que se despliegue la app.

En caso de no poder acceder a las variables de entorno, el objeto contendrá «No encontrado» como los valores de las dos claves descritas anteriormente. Antes de seguir adelante, vuelve a ejecutar el comando node index.js y recibirás la siguiente salida:

A JSON object with two keys environment and apiBaseUrl with values
Imprimiendo los valores por defecto de las variables de env.

Esto indica que tu aplicación no puede acceder actualmente a las variables de entorno. Además, ni siquiera hemos definido los valores de estas variables. Veamos las distintas formas disponibles para hacerlo en las siguientes secciones.

Tipo 1: Añadir variables de entorno mediante archivos env

Empecemos por la forma más básica de añadir variables de entorno: los archivos env. En la raíz de tu proyecto, crea un nuevo archivo llamado .env y guarda en él el siguiente código:

environment=DEV
apiBaseUrl=http://dev.myApi.com:8080/v1

A continuación, reinicia tu aplicación ejecutando de nuevo el comando node index.js y comprueba el resultado:

A JSON object with two keys environment and apiBaseUrl with values
Imprimiendo los valores de las variables de env.

Verás que la salida sigue siendo la misma. Esto se debe a que, aunque hayas definido el valor de las variables de entorno, en realidad no has indicado a tu aplicación dónde encontrarlas. Aquí es donde paquetes como dotenv resultan útiles.

Ejecuta el siguiente comando para instalar dotenv:

npm i [email protected]

Para empezar a utilizar dotenv en tu código, añade el siguiente código en la línea número 2 de tu index.js:

require('dotenv').config()

A continuación, reinicia la aplicación y comprueba la salida:

A JSON object with two keys environment and apiBaseUrl with values DEV and http://dev.myApi.com:8080/v1 in each printed on a blank HTML page.
Imprimiendo los nuevos valores de las variables env.

Como puedes ver, ¡los valores de las variables de entorno se han cargado desde tu archivo .env!

Ahora, para animar las cosas, vamos a cambiar el nombre de nuestro archivo .env por .env.dev y a crear otro archivo con el nombre .env.staging. Pega el siguiente fragmento de código en el nuevo archivo:

environment=STAGING
apiBaseUrl=http://staging.myApi.com:3000/v1

Cuando hayas terminado, sustituye la línea número 2 de tu archivo index.js por el siguiente trozo de código:

require('dotenv').config({
   path: "STAGING" === process.env.NODE_ENV?.toUpperCase() ? './.env.staging' : './.env.dev'
})

console.log(process.env.NODE_ENV)

Lo que ha cambiado aquí es que ahora estamos dando instrucciones al paquete dotenv para que obtenga el contenido de las variables de entorno de uno de los dos archivos disponibles en función de otra variable de entorno llamada NODE_ENV. ¿De dónde procede el valor de esta variable de entorno? De tu terminal.

Para probar esta configuración, ejecuta tu aplicación con el siguiente comando:

NODE_ENV=DEV node index.js

Si ahora vas a localhost:8080, verás la siguiente respuesta:

A JSON object with two keys environment and apiBaseUrl with values DEV and http://dev.myApi.com:8080/v1 in each printed on a blank HTML page.
Imprimiendo los valores env para el entorno dev.

Ahora, termina la aplicación que se está ejecutando y ejecútala de nuevo con el siguiente comando:

NODE_ENV=STAGING node index.js

Si te diriges a localhost:8080, obtendrás la siguiente respuesta:

A JSON object with keys environment and apiBaseUrl and values STAGING and http://staging.myApi.com:3000/v1 in each printed on a blank HTML page.
Imprimiendo los valores env para el entorno de staging.

Así es como puedes utilizar los archivos .env para acceder a diferentes conjuntos de variables en función de condiciones externas. La condición externa aquí es la variable de entorno externo NODE_ENV, que es esencialmente una variable de entorno de usuario, mientras que environment y apiBaseUrl eran variables de entorno en tiempo de ejecución. El perfil de usuario que llama proporciona el valor de la variable NODE_ENV y la aplicación lo utiliza para tomar decisiones internas.

En caso de que estés en Windows, puede que tengas dificultades al ejecutar los dos comandos anteriores. El terminal de Windows podría no permitirte asignar variables de entorno de usuario sobre la marcha utilizando la sintaxis KEY=VALUE (a menos que sea Bash en Windows).

Una solución rápida en ese caso es utilizar scripts y cross-env.

Instala cross-env ejecutando el siguiente comando:

npm i --save-dev cross-env

A continuación, ve a tu archivo package.json y actualiza la clave scripts para que coincida con esto:

// …
"scripts": {
   "test": "echo "Error: no test specified" && exit 1",
   "start-dev": "cross-env NODE_ENV=DEV node index.js",
   "start-staging": "cross-env NODE_ENV=STAGING node index.js"
 },
// …

Ahora puedes ejecutar los siguientes comandos para ejecutar tu aplicación con dos conjuntos diferentes de variables de entorno:

npm run start-dev		# to start with dev variables
npm run start-staging		# to start with staging variables

Esta es una solución universal y puedes utilizar estos scripts también en bash/zsh.

A continuación, vamos a ver cómo utilizar un gestor de variables de terceros.

Tipo 2: Usar el gestor de variables de entorno nativo de Heroku

Para poder seguir esta parte del tutorial, necesitarás una cuenta de Heroku. Ve y créala antes de seguir adelante.

Antes de desplegar la aplicación en Heroku, hay algunos cambios que tendrás que hacer en tu código. En primer lugar, añade un nuevo script en tu package.json llamado start:

"scripts": {
   "test": "echo "Error: no test specified" && exit 1",
   "start": "node index.js",
   "start-dev": "cross-env NODE_ENV=DEV node index.js",
   "start-staging": "cross-env NODE_ENV=STAGING node index.js"
 },

Este script será utilizado por Heroku para ejecutar tu aplicación una vez desplegada. Además, ve a la última línea de tu archivo index.js y actualízala con lo siguiente:

app.listen(process.env.PORT || 3000);

Esto asegurará que la aplicación se despliegue en el puerto especificado por Heroku.

A continuación, tienes que instalar la CLI de Heroku localmente para poder acceder a tus aplicaciones de Heroku desde tu línea de comandos. Para este tutorial, puedes utilizar el siguiente comando para instalar la CLI:

npm i -g heroku

Sin embargo, los documentos de Heroku recomiendan instalarla a través de una de las otras formas enumeradas en el enlace mencionado anteriormente para obtener un mejor soporte. Una vez instalado, ejecuta el siguiente comando para iniciar sesión en tu cuenta de Heroku:

heroku login

Una vez hecho esto, ve a dashboard.heroku.com y entra en tu cuenta. A continuación, crea una nueva aplicación haciendo clic en Nuevo > Crear nueva aplicación.

Heroku's dashboard with the new dropdown open showing an option to create a new app.
Creando una nueva app.

En la siguiente página, haz clic en el botón Crear App sin introducir ningún detalle. Esto creará una nueva heroku app para ti con un nombre aleatorio.

A form with a text input to enter the new app's name and choose a region.
Poniendo nombre a tu app.

Este es el aspecto que tendría el panel de control de tu app:

The new app's homepage with instructions to deploy for the first time.
El nuevo panel de control de la aplicación.

Esta página también contiene instrucciones sobre cómo desplegar tu aplicación en Heroku a través de la CLI. Aquí está la lista de comandos que tienes que ejecutar para desplegar tu aplicación en Heroku:

git init
heroku git:remote -a whispering-shelf-49396 # change whispering-shelf-49396 with the name of your app. You can get it in your dashboard
git add index.js package-lock.json package.json # do not push the .env files since we'll provide that via the in-app secrets manager git commit -am "Initial commit" git push heroku main 

Una vez que el despliegue se ha completado con éxito, puedes ver la aplicación desplegada a través del panel de control haciendo clic en el botón Abrir aplicación

Si lo has hecho todo bien, verás la siguiente respuesta:

A JSON object with keys environment and apiBaseUrl and values
Accediendo a tu aplicación desplegada.

¿Por qué ocurre esto, puedes pensar? Es porque aún no hemos proporcionado las variables de entorno a nuestra app de ninguna forma. Si compruebas los comandos que has utilizado para desplegar la aplicación, te darás cuenta de que no hemos enviado los archivos .env a nuestro control de versiones. Tampoco hemos definido el valor NODE_ENV en el script de inicio.

Para inyectar ahora las variables de entorno en tu aplicación, tienes que ir a Configuración > Vars de configuración en tu panel de control de Heroku. Al hacer clic en Reveal Config Vars, verás una pantalla similar:

The new app's settings page showing app information and an empty list of configuration variables.
Accediendo a los vares de configuración de tu app.

Ahora puedes introducir aquí el contenido de tu archivo .env:

The new app's settings page showing app information and a populated list of configuration variables.
Introduciendo tus variables de entorno en Heroku.

Si vuelves y actualizas la URL de tu aplicación, verás que los valores se han actualizado:

A JSON object with keys environment and apiBaseUrl and values PRODUCTION and http://prod.myApi.com/v1 in each printed on a blank HTML page.
La app desplegada en Heroku ya puede acceder a las variables de entorno.

Así es como puedes hacer uso del gestor de secretos de una plataforma de despliegue para gestionar tus variables de entorno. Sin embargo, esto requiere que gestiones manualmente las variables de entorno a través del panel de control de la plataforma. Como puedes ver en el caso de Heroku, no hay ninguna opción para importar un gran volcado de variables de entorno desde un archivo, lo que te obliga a introducirlas una a una. Esto puede resultar bastante molesto a veces.

La siguiente sección presenta un método más eficiente para gestionar los secretos de las aplicaciones: los gestores de secretos.

Tipo 3: Usar Doppler para gestionar las variables de entorno

Los métodos comentados anteriormente no proporcionan uniformidad en todas las plataformas. Por lo general, no dependes de los archivos env al desplegar a producción, y no es posible hacer uso de los gestores de variables nativos de la plataforma cuando se trabaja localmente. Los gestores secretos como Doppler llenan este vacío.

Para probarlo por ti mismo, primero tienes que crear una cuenta gratuita en Doppler.

Una vez hecho, puedes seguir. Lo más probable es que te cree automáticamente un proyecto de ejemplo con el nombre de proyecto-ejemplo. Para simplificar, vamos a dejarlo a un lado y a crear un proyecto nuevo para nuestro caso de uso.

Ve al panel de control y haz clic en el icono del signo más junto a Proyectos.

Doppler's projects section showing one project named example-project.
Tus proyectos en Doppler.

Introduce su nombre como «mi-app» y procede. Este es el aspecto que debería tener el proyecto una vez que esté listo:

A set of environments with empty lists of variables on the app dashboard in Doppler.
Los entornos y variables de tu proyecto.

Haz clic en el elemento de la lista dev config. Haz clic en Añadir Nuevo Secreto y añade dos secretos de la siguiente manera

A populated list of environment variables under the dev environment on Doppler
Añadiendo las variables dev a Doppler.

Haz clic en el botón «Guardar» para guardar los cambios. Ten en cuenta que Doppler no admite el uso de mayúsculas al nombrar tus secretos. Aunque generalmente se prefiere mantener los nombres de los secretos en mayúsculas, el uso de Doppler no te deja otra opción. Para identificar los secretos que se obtienen de Doppler, les hemos puesto el prefijo DP_

Ahora que las variables están creadas y almacenadas en Doppler, vamos a integrarlas en nuestro código. Para ello, tienes que configurar la CLI de Doppler. Aquí tienes un resumen de lo que tienes que hacer.

En primer lugar, instala la CLI localmente siguiendo las instrucciones específicas de tu sistema operativo. A continuación, inicia sesión en la CLI de Doppler con tu cuenta recién creada utilizando el siguiente comando:

doppler login

Una vez iniciada la sesión, ejecuta el siguiente comando para conectarte a tu proyecto Doppler remoto desde tu CLI:

doppler setup

Una vez que te hayas conectado al proyecto correcto, podrás acceder a tus secretos mediante el siguiente comando:

doppler run

Sin embargo, no ejecutaremos este comando directamente. En su lugar, lo añadiremos a uno de nuestros scripts de ejecución para que se ejecute automáticamente cada vez que se inicie la aplicación. Vamos a actualizar el archivo package.json con el nuevo script de ejecución para el entorno dev:

// …
"scripts": {
   "test": "echo "Error: no test specified" && exit 1",
   "start": "node index.js",
   "start-dev": "doppler run -- node index.js", // This has to be updated
   "start-staging": "cross-env NODE_ENV=STAGING node index.js"
 },
// …

Además, recuerda que hemos creado nuevos nombres de variables en Doppler que empiezan por DP_. Así que tendremos que actualizar nuestro archivo index.js para que también muestre esta variable:

const express = require("express")
require('dotenv').config({
   path: "STAGING" === process.env.NODE_ENV?.toUpperCase() ? './.env.staging' : './.env.dev'
})

console.log(process.env.NODE_ENV)

const app = express()

app.get("/", (req, res) => {
  
   // the responseMessage object extracts its values from environment variables
   // If a value is not found, it instead stores the string "not found"
   const responseMessage = {
       environment: process.env.environment || "Not found",
       apiBaseUrl: process.env.apiBaseUrl || "Not found",
       DP_ENVIRONMENT: process.env.DP_ENVIRONMENT || "Not found" // Add the new variable here
   }

   res.send(responseMessage)
})

app.listen(process.env.PORT || 3000);

Para ver las cosas en acción, ejecuta el siguiente comando:

npm run start-dev

Este es el aspecto que debería tener ahora http://localhost:3000:

A JSON object with keys environment, apiBaseUrl, and DP_ENVIRONMENT and values DEV, http://dev.myApi.com:8080/v1, and DOPPLER_DEV in each printed on a blank HTML page.
Accediendo a los secretos de Doppler en una aplicación que se ejecuta localmente.

La tercera variable de la lista (DP_ENVIRONMENT) se obtiene directamente de Doppler.

A continuación, puedes conectar Doppler con tu plataforma de despliegue para acceder a estos secretos a través de tu aplicación desplegada. Para ello, vamos a empezar creando un nuevo entorno en Doppler para un nuevo conjunto de secretos de despliegue.

Vuelve a la página de inicio de tu proyecto my-app. Haz clic en el único elemento de la lista de puesta en escena:

Lists of environment variables under the my-app project with two variables defined under the development environment.
El panel de control de tu aplicación.

Observarás que las dos variables secretas que has definido en el entorno dev ya están disponibles aquí, pero les faltan valores:

Lists of environment variables under the staging environment with missing values.
Las variables de entorno de tu app para el entorno de preparación.

Añade los siguientes valores y haz clic en Guardar:

Populated list of environment variables under the staging environment of your app.
Las variables de entorno de tu aplicación para el entorno de preparación.

Una vez hecho esto, haz clic en la pestaña Integraciones y en Añadir Sincronización en esta página para empezar a conectar con tu plataforma de despliegue. Recibirás una lista de plataformas con las que Doppler puede integrarse:

List of deployment platforms that Doppler can integrate with.
Conectando tu aplicación Doppler a Heroku.

Como nuestra app está desplegada en Heroku, vamos a hacer clic en Heroku. Sigue los pasos que aparecen en pantalla para conectar tu cuenta de Heroku a Doppler y proporcionar los roles de acceso necesarios. Una vez conectada, llegarás a una pantalla similar:

Heroku integration flow with a form on right that asks for project and config details.
Proporciona los detalles de tu aplicación para integrarla con Heroku.

Selecciona el Tipo de Proyecto como App, elige tu app de Heroku en la lista de apps disponibles, elige stg como la Configuración a sincronizar, y No Importar en las Opciones de Importación, ya que no queremos importar ningún secreto de Heroku a Doppler.

Haz clic en Configurar integración cuando hayas terminado. Llegarás a una pantalla similar cuando la integración se realice con éxito:

List of integrated apps in Heroku, with the connect name, environment, destination URL, and status.
Las integraciones de tu aplicación Doppler con Heroku.

Ahora, si compruebas la sección Config Vars en el panel de control de tu app de Heroku, verás que las variables de Doppler se han añadido automáticamente a las config vars de tu despliegue de Heroku:

Populated list of environment variables in the Config Vars section of your Heroku app.
Los secretos de Doppler están ahora sincronizados con Heroku.

También observarás que se han eliminado las dos variables de entorno originales (environment y apiBaseUrl). Esto ha ocurrido porque hemos elegido No Importar en las Opciones de Importación. Puedes seguir adelante y añadirlas de nuevo en Heroku si es necesario.

Mientras la presencia de las nuevas variables de entorno en la sección Config Vars de Heroku demuestra que has configurado con éxito Doppler para gestionar los secretos tanto localmente en tu entorno de desarrollo como en tu entorno de despliegue, puedes seguir adelante y desplegar el código actualizado en Heroku para ver los cambios en la aplicación desplegada. Este es el aspecto que tendrá cuando esté hecho:

A JSON object with keys environment, apiBaseUrl, and DP_ENVIRONMENT and values STAGING, http://staging.myApi.com:3000/v1, and DOPPLER_STAGING in each printed on a blank HTML page.
Accediendo a los secretos de Doppler en una app desplegada en Heroku.

Esto completa el tutorial para configurar variables de entorno en un proyecto Node.js utilizando tres métodos populares. A continuación, vamos a ver algunas formas de asegurar que tus variables de entorno y sus archivos estén seguros mientras se utilizan.

¿Cómo Mantener Seguros los Archivos de las Variables de Entorno?

Aunque las variables de entorno son un recurso útil en las prácticas modernas de DevOps, debes ser consciente de las implicaciones de seguridad que pueden provocar. Aquí tienes algunos consejos que puedes utilizar para mantener tus archivos de variables de entorno seguros y alejados de miradas indiscretas.

Mantén los archivos de entorno fuera del control de versiones

Una de las cosas más importantes que debes tener en cuenta al manejar cualquier secreto es mantenerlos fuera del control de versiones. El control de versiones está pensado únicamente para seguir los cambios en el código fuente de tu aplicación. Todo lo que entra en un sistema de control de versiones permanece en él hasta que se elimina explícitamente, y la mayor parte de tu equipo tiene acceso a estos datos históricos con fines de referencia.

Si has almacenado las claves de tu cubo de almacenamiento de AWS o de un servicio de API de pago en un archivo env para su uso en tu aplicación, no querrás compartirlo con todo tu equipo de desarrollo, a menos que sea necesario que tengan acceso a él. Si tu proyecto es de código abierto en una plataforma como GitHub, añadir archivos env a tu VCS podría significar compartirlo con todo el mundo Los archivos env están pensados para ser almacenados localmente. Puedes proporcionar a cada entorno de despliegue los archivos env pertinentes mediante métodos específicos.

Añade siempre el archivo env a tu archivo .gitignore (suponiendo que utilices git para el control de versiones) o emplea cualquier otra forma para que tu VCS omita los archivos env al realizar los cambios. Puedes considerar añadir un archivo env de plantilla a tu VCS para que cualquier otro miembro del equipo pueda utilizarlo como referencia para crear sus archivos env localmente.

Comprueba el nombre del paquete antes de instalarlo

Dado que normalmente instalas la mayoría de los paquetes desde NPM cuando trabajas con una aplicación Node.js, debes tener especial cuidado al hacerlo. Es bien sabido que cualquiera puede crear y desplegar un paquete NPM. Y tampoco es de extrañar que la gente se equivoque a menudo al escribir el nombre de un paquete que quiere instalar.

Se han observado múltiples casos en los que paquetes maliciosos con nombres similares a algunos paquetes populares han sido instalados accidentalmente por los usuarios debido a errores de escritura. Dichos paquetes están diseñados para obtener acceso a las variables de entorno de tu aplicación y enviarlas por Internet a sus creadores.

La única forma de salvarse es estar alerta cuando se instalen nuevos paquetes desde Internet.

Prefiere los gestores secretos a los archivos env

Con problemas como la filtración accidental al compartir y los errores de formato, los archivos env ciertamente no son la mejor opción disponible para la gestión de secretos. Entra en los gestores secretos. Los gestores de secretos, como Doppler, te permiten aislar completamente los secretos de tu aplicación del código fuente y gestionarlos en una plataforma dedicada.

Puedes conceder a tu equipo acceso a estos secretos directamente en la plataforma, y tu aplicación puede acceder a ellos a través de conexiones encriptadas en Internet. Resuelve todos los problemas asociados a los archivos env, al tiempo que te permite la flexibilidad de mantener conjuntos de secretos basados en los entornos de tu aplicación.

Sin embargo, aquí también hay advertencias. Los gestores de secretos están en una fase muy temprana de su desarrollo tecnológico. Además, los gestores de secretos son plataformas de terceros que están sujetas a su propio conjunto de problemas de seguridad. Por tanto, es importante evaluar y seleccionar cuidadosamente el gestor secreto adecuado. Además, si tu aplicación, su equipo de desarrollo o el número de secretos de la aplicación no es lo suficientemente grande, los gestores secretos podrían ser excesivos para ti.

Tabla de Referencia de las Variables de Entorno

Aquí tienes una rápida hoja de trucos para ayudarte a ponerte al día con las variables de entorno y su uso rápidamente:

Definición de las variables de entorno Variables suministradas a los procesos por sus procesos de llamada
Propósito
  • Almacenar y asegurar los secretos de la app
  • Gestionar los datos de configuración específicos del entorno
Tipos Sólo para Windows:
  • Sistema
  • Usuario
  • Tiempo de ejecución/proceso
Ejemplos populares de uso
  • Claves privadas
  • Nombres de entorno
  • URLs base de la API, etc
¿Cómo implementarlos en tu aplicación?
  • archivos .env
  • Gestores de secretos nativos de la plataforma
  • Servicio de gestión de secretos dedicado

Resumen

Las variables de entorno son importantes para aislar los datos sensibles de tu aplicación. Ayudan a asegurar los secretos de tu aplicación y te permiten cambiar fácilmente entre conjuntos de secretos en función del entorno de la aplicación. Sin embargo, gestionarlas significa otra tarea para tí.

Hay múltiples formas de asegurar y variables de entorno, como hemos comentado anteriormente. Explóralas todas y encuentra la que mejor se adapte y acelere tu proyecto.