chore(): Publish Environment variables made easy #5
2 changed files with 277 additions and 0 deletions
|
@ -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:
|
||||||
|
|
139
content/posts/environment-variables-made-easy.md
Normal file
139
content/posts/environment-variables-made-easy.md
Normal 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 !
|
Loading…
Add table
Reference in a new issue