diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+# Amazon CloudWatch Logs SDK
+
+> _Warning:_ This is an experimental preview release which is still under heavy development and not intended for public consumption, _caveat emptor_!
+
+* [description](#description)
+* [Contribute](#contribute)
+* [Licence](#licence)
+
+## Description
+
+Amazon CloudWatch Logs enables you to monitor, store, and access your system, application, and custom log files.
+
+Documentation is available via [Hackage](http://hackage.haskell.org/package/amazonka-cloudwatch-logs)
+and [AWS API Reference](http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/Welcome.html).
+
+
+## Contribute
+
+For any problems, comments, or feedback please create an issue [here on GitHub](https://github.com/brendanhay/amazonka/issues).
+
+> _Note:_ this library is an auto-generated Haskell package. Please see `amazonka-gen` for more information.
+
+
+## Licence
+
+`amazonka-cloudwatch-logs` is released under the [Mozilla Public License Version 2.0](http://www.mozilla.org/MPL/).
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/amazonka-cloudwatch-logs.cabal b/amazonka-cloudwatch-logs.cabal
new file mode 100644
--- /dev/null
+++ b/amazonka-cloudwatch-logs.cabal
@@ -0,0 +1,56 @@
+name:                  amazonka-cloudwatch-logs
+version:               0.0.0
+synopsis:              Amazon CloudWatch Logs SDK.
+homepage:              https://github.com/brendanhay/amazonka
+license:               OtherLicense
+license-file:          LICENSE
+author:                Brendan Hay
+maintainer:            Brendan Hay <brendan.g.hay@gmail.com>
+copyright:             Copyright (c) 2013-2014 Brendan Hay
+category:              Network, AWS, Cloud
+build-type:            Simple
+extra-source-files:    README.md
+cabal-version:         >= 1.10
+
+description:
+    Amazon CloudWatch Logs enables you to monitor, store, and access your
+    system, application, and custom log files.
+    .
+    /See:/ <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/Welcome.html AWS API Reference>
+    .
+    /Warning:/ This is an experimental preview release which is still under
+    heavy development and not intended for public consumption, caveat emptor!
+
+source-repository head
+    type:     git
+    location: git://github.com/brendanhay/amazonka.git
+
+library
+    default-language:  Haskell2010
+    hs-source-dirs:    src gen
+
+    ghc-options:       -Wall
+
+    exposed-modules:
+          Network.AWS.CloudWatchLogs
+        , Network.AWS.CloudWatchLogs.CreateLogGroup
+        , Network.AWS.CloudWatchLogs.CreateLogStream
+        , Network.AWS.CloudWatchLogs.DeleteLogGroup
+        , Network.AWS.CloudWatchLogs.DeleteLogStream
+        , Network.AWS.CloudWatchLogs.DeleteMetricFilter
+        , Network.AWS.CloudWatchLogs.DeleteRetentionPolicy
+        , Network.AWS.CloudWatchLogs.DescribeLogGroups
+        , Network.AWS.CloudWatchLogs.DescribeLogStreams
+        , Network.AWS.CloudWatchLogs.DescribeMetricFilters
+        , Network.AWS.CloudWatchLogs.GetLogEvents
+        , Network.AWS.CloudWatchLogs.PutLogEvents
+        , Network.AWS.CloudWatchLogs.PutMetricFilter
+        , Network.AWS.CloudWatchLogs.PutRetentionPolicy
+        , Network.AWS.CloudWatchLogs.TestMetricFilter
+        , Network.AWS.CloudWatchLogs.Types
+
+    other-modules:
+
+    build-depends:
+          amazonka-core
+        , base          >= 4.7 && < 5
diff --git a/gen/Network/AWS/CloudWatchLogs.hs b/gen/Network/AWS/CloudWatchLogs.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs.hs
@@ -0,0 +1,45 @@
+-- Module      : Network.AWS.CloudWatchLogs
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Amazon CloudWatch Logs enables you to monitor, store, and access your
+-- system, application, and custom log files.
+module Network.AWS.CloudWatchLogs
+    ( module Network.AWS.CloudWatchLogs.CreateLogGroup
+    , module Network.AWS.CloudWatchLogs.CreateLogStream
+    , module Network.AWS.CloudWatchLogs.DeleteLogGroup
+    , module Network.AWS.CloudWatchLogs.DeleteLogStream
+    , module Network.AWS.CloudWatchLogs.DeleteMetricFilter
+    , module Network.AWS.CloudWatchLogs.DeleteRetentionPolicy
+    , module Network.AWS.CloudWatchLogs.DescribeLogGroups
+    , module Network.AWS.CloudWatchLogs.DescribeLogStreams
+    , module Network.AWS.CloudWatchLogs.DescribeMetricFilters
+    , module Network.AWS.CloudWatchLogs.GetLogEvents
+    , module Network.AWS.CloudWatchLogs.PutLogEvents
+    , module Network.AWS.CloudWatchLogs.PutMetricFilter
+    , module Network.AWS.CloudWatchLogs.PutRetentionPolicy
+    , module Network.AWS.CloudWatchLogs.TestMetricFilter
+    , module Network.AWS.CloudWatchLogs.Types
+    ) where
+
+import Network.AWS.CloudWatchLogs.CreateLogGroup
+import Network.AWS.CloudWatchLogs.CreateLogStream
+import Network.AWS.CloudWatchLogs.DeleteLogGroup
+import Network.AWS.CloudWatchLogs.DeleteLogStream
+import Network.AWS.CloudWatchLogs.DeleteMetricFilter
+import Network.AWS.CloudWatchLogs.DeleteRetentionPolicy
+import Network.AWS.CloudWatchLogs.DescribeLogGroups
+import Network.AWS.CloudWatchLogs.DescribeLogStreams
+import Network.AWS.CloudWatchLogs.DescribeMetricFilters
+import Network.AWS.CloudWatchLogs.GetLogEvents
+import Network.AWS.CloudWatchLogs.PutLogEvents
+import Network.AWS.CloudWatchLogs.PutMetricFilter
+import Network.AWS.CloudWatchLogs.PutRetentionPolicy
+import Network.AWS.CloudWatchLogs.TestMetricFilter
+import Network.AWS.CloudWatchLogs.Types
diff --git a/gen/Network/AWS/CloudWatchLogs/CreateLogGroup.hs b/gen/Network/AWS/CloudWatchLogs/CreateLogGroup.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/CreateLogGroup.hs
@@ -0,0 +1,95 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.CreateLogGroup
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Creates a new log group with the specified name. The name of the log group
+-- must be unique within a region for an AWS account. You can create up to 500
+-- log groups per account. You must use the following guidelines when naming a
+-- log group: Log group names can be between 1 and 512 characters long.
+-- Allowed characters are a-z, A-Z, 0-9, '_' (underscore), '-' (hyphen), '/'
+-- (forward slash), and '.' (period).
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html>
+module Network.AWS.CloudWatchLogs.CreateLogGroup
+    (
+    -- * Request
+      CreateLogGroup
+    -- ** Request constructor
+    , createLogGroup
+    -- ** Request lenses
+    , clgLogGroupName
+
+    -- * Response
+    , CreateLogGroupResponse
+    -- ** Response constructor
+    , createLogGroupResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+newtype CreateLogGroup = CreateLogGroup
+    { _clgLogGroupName :: Text
+    } deriving (Eq, Ord, Show, Monoid, IsString)
+
+-- | 'CreateLogGroup' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'clgLogGroupName' @::@ 'Text'
+--
+createLogGroup :: Text -- ^ 'clgLogGroupName'
+               -> CreateLogGroup
+createLogGroup p1 = CreateLogGroup
+    { _clgLogGroupName = p1
+    }
+
+clgLogGroupName :: Lens' CreateLogGroup Text
+clgLogGroupName = lens _clgLogGroupName (\s a -> s { _clgLogGroupName = a })
+
+data CreateLogGroupResponse = CreateLogGroupResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'CreateLogGroupResponse' constructor.
+createLogGroupResponse :: CreateLogGroupResponse
+createLogGroupResponse = CreateLogGroupResponse
+
+instance ToPath CreateLogGroup where
+    toPath = const "/"
+
+instance ToQuery CreateLogGroup where
+    toQuery = const mempty
+
+instance ToHeaders CreateLogGroup
+
+instance ToJSON CreateLogGroup where
+    toJSON CreateLogGroup{..} = object
+        [ "logGroupName" .= _clgLogGroupName
+        ]
+
+instance AWSRequest CreateLogGroup where
+    type Sv CreateLogGroup = CloudWatchLogs
+    type Rs CreateLogGroup = CreateLogGroupResponse
+
+    request  = post "CreateLogGroup"
+    response = nullResponse CreateLogGroupResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/CreateLogStream.hs b/gen/Network/AWS/CloudWatchLogs/CreateLogStream.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/CreateLogStream.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.CreateLogStream
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Creates a new log stream in the specified log group. The name of the log
+-- stream must be unique within the log group. There is no limit on the number
+-- of log streams that can exist in a log group. You must use the following
+-- guidelines when naming a log stream: Log stream names can be between 1 and
+-- 512 characters long. The ':' colon character is not allowed.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html>
+module Network.AWS.CloudWatchLogs.CreateLogStream
+    (
+    -- * Request
+      CreateLogStream
+    -- ** Request constructor
+    , createLogStream
+    -- ** Request lenses
+    , clsLogGroupName
+    , clsLogStreamName
+
+    -- * Response
+    , CreateLogStreamResponse
+    -- ** Response constructor
+    , createLogStreamResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data CreateLogStream = CreateLogStream
+    { _clsLogGroupName  :: Text
+    , _clsLogStreamName :: Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'CreateLogStream' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'clsLogGroupName' @::@ 'Text'
+--
+-- * 'clsLogStreamName' @::@ 'Text'
+--
+createLogStream :: Text -- ^ 'clsLogGroupName'
+                -> Text -- ^ 'clsLogStreamName'
+                -> CreateLogStream
+createLogStream p1 p2 = CreateLogStream
+    { _clsLogGroupName  = p1
+    , _clsLogStreamName = p2
+    }
+
+clsLogGroupName :: Lens' CreateLogStream Text
+clsLogGroupName = lens _clsLogGroupName (\s a -> s { _clsLogGroupName = a })
+
+clsLogStreamName :: Lens' CreateLogStream Text
+clsLogStreamName = lens _clsLogStreamName (\s a -> s { _clsLogStreamName = a })
+
+data CreateLogStreamResponse = CreateLogStreamResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'CreateLogStreamResponse' constructor.
+createLogStreamResponse :: CreateLogStreamResponse
+createLogStreamResponse = CreateLogStreamResponse
+
+instance ToPath CreateLogStream where
+    toPath = const "/"
+
+instance ToQuery CreateLogStream where
+    toQuery = const mempty
+
+instance ToHeaders CreateLogStream
+
+instance ToJSON CreateLogStream where
+    toJSON CreateLogStream{..} = object
+        [ "logGroupName"  .= _clsLogGroupName
+        , "logStreamName" .= _clsLogStreamName
+        ]
+
+instance AWSRequest CreateLogStream where
+    type Sv CreateLogStream = CloudWatchLogs
+    type Rs CreateLogStream = CreateLogStreamResponse
+
+    request  = post "CreateLogStream"
+    response = nullResponse CreateLogStreamResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/DeleteLogGroup.hs b/gen/Network/AWS/CloudWatchLogs/DeleteLogGroup.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/DeleteLogGroup.hs
@@ -0,0 +1,91 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.DeleteLogGroup
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Deletes the log group with the specified name and permanently deletes all
+-- the archived log events associated with it.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteLogGroup.html>
+module Network.AWS.CloudWatchLogs.DeleteLogGroup
+    (
+    -- * Request
+      DeleteLogGroup
+    -- ** Request constructor
+    , deleteLogGroup
+    -- ** Request lenses
+    , dlgLogGroupName
+
+    -- * Response
+    , DeleteLogGroupResponse
+    -- ** Response constructor
+    , deleteLogGroupResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+newtype DeleteLogGroup = DeleteLogGroup
+    { _dlgLogGroupName :: Text
+    } deriving (Eq, Ord, Show, Monoid, IsString)
+
+-- | 'DeleteLogGroup' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dlgLogGroupName' @::@ 'Text'
+--
+deleteLogGroup :: Text -- ^ 'dlgLogGroupName'
+               -> DeleteLogGroup
+deleteLogGroup p1 = DeleteLogGroup
+    { _dlgLogGroupName = p1
+    }
+
+dlgLogGroupName :: Lens' DeleteLogGroup Text
+dlgLogGroupName = lens _dlgLogGroupName (\s a -> s { _dlgLogGroupName = a })
+
+data DeleteLogGroupResponse = DeleteLogGroupResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'DeleteLogGroupResponse' constructor.
+deleteLogGroupResponse :: DeleteLogGroupResponse
+deleteLogGroupResponse = DeleteLogGroupResponse
+
+instance ToPath DeleteLogGroup where
+    toPath = const "/"
+
+instance ToQuery DeleteLogGroup where
+    toQuery = const mempty
+
+instance ToHeaders DeleteLogGroup
+
+instance ToJSON DeleteLogGroup where
+    toJSON DeleteLogGroup{..} = object
+        [ "logGroupName" .= _dlgLogGroupName
+        ]
+
+instance AWSRequest DeleteLogGroup where
+    type Sv DeleteLogGroup = CloudWatchLogs
+    type Rs DeleteLogGroup = DeleteLogGroupResponse
+
+    request  = post "DeleteLogGroup"
+    response = nullResponse DeleteLogGroupResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/DeleteLogStream.hs b/gen/Network/AWS/CloudWatchLogs/DeleteLogStream.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/DeleteLogStream.hs
@@ -0,0 +1,101 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.DeleteLogStream
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Deletes a log stream and permanently deletes all the archived log events
+-- associated with it.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteLogStream.html>
+module Network.AWS.CloudWatchLogs.DeleteLogStream
+    (
+    -- * Request
+      DeleteLogStream
+    -- ** Request constructor
+    , deleteLogStream
+    -- ** Request lenses
+    , dlsLogGroupName
+    , dlsLogStreamName
+
+    -- * Response
+    , DeleteLogStreamResponse
+    -- ** Response constructor
+    , deleteLogStreamResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data DeleteLogStream = DeleteLogStream
+    { _dlsLogGroupName  :: Text
+    , _dlsLogStreamName :: Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'DeleteLogStream' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dlsLogGroupName' @::@ 'Text'
+--
+-- * 'dlsLogStreamName' @::@ 'Text'
+--
+deleteLogStream :: Text -- ^ 'dlsLogGroupName'
+                -> Text -- ^ 'dlsLogStreamName'
+                -> DeleteLogStream
+deleteLogStream p1 p2 = DeleteLogStream
+    { _dlsLogGroupName  = p1
+    , _dlsLogStreamName = p2
+    }
+
+dlsLogGroupName :: Lens' DeleteLogStream Text
+dlsLogGroupName = lens _dlsLogGroupName (\s a -> s { _dlsLogGroupName = a })
+
+dlsLogStreamName :: Lens' DeleteLogStream Text
+dlsLogStreamName = lens _dlsLogStreamName (\s a -> s { _dlsLogStreamName = a })
+
+data DeleteLogStreamResponse = DeleteLogStreamResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'DeleteLogStreamResponse' constructor.
+deleteLogStreamResponse :: DeleteLogStreamResponse
+deleteLogStreamResponse = DeleteLogStreamResponse
+
+instance ToPath DeleteLogStream where
+    toPath = const "/"
+
+instance ToQuery DeleteLogStream where
+    toQuery = const mempty
+
+instance ToHeaders DeleteLogStream
+
+instance ToJSON DeleteLogStream where
+    toJSON DeleteLogStream{..} = object
+        [ "logGroupName"  .= _dlsLogGroupName
+        , "logStreamName" .= _dlsLogStreamName
+        ]
+
+instance AWSRequest DeleteLogStream where
+    type Sv DeleteLogStream = CloudWatchLogs
+    type Rs DeleteLogStream = DeleteLogStreamResponse
+
+    request  = post "DeleteLogStream"
+    response = nullResponse DeleteLogStreamResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/DeleteMetricFilter.hs b/gen/Network/AWS/CloudWatchLogs/DeleteMetricFilter.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/DeleteMetricFilter.hs
@@ -0,0 +1,100 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.DeleteMetricFilter
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Deletes a metric filter associated with the specified log group.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteMetricFilter.html>
+module Network.AWS.CloudWatchLogs.DeleteMetricFilter
+    (
+    -- * Request
+      DeleteMetricFilter
+    -- ** Request constructor
+    , deleteMetricFilter
+    -- ** Request lenses
+    , dmf1FilterName
+    , dmf1LogGroupName
+
+    -- * Response
+    , DeleteMetricFilterResponse
+    -- ** Response constructor
+    , deleteMetricFilterResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data DeleteMetricFilter = DeleteMetricFilter
+    { _dmf1FilterName   :: Text
+    , _dmf1LogGroupName :: Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'DeleteMetricFilter' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dmf1FilterName' @::@ 'Text'
+--
+-- * 'dmf1LogGroupName' @::@ 'Text'
+--
+deleteMetricFilter :: Text -- ^ 'dmf1LogGroupName'
+                   -> Text -- ^ 'dmf1FilterName'
+                   -> DeleteMetricFilter
+deleteMetricFilter p1 p2 = DeleteMetricFilter
+    { _dmf1LogGroupName = p1
+    , _dmf1FilterName   = p2
+    }
+
+dmf1FilterName :: Lens' DeleteMetricFilter Text
+dmf1FilterName = lens _dmf1FilterName (\s a -> s { _dmf1FilterName = a })
+
+dmf1LogGroupName :: Lens' DeleteMetricFilter Text
+dmf1LogGroupName = lens _dmf1LogGroupName (\s a -> s { _dmf1LogGroupName = a })
+
+data DeleteMetricFilterResponse = DeleteMetricFilterResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'DeleteMetricFilterResponse' constructor.
+deleteMetricFilterResponse :: DeleteMetricFilterResponse
+deleteMetricFilterResponse = DeleteMetricFilterResponse
+
+instance ToPath DeleteMetricFilter where
+    toPath = const "/"
+
+instance ToQuery DeleteMetricFilter where
+    toQuery = const mempty
+
+instance ToHeaders DeleteMetricFilter
+
+instance ToJSON DeleteMetricFilter where
+    toJSON DeleteMetricFilter{..} = object
+        [ "logGroupName" .= _dmf1LogGroupName
+        , "filterName"   .= _dmf1FilterName
+        ]
+
+instance AWSRequest DeleteMetricFilter where
+    type Sv DeleteMetricFilter = CloudWatchLogs
+    type Rs DeleteMetricFilter = DeleteMetricFilterResponse
+
+    request  = post "DeleteMetricFilter"
+    response = nullResponse DeleteMetricFilterResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/DeleteRetentionPolicy.hs b/gen/Network/AWS/CloudWatchLogs/DeleteRetentionPolicy.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/DeleteRetentionPolicy.hs
@@ -0,0 +1,91 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.DeleteRetentionPolicy
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Deletes the retention policy of the specified log group. Log events would
+-- not expire if they belong to log groups without a retention policy.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteRetentionPolicy.html>
+module Network.AWS.CloudWatchLogs.DeleteRetentionPolicy
+    (
+    -- * Request
+      DeleteRetentionPolicy
+    -- ** Request constructor
+    , deleteRetentionPolicy
+    -- ** Request lenses
+    , drpLogGroupName
+
+    -- * Response
+    , DeleteRetentionPolicyResponse
+    -- ** Response constructor
+    , deleteRetentionPolicyResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+newtype DeleteRetentionPolicy = DeleteRetentionPolicy
+    { _drpLogGroupName :: Text
+    } deriving (Eq, Ord, Show, Monoid, IsString)
+
+-- | 'DeleteRetentionPolicy' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'drpLogGroupName' @::@ 'Text'
+--
+deleteRetentionPolicy :: Text -- ^ 'drpLogGroupName'
+                      -> DeleteRetentionPolicy
+deleteRetentionPolicy p1 = DeleteRetentionPolicy
+    { _drpLogGroupName = p1
+    }
+
+drpLogGroupName :: Lens' DeleteRetentionPolicy Text
+drpLogGroupName = lens _drpLogGroupName (\s a -> s { _drpLogGroupName = a })
+
+data DeleteRetentionPolicyResponse = DeleteRetentionPolicyResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'DeleteRetentionPolicyResponse' constructor.
+deleteRetentionPolicyResponse :: DeleteRetentionPolicyResponse
+deleteRetentionPolicyResponse = DeleteRetentionPolicyResponse
+
+instance ToPath DeleteRetentionPolicy where
+    toPath = const "/"
+
+instance ToQuery DeleteRetentionPolicy where
+    toQuery = const mempty
+
+instance ToHeaders DeleteRetentionPolicy
+
+instance ToJSON DeleteRetentionPolicy where
+    toJSON DeleteRetentionPolicy{..} = object
+        [ "logGroupName" .= _drpLogGroupName
+        ]
+
+instance AWSRequest DeleteRetentionPolicy where
+    type Sv DeleteRetentionPolicy = CloudWatchLogs
+    type Rs DeleteRetentionPolicy = DeleteRetentionPolicyResponse
+
+    request  = post "DeleteRetentionPolicy"
+    response = nullResponse DeleteRetentionPolicyResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/DescribeLogGroups.hs b/gen/Network/AWS/CloudWatchLogs/DescribeLogGroups.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/DescribeLogGroups.hs
@@ -0,0 +1,144 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.DescribeLogGroups
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Returns all the log groups that are associated with the AWS account making
+-- the request. The list returned in the response is ASCII-sorted by log group
+-- name. By default, this operation returns up to 50 log groups. If there are
+-- more log groups to list, the response would contain a nextToken value in
+-- the response body. You can also limit the number of log groups returned in
+-- the response by specifying the limit parameter in the request.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogGroups.html>
+module Network.AWS.CloudWatchLogs.DescribeLogGroups
+    (
+    -- * Request
+      DescribeLogGroups
+    -- ** Request constructor
+    , describeLogGroups
+    -- ** Request lenses
+    , dlgLimit
+    , dlgLogGroupNamePrefix
+    , dlgNextToken
+
+    -- * Response
+    , DescribeLogGroupsResponse
+    -- ** Response constructor
+    , describeLogGroupsResponse
+    -- ** Response lenses
+    , dlgrLogGroups
+    , dlgrNextToken
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data DescribeLogGroups = DescribeLogGroups
+    { _dlgLimit              :: Maybe Nat
+    , _dlgLogGroupNamePrefix :: Maybe Text
+    , _dlgNextToken          :: Maybe Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'DescribeLogGroups' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dlgLimit' @::@ 'Maybe' 'Natural'
+--
+-- * 'dlgLogGroupNamePrefix' @::@ 'Maybe' 'Text'
+--
+-- * 'dlgNextToken' @::@ 'Maybe' 'Text'
+--
+describeLogGroups :: DescribeLogGroups
+describeLogGroups = DescribeLogGroups
+    { _dlgLogGroupNamePrefix = Nothing
+    , _dlgNextToken          = Nothing
+    , _dlgLimit              = Nothing
+    }
+
+-- | The maximum number of items returned in the response. If you don't
+-- specify a value, the request would return up to 50 items.
+dlgLimit :: Lens' DescribeLogGroups (Maybe Natural)
+dlgLimit = lens _dlgLimit (\s a -> s { _dlgLimit = a }) . mapping _Nat
+
+dlgLogGroupNamePrefix :: Lens' DescribeLogGroups (Maybe Text)
+dlgLogGroupNamePrefix =
+    lens _dlgLogGroupNamePrefix (\s a -> s { _dlgLogGroupNamePrefix = a })
+
+-- | A string token used for pagination that points to the next page of
+-- results. It must be a value obtained from the response of the previous
+-- DescribeLogGroups request.
+dlgNextToken :: Lens' DescribeLogGroups (Maybe Text)
+dlgNextToken = lens _dlgNextToken (\s a -> s { _dlgNextToken = a })
+
+data DescribeLogGroupsResponse = DescribeLogGroupsResponse
+    { _dlgrLogGroups :: List "logGroups" LogGroup
+    , _dlgrNextToken :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'DescribeLogGroupsResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dlgrLogGroups' @::@ ['LogGroup']
+--
+-- * 'dlgrNextToken' @::@ 'Maybe' 'Text'
+--
+describeLogGroupsResponse :: DescribeLogGroupsResponse
+describeLogGroupsResponse = DescribeLogGroupsResponse
+    { _dlgrLogGroups = mempty
+    , _dlgrNextToken = Nothing
+    }
+
+dlgrLogGroups :: Lens' DescribeLogGroupsResponse [LogGroup]
+dlgrLogGroups = lens _dlgrLogGroups (\s a -> s { _dlgrLogGroups = a }) . _List
+
+dlgrNextToken :: Lens' DescribeLogGroupsResponse (Maybe Text)
+dlgrNextToken = lens _dlgrNextToken (\s a -> s { _dlgrNextToken = a })
+
+instance ToPath DescribeLogGroups where
+    toPath = const "/"
+
+instance ToQuery DescribeLogGroups where
+    toQuery = const mempty
+
+instance ToHeaders DescribeLogGroups
+
+instance ToJSON DescribeLogGroups where
+    toJSON DescribeLogGroups{..} = object
+        [ "logGroupNamePrefix" .= _dlgLogGroupNamePrefix
+        , "nextToken"          .= _dlgNextToken
+        , "limit"              .= _dlgLimit
+        ]
+
+instance AWSRequest DescribeLogGroups where
+    type Sv DescribeLogGroups = CloudWatchLogs
+    type Rs DescribeLogGroups = DescribeLogGroupsResponse
+
+    request  = post "DescribeLogGroups"
+    response = jsonResponse
+
+instance FromJSON DescribeLogGroupsResponse where
+    parseJSON = withObject "DescribeLogGroupsResponse" $ \o -> DescribeLogGroupsResponse
+        <$> o .:  "logGroups"
+        <*> o .:? "nextToken"
diff --git a/gen/Network/AWS/CloudWatchLogs/DescribeLogStreams.hs b/gen/Network/AWS/CloudWatchLogs/DescribeLogStreams.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/DescribeLogStreams.hs
@@ -0,0 +1,154 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.DescribeLogStreams
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Returns all the log streams that are associated with the specified log
+-- group. The list returned in the response is ASCII-sorted by log stream
+-- name. By default, this operation returns up to 50 log streams. If there are
+-- more log streams to list, the response would contain a nextToken value in
+-- the response body. You can also limit the number of log streams returned in
+-- the response by specifying the limit parameter in the request.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html>
+module Network.AWS.CloudWatchLogs.DescribeLogStreams
+    (
+    -- * Request
+      DescribeLogStreams
+    -- ** Request constructor
+    , describeLogStreams
+    -- ** Request lenses
+    , dls1Limit
+    , dls1LogGroupName
+    , dls1LogStreamNamePrefix
+    , dls1NextToken
+
+    -- * Response
+    , DescribeLogStreamsResponse
+    -- ** Response constructor
+    , describeLogStreamsResponse
+    -- ** Response lenses
+    , dlsrLogStreams
+    , dlsrNextToken
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data DescribeLogStreams = DescribeLogStreams
+    { _dls1Limit               :: Maybe Nat
+    , _dls1LogGroupName        :: Text
+    , _dls1LogStreamNamePrefix :: Maybe Text
+    , _dls1NextToken           :: Maybe Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'DescribeLogStreams' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dls1Limit' @::@ 'Maybe' 'Natural'
+--
+-- * 'dls1LogGroupName' @::@ 'Text'
+--
+-- * 'dls1LogStreamNamePrefix' @::@ 'Maybe' 'Text'
+--
+-- * 'dls1NextToken' @::@ 'Maybe' 'Text'
+--
+describeLogStreams :: Text -- ^ 'dls1LogGroupName'
+                   -> DescribeLogStreams
+describeLogStreams p1 = DescribeLogStreams
+    { _dls1LogGroupName        = p1
+    , _dls1LogStreamNamePrefix = Nothing
+    , _dls1NextToken           = Nothing
+    , _dls1Limit               = Nothing
+    }
+
+-- | The maximum number of items returned in the response. If you don't
+-- specify a value, the request would return up to 50 items.
+dls1Limit :: Lens' DescribeLogStreams (Maybe Natural)
+dls1Limit = lens _dls1Limit (\s a -> s { _dls1Limit = a }) . mapping _Nat
+
+dls1LogGroupName :: Lens' DescribeLogStreams Text
+dls1LogGroupName = lens _dls1LogGroupName (\s a -> s { _dls1LogGroupName = a })
+
+dls1LogStreamNamePrefix :: Lens' DescribeLogStreams (Maybe Text)
+dls1LogStreamNamePrefix =
+    lens _dls1LogStreamNamePrefix (\s a -> s { _dls1LogStreamNamePrefix = a })
+
+-- | A string token used for pagination that points to the next page of
+-- results. It must be a value obtained from the response of the previous
+-- DescribeLogStreams request.
+dls1NextToken :: Lens' DescribeLogStreams (Maybe Text)
+dls1NextToken = lens _dls1NextToken (\s a -> s { _dls1NextToken = a })
+
+data DescribeLogStreamsResponse = DescribeLogStreamsResponse
+    { _dlsrLogStreams :: List "logStreams" LogStream
+    , _dlsrNextToken  :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'DescribeLogStreamsResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dlsrLogStreams' @::@ ['LogStream']
+--
+-- * 'dlsrNextToken' @::@ 'Maybe' 'Text'
+--
+describeLogStreamsResponse :: DescribeLogStreamsResponse
+describeLogStreamsResponse = DescribeLogStreamsResponse
+    { _dlsrLogStreams = mempty
+    , _dlsrNextToken  = Nothing
+    }
+
+dlsrLogStreams :: Lens' DescribeLogStreamsResponse [LogStream]
+dlsrLogStreams = lens _dlsrLogStreams (\s a -> s { _dlsrLogStreams = a }) . _List
+
+dlsrNextToken :: Lens' DescribeLogStreamsResponse (Maybe Text)
+dlsrNextToken = lens _dlsrNextToken (\s a -> s { _dlsrNextToken = a })
+
+instance ToPath DescribeLogStreams where
+    toPath = const "/"
+
+instance ToQuery DescribeLogStreams where
+    toQuery = const mempty
+
+instance ToHeaders DescribeLogStreams
+
+instance ToJSON DescribeLogStreams where
+    toJSON DescribeLogStreams{..} = object
+        [ "logGroupName"        .= _dls1LogGroupName
+        , "logStreamNamePrefix" .= _dls1LogStreamNamePrefix
+        , "nextToken"           .= _dls1NextToken
+        , "limit"               .= _dls1Limit
+        ]
+
+instance AWSRequest DescribeLogStreams where
+    type Sv DescribeLogStreams = CloudWatchLogs
+    type Rs DescribeLogStreams = DescribeLogStreamsResponse
+
+    request  = post "DescribeLogStreams"
+    response = jsonResponse
+
+instance FromJSON DescribeLogStreamsResponse where
+    parseJSON = withObject "DescribeLogStreamsResponse" $ \o -> DescribeLogStreamsResponse
+        <$> o .:  "logStreams"
+        <*> o .:? "nextToken"
diff --git a/gen/Network/AWS/CloudWatchLogs/DescribeMetricFilters.hs b/gen/Network/AWS/CloudWatchLogs/DescribeMetricFilters.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/DescribeMetricFilters.hs
@@ -0,0 +1,156 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.DescribeMetricFilters
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Returns all the metrics filters associated with the specified log group.
+-- The list returned in the response is ASCII-sorted by filter name. By
+-- default, this operation returns up to 50 metric filters. If there are more
+-- metric filters to list, the response would contain a nextToken value in the
+-- response body. You can also limit the number of metric filters returned in
+-- the response by specifying the limit parameter in the request.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeMetricFilters.html>
+module Network.AWS.CloudWatchLogs.DescribeMetricFilters
+    (
+    -- * Request
+      DescribeMetricFilters
+    -- ** Request constructor
+    , describeMetricFilters
+    -- ** Request lenses
+    , dmfFilterNamePrefix
+    , dmfLimit
+    , dmfLogGroupName
+    , dmfNextToken
+
+    -- * Response
+    , DescribeMetricFiltersResponse
+    -- ** Response constructor
+    , describeMetricFiltersResponse
+    -- ** Response lenses
+    , dmfrMetricFilters
+    , dmfrNextToken
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data DescribeMetricFilters = DescribeMetricFilters
+    { _dmfFilterNamePrefix :: Maybe Text
+    , _dmfLimit            :: Maybe Nat
+    , _dmfLogGroupName     :: Text
+    , _dmfNextToken        :: Maybe Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'DescribeMetricFilters' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dmfFilterNamePrefix' @::@ 'Maybe' 'Text'
+--
+-- * 'dmfLimit' @::@ 'Maybe' 'Natural'
+--
+-- * 'dmfLogGroupName' @::@ 'Text'
+--
+-- * 'dmfNextToken' @::@ 'Maybe' 'Text'
+--
+describeMetricFilters :: Text -- ^ 'dmfLogGroupName'
+                      -> DescribeMetricFilters
+describeMetricFilters p1 = DescribeMetricFilters
+    { _dmfLogGroupName     = p1
+    , _dmfFilterNamePrefix = Nothing
+    , _dmfNextToken        = Nothing
+    , _dmfLimit            = Nothing
+    }
+
+dmfFilterNamePrefix :: Lens' DescribeMetricFilters (Maybe Text)
+dmfFilterNamePrefix =
+    lens _dmfFilterNamePrefix (\s a -> s { _dmfFilterNamePrefix = a })
+
+-- | The maximum number of items returned in the response. If you don't
+-- specify a value, the request would return up to 50 items.
+dmfLimit :: Lens' DescribeMetricFilters (Maybe Natural)
+dmfLimit = lens _dmfLimit (\s a -> s { _dmfLimit = a }) . mapping _Nat
+
+dmfLogGroupName :: Lens' DescribeMetricFilters Text
+dmfLogGroupName = lens _dmfLogGroupName (\s a -> s { _dmfLogGroupName = a })
+
+-- | A string token used for pagination that points to the next page of
+-- results. It must be a value obtained from the response of the previous
+-- DescribeMetricFilters request.
+dmfNextToken :: Lens' DescribeMetricFilters (Maybe Text)
+dmfNextToken = lens _dmfNextToken (\s a -> s { _dmfNextToken = a })
+
+data DescribeMetricFiltersResponse = DescribeMetricFiltersResponse
+    { _dmfrMetricFilters :: List "metricFilters" MetricFilter
+    , _dmfrNextToken     :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'DescribeMetricFiltersResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dmfrMetricFilters' @::@ ['MetricFilter']
+--
+-- * 'dmfrNextToken' @::@ 'Maybe' 'Text'
+--
+describeMetricFiltersResponse :: DescribeMetricFiltersResponse
+describeMetricFiltersResponse = DescribeMetricFiltersResponse
+    { _dmfrMetricFilters = mempty
+    , _dmfrNextToken     = Nothing
+    }
+
+dmfrMetricFilters :: Lens' DescribeMetricFiltersResponse [MetricFilter]
+dmfrMetricFilters =
+    lens _dmfrMetricFilters (\s a -> s { _dmfrMetricFilters = a })
+        . _List
+
+dmfrNextToken :: Lens' DescribeMetricFiltersResponse (Maybe Text)
+dmfrNextToken = lens _dmfrNextToken (\s a -> s { _dmfrNextToken = a })
+
+instance ToPath DescribeMetricFilters where
+    toPath = const "/"
+
+instance ToQuery DescribeMetricFilters where
+    toQuery = const mempty
+
+instance ToHeaders DescribeMetricFilters
+
+instance ToJSON DescribeMetricFilters where
+    toJSON DescribeMetricFilters{..} = object
+        [ "logGroupName"     .= _dmfLogGroupName
+        , "filterNamePrefix" .= _dmfFilterNamePrefix
+        , "nextToken"        .= _dmfNextToken
+        , "limit"            .= _dmfLimit
+        ]
+
+instance AWSRequest DescribeMetricFilters where
+    type Sv DescribeMetricFilters = CloudWatchLogs
+    type Rs DescribeMetricFilters = DescribeMetricFiltersResponse
+
+    request  = post "DescribeMetricFilters"
+    response = jsonResponse
+
+instance FromJSON DescribeMetricFiltersResponse where
+    parseJSON = withObject "DescribeMetricFiltersResponse" $ \o -> DescribeMetricFiltersResponse
+        <$> o .:  "metricFilters"
+        <*> o .:? "nextToken"
diff --git a/gen/Network/AWS/CloudWatchLogs/GetLogEvents.hs b/gen/Network/AWS/CloudWatchLogs/GetLogEvents.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/GetLogEvents.hs
@@ -0,0 +1,199 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.GetLogEvents
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Retrieves log events from the specified log stream. You can provide an
+-- optional time range to filter the results on the event timestamp. By
+-- default, this operation returns as much log events as can fit in a response
+-- size of 1MB, up to 10,000 log events. The response will always include a
+-- nextForwardToken and a nextBackwardToken in the response body. You can use
+-- any of these tokens in subsequent GetLogEvents requests to paginate through
+-- events in either forward or backward direction. You can also limit the
+-- number of log events returned in the response by specifying the limit
+-- parameter in the request.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetLogEvents.html>
+module Network.AWS.CloudWatchLogs.GetLogEvents
+    (
+    -- * Request
+      GetLogEvents
+    -- ** Request constructor
+    , getLogEvents
+    -- ** Request lenses
+    , gleEndTime
+    , gleLimit
+    , gleLogGroupName
+    , gleLogStreamName
+    , gleNextToken
+    , gleStartFromHead
+    , gleStartTime
+
+    -- * Response
+    , GetLogEventsResponse
+    -- ** Response constructor
+    , getLogEventsResponse
+    -- ** Response lenses
+    , glerEvents
+    , glerNextBackwardToken
+    , glerNextForwardToken
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data GetLogEvents = GetLogEvents
+    { _gleEndTime       :: Maybe Nat
+    , _gleLimit         :: Maybe Nat
+    , _gleLogGroupName  :: Text
+    , _gleLogStreamName :: Text
+    , _gleNextToken     :: Maybe Text
+    , _gleStartFromHead :: Maybe Bool
+    , _gleStartTime     :: Maybe Nat
+    } deriving (Eq, Ord, Show)
+
+-- | 'GetLogEvents' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'gleEndTime' @::@ 'Maybe' 'Natural'
+--
+-- * 'gleLimit' @::@ 'Maybe' 'Natural'
+--
+-- * 'gleLogGroupName' @::@ 'Text'
+--
+-- * 'gleLogStreamName' @::@ 'Text'
+--
+-- * 'gleNextToken' @::@ 'Maybe' 'Text'
+--
+-- * 'gleStartFromHead' @::@ 'Maybe' 'Bool'
+--
+-- * 'gleStartTime' @::@ 'Maybe' 'Natural'
+--
+getLogEvents :: Text -- ^ 'gleLogGroupName'
+             -> Text -- ^ 'gleLogStreamName'
+             -> GetLogEvents
+getLogEvents p1 p2 = GetLogEvents
+    { _gleLogGroupName  = p1
+    , _gleLogStreamName = p2
+    , _gleStartTime     = Nothing
+    , _gleEndTime       = Nothing
+    , _gleNextToken     = Nothing
+    , _gleLimit         = Nothing
+    , _gleStartFromHead = Nothing
+    }
+
+gleEndTime :: Lens' GetLogEvents (Maybe Natural)
+gleEndTime = lens _gleEndTime (\s a -> s { _gleEndTime = a }) . mapping _Nat
+
+-- | The maximum number of log events returned in the response. If you don't
+-- specify a value, the request would return as much log events as can fit
+-- in a response size of 1MB, up to 10,000 log events.
+gleLimit :: Lens' GetLogEvents (Maybe Natural)
+gleLimit = lens _gleLimit (\s a -> s { _gleLimit = a }) . mapping _Nat
+
+gleLogGroupName :: Lens' GetLogEvents Text
+gleLogGroupName = lens _gleLogGroupName (\s a -> s { _gleLogGroupName = a })
+
+gleLogStreamName :: Lens' GetLogEvents Text
+gleLogStreamName = lens _gleLogStreamName (\s a -> s { _gleLogStreamName = a })
+
+-- | A string token used for pagination that points to the next page of
+-- results. It must be a value obtained from the nextForwardToken or
+-- nextBackwardToken fields in the response of the previous GetLogEvents
+-- request.
+gleNextToken :: Lens' GetLogEvents (Maybe Text)
+gleNextToken = lens _gleNextToken (\s a -> s { _gleNextToken = a })
+
+-- | If set to true, the earliest log events would be returned first. The
+-- default is false (the latest log events are returned first).
+gleStartFromHead :: Lens' GetLogEvents (Maybe Bool)
+gleStartFromHead = lens _gleStartFromHead (\s a -> s { _gleStartFromHead = a })
+
+gleStartTime :: Lens' GetLogEvents (Maybe Natural)
+gleStartTime = lens _gleStartTime (\s a -> s { _gleStartTime = a }) . mapping _Nat
+
+data GetLogEventsResponse = GetLogEventsResponse
+    { _glerEvents            :: List "events" OutputLogEvent
+    , _glerNextBackwardToken :: Maybe Text
+    , _glerNextForwardToken  :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'GetLogEventsResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'glerEvents' @::@ ['OutputLogEvent']
+--
+-- * 'glerNextBackwardToken' @::@ 'Maybe' 'Text'
+--
+-- * 'glerNextForwardToken' @::@ 'Maybe' 'Text'
+--
+getLogEventsResponse :: GetLogEventsResponse
+getLogEventsResponse = GetLogEventsResponse
+    { _glerEvents            = mempty
+    , _glerNextForwardToken  = Nothing
+    , _glerNextBackwardToken = Nothing
+    }
+
+glerEvents :: Lens' GetLogEventsResponse [OutputLogEvent]
+glerEvents = lens _glerEvents (\s a -> s { _glerEvents = a }) . _List
+
+glerNextBackwardToken :: Lens' GetLogEventsResponse (Maybe Text)
+glerNextBackwardToken =
+    lens _glerNextBackwardToken (\s a -> s { _glerNextBackwardToken = a })
+
+glerNextForwardToken :: Lens' GetLogEventsResponse (Maybe Text)
+glerNextForwardToken =
+    lens _glerNextForwardToken (\s a -> s { _glerNextForwardToken = a })
+
+instance ToPath GetLogEvents where
+    toPath = const "/"
+
+instance ToQuery GetLogEvents where
+    toQuery = const mempty
+
+instance ToHeaders GetLogEvents
+
+instance ToJSON GetLogEvents where
+    toJSON GetLogEvents{..} = object
+        [ "logGroupName"  .= _gleLogGroupName
+        , "logStreamName" .= _gleLogStreamName
+        , "startTime"     .= _gleStartTime
+        , "endTime"       .= _gleEndTime
+        , "nextToken"     .= _gleNextToken
+        , "limit"         .= _gleLimit
+        , "startFromHead" .= _gleStartFromHead
+        ]
+
+instance AWSRequest GetLogEvents where
+    type Sv GetLogEvents = CloudWatchLogs
+    type Rs GetLogEvents = GetLogEventsResponse
+
+    request  = post "GetLogEvents"
+    response = jsonResponse
+
+instance FromJSON GetLogEventsResponse where
+    parseJSON = withObject "GetLogEventsResponse" $ \o -> GetLogEventsResponse
+        <$> o .:  "events"
+        <*> o .:? "nextBackwardToken"
+        <*> o .:? "nextForwardToken"
diff --git a/gen/Network/AWS/CloudWatchLogs/PutLogEvents.hs b/gen/Network/AWS/CloudWatchLogs/PutLogEvents.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/PutLogEvents.hs
@@ -0,0 +1,149 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.PutLogEvents
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Uploads a batch of log events to the specified log stream. Every
+-- PutLogEvents request must include the sequenceToken obtained from the
+-- response of the previous request. An upload in a newly created log stream
+-- does not require a sequenceToken. The batch of events must satisfy the
+-- following constraints: The maximum batch size is 32,768 bytes, and this
+-- size is calculated as the sum of all event messages in UTF-8, plus 26 bytes
+-- for each log event. None of the log events in the batch can be more than 2
+-- hours in the future. None of the log events in the batch can be older than
+-- 14 days or the retention period of the log group. The log events in the
+-- batch must be in chronological ordered by their timestamp. The maximum
+-- number of log events in a batch is 1,000.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html>
+module Network.AWS.CloudWatchLogs.PutLogEvents
+    (
+    -- * Request
+      PutLogEvents
+    -- ** Request constructor
+    , putLogEvents
+    -- ** Request lenses
+    , pleLogEvents
+    , pleLogGroupName
+    , pleLogStreamName
+    , pleSequenceToken
+
+    -- * Response
+    , PutLogEventsResponse
+    -- ** Response constructor
+    , putLogEventsResponse
+    -- ** Response lenses
+    , plerNextSequenceToken
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data PutLogEvents = PutLogEvents
+    { _pleLogEvents     :: List1 "logEvents" InputLogEvent
+    , _pleLogGroupName  :: Text
+    , _pleLogStreamName :: Text
+    , _pleSequenceToken :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'PutLogEvents' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'pleLogEvents' @::@ 'NonEmpty' 'InputLogEvent'
+--
+-- * 'pleLogGroupName' @::@ 'Text'
+--
+-- * 'pleLogStreamName' @::@ 'Text'
+--
+-- * 'pleSequenceToken' @::@ 'Maybe' 'Text'
+--
+putLogEvents :: Text -- ^ 'pleLogGroupName'
+             -> Text -- ^ 'pleLogStreamName'
+             -> NonEmpty InputLogEvent -- ^ 'pleLogEvents'
+             -> PutLogEvents
+putLogEvents p1 p2 p3 = PutLogEvents
+    { _pleLogGroupName  = p1
+    , _pleLogStreamName = p2
+    , _pleLogEvents     = withIso _List1 (const id) p3
+    , _pleSequenceToken = Nothing
+    }
+
+pleLogEvents :: Lens' PutLogEvents (NonEmpty InputLogEvent)
+pleLogEvents = lens _pleLogEvents (\s a -> s { _pleLogEvents = a }) . _List1
+
+pleLogGroupName :: Lens' PutLogEvents Text
+pleLogGroupName = lens _pleLogGroupName (\s a -> s { _pleLogGroupName = a })
+
+pleLogStreamName :: Lens' PutLogEvents Text
+pleLogStreamName = lens _pleLogStreamName (\s a -> s { _pleLogStreamName = a })
+
+-- | A string token that must be obtained from the response of the previous
+-- PutLogEvents request.
+pleSequenceToken :: Lens' PutLogEvents (Maybe Text)
+pleSequenceToken = lens _pleSequenceToken (\s a -> s { _pleSequenceToken = a })
+
+newtype PutLogEventsResponse = PutLogEventsResponse
+    { _plerNextSequenceToken :: Maybe Text
+    } deriving (Eq, Ord, Show, Monoid)
+
+-- | 'PutLogEventsResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'plerNextSequenceToken' @::@ 'Maybe' 'Text'
+--
+putLogEventsResponse :: PutLogEventsResponse
+putLogEventsResponse = PutLogEventsResponse
+    { _plerNextSequenceToken = Nothing
+    }
+
+plerNextSequenceToken :: Lens' PutLogEventsResponse (Maybe Text)
+plerNextSequenceToken =
+    lens _plerNextSequenceToken (\s a -> s { _plerNextSequenceToken = a })
+
+instance ToPath PutLogEvents where
+    toPath = const "/"
+
+instance ToQuery PutLogEvents where
+    toQuery = const mempty
+
+instance ToHeaders PutLogEvents
+
+instance ToJSON PutLogEvents where
+    toJSON PutLogEvents{..} = object
+        [ "logGroupName"  .= _pleLogGroupName
+        , "logStreamName" .= _pleLogStreamName
+        , "logEvents"     .= _pleLogEvents
+        , "sequenceToken" .= _pleSequenceToken
+        ]
+
+instance AWSRequest PutLogEvents where
+    type Sv PutLogEvents = CloudWatchLogs
+    type Rs PutLogEvents = PutLogEventsResponse
+
+    request  = post "PutLogEvents"
+    response = jsonResponse
+
+instance FromJSON PutLogEventsResponse where
+    parseJSON = withObject "PutLogEventsResponse" $ \o -> PutLogEventsResponse
+        <$> o .:? "nextSequenceToken"
diff --git a/gen/Network/AWS/CloudWatchLogs/PutMetricFilter.hs b/gen/Network/AWS/CloudWatchLogs/PutMetricFilter.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/PutMetricFilter.hs
@@ -0,0 +1,125 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.PutMetricFilter
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Creates or updates a metric filter and associates it with the specified log
+-- group. Metric filters allow you to configure rules to extract metric data
+-- from log events ingested through PutLogEvents requests.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutMetricFilter.html>
+module Network.AWS.CloudWatchLogs.PutMetricFilter
+    (
+    -- * Request
+      PutMetricFilter
+    -- ** Request constructor
+    , putMetricFilter
+    -- ** Request lenses
+    , pmfFilterName
+    , pmfFilterPattern
+    , pmfLogGroupName
+    , pmfMetricTransformations
+
+    -- * Response
+    , PutMetricFilterResponse
+    -- ** Response constructor
+    , putMetricFilterResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data PutMetricFilter = PutMetricFilter
+    { _pmfFilterName            :: Text
+    , _pmfFilterPattern         :: Text
+    , _pmfLogGroupName          :: Text
+    , _pmfMetricTransformations :: List1 "metricTransformations" MetricTransformation
+    } deriving (Eq, Show)
+
+-- | 'PutMetricFilter' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'pmfFilterName' @::@ 'Text'
+--
+-- * 'pmfFilterPattern' @::@ 'Text'
+--
+-- * 'pmfLogGroupName' @::@ 'Text'
+--
+-- * 'pmfMetricTransformations' @::@ 'NonEmpty' 'MetricTransformation'
+--
+putMetricFilter :: Text -- ^ 'pmfLogGroupName'
+                -> Text -- ^ 'pmfFilterName'
+                -> Text -- ^ 'pmfFilterPattern'
+                -> NonEmpty MetricTransformation -- ^ 'pmfMetricTransformations'
+                -> PutMetricFilter
+putMetricFilter p1 p2 p3 p4 = PutMetricFilter
+    { _pmfLogGroupName          = p1
+    , _pmfFilterName            = p2
+    , _pmfFilterPattern         = p3
+    , _pmfMetricTransformations = withIso _List1 (const id) p4
+    }
+
+pmfFilterName :: Lens' PutMetricFilter Text
+pmfFilterName = lens _pmfFilterName (\s a -> s { _pmfFilterName = a })
+
+pmfFilterPattern :: Lens' PutMetricFilter Text
+pmfFilterPattern = lens _pmfFilterPattern (\s a -> s { _pmfFilterPattern = a })
+
+pmfLogGroupName :: Lens' PutMetricFilter Text
+pmfLogGroupName = lens _pmfLogGroupName (\s a -> s { _pmfLogGroupName = a })
+
+pmfMetricTransformations :: Lens' PutMetricFilter (NonEmpty MetricTransformation)
+pmfMetricTransformations =
+    lens _pmfMetricTransformations
+        (\s a -> s { _pmfMetricTransformations = a })
+            . _List1
+
+data PutMetricFilterResponse = PutMetricFilterResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'PutMetricFilterResponse' constructor.
+putMetricFilterResponse :: PutMetricFilterResponse
+putMetricFilterResponse = PutMetricFilterResponse
+
+instance ToPath PutMetricFilter where
+    toPath = const "/"
+
+instance ToQuery PutMetricFilter where
+    toQuery = const mempty
+
+instance ToHeaders PutMetricFilter
+
+instance ToJSON PutMetricFilter where
+    toJSON PutMetricFilter{..} = object
+        [ "logGroupName"          .= _pmfLogGroupName
+        , "filterName"            .= _pmfFilterName
+        , "filterPattern"         .= _pmfFilterPattern
+        , "metricTransformations" .= _pmfMetricTransformations
+        ]
+
+instance AWSRequest PutMetricFilter where
+    type Sv PutMetricFilter = CloudWatchLogs
+    type Rs PutMetricFilter = PutMetricFilterResponse
+
+    request  = post "PutMetricFilter"
+    response = nullResponse PutMetricFilterResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/PutRetentionPolicy.hs b/gen/Network/AWS/CloudWatchLogs/PutRetentionPolicy.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/PutRetentionPolicy.hs
@@ -0,0 +1,103 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.PutRetentionPolicy
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Sets the retention of the specified log group. A retention policy allows
+-- you to configure the number of days you want to retain log events in the
+-- specified log group.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutRetentionPolicy.html>
+module Network.AWS.CloudWatchLogs.PutRetentionPolicy
+    (
+    -- * Request
+      PutRetentionPolicy
+    -- ** Request constructor
+    , putRetentionPolicy
+    -- ** Request lenses
+    , prpLogGroupName
+    , prpRetentionInDays
+
+    -- * Response
+    , PutRetentionPolicyResponse
+    -- ** Response constructor
+    , putRetentionPolicyResponse
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data PutRetentionPolicy = PutRetentionPolicy
+    { _prpLogGroupName    :: Text
+    , _prpRetentionInDays :: Int
+    } deriving (Eq, Ord, Show)
+
+-- | 'PutRetentionPolicy' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'prpLogGroupName' @::@ 'Text'
+--
+-- * 'prpRetentionInDays' @::@ 'Int'
+--
+putRetentionPolicy :: Text -- ^ 'prpLogGroupName'
+                   -> Int -- ^ 'prpRetentionInDays'
+                   -> PutRetentionPolicy
+putRetentionPolicy p1 p2 = PutRetentionPolicy
+    { _prpLogGroupName    = p1
+    , _prpRetentionInDays = p2
+    }
+
+prpLogGroupName :: Lens' PutRetentionPolicy Text
+prpLogGroupName = lens _prpLogGroupName (\s a -> s { _prpLogGroupName = a })
+
+prpRetentionInDays :: Lens' PutRetentionPolicy Int
+prpRetentionInDays =
+    lens _prpRetentionInDays (\s a -> s { _prpRetentionInDays = a })
+
+data PutRetentionPolicyResponse = PutRetentionPolicyResponse
+    deriving (Eq, Ord, Show, Generic)
+
+-- | 'PutRetentionPolicyResponse' constructor.
+putRetentionPolicyResponse :: PutRetentionPolicyResponse
+putRetentionPolicyResponse = PutRetentionPolicyResponse
+
+instance ToPath PutRetentionPolicy where
+    toPath = const "/"
+
+instance ToQuery PutRetentionPolicy where
+    toQuery = const mempty
+
+instance ToHeaders PutRetentionPolicy
+
+instance ToJSON PutRetentionPolicy where
+    toJSON PutRetentionPolicy{..} = object
+        [ "logGroupName"    .= _prpLogGroupName
+        , "retentionInDays" .= _prpRetentionInDays
+        ]
+
+instance AWSRequest PutRetentionPolicy where
+    type Sv PutRetentionPolicy = CloudWatchLogs
+    type Rs PutRetentionPolicy = PutRetentionPolicyResponse
+
+    request  = post "PutRetentionPolicy"
+    response = nullResponse PutRetentionPolicyResponse
diff --git a/gen/Network/AWS/CloudWatchLogs/TestMetricFilter.hs b/gen/Network/AWS/CloudWatchLogs/TestMetricFilter.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/TestMetricFilter.hs
@@ -0,0 +1,127 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.TestMetricFilter
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Tests the filter pattern of a metric filter against a sample of log event
+-- messages. You can use this operation to validate the correctness of a
+-- metric filter pattern.
+--
+-- <http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_TestMetricFilter.html>
+module Network.AWS.CloudWatchLogs.TestMetricFilter
+    (
+    -- * Request
+      TestMetricFilter
+    -- ** Request constructor
+    , testMetricFilter
+    -- ** Request lenses
+    , tmfFilterPattern
+    , tmfLogEventMessages
+
+    -- * Response
+    , TestMetricFilterResponse
+    -- ** Response constructor
+    , testMetricFilterResponse
+    -- ** Response lenses
+    , tmfrMatches
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.CloudWatchLogs.Types
+import qualified GHC.Exts
+
+data TestMetricFilter = TestMetricFilter
+    { _tmfFilterPattern    :: Text
+    , _tmfLogEventMessages :: List1 "logEventMessages" Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'TestMetricFilter' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'tmfFilterPattern' @::@ 'Text'
+--
+-- * 'tmfLogEventMessages' @::@ 'NonEmpty' 'Text'
+--
+testMetricFilter :: Text -- ^ 'tmfFilterPattern'
+                 -> NonEmpty Text -- ^ 'tmfLogEventMessages'
+                 -> TestMetricFilter
+testMetricFilter p1 p2 = TestMetricFilter
+    { _tmfFilterPattern    = p1
+    , _tmfLogEventMessages = withIso _List1 (const id) p2
+    }
+
+tmfFilterPattern :: Lens' TestMetricFilter Text
+tmfFilterPattern = lens _tmfFilterPattern (\s a -> s { _tmfFilterPattern = a })
+
+tmfLogEventMessages :: Lens' TestMetricFilter (NonEmpty Text)
+tmfLogEventMessages =
+    lens _tmfLogEventMessages (\s a -> s { _tmfLogEventMessages = a })
+        . _List1
+
+newtype TestMetricFilterResponse = TestMetricFilterResponse
+    { _tmfrMatches :: List "matches" MetricFilterMatchRecord
+    } deriving (Eq, Show, Monoid, Semigroup)
+
+instance GHC.Exts.IsList TestMetricFilterResponse where
+    type Item TestMetricFilterResponse = MetricFilterMatchRecord
+
+    fromList = TestMetricFilterResponse . GHC.Exts.fromList
+    toList   = GHC.Exts.toList . _tmfrMatches
+
+-- | 'TestMetricFilterResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'tmfrMatches' @::@ ['MetricFilterMatchRecord']
+--
+testMetricFilterResponse :: TestMetricFilterResponse
+testMetricFilterResponse = TestMetricFilterResponse
+    { _tmfrMatches = mempty
+    }
+
+tmfrMatches :: Lens' TestMetricFilterResponse [MetricFilterMatchRecord]
+tmfrMatches = lens _tmfrMatches (\s a -> s { _tmfrMatches = a }) . _List
+
+instance ToPath TestMetricFilter where
+    toPath = const "/"
+
+instance ToQuery TestMetricFilter where
+    toQuery = const mempty
+
+instance ToHeaders TestMetricFilter
+
+instance ToJSON TestMetricFilter where
+    toJSON TestMetricFilter{..} = object
+        [ "filterPattern"    .= _tmfFilterPattern
+        , "logEventMessages" .= _tmfLogEventMessages
+        ]
+
+instance AWSRequest TestMetricFilter where
+    type Sv TestMetricFilter = CloudWatchLogs
+    type Rs TestMetricFilter = TestMetricFilterResponse
+
+    request  = post "TestMetricFilter"
+    response = jsonResponse
+
+instance FromJSON TestMetricFilterResponse where
+    parseJSON = withObject "TestMetricFilterResponse" $ \o -> TestMetricFilterResponse
+        <$> o .:  "matches"
diff --git a/gen/Network/AWS/CloudWatchLogs/Types.hs b/gen/Network/AWS/CloudWatchLogs/Types.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/CloudWatchLogs/Types.hs
@@ -0,0 +1,517 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.CloudWatchLogs.Types
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+module Network.AWS.CloudWatchLogs.Types
+    (
+    -- * Service
+      CloudWatchLogs
+    -- ** Error
+    , JSONError
+
+    -- * MetricFilter
+    , MetricFilter
+    , metricFilter
+    , mfCreationTime
+    , mfFilterName
+    , mfFilterPattern
+    , mfMetricTransformations
+
+    -- * MetricFilterMatchRecord
+    , MetricFilterMatchRecord
+    , metricFilterMatchRecord
+    , mfmrEventMessage
+    , mfmrEventNumber
+    , mfmrExtractedValues
+
+    -- * MetricTransformation
+    , MetricTransformation
+    , metricTransformation
+    , mtMetricName
+    , mtMetricNamespace
+    , mtMetricValue
+
+    -- * LogStream
+    , LogStream
+    , logStream
+    , lsArn
+    , lsCreationTime
+    , lsFirstEventTimestamp
+    , lsLastEventTimestamp
+    , lsLastIngestionTime
+    , lsLogStreamName
+    , lsStoredBytes
+    , lsUploadSequenceToken
+
+    -- * LogGroup
+    , LogGroup
+    , logGroup
+    , lgArn
+    , lgCreationTime
+    , lgLogGroupName
+    , lgMetricFilterCount
+    , lgRetentionInDays
+    , lgStoredBytes
+
+    -- * InputLogEvent
+    , InputLogEvent
+    , inputLogEvent
+    , ileMessage
+    , ileTimestamp
+
+    -- * OutputLogEvent
+    , OutputLogEvent
+    , outputLogEvent
+    , oleIngestionTime
+    , oleMessage
+    , oleTimestamp
+    ) where
+
+import Data.Char (isUpper)
+import Network.AWS.Error
+import Network.AWS.Prelude
+import Network.AWS.Signing.V4
+import qualified GHC.Exts
+
+-- | Version @2014-03-28@ of the Amazon CloudWatch Logs service.
+data CloudWatchLogs
+
+instance AWSService CloudWatchLogs where
+    type Sg CloudWatchLogs = V4
+    type Er CloudWatchLogs = JSONError
+
+    service = Service
+        { _svcEndpoint     = regional
+        , _svcAbbrev       = "CloudWatchLogs"
+        , _svcPrefix       = "logs"
+        , _svcVersion      = "2014-03-28"
+        , _svcTargetPrefix = Just "Logs_20140328"
+        , _svcJSONVersion  = Just "1.1"
+        }
+
+    handle = jsonError statusSuccess
+
+data MetricFilter = MetricFilter
+    { _mfCreationTime          :: Maybe Nat
+    , _mfFilterName            :: Maybe Text
+    , _mfFilterPattern         :: Maybe Text
+    , _mfMetricTransformations :: List1 "metricTransformations" MetricTransformation
+    } deriving (Eq, Show)
+
+-- | 'MetricFilter' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'mfCreationTime' @::@ 'Maybe' 'Natural'
+--
+-- * 'mfFilterName' @::@ 'Maybe' 'Text'
+--
+-- * 'mfFilterPattern' @::@ 'Maybe' 'Text'
+--
+-- * 'mfMetricTransformations' @::@ 'NonEmpty' 'MetricTransformation'
+--
+metricFilter :: NonEmpty MetricTransformation -- ^ 'mfMetricTransformations'
+             -> MetricFilter
+metricFilter p1 = MetricFilter
+    { _mfMetricTransformations = withIso _List1 (const id) p1
+    , _mfFilterName            = Nothing
+    , _mfFilterPattern         = Nothing
+    , _mfCreationTime          = Nothing
+    }
+
+mfCreationTime :: Lens' MetricFilter (Maybe Natural)
+mfCreationTime = lens _mfCreationTime (\s a -> s { _mfCreationTime = a }) . mapping _Nat
+
+mfFilterName :: Lens' MetricFilter (Maybe Text)
+mfFilterName = lens _mfFilterName (\s a -> s { _mfFilterName = a })
+
+mfFilterPattern :: Lens' MetricFilter (Maybe Text)
+mfFilterPattern = lens _mfFilterPattern (\s a -> s { _mfFilterPattern = a })
+
+mfMetricTransformations :: Lens' MetricFilter (NonEmpty MetricTransformation)
+mfMetricTransformations =
+    lens _mfMetricTransformations (\s a -> s { _mfMetricTransformations = a })
+        . _List1
+
+instance FromJSON MetricFilter where
+    parseJSON = withObject "MetricFilter" $ \o -> MetricFilter
+        <$> o .:? "creationTime"
+        <*> o .:? "filterName"
+        <*> o .:? "filterPattern"
+        <*> o .:  "metricTransformations"
+
+instance ToJSON MetricFilter where
+    toJSON MetricFilter{..} = object
+        [ "filterName"            .= _mfFilterName
+        , "filterPattern"         .= _mfFilterPattern
+        , "metricTransformations" .= _mfMetricTransformations
+        , "creationTime"          .= _mfCreationTime
+        ]
+
+data MetricFilterMatchRecord = MetricFilterMatchRecord
+    { _mfmrEventMessage    :: Maybe Text
+    , _mfmrEventNumber     :: Maybe Integer
+    , _mfmrExtractedValues :: Map Text Text
+    } deriving (Eq, Show)
+
+-- | 'MetricFilterMatchRecord' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'mfmrEventMessage' @::@ 'Maybe' 'Text'
+--
+-- * 'mfmrEventNumber' @::@ 'Maybe' 'Integer'
+--
+-- * 'mfmrExtractedValues' @::@ 'HashMap' 'Text' 'Text'
+--
+metricFilterMatchRecord :: MetricFilterMatchRecord
+metricFilterMatchRecord = MetricFilterMatchRecord
+    { _mfmrEventNumber     = Nothing
+    , _mfmrEventMessage    = Nothing
+    , _mfmrExtractedValues = mempty
+    }
+
+mfmrEventMessage :: Lens' MetricFilterMatchRecord (Maybe Text)
+mfmrEventMessage = lens _mfmrEventMessage (\s a -> s { _mfmrEventMessage = a })
+
+mfmrEventNumber :: Lens' MetricFilterMatchRecord (Maybe Integer)
+mfmrEventNumber = lens _mfmrEventNumber (\s a -> s { _mfmrEventNumber = a })
+
+mfmrExtractedValues :: Lens' MetricFilterMatchRecord (HashMap Text Text)
+mfmrExtractedValues =
+    lens _mfmrExtractedValues (\s a -> s { _mfmrExtractedValues = a })
+        . _Map
+
+instance FromJSON MetricFilterMatchRecord where
+    parseJSON = withObject "MetricFilterMatchRecord" $ \o -> MetricFilterMatchRecord
+        <$> o .:? "eventMessage"
+        <*> o .:? "eventNumber"
+        <*> o .:  "extractedValues"
+
+instance ToJSON MetricFilterMatchRecord where
+    toJSON MetricFilterMatchRecord{..} = object
+        [ "eventNumber"     .= _mfmrEventNumber
+        , "eventMessage"    .= _mfmrEventMessage
+        , "extractedValues" .= _mfmrExtractedValues
+        ]
+
+data MetricTransformation = MetricTransformation
+    { _mtMetricName      :: Text
+    , _mtMetricNamespace :: Text
+    , _mtMetricValue     :: Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'MetricTransformation' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'mtMetricName' @::@ 'Text'
+--
+-- * 'mtMetricNamespace' @::@ 'Text'
+--
+-- * 'mtMetricValue' @::@ 'Text'
+--
+metricTransformation :: Text -- ^ 'mtMetricName'
+                     -> Text -- ^ 'mtMetricNamespace'
+                     -> Text -- ^ 'mtMetricValue'
+                     -> MetricTransformation
+metricTransformation p1 p2 p3 = MetricTransformation
+    { _mtMetricName      = p1
+    , _mtMetricNamespace = p2
+    , _mtMetricValue     = p3
+    }
+
+mtMetricName :: Lens' MetricTransformation Text
+mtMetricName = lens _mtMetricName (\s a -> s { _mtMetricName = a })
+
+mtMetricNamespace :: Lens' MetricTransformation Text
+mtMetricNamespace =
+    lens _mtMetricNamespace (\s a -> s { _mtMetricNamespace = a })
+
+mtMetricValue :: Lens' MetricTransformation Text
+mtMetricValue = lens _mtMetricValue (\s a -> s { _mtMetricValue = a })
+
+instance FromJSON MetricTransformation where
+    parseJSON = withObject "MetricTransformation" $ \o -> MetricTransformation
+        <$> o .:  "metricName"
+        <*> o .:  "metricNamespace"
+        <*> o .:  "metricValue"
+
+instance ToJSON MetricTransformation where
+    toJSON MetricTransformation{..} = object
+        [ "metricName"      .= _mtMetricName
+        , "metricNamespace" .= _mtMetricNamespace
+        , "metricValue"     .= _mtMetricValue
+        ]
+
+data LogStream = LogStream
+    { _lsArn                 :: Maybe Text
+    , _lsCreationTime        :: Maybe Nat
+    , _lsFirstEventTimestamp :: Maybe Nat
+    , _lsLastEventTimestamp  :: Maybe Nat
+    , _lsLastIngestionTime   :: Maybe Nat
+    , _lsLogStreamName       :: Maybe Text
+    , _lsStoredBytes         :: Maybe Nat
+    , _lsUploadSequenceToken :: Maybe Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'LogStream' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'lsArn' @::@ 'Maybe' 'Text'
+--
+-- * 'lsCreationTime' @::@ 'Maybe' 'Natural'
+--
+-- * 'lsFirstEventTimestamp' @::@ 'Maybe' 'Natural'
+--
+-- * 'lsLastEventTimestamp' @::@ 'Maybe' 'Natural'
+--
+-- * 'lsLastIngestionTime' @::@ 'Maybe' 'Natural'
+--
+-- * 'lsLogStreamName' @::@ 'Maybe' 'Text'
+--
+-- * 'lsStoredBytes' @::@ 'Maybe' 'Natural'
+--
+-- * 'lsUploadSequenceToken' @::@ 'Maybe' 'Text'
+--
+logStream :: LogStream
+logStream = LogStream
+    { _lsLogStreamName       = Nothing
+    , _lsCreationTime        = Nothing
+    , _lsFirstEventTimestamp = Nothing
+    , _lsLastEventTimestamp  = Nothing
+    , _lsLastIngestionTime   = Nothing
+    , _lsUploadSequenceToken = Nothing
+    , _lsArn                 = Nothing
+    , _lsStoredBytes         = Nothing
+    }
+
+lsArn :: Lens' LogStream (Maybe Text)
+lsArn = lens _lsArn (\s a -> s { _lsArn = a })
+
+lsCreationTime :: Lens' LogStream (Maybe Natural)
+lsCreationTime = lens _lsCreationTime (\s a -> s { _lsCreationTime = a }) . mapping _Nat
+
+lsFirstEventTimestamp :: Lens' LogStream (Maybe Natural)
+lsFirstEventTimestamp =
+    lens _lsFirstEventTimestamp (\s a -> s { _lsFirstEventTimestamp = a })
+        . mapping _Nat
+
+lsLastEventTimestamp :: Lens' LogStream (Maybe Natural)
+lsLastEventTimestamp =
+    lens _lsLastEventTimestamp (\s a -> s { _lsLastEventTimestamp = a })
+        . mapping _Nat
+
+lsLastIngestionTime :: Lens' LogStream (Maybe Natural)
+lsLastIngestionTime =
+    lens _lsLastIngestionTime (\s a -> s { _lsLastIngestionTime = a })
+        . mapping _Nat
+
+lsLogStreamName :: Lens' LogStream (Maybe Text)
+lsLogStreamName = lens _lsLogStreamName (\s a -> s { _lsLogStreamName = a })
+
+lsStoredBytes :: Lens' LogStream (Maybe Natural)
+lsStoredBytes = lens _lsStoredBytes (\s a -> s { _lsStoredBytes = a }) . mapping _Nat
+
+lsUploadSequenceToken :: Lens' LogStream (Maybe Text)
+lsUploadSequenceToken =
+    lens _lsUploadSequenceToken (\s a -> s { _lsUploadSequenceToken = a })
+
+instance FromJSON LogStream where
+    parseJSON = withObject "LogStream" $ \o -> LogStream
+        <$> o .:? "arn"
+        <*> o .:? "creationTime"
+        <*> o .:? "firstEventTimestamp"
+        <*> o .:? "lastEventTimestamp"
+        <*> o .:? "lastIngestionTime"
+        <*> o .:? "logStreamName"
+        <*> o .:? "storedBytes"
+        <*> o .:? "uploadSequenceToken"
+
+instance ToJSON LogStream where
+    toJSON LogStream{..} = object
+        [ "logStreamName"       .= _lsLogStreamName
+        , "creationTime"        .= _lsCreationTime
+        , "firstEventTimestamp" .= _lsFirstEventTimestamp
+        , "lastEventTimestamp"  .= _lsLastEventTimestamp
+        , "lastIngestionTime"   .= _lsLastIngestionTime
+        , "uploadSequenceToken" .= _lsUploadSequenceToken
+        , "arn"                 .= _lsArn
+        , "storedBytes"         .= _lsStoredBytes
+        ]
+
+data LogGroup = LogGroup
+    { _lgArn               :: Maybe Text
+    , _lgCreationTime      :: Maybe Nat
+    , _lgLogGroupName      :: Maybe Text
+    , _lgMetricFilterCount :: Maybe Int
+    , _lgRetentionInDays   :: Maybe Int
+    , _lgStoredBytes       :: Maybe Nat
+    } deriving (Eq, Ord, Show)
+
+-- | 'LogGroup' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'lgArn' @::@ 'Maybe' 'Text'
+--
+-- * 'lgCreationTime' @::@ 'Maybe' 'Natural'
+--
+-- * 'lgLogGroupName' @::@ 'Maybe' 'Text'
+--
+-- * 'lgMetricFilterCount' @::@ 'Maybe' 'Int'
+--
+-- * 'lgRetentionInDays' @::@ 'Maybe' 'Int'
+--
+-- * 'lgStoredBytes' @::@ 'Maybe' 'Natural'
+--
+logGroup :: LogGroup
+logGroup = LogGroup
+    { _lgLogGroupName      = Nothing
+    , _lgCreationTime      = Nothing
+    , _lgRetentionInDays   = Nothing
+    , _lgMetricFilterCount = Nothing
+    , _lgArn               = Nothing
+    , _lgStoredBytes       = Nothing
+    }
+
+lgArn :: Lens' LogGroup (Maybe Text)
+lgArn = lens _lgArn (\s a -> s { _lgArn = a })
+
+lgCreationTime :: Lens' LogGroup (Maybe Natural)
+lgCreationTime = lens _lgCreationTime (\s a -> s { _lgCreationTime = a }) . mapping _Nat
+
+lgLogGroupName :: Lens' LogGroup (Maybe Text)
+lgLogGroupName = lens _lgLogGroupName (\s a -> s { _lgLogGroupName = a })
+
+lgMetricFilterCount :: Lens' LogGroup (Maybe Int)
+lgMetricFilterCount =
+    lens _lgMetricFilterCount (\s a -> s { _lgMetricFilterCount = a })
+
+lgRetentionInDays :: Lens' LogGroup (Maybe Int)
+lgRetentionInDays =
+    lens _lgRetentionInDays (\s a -> s { _lgRetentionInDays = a })
+
+lgStoredBytes :: Lens' LogGroup (Maybe Natural)
+lgStoredBytes = lens _lgStoredBytes (\s a -> s { _lgStoredBytes = a }) . mapping _Nat
+
+instance FromJSON LogGroup where
+    parseJSON = withObject "LogGroup" $ \o -> LogGroup
+        <$> o .:? "arn"
+        <*> o .:? "creationTime"
+        <*> o .:? "logGroupName"
+        <*> o .:? "metricFilterCount"
+        <*> o .:? "retentionInDays"
+        <*> o .:? "storedBytes"
+
+instance ToJSON LogGroup where
+    toJSON LogGroup{..} = object
+        [ "logGroupName"      .= _lgLogGroupName
+        , "creationTime"      .= _lgCreationTime
+        , "retentionInDays"   .= _lgRetentionInDays
+        , "metricFilterCount" .= _lgMetricFilterCount
+        , "arn"               .= _lgArn
+        , "storedBytes"       .= _lgStoredBytes
+        ]
+
+data InputLogEvent = InputLogEvent
+    { _ileMessage   :: Text
+    , _ileTimestamp :: Nat
+    } deriving (Eq, Ord, Show)
+
+-- | 'InputLogEvent' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ileMessage' @::@ 'Text'
+--
+-- * 'ileTimestamp' @::@ 'Natural'
+--
+inputLogEvent :: Natural -- ^ 'ileTimestamp'
+              -> Text -- ^ 'ileMessage'
+              -> InputLogEvent
+inputLogEvent p1 p2 = InputLogEvent
+    { _ileTimestamp = withIso _Nat (const id) p1
+    , _ileMessage   = p2
+    }
+
+ileMessage :: Lens' InputLogEvent Text
+ileMessage = lens _ileMessage (\s a -> s { _ileMessage = a })
+
+ileTimestamp :: Lens' InputLogEvent Natural
+ileTimestamp = lens _ileTimestamp (\s a -> s { _ileTimestamp = a }) . _Nat
+
+instance FromJSON InputLogEvent where
+    parseJSON = withObject "InputLogEvent" $ \o -> InputLogEvent
+        <$> o .:  "message"
+        <*> o .:  "timestamp"
+
+instance ToJSON InputLogEvent where
+    toJSON InputLogEvent{..} = object
+        [ "timestamp" .= _ileTimestamp
+        , "message"   .= _ileMessage
+        ]
+
+data OutputLogEvent = OutputLogEvent
+    { _oleIngestionTime :: Maybe Nat
+    , _oleMessage       :: Maybe Text
+    , _oleTimestamp     :: Maybe Nat
+    } deriving (Eq, Ord, Show)
+
+-- | 'OutputLogEvent' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'oleIngestionTime' @::@ 'Maybe' 'Natural'
+--
+-- * 'oleMessage' @::@ 'Maybe' 'Text'
+--
+-- * 'oleTimestamp' @::@ 'Maybe' 'Natural'
+--
+outputLogEvent :: OutputLogEvent
+outputLogEvent = OutputLogEvent
+    { _oleTimestamp     = Nothing
+    , _oleMessage       = Nothing
+    , _oleIngestionTime = Nothing
+    }
+
+oleIngestionTime :: Lens' OutputLogEvent (Maybe Natural)
+oleIngestionTime = lens _oleIngestionTime (\s a -> s { _oleIngestionTime = a }) . mapping _Nat
+
+oleMessage :: Lens' OutputLogEvent (Maybe Text)
+oleMessage = lens _oleMessage (\s a -> s { _oleMessage = a })
+
+oleTimestamp :: Lens' OutputLogEvent (Maybe Natural)
+oleTimestamp = lens _oleTimestamp (\s a -> s { _oleTimestamp = a }) . mapping _Nat
+
+instance FromJSON OutputLogEvent where
+    parseJSON = withObject "OutputLogEvent" $ \o -> OutputLogEvent
+        <$> o .:? "ingestionTime"
+        <*> o .:? "message"
+        <*> o .:? "timestamp"
+
+instance ToJSON OutputLogEvent where
+    toJSON OutputLogEvent{..} = object
+        [ "timestamp"     .= _oleTimestamp
+        , "message"       .= _oleMessage
+        , "ingestionTime" .= _oleIngestionTime
+        ]
