All Projects → Nebo15 → Confex

Nebo15 / Confex

Licence: mit
Useful helper to read and use application configuration from environment variables.

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Confex

ngx-env
Easily inject environment variables into your Angular applications
Stars: ✭ 73 (-73.16%)
Mutual labels:  system, configuration, environment-variables
parse it
A python library for parsing multiple types of config files, envvars & command line arguments that takes the headache out of setting app configurations.
Stars: ✭ 86 (-68.38%)
Mutual labels:  package, configuration, environment-variables
rbmq
Simple API for spawning RabbitMQ Producers and Consumers.
Stars: ✭ 20 (-92.65%)
Mutual labels:  hex, package
laravel-conditional-providers
THIS PACKAGE HAS BEEN DEPRECATED — Load Laravel service providers and facades based on the current environment.
Stars: ✭ 26 (-90.44%)
Mutual labels:  package, configuration
goodconf
Transparently load variables from environment or JSON/YAML file.
Stars: ✭ 80 (-70.59%)
Mutual labels:  configuration, environment-variables
envkey-python
EnvKey's python library. Protect API keys and credentials. Keep configuration in sync.
Stars: ✭ 24 (-91.18%)
Mutual labels:  configuration, environment-variables
shd
Show pretty HDD/SSD list
Stars: ✭ 37 (-86.4%)
Mutual labels:  system, management
arkenv
Type-safe Kotlin configuration by delegates
Stars: ✭ 15 (-94.49%)
Mutual labels:  configuration, environment-variables
sccm
Microsoft System Center Configuration Manager
Stars: ✭ 21 (-92.28%)
Mutual labels:  system, configuration
HotelManagementSystem
Hotel Management System created with Restify and Angular 9
Stars: ✭ 23 (-91.54%)
Mutual labels:  system, management
gconfigs
gConfigs - Config and Secret parser
Stars: ✭ 42 (-84.56%)
Mutual labels:  configuration, environment-variables
climatecontrol
Python library for loading settings and config data from files and environment variables
Stars: ✭ 20 (-92.65%)
Mutual labels:  configuration, environment-variables
dart environment config
Environment specific config generator for Dart and Flutter applications during CI/CD builds
Stars: ✭ 87 (-68.01%)
Mutual labels:  configuration, environment-variables
envkey-ruby
EnvKey's official Ruby client library
Stars: ✭ 24 (-91.18%)
Mutual labels:  configuration, environment-variables
superconfig
Access environment variables. Also includes presence validation, type coercion and default values.
Stars: ✭ 33 (-87.87%)
Mutual labels:  configuration, environment-variables
paerser
No description or website provided.
Stars: ✭ 38 (-86.03%)
Mutual labels:  configuration, environment-variables
read-env
🔧 Transform environment variables into JSON object with sanitized values.
Stars: ✭ 60 (-77.94%)
Mutual labels:  configuration, environment-variables
core
Liman Core allows you to centrally manage all servers in your IT processes remotely, with stable and secure. You can improve the features with expandable extensions and modules.
Stars: ✭ 35 (-87.13%)
Mutual labels:  system, management
flagga
An extensible Go library for handling program configuration using flags.
Stars: ✭ 28 (-89.71%)
Mutual labels:  configuration, environment-variables
env
A lightweight package for loading OS environment variables into structs for Go projects
Stars: ✭ 24 (-91.18%)
Mutual labels:  configuration, environment-variables

Confex

Inline docs Hex.pm Downloads Latest Version License Build Status Coverage Status Ebert

Confex simplifies reading configuration at run-time with adapter-based system for fetch values from any source. It's inspired by Phoenix {:system, value} definition for HTTP port and have no external dependencies.

Installation

It's available on hex.pm and can be installed as project dependency:

  1. Add confex to your list of dependencies in mix.exs:

    def deps do
      [{:confex, "~> 3.5.0"}]
    end
    
  2. Ensure confex is started before your application either by adding it to applications list as shown below or by making sure you use extra_applications option instead of applications (this feature is available since Elixir 1.4 and enabled by default for new projects):

    def application do
      [applications: [:confex]]
    end
    

Usage

  1. Replace values with configuration tuples

    Define configuration in your config.exs:

    config :my_app, MyApp.MyQueue,
      queue: [
        name:        {:system, "OUT_QUEUE_NAME", "MyQueueOut"},
        error_name:  {:system, "OUT_ERROR_QUEUE_NAME", "MyQueueOut.Errors"},
        routing_key: {:system, "OUT_ROUTING_KEY", ""},
        durable:     {:system, "OUT_DURABLE", false},
        port:        {:system, :integer, "OUT_PORT", 1234},
      ]
    

    Configuration tuples examples:

    • var - any bare values will be left as-is.
    • {:system, "ENV_NAME", "default"} - read string from system environment or fallback to "default" if it is not set.
    • {:system, "ENV_NAME"} - same as above, but raise error if ENV_NAME is not set.

    Additionally you can cast string values to common types:

    • {:system, :string, "ENV_NAME", "default"} (string is a default type).
    • {:system, :string, "ENV_NAME"}.
    • {:system, :integer, "ENV_NAME", 123}.
    • {:system, :integer, "ENV_NAME"}.
    • {:system, :float, "ENV_NAME", 123.5}.
    • {:system, :float, "ENV_NAME"}.
    • {:system, :boolean, "ENV_NAME", true}.
    • {:system, :boolean, "ENV_NAME"}.
    • {:system, :atom, "ENV_NAME"}.
    • {:system, :atom, "ENV_NAME", :default}.
    • {:system, :module, "ENV_NAME"}.
    • {:system, :module, "ENV_NAME", MyDefault}.
    • {:system, :list, "ENV_NAME"}.
    • {:system, :list, "ENV_NAME", ["a", "b", "c"]}.
    • {:system, :charlist, "ENV_NAME"}.
    • {:system, :charlist, "ENV_NAME", 'default'}.

    :system can be replaced with a {:via, adapter} tuple, where adapter is a module that implements Confex.Adapter behaviour.

    Type can be replaced with {module, function, arguments} tuple, in this case Confex will use external function to resolve the type. Function must returns either {:ok, value} or {:error, reason :: String.t} tuple.

  2. Read configuration by replacing Application.fetch_env/2, Application.fetch_env!/2 and Application.get_env/3 calls with Confex functions

    Fetch string values:

    iex> Confex.fetch_env(:myapp, MyKey)
    {:ok, "abc"}
    

    Fetch integer values:

    iex> Confex.fetch_env(:myapp, MyIntKey)
    {:ok, 123}
    

    Fetch configuration from maps or keywords:

    iex> Confex.fetch_env(:myapp, MyIntKey)
    {:ok, [a: 123, b: "abc"]}
    

Integrating with Ecto

Ecto.Repo has a init/2 callback, you can use it with Confex to read environment variables. We used to have all our repos to look like this:

defmodule MyApp do
  use Ecto.Repo, otp_app: :my_app

  @doc """
  Dynamically loads the repository configuration from the environment variables.
  """
  def init(_, config) do
    url = System.get_env("DATABASE_URL")
    config = if url, do: [url: url] ++ config, else: Confex.Resolver.resolve!(config)

    unless config[:database] do
      raise "Set DB_NAME environment variable!"
    end

    {:ok, config}
  end
end

Integrating with Phoenix

Same for Phoenix, use init/2 callback of Phoenix.Endpoint:

defmodule MyApp.Web.Endpoint do

  # Some code here

  @doc """
  Dynamically loads configuration from the system environment
  on startup.

  It receives the endpoint configuration from the config files
  and must return the updated configuration.
  """
  def init(_type, config) do
    {:ok, config} = Confex.Resolver.resolve(config)

    unless config[:secret_key_base] do
      raise "Set SECRET_KEY environment variable!"
    end

    {:ok, config}
  end
end

Populating configuration at start-time

In case you want to keep using Application.get_env/2 and other methods to keep accessing configuration, you can resolve it one-time when application is started:

defmodule MyApp do
  use Application

  def start(_type, _args) do
    # Replace Application environment with resolved values
    Confex.resolve_env!(:my_app)

    # ...
  end
end

However, don't drink too much Kool-Aid. Direct calls to the Confex are more explicit and should be default way to go, you don't want your colleagues to waste their time finding out how that resolved value got into the configuration, right?

Using Confex macros

Confex is supplied with helper macros that allow to attach configuration to specific modules of your application.

defmodule Connection do
  use Confex, otp_app: :myapp
end

It will add config/0 function to Connection module that reads configuration at run-time for :myapp OTP application with key Connection.

You can add defaults by extending macro options:

defmodule Connection do
  use Confex,
    otp_app: :myapp,
    some_value: {:system, "ENV_NAME", "this_will_be_default value"}
end

If application environment contains values in Keyword or Map structs, default values will be recursively merged with application configuration.

We recommend to avoid using tuples without default values in this case, since config/0 calls will raise exceptions if they are not resolved.

You can validate configuration by overriding validate_config!/1 function, which will receive configuration and must return it back to caller function. It will be evaluated each time config/1 is called.

defmodule Connection do
  use Confex, otp_app: :myapp

  def validate_config!(config) do
    unless config[:password] do
      raise "Password is not set!"
    end

    config
  end
end

Adapters

Currently Confex supports two embedded adapters:

  • :system - read configuration from system environment;
  • :system_file - read file path from system environment and read configuration from this file. Useful when you want to resolve Docker, Swarm or Kubernetes secrets that are stored in files.

You can create adapter by implementing Confex.Adapter behaviour with your own logic.

Helpful links

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].