XUtils

ex_aws

AWS client, supporting Dynamo, Kinesis, Lambda, SQS, and S3.


ExAws

GitHub Workflow Status hex.pm hex.pm hex.pm hexdocs.pm github.com

A flexible easy to use set of AWS APIs.

Available Services: https://github.com/ex-aws?q=service&type=&language=

Getting Started

ExAws v2.0 breaks out every service into its own package. To use the S3 service, you need both the core :ex_aws package as well as the :ex_aws_s3 package.

As with all ExAws services, you’ll need a compatible HTTP client (defaults to :hackney) and whatever JSON or XML codecs needed by the services you want to use. Consult individual service documentation for details on what each service needs.

defp deps do
  [
    {:ex_aws, "~> 2.1"},
    {:ex_aws_s3, "~> 2.0"},
    {:hackney, "~> 1.9"},
    {:sweet_xml, "~> 0.6"},
  ]
end

With these deps you can use ExAws precisely as you’re used to:

# make a request (with the default region)
ExAws.S3.list_objects("my-bucket") |> ExAws.request()

# or specify the region
ExAws.S3.list_objects("my-bucket") |> ExAws.request(region: "us-west-1")

#### Session token configuration

Alternatively, you can also provide `AWS_SESSION_TOKEN` to `security_token` to authenticate
with session token:

```elixir
config :ex_aws,
  access_key_id: {:system, "AWS_ACCESS_KEY_ID"},
  security_token: {:system, "AWS_SESSION_TOKEN"},
  secret_access_key: {:system, "AWS_SECRET_ACCESS_KEY"}

Hackney configuration

ExAws by default uses hackney to make HTTP requests to AWS API. You can modify the options as such:

config :ex_aws, :hackney_opts,
  follow_redirect: true,
  recv_timeout: 30_000

AWS Region Configuration.

You can set the region used by default for requests.

config :ex_aws,
  region: "us-west-2",

Alternatively, the region can be set in an environment variable:

config :ex_aws,
  region: {:system, "AWS_REGION"}

JSON Codec Configuration

The default JSON codec is Jason. You can choose a different one:

config :ex_aws,
  json_codec: Poison

Path Normalization

Paths that include multiple consecutive /’s will by default be normalized to a single slash. There are cases when paths need to be literal (S3) and this normalization behaviour can be turned off via configuration:

config :ex_aws,
  normalize_path: false

Examples

Redshift DescribeClusters

action = :describe_clusters
action_string = action |> Atom.to_string |> Macro.camelize

operation =
  %ExAws.Operation.Query{
    path: "/",
    params: %{"Action" => action_string},
    service: :redshift,
    action: action
  }

ExAws.request(operation)

ECS RunTask

data = %{
  taskDefinition: "hello_world",
  launchType: "FARGATE",
  networkConfiguration: %{
    awsvpcConfiguration: %{
      subnets: ["subnet-1a2b3c4d", "subnet-4d3c2b1a"],
      securityGroups: ["sg-1a2b3c4d"],
      assignPublicIp: "ENABLED"
    }
  }
}

operation =
  %ExAws.Operation.JSON{
    http_method: :post,
    headers: [
      {"x-amz-target", "AmazonEC2ContainerServiceV20141113.RunTask"},
      {"content-type", "application/x-amz-json-1.1"}
    ],
    path: "/",
    data: data,
    service: :ecs
}

ExAws.request(operation)

Highlighted Features

  • Easy configuration.
  • Minimal dependencies. Choose your favorite JSON codec and HTTP client.
  • Elixir streams to automatically retrieve paginated resources.
  • Elixir protocols allow easy customization of Dynamo encoding / decoding.
  • Simple. ExAws aims to provide a clear and consistent elixir wrapping around AWS APIs, not abstract them away entirely. For every action in a given AWS API there is a corresponding function within the appropriate module. Higher level abstractions like the aforementioned streams are in addition to and not instead of basic API calls.

That’s it!

Retries

ExAws will retry failed AWS API requests using exponential backoff per the “Full Jitter” formula described in https://www.awsarchitectureblog.com/2015/03/backoff.html

The algorithm uses three values, which are configurable:

# default values shown below

config :ex_aws, :retries,
  max_attempts: 10,
  base_backoff_in_ms: 10,
  max_backoff_in_ms: 10_000
  • max_attempts is the maximum number of possible attempts with backoffs in between each one
  • base_backoff_in_ms corresponds to the base value described in the blog post
  • max_backoff_in_ms corresponds to the cap value described in the blog post

Testing

If you want to run mix test, you’ll need to have a local dynamodb running on port 8000:

docker run --rm -d -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -port 8000

For more info please see Setting up DynamoDB Local.

The redirect test will intentionally cause a warning to be issued.


Articles

  • coming soon...