amazonka-1.0.0: Comprehensive Amazon Web Services SDK

Copyright(c) 2013-2015 Brendan Hay
LicenseMozilla Public License, v. 2.0.
MaintainerBrendan Hay <brendan.g.hay@gmail.com>
Stabilityprovisional
Portabilitynon-portable (GHC extensions)
Safe HaskellNone
LanguageHaskell2010

Control.Monad.Trans.AWS

Contents

Description

The AWST transformer provides the environment required to perform AWS operations and constructs a Command AST using FreeT which can then be interpreted using runAWST. The transformer is intended to be used directly or embedded as a layer within a transformer stack.

Network.AWS contains a IO specialised version of AWST with a typeclass to assist in automatically lifting operations.

Synopsis

Running AWS Actions

data AWST m a Source

The AWST transformer.

runAWST :: (MonadCatch m, MonadResource m, HasEnv r) => r -> AWST m a -> m a Source

Run an AWST action with the specified HasEnv environment. Any outstanding HTTP responses' ResumableSource will be closed when the ResourceT computation is unwrapped with runResourceT.

Throws Error during interpretation of the underlying FreeT Command AST.

See: runResourceT.

execAWST Source

Arguments

:: (MonadCatch m, MonadResource m, HasEnv r) 
=> (forall a. Either Error a -> m a)

Lift an Error into the base Monad.

-> r 
-> AWST m b 
-> m b 

Run an AWST action with configurable Error handling.

Does not explictly throw Errors and instead uses the supplied lift function.

Authentication and Environment

newEnv Source

Arguments

:: (Applicative m, MonadIO m, MonadCatch m) 
=> Region

Initial region to operate in.

-> Credentials

Credential discovery mechanism.

-> m Env 

Creates a new environment with a new Manager without debug logging and uses getAuth to expand/discover the supplied Credentials. Lenses from HasEnv can be used to further configure the resulting Env.

Throws AuthError when environment variables or IAM profiles cannot be read.

See: newEnvWith.

data Env Source

The environment containing the parameters required to make AWS requests.

Instances

class HasEnv a where Source

Minimal complete definition

environment

Methods

environment :: Lens' a Env Source

envRegion :: Lens' a Region Source

The current region.

envLogger :: Lens' a Logger Source

The function used to output log messages.

envRetryCheck :: Lens' a (Int -> HttpException -> IO Bool) Source

The function used to determine if an HttpException should be retried.

envRetryPolicy :: Lens' a (Maybe RetryPolicy) Source

The RetryPolicy used to determine backoff/on and retry delay/growth.

envTimeout :: Lens' a (Maybe Seconds) Source

A HTTP response timeout override to apply. This defaults to Nothing, and the timeout selection is outlined below.

Timeouts are chosen by considering:

envManager :: Lens' a Manager Source

The Manager used to create and manage open HTTP connections.

envAuth :: Lens' a Auth Source

The credentials used to sign requests for authentication with AWS.

envEC2 :: Getter a (IORef (Maybe Bool)) Source

A memoised predicate for whether the underlying host is an EC2 instance.

Instances

Credential Discovery

data Credentials Source

Determines how AuthN/AuthZ information is retrieved.

Constructors

FromKeys AccessKey SecretKey

Explicit access and secret keys. See fromKeys.

FromSession AccessKey SecretKey SessionToken

Explicit access key, secret key and a session token. See fromSession.

FromEnv Text Text (Maybe Text)

Lookup specific environment variables for access key, secret key, and an optional session token respectively.

FromProfile Text

An IAM Profile name to lookup from the local EC2 instance-data. ^ Environment variables to lookup for the access key, secret key and optional session token.

FromFile Text FilePath

A credentials profile name (the INI section) and the path to the AWS credentials file.

Discover

Attempt to credentials discovery via the following steps:

  • Read the envAccessKey and envSecretKey from the environment if they are set.
  • Read the credentials file if credFile exists.
  • Retrieve the first available IAM profile if running on EC2.

An attempt is made to resolve http://instance-data rather than directly retrieving http://169.254.169.254 for IAM profile information. This assists in ensuring the DNS lookup terminates promptly if not running on EC2.

AuthN/AuthZ information is handled similarly to other AWS SDKs. You can read some of the options available here.

When running on an EC2 instance and using FromProfile or Discover, a thread is forked which transparently handles the expiry and subsequent refresh of IAM profile information. See fromProfileName for more information.

Supported Regions

data Region :: *

The sum of available AWS regions.

Constructors

Ireland

Europe / eu-west-1

Frankfurt

Europe / eu-central-1

Tokyo

Asia Pacific / ap-northeast-1

Singapore

Asia Pacific / ap-southeast-1

Sydney

Asia Pacific / ap-southeast-2

Beijing

China / cn-north-1

NorthVirginia

US / us-east-1

NorthCalifornia

US / us-west-1

Oregon

US / us-west-2

GovCloud

AWS GovCloud / us-gov-west-1

GovCloudFIPS

AWS GovCloud (FIPS 140-2) S3 Only / fips-us-gov-west-1

SaoPaulo

South America / sa-east-1

Instances

Eq Region 
Data Region 
Ord Region 
Read Region 
Show Region 
Generic Region 
Hashable Region 
ToLog Region 
FromXML Region 
ToXML Region 
ToByteString Region 
FromText Region 
ToText Region 
Typeable * Region 
type Rep Region = D1 D1Region ((:+:) ((:+:) ((:+:) (C1 C1_0Region U1) ((:+:) (C1 C1_1Region U1) (C1 C1_2Region U1))) ((:+:) (C1 C1_3Region U1) ((:+:) (C1 C1_4Region U1) (C1 C1_5Region U1)))) ((:+:) ((:+:) (C1 C1_6Region U1) ((:+:) (C1 C1_7Region U1) (C1 C1_8Region U1))) ((:+:) (C1 C1_9Region U1) ((:+:) (C1 C1_10Region U1) (C1 C1_11Region U1))))) 

Sending Requests

To send a request you need to create a value of the desired operation type using the relevant constructor, as well as any further modifications of default/optional parameters using the appropriate lenses. This value can then be sent using send or paginate and the library will take care of serialisation/authentication and so forth.

The default Service configuration for a request (or the supplied Service configuration when using the *With variants) contains retry configuration that is used to determine if a request can safely be retried and what kind of back off/on strategy should be used. (Usually exponential.) Typically services define retry strategies that handle throttling, general server errors and transport errors. Streaming requests are never retried.

send :: (MonadFree Command m, AWSRequest a) => a -> m (Rs a) Source

Send a request, returning the associated response if successful.

See: sendWith

Pagination

Some AWS operations return results that are incomplete and require subsequent requests in order to obtain the entire result set. The process of sending subsequent requests to continue where a previous request left off is called pagination. For example, the ListObjects operation of Amazon S3 returns up to 1000 objects at a time, and you must send subsequent requests with the appropriate Marker in order to retrieve the next page of results.

Operations that have an AWSPager instance can transparently perform subsequent requests, correctly setting Markers and other request facets to iterate through the entire result set of a truncated API operation. Operations which support this have an additional note in the documentation.

Many operations have the ability to filter results on the server side. See the individual operation parameters for details.

paginate :: (MonadFree Command m, AWSPager a) => a -> Source m (Rs a) Source

Repeatedly send a request, automatically setting markers and paginating over multiple responses while available.

See: paginateWith

Waiters

Waiters poll by repeatedly sending a request until some remote success condition configured by the Wait specification is fulfilled. The Wait specification determines how many attempts should be made, in addition to delay and retry strategies. Error conditions that are not handled by the Wait configuration will be thrown, or the first successful response that fulfills the success condition will be returned.

Wait specifications can be found under the Network.AWS.{ServiceName}.Waiters namespace for services which support await.

await :: (MonadFree Command m, AWSRequest a) => Wait a -> a -> m (Rs a) Source

Poll the API with the supplied request until a specific Wait condition is fulfilled.

See: awaitWith

Overriding Service Configuration

When a request is sent, various configuration values such as the endpoint, retry strategy, timeout and error handlers are taken from the associated Service configuration.

You can override the default configuration for a series of one or more actions by using within, once and timeout, or by using the *With suffixed functions on an individual request basis below.

Scoped Actions

within :: (MonadReader r m, HasEnv r) => Region -> m a -> m a Source

Scope an action within the specific Region.

once :: (MonadReader r m, HasEnv r) => m a -> m a Source

Scope an action such that any retry logic for the Service is ignored and any requests will at most be sent once.

timeout :: (MonadReader r m, HasEnv r) => Seconds -> m a -> m a Source

Scope an action such that any HTTP response will use this timeout value.

Per Request

sendWith Source

Arguments

:: (MonadFree Command m, AWSSigner (Sg s), AWSRequest a) 
=> (Service (Sv a) -> Service s)

Modify the default service configuration.

-> a

Request.

-> m (Rs a) 

A variant of send that allows modifying the default Service definition used to configure the request.

paginateWith Source

Arguments

:: (MonadFree Command m, AWSSigner (Sg s), AWSPager a) 
=> (Service (Sv a) -> Service s)

Modify the default service configuration.

-> a

Initial request.

-> Source m (Rs a) 

A variant of paginate that allows modifying the default Service definition used to configure the request.

awaitWith Source

Arguments

:: (MonadFree Command m, AWSSigner (Sg s), AWSRequest a) 
=> (Service (Sv a) -> Service s)

Modify the default service configuration.

-> Wait a

Polling, error and acceptance criteria.

-> a

Request to poll with.

-> m (Rs a) 

A variant of await that allows modifying the default Service definition used to configure the request.

presignWith Source

Arguments

:: (MonadFree Command m, AWSPresigner (Sg s), AWSRequest a) 
=> (Service (Sv a) -> Service s)

Function to modify the service configuration.

-> UTCTime

Signing time.

-> Seconds

Expiry time.

-> a

Request to presign.

-> m ClientRequest 

A variant of presign that allows specifying the Service definition used to configure the request.

Streaming

Streaming request bodies (such as PutObject) require a precomputed SHA256 for signing purposes. The ToBody typeclass has instances available to construct a RqBody, automatically calculating the hash as needed for types such as Text and ByteString.

For reading files and handles, functions such sourceFileIO or sourceHandle can be used. For responses that contain streaming bodies (such as GetObject), you can use sinkBody to connect the response body to a conduit compatible sink.

Request Bodies

class ToBody a where

Anything that can be safely converted to a RqBody.

Methods

toBody :: a -> RqBody

Convert a value to a request body.

sourceBody :: Digest SHA256 -> Int64 -> Source (ResourceT IO) ByteString -> RqBody Source

Construct a RqBody from a source, manually specifying the SHA256 hash and file size.

sourceHandle :: Digest SHA256 -> Int64 -> Handle -> RqBody Source

Construct a RqBody from a Handle, manually specifying the SHA256 hash and file size.

sourceFile :: Digest SHA256 -> Int64 -> FilePath -> RqBody Source

Construct a RqBody from a FilePath, manually specifying the SHA256 hash and file size.

sourceFileIO :: MonadIO m => FilePath -> m RqBody Source

Construct a RqBody from a FilePath, calculating the SHA256 hash and file size.

Note: While this function will perform in constant space, it will enumerate the entirety of the file contents _twice_. Firstly to calculate the SHA256 and lastly to stream the contents to the socket during sending.

Response Bodies

sinkBody :: MonadResource m => RsBody -> Sink ByteString m a -> m a Source

Connect a Sink to a reponse body.

File Size and MD5/SHA256

getFileSize :: MonadIO m => FilePath -> m Int64 Source

Convenience function for obtaining the size of a file.

Presigning Requests

Presigning requires the Service signer to be an instance of AWSPresigner. Not all signing algorithms support this.

presignURL Source

Arguments

:: (MonadFree Command m, AWSPresigner (Sg (Sv a)), AWSRequest a) 
=> UTCTime

Signing time.

-> Seconds

Expiry time.

-> a

Request to presign.

-> m ByteString 

Presign an URL that is valid from the specified time until the number of seconds expiry has elapsed.

See: presign, presignWith

presign Source

Arguments

:: (MonadFree Command m, AWSPresigner (Sg (Sv a)), AWSRequest a) 
=> UTCTime

Signing time.

-> Seconds

Expiry time.

-> a

Request to presign.

-> m ClientRequest 

Presign an HTTP request that is valid from the specified time until the number of seconds expiry has elapsed.

See: presignWith

EC2 Instance Metadata

Metadata can be retrieved from the underlying host assuming that you're running the code on an EC2 instance or have a compatible instance-data endpoint available.

isEC2 :: MonadFree Command m => m Bool Source

Test whether the underlying host is running on EC2. For IO based interpretations of FreeT Command, this is memoised and any external check occurs for the first call only.

dynamic :: MonadFree Command m => Dynamic -> m ByteString Source

Retrieve the specified Dynamic data.

metadata :: MonadFree Command m => Metadata -> m ByteString Source

Retrieve the specified Metadata.

userdata :: MonadFree Command m => m (Maybe ByteString) Source

Retrieve the user data. Returns Nothing if no user data is assigned to the instance.

data Dynamic Source

Constructors

FWS

Value showing whether the customer has enabled detailed one-minute monitoring in CloudWatch.

Valid values: enabled | disabled.

Document

JSON containing instance attributes, such as instance-id, private IP address, etc.

PKCS7

Used to verify the document's authenticity and content against the signature.

Signature 

data Metadata Source

Constructors

AMIId

The AMI ID used to launch the instance.

AMILaunchIndex

If you started more than one instance at the same time, this value indicates the order in which the instance was launched. The value of the first instance launched is 0.

AMIManifestPath

The path to the AMI's manifest file in Amazon S3. If you used an Amazon EBS-backed AMI to launch the instance, the returned result is unknown.

AncestorAMIIds

The AMI IDs of any instances that were rebundled to create this AMI. This value will only exist if the AMI manifest file contained an ancestor-amis key.

BlockDevice !Mapping

See: Mapping

Hostname

The private hostname of the instance. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0).

IAM !Info

See: Info

InstanceAction

Notifies the instance that it should reboot in preparation for bundling. Valid values: none | shutdown | bundle-pending.

InstanceId

The ID of this instance.

InstanceType

The type of instance.

See: InstanceType

KernelId

The ID of the kernel launched with this instance, if applicable.

LocalHostname

The private DNS hostname of the instance. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0).

LocalIPV4

The private IP address of the instance. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0).

MAC

The instance's media access control (MAC) address. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0).

Network !Text !Interface

See: Interface

AvailabilityZone

The Availability Zone in which the instance launched.

ProductCodes

Product codes associated with the instance, if any.

PublicHostname

The instance's public DNS. If the instance is in a VPC, this category is only returned if the enableDnsHostnames attribute is set to true. For more information, see Using DNS with Your VPC.

PublicIPV4

The public IP address. If an Elastic IP address is associated with the instance, the value returned is the Elastic IP address.

OpenSSHKey

Public key. Only available if supplied at instance launch time.

RAMDiskId

The ID of the RAM disk specified at launch time, if applicable.

ReservationId

ID of the reservation.

SecurityGroups

The names of the security groups applied to the instance.

Running Asynchronous Actions

Requests can be sent asynchronously, but due to guarantees about resource closure require the use of lifted-async.

The following example demonstrates retrieving two objects from S3 concurrently:

import Control.Concurrent.Async.Lifted
import Control.Lens
import Control.Monad.Trans.AWS
import Network.AWS.S3

do x   <- async . send $ getObject "bucket" "prefix/object-foo"
   y   <- async . send $ getObject "bucket" "prefix/object-bar"
   foo <- wait x
   bar <- wait y
   ...

See: Control.Concurrent.Async.Lifted

Handling Errors

Errors are thrown by the library using MonadThrow (unless Control.Monad.Error.AWS is used). Sub-errors of the canonical Error type can be caught using trying or catching and the appropriate AsError Prism:

trying _Error          (send $ ListObjects "bucket-name") :: Either Error          ListObjectsResponse
trying _TransportError (send $ ListObjects "bucket-name") :: Either HttpException  ListObjectsResponse
trying _SerializeError (send $ ListObjects "bucket-name") :: Either SerializeError ListObjectsResponse
trying _ServiceError   (send $ ListObjects "bucket-name") :: Either ServiceError   ListObjectsResponse

Many of the individual amazonka-* libraries export compatible Getters for matching service specific error codes and messages in the style above. See the Error Matchers heading in each respective library for details.

class AsError a where

Minimal complete definition

_Error

Methods

_Error :: Prism' a Error

A general Amazonka error.

_TransportError :: Prism' a HttpException

An error occured while communicating over HTTP with a remote service.

_SerializeError :: Prism' a SerializeError

A serialisation error occured when attempting to deserialise a response.

_ServiceError :: Prism' a ServiceError

A service specific error returned by the remote service.

class AsAuthError a where Source

Minimal complete definition

_AuthError

Methods

_AuthError :: Prism' a AuthError Source

A general authentication error.

_RetrievalError :: Prism' a HttpException Source

An error occured while communicating over HTTP with the local metadata endpoint.

_MissingEnvError :: Prism' a Text Source

An error occured looking up a named environment variable.

_MissingFileError :: Prism' a FilePath Source

The specified credentials file could not be found.

_InvalidFileError :: Prism' a Text Source

An error occured parsing the credentials file.

_InvalidIAMError :: Prism' a Text Source

The specified IAM profile could not be found or deserialised.

trying :: MonadCatch m => Getting (First a) SomeException a -> m r -> m (Either a r)

A variant of try that takes a Prism (or any Fold) to select which exceptions are caught (c.f. tryJust, catchJust). If the Exception does not match the predicate, it is re-thrown.

trying :: MonadCatch m => Prism'     SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Lens'      SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Traversal' SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Iso'       SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Getter     SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Fold       SomeException a -> m r -> m (Either a r)

catching :: MonadCatch m => Getting (First a) SomeException a -> m r -> (a -> m r) -> m r

Catch exceptions that match a given Prism (or any Fold, really).

>>> catching _AssertionFailed (assert False (return "uncaught")) $ \ _ -> return "caught"
"caught"
catching :: MonadCatch m => Prism' SomeException a     -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Lens' SomeException a      -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Traversal' SomeException a -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Iso' SomeException a       -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Getter SomeException a     -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Fold SomeException a       -> m r -> (a -> m r) -> m r

Logging

The exposed logging interface is a primitive Logger function which gets threaded through service calls and serialisation routines. This allows the library to output useful information and diagnostics.

The newLogger function can be used to construct a simple logger which writes output to a Handle, but in most production code you should probably consider using a more robust logging library such as tiny-log or fast-logger.

type Logger = LogLevel -> Builder -> IO ()

A function threaded through various request and serialisation routines to log informational and debug messages.

data LogLevel :: *

Constructors

Error

Error messages only.

Info

Info messages supplied by the user - this level is not emitted by the library.

Debug

Useful debug information + info + error levels.

Trace

Includes potentially sensitive signing metadata, and non-streaming response bodies.

Constructing a Logger

newLogger :: MonadIO m => LogLevel -> Handle -> m Logger Source

This is a primitive logger which can be used to log builds to a Handle.

Note: A more sophisticated logging library such as tinylog or fast-logger should be used in production code.

Re-exported Types

data RqBody :: *

An opaque request body containing a SHA256 hash.

data RsBody :: *

A streaming, exception safe response body.

Instances

runResourceT

runResourceT :: MonadBaseControl IO m => ResourceT m a -> m a

Unwrap a ResourceT transformer, and call all registered release actions.

Note that there is some reference counting involved due to resourceForkIO. If multiple threads are sharing the same collection of resources, only the last call to runResourceT will deallocate the resources.

Since 0.3.0