Contents
Background
The FunWithFlags library for Elixir makes it easy to manage feature flags. On a recent project, we needed to set flags in a development environment via environment variables.
Here is an easy way to do that using environment variables.
Create an Initializer
This initializer does a few things:
- Loads the flag definitions from
config/flags.exs
- Loads any env variables that match our flag’s with a predefined pattern
- If a matching var is found and corresponds to a boolean flag, it sets the flag to the value of the environment variable.
This is a simple implementation that only allows setting boolean flags.
Here’s an example initializer:
defmodule MyApp.FlagInitializer do
require Logger
def init do
{:ok, all_flags} = FunWithFlags.all_flags()
Enum.each(all_flags, &update_flag_from_env/1)
end
defp update_flag_from_env(%FunWithFlags.Flag{name: flag_name, gates: gates}) do
if has_boolean_gate?(gates) do
env_var_name = flag_name
|> to_string()
|> String.upcase()
|> then(&("FEATURE_FLAG_" <> &1))
case System.get_env(env_var_name) do
"true" -> update_flag(flag_name, true)
"false" -> update_flag(flag_name, false)
nil -> :ok
_ -> Logger.warning("FEATURE FLAG: #{flag_name} Invalid value set")
end
else
:ok
end
end
defp has_boolean_gate?(gates) do
Enum.any?(gates, &match?(%FunWithFlags.Gate{type: :boolean}, &1))
end
defp update_flag(flag_name, true) do
{:ok, _} = FunWithFlags.enable(flag_name)
Logger.info("FEATURE FLAG: #{flag_name} Enabled")
end
defp update_flag(flag_name, false) do
{:ok, _} = FunWithFlags.disable(flag_name)
Logger.info("FEATURE FLAG: #{flag_name} Disabled")
end
end
Add to Your Application
You can add this initializer to your application by adding the following to your application.ex
file:
#Application
def start(_type, _args) do
# ...
# ...
# ...
result = Supervisor.start_link(children, opts)
MyApp.FlagInitializer.init()
result
end
Of course, there are alternatives to this initializer, but this is a simple approach to set the flags.
Setting Flags
Now, you can set the flag in your environment:
FEATURE_FLAG_MY_FLAG=true