chore(): Publish Environment variables made easy #5

Merged
elia merged 1 commit from direnv into main 2025-02-20 20:14:39 +00:00
2 changed files with 277 additions and 0 deletions

View file

@ -5596,6 +5596,144 @@ cannot deny the fact that they are very customisable. If you don't like
something with your keyboard, simply change it. The beauty of it all is that the something with your keyboard, simply change it. The beauty of it all is that the
firmware is open sourced. The community delivers, yet again ! firmware is open sourced. The community delivers, yet again !
*** DONE Environment Variables Made Easy :env:environment_variable:envrc:direnv:dev:developement:
:PROPERTIES:
:EXPORT_HUGO_LASTMOD: 2025-02-20
:EXPORT_DATE: 2025-02-20
:EXPORT_FILE_NAME: environment-variables-made-easy
:CUSTOM_ID: environment-variables-made-easy
:END:
If you've written software in the last decade, then you're probably familiar
with the current technologies at play. You write your code, locally, in your
IDE, build and test it. You've made your /commit/ and pushed it to the revision
control system server and created a /pull request/. Pipelines started, code
built, unit tests ran, magic all over and now it's deployed in /staging/. Once
the code lives in /staging/ long enough to build trust in its performance it
goes to /production/.
This is in a nutshell how it looks like. The big elephant in the room is, of
course, that all of these different environments are, well... different !
This means that the values I used to test my code locally is different than the
values used to test in the pipeline, for security reasons. The same goes for
every single environment. Configuration files could solve a lot of these issues
but, as we all know, they don't solve all of them.
Another solution is to use /environment variables/, which could be easily
injected into scripts, environments and even containers. It's a win-win
everywhere except managing them locally. You're probably thinking my ~.profile~
file looks like a mess. You'd be surprised to know that mine is empty, but how ?
#+hugo: more
**** Direnv
~Direnv~ is [[https://github.com/direnv/direnv][described]] by the developers as
#+begin_quote
an extension for your shell. It augments existing shells with a new feature that
can load and unload environment variables depending on the current directory.
#+end_quote
It's as simple as that !
~Direnv~ runs on most /operating systems/ and a wide variety of /shells/. The
[[https://direnv.net/docs/installation.html][installation]] process is well documented and the same goes for configuring
~direnv~ to [[https://direnv.net/docs/hook.html][hook]] to your favorite /shell/.
**** How does it work ?
First, let's start by creating a /new/ project.
#+begin_src shell
$ mkdir project-1
$ cd project-1
#+end_src
Now that we've created a project, let's create a ~.envrc~ file and populate it
with the following.
#+begin_src bash
# Add build/bin to $PATH
PATH_add build/bin
# Export environment variables
export DB_HOST="localhost"
export DB_PORT="5432"
export DB_USERNAME="dummy-user"
export DB_PASSWORD="super-secret"
#+end_src
Once I save the file and exit the editor, I get greeted with a /lovely/ *error*.
#+begin_src shell
direnv: error ~/project-1/.envrc is blocked. Run `direnv allow` to approve its content
#+end_src
The reason for this is very simple. The ~.envrc~ file can do a lot, making it a
security risk. This error is there to make sure that you check the ~.envrc~ and
*only* allow ~direnv~ with /trusted/ ~.envrc~ files.
I wrote this ~.envrc~ file, so I can safely trust it. But you can't !
#+begin_src shell
$ direnv allow
direnv: loading ~/project-1/.envrc
direnv: export +DB_HOST +DB_PASSWORD +DB_PORT +DB_USERNAME ~PATH
#+end_src
This tells us that we've exported a list of environment variables. Let's check
them out.
#+begin_src shell
$ env | grep DB_
DB_PORT=5432
DB_HOST=localhost
DB_PASSWORD=super-secret
DB_USERNAME=dummy-user
#+end_src
We've also used the =PATH_add= to add a project specific directory to our =PATH=
allowing us to run the binaries directly without having to navigate to the
/build/ directory.
#+BEGIN_EXPORT html
<div class="admonition warning">
<p class="admonition-title"><b>Warning</b></p>
#+END_EXPORT
It is very important, at this stage, for me to *warn* you about the dangers of
committing your ~.envrc~ to your /revision control/. This bad boy's got
/passwords/ in it ! Don't do it !
#+BEGIN_EXPORT html
</div>
#+END_EXPORT
That's impressive and all but...
I know what you're gonna ask me next and here's the answer.
#+begin_src shell
$ cd ..
direnv: unloading
#+end_src
and now...
#+begin_src shell
$ env | grep DB_
$
#+end_src
Nothing at all. All variables have been unloaded automatically. They will be
loaded again the next time you navigate to the project's directory.
**** Conclusion
Next time you're working on your project, give ~direnv~ a try. It will change
the way you work for the better, I hope.
Happy Hacking !
** Monitoring :@monitoring: ** Monitoring :@monitoring:
*** DONE Simple cron monitoring with HealthChecks :healthchecks:cron: *** DONE Simple cron monitoring with HealthChecks :healthchecks:cron:
:PROPERTIES: :PROPERTIES:

View file

@ -0,0 +1,139 @@
+++
title = "Environment Variables Made Easy"
author = ["Elia el Lazkani"]
date = 2025-02-20
lastmod = 2025-02-20
tags = ["env", "environment-variable", "envrc", "direnv", "dev", "developement"]
categories = ["misc"]
draft = false
+++
If you've written software in the last decade, then you're probably familiar
with the current technologies at play. You write your code, locally, in your
IDE, build and test it. You've made your _commit_ and pushed it to the revision
control system server and created a _pull request_. Pipelines started, code
built, unit tests ran, magic all over and now it's deployed in _staging_. Once
the code lives in _staging_ long enough to build trust in its performance it
goes to _production_.
This is in a nutshell how it looks like. The big elephant in the room is, of
course, that all of these different environments are, well... different !
This means that the values I used to test my code locally is different than the
values used to test in the pipeline, for security reasons. The same goes for
every single environment. Configuration files could solve a lot of these issues
but, as we all know, they don't solve all of them.
Another solution is to use _environment variables_, which could be easily
injected into scripts, environments and even containers. It's a win-win
everywhere except managing them locally. You're probably thinking my `.profile`
file looks like a mess. You'd be surprised to know that mine is empty, but how ?
<!--more-->
## Direnv {#direnv}
`Direnv` is [described](https://github.com/direnv/direnv) by the developers as
> an extension for your shell. It augments existing shells with a new feature that
> can load and unload environment variables depending on the current directory.
It's as simple as that !
`Direnv` runs on most _operating systems_ and a wide variety of _shells_. The
[installation](https://direnv.net/docs/installation.html) process is well documented and the same goes for configuring
`direnv` to [hook](https://direnv.net/docs/hook.html) to your favorite _shell_.
## How does it work ? {#how-does-it-work}
First, let's start by creating a _new_ project.
```shell
$ mkdir project-1
$ cd project-1
```
Now that we've created a project, let's create a `.envrc` file and populate it
with the following.
```bash
# Add build/bin to $PATH
PATH_add build/bin
# Export environment variables
export DB_HOST="localhost"
export DB_PORT="5432"
export DB_USERNAME="dummy-user"
export DB_PASSWORD="super-secret"
```
Once I save the file and exit the editor, I get greeted with a _lovely_ **error**.
```shell
direnv: error ~/project-1/.envrc is blocked. Run `direnv allow` to approve its content
```
The reason for this is very simple. The `.envrc` file can do a lot, making it a
security risk. This error is there to make sure that you check the `.envrc` and
**only** allow `direnv` with _trusted_ `.envrc` files.
I wrote this `.envrc` file, so I can safely trust it. But you can't !
```shell
$ direnv allow
direnv: loading ~/project-1/.envrc
direnv: export +DB_HOST +DB_PASSWORD +DB_PORT +DB_USERNAME ~PATH
```
This tells us that we've exported a list of environment variables. Let's check
them out.
```shell
$ env | grep DB_
DB_PORT=5432
DB_HOST=localhost
DB_PASSWORD=super-secret
DB_USERNAME=dummy-user
```
We've also used the `PATH_add` to add a project specific directory to our `PATH`
allowing us to run the binaries directly without having to navigate to the
_build_ directory.
<div class="admonition warning">
<p class="admonition-title"><b>Warning</b></p>
It is very important, at this stage, for me to **warn** you about the dangers of
committing your `.envrc` to your _revision control_. This bad boy's got
_passwords_ in it ! Don't do it !
</div>
That's impressive and all but...
I know what you're gonna ask me next and here's the answer.
```shell
$ cd ..
direnv: unloading
```
and now...
```shell
$ env | grep DB_
$
```
Nothing at all. All variables have been unloaded automatically. They will be
loaded again the next time you navigate to the project's directory.
## Conclusion {#conclusion}
Next time you're working on your project, give `direnv` a try. It will change
the way you work for the better, I hope.
Happy Hacking !