https://d226lax1qjow5r.cloudfront.net/blog/blogposts/working-with-environment-variables-in-ruby/environment-variables_ruby.png

Travailler avec des variables d'environnement en Ruby

Publié le November 14, 2023

Temps de lecture : 10 minutes

Lorsqu'ils travaillent sur des applications web, les développeurs doivent gérer un grand nombre de pièces mobiles différentes. La plupart du temps, nous ne nous arrêtons pas vraiment pour réfléchir à la nature de ces différents éléments et à leur fonctionnement exact. Dans cet article, nous allons explorer une seule de ces parties : les variables d'environnement.

Si vous avez déjà construit et déployé une application web en Ruby, vous avez probablement utilisé des variables d'environnement. Si cette application a été construite avec Ruby on Rails, alors vous aurez eu besoin de mettre RAILS_ENV à 'production' au cours du processus de déploiement. Si l'application intégrait des services externes ou des API, vous aurez probablement utilisé des variables d'environnement pour gérer les identifiants de ces services.

Mais qu'est-ce que sont variables d'environnement, pourquoi sont-elles utiles, et comment les utiliser lors du développement et du déploiement d'applications Ruby ?

Que sont les variables d'environnement ?

Comme leur nom l'indique, les variables d'environnement sont des variables qui stockent des informations sur l'environnement dans lequel notre application fonctionne. Vous êtes probablement déjà familiarisé avec le concept de variables et leur fonctionnement, alors regardons de plus près la deuxième partie : environnement.

Dans ce contexte, l'environnement peut faire référence au système d'exploitation sur lequel votre programme s'exécute, mais aussi au processus ou aux processus utilisés pour exécuter le programme. Cela peut devenir un peu plus clair si nous examinons quelques exemples.

Lorsque vous ouvrez une fenêtre de terminal sur votre ordinateur, vous lancez un processus Shell. Un Shell est essentiellement un programme qui vous permet d'interagir avec votre système en traitant les commandes émises via le Shell et en affichant le résultat. Par exemple, lorsque vous démarrez une application Rails sur votre machine locale, vous lancez une commande comme rails s et vous obtiendrez un résultat semblable à celui-ci :

=> Booting Puma
=> Rails 7.0.4.3 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.5 (ruby 3.0.0-p0) ("Birdie's Version")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 126917
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop

Ce processus, le Shell, connaît des choses sur l'environnement dans lequel il est exécuté, et il stocke ces choses dans des variables. Les processus héritent d'une copie des variables d'environnement de leur processus parent, de sorte que le Shell possède une copie des variables d'environnement du système d'exploitation (ou plus précisément du noyau). De même, tout processus exécuté dans le Shell héritera d'une copie des variables d'environnement de ce Shell.

Accès aux variables d'environnement

Sur les systèmes basés sur UNIX (par exemple Linux et OSX), vous pouvez accéder à toutes les variables d'environnement du Shell en utilisant la commande env pour accéder à toutes les variables d'environnement de l'interpréteur de commandes. Windows dispose d'une commande équivalente set mais, dans le cadre de cet article, nous ne parlerons que des commandes utilisées sur les systèmes UNIX.

Si vous souhaitez imprimer une variable d'environnement spécifique, vous pouvez utiliser la commande printenv pour imprimer une variable d'environnement spécifique. Par exemple, si je veux vérifier la langue que j'ai définie sur mon système, je peux lancer la commande printenv suivie du nom de la variable d'environnement qui contient ces données, dans ce cas-ci LANG. La commande affichera la langue, qui est, sur mon système, la suivante en_GB.UTF-8:

$ printenv LANG
en_GB.UTF-8

Un exemple plus centré sur Ruby serait RUBY_VERSION:

$ printenv RUBY_VERSION
ruby-3.2.2

Si vous deviez exécuter un processus Ruby à partir de votre Shell, il s'agit de la version de Ruby que le processus utiliserait. Si vous avez installé un gestionnaire de version de Ruby, tel que chruby, rbenvou rvmessayez d'exécuter la commande printenv RUBY_VERSION puis de changer votre version de Ruby avec votre gestionnaire de version et d'exécuter à nouveau la commande printenv RUBY_VERSION à nouveau. Vous devriez voir la version de Ruby que vous venez de changer.

En parlant de processus Ruby, nous pouvons accéder aux variables d'environnement à partir d'un programme Ruby via l'objet Ruby ENV de Ruby. Comme l'indique la documentation Ruby explique :

ENV est un accesseur de type hash pour les variables d'environnement.

La classe ENV possède plusieurs méthodes différentes qui vous permettent d'interagir avec les valeurs stockées dans un objet. ENV dans un objet. Dans le cadre de cet article, nous ne nous intéresserons qu'à l'accès aux valeurs en utilisant la notation entre crochets, mais n'hésitez pas à explorer le reste des fonctionnalités décrites dans la documentation Ruby.

Nous pouvons accéder à la valeur d'une variable d'environnement via ENV grâce à la notation entre crochets, de la même manière que nous accéderions aux valeurs d'un Ruby Hash, en utilisant le nom de la variable d'environnement comme clé.

ENV['RUBY_VERSION'] # => ruby-3.2.2

Notez que le nom de la variable, RUBY_VERSIONen tant que chaîne de caractères dans les ENV en tant que chaîne de caractères.

Testons cela dans notre Shell :

$ printenv RUBY_VERSION
ruby-3.2.2
$ ruby -e "puts ENV['RUBY_VERSION']"
ruby-3.2.2

Dans l'exemple ci-dessus, nous utilisons d'abord la commande printenv pour afficher la valeur de la variable d'environnement du Shell, qui est RUBY_VERSION du Shell, qui est ruby-3.2.2. Nous invoquons ensuite la commande ruby avec l'option -e . Celle-ci indique à l'interpréteur Ruby de ne pas exécuter la chaîne de caractères que nous lui transmettons en tant que code Ruby. Ce code Ruby produit la valeur associée à l'objet ENV de l'objet RUBY_VERSION de l'objet. Comme nous pouvons le voir, la valeur de 'RUBY_VERSION' à l'intérieur du processus Ruby est la même que la valeur de RUBY_VERSION à l'intérieur du processus Shell parent.

Définition des variables d'environnement

Jusqu'à présent, nous n'avons exploré que la manière d'accéder aux variables d'environnement existantes. Elles deviennent encore plus utiles lorsque vous commencez à définir les vôtres.

Dans un shell UNIX, les variables d'environnement peuvent être définies à l'aide de la commande export combinée à la syntaxe d'affectation :

$ export FOO=bar
$ printenv FOO
bar

Comme pour les variables d'environnement préexistantes, celles que vous créez au sein d'un processus sont également héritées par les processus enfants. Une fois de plus, nous pouvons tester cela au sein d'un processus Ruby.

$ export FOO=bar
$ printenv FOO
bar
$ ruby -e "puts ENV['FOO']"
bar

Il est important de noter que les processus frères conservent leurs propres copies des variables d'environnement au lieu de les partager. Si vous ouvrez une deuxième fenêtre de terminal et que vous exécutez printenv FOOrien ne sort.

Dans le même ordre d'idées, les variables d'environnement créées au sein d'un processus meurent avec ce processus. Par exemple, si vous exécutez export FOO=barferme la fenêtre du terminal, puis ouvre une nouvelle fenêtre de terminal et exécute printenv FOOrien ne sort.

Pourquoi utiliser des variables d'environnement ?

L'une des principales utilisations des variables d'environnement consiste à définir des données de configuration lors du développement ou du déploiement d'une application. Un exemple courant est la définition des informations d'identification de l'API lors de l'utilisation d'un service externe tel que l'API de API de Vonage Communications.

Supposons, par exemple, que vous ayez un fichier Ruby appelé send_sms.rb. Le code de ce fichier envoie un SMS via l'API Vonage SMS API de Vonage en utilisant le SDK Ruby de Vonage. Pour authentifier votre demande à l'API SMS de Vonage, vous devez instancier un objet Vonage::Client avec un objet api_key et api_secret.

client = Vonage::Client.new(api_key: 'abc123', api_secret: 'ab1CDef2GhIjkLmn')

client.sms.send(from: 'Ruby', to: '447700900000', text: 'Hello world')

En règle générale, il n'est pas souhaitable de coder en dur ces identifiants dans votre code source. Vous allez probablement soumettre ce code à un service de contrôle de version comme GitHub ; même si le dépôt n'est pas public, ce n'est pas vraiment une bonne idée d'exposer vos identifiants d'API dans votre historique Git. En outre, il se peut que vous utilisiez des identifiants d'API différents en développement et en production (et éventuellement dans d'autres environnements, tels que staging ou QA). Les variables d'environnement peuvent être mises à jour entre les déploiements sans avoir à modifier le code source.

Dans le contexte d'une application Ruby, c'est ici que nous pouvons tirer parti de l'objet Ruby ENV de Ruby. Notre code mis à jour send_sms.rb pourrait ressembler à ceci :

client = Vonage::Client.new(api_key: ENV['VONAGE_API_KEY'], api_secret: ENV['VONAGE_API_SECRET'])

client.sms.send(from: 'Ruby', to: '447700900000', text: 'Hello world')

Vous pouvez alors utiliser export pour définir VONAGE_API_KEY et VONAGE_API_SECRET comme variables d'environnement :

$ export VONAGE_API_KEY=abc123 VONAGE_API_SECRET=ab1CDef2GhIjkLmn

Lorsque vous exécutez ensuite le fichier send_sms.rb l'objet ENV dans le processus Ruby qui exécute le code aura accès aux variables d'environnement que vous avez définies.

$ ruby send_sms.rb

Par ailleurs, si vous ne passez pas les paramètres api_key et api_secret à Vonage::Client.newle SDK Ruby de Vonage vérifiera automatiquement l'objet ENV pour les variables d'environnement nommées VONAGE_API_KEY et VONAGE_API_SECRET. Tant que ces variables d'environnement sont définies lors de l'utilisation des API de Vonage qui nécessitent une clé et un secret d'API pour l'authentification, vous pouvez instancier l'objet Vonage::Client comme suit :

client = Vonage::Client.new

Vous voulez voir cela en action dans une application Rails ? Consultez notre tutoriel sur l'envoi de SMS avec Ruby on Rails en utilisant des variables d'environnement pour les identifiants Vonage.

Comment utiliser les variables d'environnement

Dans les exemples précédents, vous avez utilisé export pour définir vos variables d'environnement. Faire cela à chaque fois que vous exécutez un processus Ruby dans un nouveau Shell ou un nouvel environnement peut devenir un peu laborieux, surtout si vous avez un grand nombre de variables d'environnement à définir. Heureusement, il existe d'autres solutions pour le développement et la production.

En cours de développement

Une option intéressante en matière de développement est la dotenv bibliothèque. Il s'agit d'un RubyGem que vous pouvez inclure dans votre fichier Gemfile ou l'installer localement. Pour l'utiliser, vous devez créer un fichier .env à la racine de votre projet Ruby. Dans ce fichier, vous définissez les variables d'environnement dont votre application a besoin sous forme de paires clé-valeur.

VONAGE_API_KEY=abc123
VONAGE_API_SECRET=ab1CDef2GhIjkLmn

Dans votre application Ruby, vous pouvez alors require la gem et appeler la méthode load sur la classe Dotenv et appeler la méthode sur la classe Cela charge toutes les variables d'environnement définies dans votre fichier .env dans l'objet ENV pour le processus Ruby en cours.

require 'dotenv'
Dotenv.load

client = Vonage::Client.new(api_key: ENV['VONAGE_API_KEY'], api_secret: ENV['VONAGE_API_SECRET'])

client.sms.send(from: 'Ruby', to: '447700900000', text: 'Hello world')

Il existe également une dotenv-rails gem incluse dans la bibliothèque, qui est spécifiquement destinée aux applications Rails. L'utilisation est légèrement différente de la dotenv standard, mais le concept est le même.

La bibliothèque possède d'autres fonctionnalités, que je n'aborderai pas ici, mais que vous pouvez découvrir dans la documentation.

Un dernier point : que l'on utilise dotenv ou dotenv-rails vous devez toujours vous assurer que vous ajoutez votre fichier .env à .gitignore afin qu'il ne soit pas archivé dans votre dépôt Git.

Si vous construisez une application Rails qui a besoin de tester des webhooks, vous voudrez probablement utiliser ngrok avec dotenv. Consultez notre Guide d'installation de Rails + ngrok pour une description complète.

En production

Bien que, d'après la documentation, vous puissiez pouvez utiliser dotenv en productiond'autres outils et options sont mieux adaptés à la gestion des variables d'environnement en production.

  • Outils de gestion de la configuration tels que Chef, Puppetet Ansible sont des options puissantes et complètes. Ces outils sont probablement mieux adaptés au travail à grande échelle, mais ils sont sans doute excessifs pour les petits projets si tout ce que vous voulez faire est de définir quelques variables d'environnement.

  • Une solution de conteneurisation comme Docker fournit une manière spécifique de gérer les variables d'environnement pour les données sensibles telles que les clés d'API.

  • Si vous utilisez un service tel que Render ou Heroku pour déployer et héberger vos applications Ruby, vous pouvez généralement définir vos variables d'environnement sous forme de paires clé-valeur dans l'interface utilisateur fournie par le service, que ce soit pour une seule application ou un groupe d'applications (voir la capture d'écran ci-dessous). Certaines variables d'environnement couramment utilisées peuvent même être définies pour vous ; par exemple, Render définit automatiquement RAILS_ENV à production pour les applications Ruby.

Screenshot of the Render Dashboard for adding environment variables, showing a form with 'key' and 'value' fieldsRender Environment Variable form

Une brève note sur les informations d'identification de Rails

Si vous travaillez spécifiquement avec Rails, une alternative à l'utilisation de variables d'environnement est d'utiliser Rails Credentialsmais c'est un sujet pour un autre article de blog !

Conclusion

C'est tout pour l'instant ! J'espère que vous avez trouvé cet article intéressant et instructif.

Si vous êtes prêt à voir les variables d'environnement alimenter une véritable expérience de messagerie, consultez ce tutoriel sur l'envoi de réponses suggérées RCS avec Ruby on Rails. Il montre comment combiner la configuration de l'environnement, Rails et l'API Messages API de Vonage dans un cas d'utilisation pratique.

Vous avez une question ou souhaitez partager ce que vous construisez ?

Restez connecté et tenez-vous au courant des dernières nouvelles, astuces et événements concernant les développeurs.

Partager:

https://a.storyblok.com/f/270183/373x376/e8d3211236/karl-lingiah.png
Karl LingiahDéveloppeur Ruby Advocate

Karl est un défenseur des développeurs pour Vonage, qui se concentre sur la maintenance de nos SDK de serveur Ruby et sur l'amélioration de l'expérience des développeurs pour notre communauté. Il aime apprendre, fabriquer des objets, partager ses connaissances et tout ce qui a trait à la technologie du web.