Skip to content

Commit

Permalink
Swap default for fail if unavailable
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Nov 14, 2023
1 parent e4ab33c commit a8e72f7
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 42 deletions.
70 changes: 36 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,46 @@ aws_credentials
This is a library to retrieve AWS credentials from a variety of possible
sources in the following default order:

1. Erlang environment variables
1. Erlang application environment variables
2. OS environment variables
3. An AWS [credentials file][1]
4. ECS task credentials
5. EC2 metadata

Usage
-----
Include the library in your rebar.config file, and then...

```erlang
{ok, _} = application:ensure_all_started(aws_credentials),
Credentials = aws_credentials:get_credentials().
```

Credentials is either `undefined`, if no credentials are available,
or a map of the shape:

```erlang
#{
provider_source => Provider :: atom(),
access_key_id => AccessKey :: binary(),
secret_access_key => SecretKey :: binary(),
token => Token :: binary(),
region => Region :: binary()
}
```

Not all providers will populate all map keys.

If no credentials are found, the library will attempt to fetch them
again in 5 seconds. If you'd prefer for the application to not boot at all
without credentials, you can set `fail_if_unavailable` environment variable
for `aws_credentials` to true.

It is best practice to **not** cache these credentials inside of your own
application. Always use the aws_credentials library to retrieve them - this way
you will always get "fresh" credentials from the internal state of the
application.

Dependencies
------------
This library depends on the following libraries:
Expand All @@ -33,18 +67,6 @@ the module name to the default list of modules to attempt.
### Provider return values ###
Providers are expected to return either `{error, Reason :: term()}` or
`{ok, Credentials :: map(), Expiration :: infinity | binary() | pos_integer()}`.
The Credentials map typically looks like the following:

```erlang
#{
provider_source => Provider :: atom(),
access_key_id => AccessKey :: binary(),
secret_access_key => SecretKey :: binary(),
token => Token :: binary(),
region => Region :: binary()
}
```
Not all providers will populate all map keys.

The expiration time from a provider can either be expressed as:
* the atom `infinity`,
Expand All @@ -59,34 +81,14 @@ credential's expiration time. 5 minutes before expiration time the gen_server
will attempt to acquire new credentials, so credentials will automatically be
refreshed in the background.

Usage
-----
Include the library in your rebar.config file, and then...

```erlang
{ok, _} = application:ensure_all_started(aws_credentials),
Credentials = aws_credentials:get_credentials(),
```

By default if the library is unable to obtain credentials, it will fail to
start with a `bad_match` exception, however if you set `fail_if_unavailable`
to `false` then the library will ignore the exception and attempt to
fetch credentials again after 5 seconds.

It is best practice to **not** cache these credentials inside of your own
application. Always use the aws_credentials library to retrieve them - this way
you will always get "fresh" credentials from the internal state of the
application.

### Choosing certain credentials providers ###

If you want to change the order of providers used to retrieve credentials, you
can change the list of modules in your erlang environment variables as in
this example:

```erlang
{aws_credentials, [{credential_providers, [aws_credentials_ecs]}]
},
{aws_credentials, [{credential_providers, [aws_credentials_ecs]}]}.
```

Different credential providers may have other settings which you can use to
Expand Down
14 changes: 6 additions & 8 deletions src/aws_credentials.erl
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
%% @doc This is the main interface to the library. It provides a function
%% `get_credentials/0' which should return `{ok, Credentials :: map()}' of
%% credentials. If you set `fail_if_unavailable' to `false' in the Erlang
%% environment then the application will return `{ok, unavailable}' and attempt
%% to get credentials again after 5 seconds delay.
%% `get_credentials/0' which should return `Credentials :: map()' or `undefined`.
%% If undefined, it will attempt to get credentials again after 5 seconds delay.
%% @end
-module(aws_credentials).
-behaviour(gen_server).
Expand Down Expand Up @@ -97,21 +95,21 @@ stop() ->
gen_server:stop(?MODULE).

%% @doc Get cached credential information.
-spec get_credentials() -> credentials().
-spec get_credentials() -> credentials() | undefined.
get_credentials() ->
gen_server:call(?MODULE, get_credentials).

%% @doc Force a credentials update (using the application environment
%% options if any).
-spec force_credentials_refresh() -> credentials() | {error, any()}.
-spec force_credentials_refresh() -> credentials() | undefined | {error, any()}.
force_credentials_refresh() ->
ProviderOptions = application:get_env(aws_credentials, provider_options, #{}),
force_credentials_refresh(ProviderOptions).

%% @doc Force a credentials update, passing options (which possibly override
%% the options set in the erlang environment.)
-spec force_credentials_refresh(aws_credentials_provider:options()) ->
credentials() | {error, any()}.
credentials() | undefined | {error, any()}.
force_credentials_refresh(Options) ->
gen_server:call(?MODULE, {force_refresh, Options}).

Expand Down Expand Up @@ -180,7 +178,7 @@ log_error(String, Args, Metadata) ->
-spec fetch_credentials(aws_credentials_provider:options()) ->
{ok, credentials() | 'undefined', reference() | 'undefined'}.
fetch_credentials(Options) ->
ShouldCatch = not application:get_env(aws_credentials, fail_if_unavailable, true),
ShouldCatch = not application:get_env(aws_credentials, fail_if_unavailable, false),
try aws_credentials_provider:fetch(Options) of
{ok, Credentials, ExpirationTime} ->
Tref = setup_update_callback(ExpirationTime),
Expand Down

0 comments on commit a8e72f7

Please sign in to comment.