marinakr
Vault configuration best practice
Hi Friends,
I am about using libvault to read DATABASE_URL and other secrets.
I m going to use Vault.Auth.Kubernetes
I am not sure I am following mix release guide and ConfigProvider
Should I define a module VaultConfigProvider with codes like
def init(vault_config) when is_list(vault_config) do
vault_config
end
def load(config, vault_config) do
# We need to start any app we may depend on.
{:ok, _} = Application.ensure_all_started(:jason)
{:ok, vault} =
Vault.new(
engine: Vault.Engine.KVV2,
auth: Vault.Auth.Kubernetes,
http: Vault.HTTP.Tesla,
host: host
)
|> Vault.auth(%{role: role, jwt: jwt})
{:ok,
%{
"SECRET_KEY_BASE" => "..",
"DATABASE_URL" => "ecto://dbhost:5432/.."
} = json} = Vault.read(vault, "myapp/env")
Config.Reader.merge(
config,
my_app: [
some_value: json["DATABASE_URL"],
another_value: json["DATABASE_URL"],
]
)
and then remove all lines that get system env from releases.exs?
Is there the easiest way to get the vault secrets?
Where is the best place to define vault_config_provider.ex?
Marked As Solved
marinakr
So I decided to use runtime. exs in mix release
config/runtime.exs now looks like:
import Config
if config_env() == :prod do
{:ok, _} = Application.ensure_all_started(:jason)
{:ok, _} = Application.ensure_all_started(:hackney)
jwt =
System.get_env("JWT_TOKEN_PATH")
|> Kernel.||("/var/run/secrets/kubernetes.io/serviceaccount/token")
|> File.read!()
vault_host = System.fetch_env!("VAULT_ADDR")
vault_k8s_role = System.fetch_env!("VAULT_K8S_ROLE")
vault_prefix = System.fetch_env!("VAULT_PREFIX")
vault_env_path = System.get_env("VAULT_ENV_PATH") || "secrets"
{:ok, vault} =
Vault.new(
engine: Vault.Engine.KVV2,
auth: Vault.Auth.Kubernetes,
http: Vault.HTTP.Tesla,
host: vault_host
)
|> Vault.auth(%{role: vault_k8s_role, jwt: jwt})
{:ok, vault_secrets} = Vault.read(vault, "#{vault_prefix}/#{vault_env_path}")
################################################################################
## Release Config (with Vault secrets)
################################################################################
config :myapp, MS.Repo,
# ssl: true,
url: Map.fetch!(vault_secrets, "DATABASE_URL"),
pool_size: String.to_integer(vault_secrets["POOL_SIZE"]) || 10
...
end
and to include runtime.exs on release start runtime_config_path should be added to mix.exs:
releases: [
myapp_web: [
runtime_config_path: "config/runtime.exs",
version: "0.0.1",
applications: [
myapp_web: :permanent
...
So no additional config readers were used
Last Post!
Aktaeon
Thank you for sharing the code Marina. I think it mostly similar to what I had in mind when I asked the question and likely will fallback on this definitely a good answer.
I have rewritten my solution as a configprovider with the idea of using an agent for vault to do later dynamic secrets and updates of tokens, but I am seeing the currently my configprovider is not starting with a simple iex -S mix phx.server only when doing a full release.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










