diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,367 @@
+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.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,46 @@
+# Amazon WAF SDK
+
+* [Version](#version)
+* [Description](#description)
+* [Contribute](#contribute)
+* [Licence](#licence)
+
+
+## Version
+
+`1.3.3`
+
+
+## Description
+
+This is the /AWS WAF API Reference/. This guide is for developers who
+need detailed information about the AWS WAF API actions, data types, and
+errors. For detailed information about AWS WAF features and an overview
+of how to use the AWS WAF API, see the
+<http://docs.aws.amazon.com/waf/latest/dev/ AWS WAF Developer Guide>.
+
+Documentation is available via [Hackage](http://hackage.haskell.org/package/amazonka-waf)
+and the [AWS API Reference](http://docs.aws.amazon.com/waf/latest/APIReference/Welcome.html).
+
+The types from this library are intended to be used with [amazonka](http://hackage.haskell.org/package/amazonka),
+which provides mechanisms for specifying AuthN/AuthZ information and sending requests.
+
+Use of lenses is required for constructing and manipulating types.
+This is due to the amount of nesting of AWS types and transparency regarding
+de/serialisation into more palatable Haskell values.
+The provided lenses should be compatible with any of the major lens libraries
+[lens](http://hackage.haskell.org/package/lens) or [lens-family-core](http://hackage.haskell.org/package/lens-family-core).
+
+## 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-waf` is released under the [Mozilla Public License Version 2.0](http://www.mozilla.org/MPL/).
+
+Parts of the code are derived from AWS service descriptions, licensed under Apache 2.0.
+Source files subject to this contain an additional licensing clause in their header.
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-waf.cabal b/amazonka-waf.cabal
new file mode 100644
--- /dev/null
+++ b/amazonka-waf.cabal
@@ -0,0 +1,114 @@
+name:                  amazonka-waf
+version:               1.3.3
+synopsis:              Amazon WAF SDK.
+homepage:              https://github.com/brendanhay/amazonka
+bug-reports:           https://github.com/brendanhay/amazonka/issues
+license:               OtherLicense
+license-file:          LICENSE
+author:                Brendan Hay
+maintainer:            Brendan Hay <brendan.g.hay@gmail.com>
+copyright:             Copyright (c) 2013-2015 Brendan Hay
+category:              Network, AWS, Cloud, Distributed Computing
+build-type:            Simple
+cabal-version:         >= 1.10
+extra-source-files:    README.md fixture/*.yaml fixture/*.proto
+description:
+    This is the /AWS WAF API Reference/. This guide is for developers who
+    need detailed information about the AWS WAF API actions, data types, and
+    errors. For detailed information about AWS WAF features and an overview
+    of how to use the AWS WAF API, see the
+    <http://docs.aws.amazon.com/waf/latest/dev/ AWS WAF Developer Guide>.
+    .
+    The types from this library are intended to be used with
+    <http://hackage.haskell.org/package/amazonka amazonka>, which provides
+    mechanisms for specifying AuthN/AuthZ information and sending requests.
+    .
+    Use of lenses is required for constructing and manipulating types.
+    This is due to the amount of nesting of AWS types and transparency regarding
+    de/serialisation into more palatable Haskell values.
+    The provided lenses should be compatible with any of the major lens libraries
+    such as <http://hackage.haskell.org/package/lens lens> or
+    <http://hackage.haskell.org/package/lens-family-core lens-family-core>.
+    .
+    See "Network.AWS.WAF" and the <http://docs.aws.amazon.com/waf/latest/APIReference/Welcome.html AWS API Reference>
+    to get started.
+
+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.WAF
+        , Network.AWS.WAF.CreateByteMatchSet
+        , Network.AWS.WAF.CreateIPSet
+        , Network.AWS.WAF.CreateRule
+        , Network.AWS.WAF.CreateSqlInjectionMatchSet
+        , Network.AWS.WAF.CreateWebACL
+        , Network.AWS.WAF.DeleteByteMatchSet
+        , Network.AWS.WAF.DeleteIPSet
+        , Network.AWS.WAF.DeleteRule
+        , Network.AWS.WAF.DeleteSqlInjectionMatchSet
+        , Network.AWS.WAF.DeleteWebACL
+        , Network.AWS.WAF.GetByteMatchSet
+        , Network.AWS.WAF.GetChangeToken
+        , Network.AWS.WAF.GetChangeTokenStatus
+        , Network.AWS.WAF.GetIPSet
+        , Network.AWS.WAF.GetRule
+        , Network.AWS.WAF.GetSampledRequests
+        , Network.AWS.WAF.GetSqlInjectionMatchSet
+        , Network.AWS.WAF.GetWebACL
+        , Network.AWS.WAF.ListByteMatchSets
+        , Network.AWS.WAF.ListIPSets
+        , Network.AWS.WAF.ListRules
+        , Network.AWS.WAF.ListSqlInjectionMatchSets
+        , Network.AWS.WAF.ListWebACLs
+        , Network.AWS.WAF.Types
+        , Network.AWS.WAF.UpdateByteMatchSet
+        , Network.AWS.WAF.UpdateIPSet
+        , Network.AWS.WAF.UpdateRule
+        , Network.AWS.WAF.UpdateSqlInjectionMatchSet
+        , Network.AWS.WAF.UpdateWebACL
+        , Network.AWS.WAF.Waiters
+
+    other-modules:
+          Network.AWS.WAF.Types.Product
+        , Network.AWS.WAF.Types.Sum
+
+    build-depends:
+          amazonka-core == 1.3.3.*
+        , base          >= 4.7     && < 5
+
+test-suite amazonka-waf-test
+    type:              exitcode-stdio-1.0
+    default-language:  Haskell2010
+    hs-source-dirs:    test
+    main-is:           Main.hs
+
+    ghc-options:       -Wall -threaded
+
+    -- This section is encoded by the template and any modules added by
+    -- hand outside these namespaces will not correctly be added to the
+    -- distribution package.
+    other-modules:
+          Test.AWS.WAF
+        , Test.AWS.Gen.WAF
+        , Test.AWS.WAF.Internal
+
+    build-depends:
+          amazonka-core == 1.3.3.*
+        , amazonka-test == 1.3.3.*
+        , amazonka-waf == 1.3.3.*
+        , base
+        , bytestring
+        , lens
+        , tasty
+        , tasty-hunit
+        , text
+        , time
+        , unordered-containers
diff --git a/fixture/CreateByteMatchSet.yaml b/fixture/CreateByteMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CreateByteMatchSet.yaml
diff --git a/fixture/CreateByteMatchSetResponse.proto b/fixture/CreateByteMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CreateByteMatchSetResponse.proto
diff --git a/fixture/CreateIPSet.yaml b/fixture/CreateIPSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CreateIPSet.yaml
diff --git a/fixture/CreateIPSetResponse.proto b/fixture/CreateIPSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CreateIPSetResponse.proto
diff --git a/fixture/CreateRule.yaml b/fixture/CreateRule.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CreateRule.yaml
diff --git a/fixture/CreateRuleResponse.proto b/fixture/CreateRuleResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CreateRuleResponse.proto
diff --git a/fixture/CreateSqlInjectionMatchSet.yaml b/fixture/CreateSqlInjectionMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CreateSqlInjectionMatchSet.yaml
diff --git a/fixture/CreateSqlInjectionMatchSetResponse.proto b/fixture/CreateSqlInjectionMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CreateSqlInjectionMatchSetResponse.proto
diff --git a/fixture/CreateWebACL.yaml b/fixture/CreateWebACL.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CreateWebACL.yaml
diff --git a/fixture/CreateWebACLResponse.proto b/fixture/CreateWebACLResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CreateWebACLResponse.proto
diff --git a/fixture/DeleteByteMatchSet.yaml b/fixture/DeleteByteMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteByteMatchSet.yaml
diff --git a/fixture/DeleteByteMatchSetResponse.proto b/fixture/DeleteByteMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteByteMatchSetResponse.proto
diff --git a/fixture/DeleteIPSet.yaml b/fixture/DeleteIPSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteIPSet.yaml
diff --git a/fixture/DeleteIPSetResponse.proto b/fixture/DeleteIPSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteIPSetResponse.proto
diff --git a/fixture/DeleteRule.yaml b/fixture/DeleteRule.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteRule.yaml
diff --git a/fixture/DeleteRuleResponse.proto b/fixture/DeleteRuleResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteRuleResponse.proto
diff --git a/fixture/DeleteSqlInjectionMatchSet.yaml b/fixture/DeleteSqlInjectionMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteSqlInjectionMatchSet.yaml
diff --git a/fixture/DeleteSqlInjectionMatchSetResponse.proto b/fixture/DeleteSqlInjectionMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteSqlInjectionMatchSetResponse.proto
diff --git a/fixture/DeleteWebACL.yaml b/fixture/DeleteWebACL.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteWebACL.yaml
diff --git a/fixture/DeleteWebACLResponse.proto b/fixture/DeleteWebACLResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteWebACLResponse.proto
diff --git a/fixture/GetByteMatchSet.yaml b/fixture/GetByteMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetByteMatchSet.yaml
diff --git a/fixture/GetByteMatchSetResponse.proto b/fixture/GetByteMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetByteMatchSetResponse.proto
diff --git a/fixture/GetChangeToken.yaml b/fixture/GetChangeToken.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetChangeToken.yaml
diff --git a/fixture/GetChangeTokenResponse.proto b/fixture/GetChangeTokenResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetChangeTokenResponse.proto
diff --git a/fixture/GetChangeTokenStatus.yaml b/fixture/GetChangeTokenStatus.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetChangeTokenStatus.yaml
diff --git a/fixture/GetChangeTokenStatusResponse.proto b/fixture/GetChangeTokenStatusResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetChangeTokenStatusResponse.proto
diff --git a/fixture/GetIPSet.yaml b/fixture/GetIPSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetIPSet.yaml
diff --git a/fixture/GetIPSetResponse.proto b/fixture/GetIPSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetIPSetResponse.proto
diff --git a/fixture/GetRule.yaml b/fixture/GetRule.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetRule.yaml
diff --git a/fixture/GetRuleResponse.proto b/fixture/GetRuleResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetRuleResponse.proto
diff --git a/fixture/GetSampledRequests.yaml b/fixture/GetSampledRequests.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetSampledRequests.yaml
diff --git a/fixture/GetSampledRequestsResponse.proto b/fixture/GetSampledRequestsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetSampledRequestsResponse.proto
diff --git a/fixture/GetSqlInjectionMatchSet.yaml b/fixture/GetSqlInjectionMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetSqlInjectionMatchSet.yaml
diff --git a/fixture/GetSqlInjectionMatchSetResponse.proto b/fixture/GetSqlInjectionMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetSqlInjectionMatchSetResponse.proto
diff --git a/fixture/GetWebACL.yaml b/fixture/GetWebACL.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetWebACL.yaml
diff --git a/fixture/GetWebACLResponse.proto b/fixture/GetWebACLResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetWebACLResponse.proto
diff --git a/fixture/ListByteMatchSets.yaml b/fixture/ListByteMatchSets.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListByteMatchSets.yaml
diff --git a/fixture/ListByteMatchSetsResponse.proto b/fixture/ListByteMatchSetsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListByteMatchSetsResponse.proto
diff --git a/fixture/ListIPSets.yaml b/fixture/ListIPSets.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListIPSets.yaml
diff --git a/fixture/ListIPSetsResponse.proto b/fixture/ListIPSetsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListIPSetsResponse.proto
diff --git a/fixture/ListRules.yaml b/fixture/ListRules.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListRules.yaml
diff --git a/fixture/ListRulesResponse.proto b/fixture/ListRulesResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListRulesResponse.proto
diff --git a/fixture/ListSqlInjectionMatchSets.yaml b/fixture/ListSqlInjectionMatchSets.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListSqlInjectionMatchSets.yaml
diff --git a/fixture/ListSqlInjectionMatchSetsResponse.proto b/fixture/ListSqlInjectionMatchSetsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListSqlInjectionMatchSetsResponse.proto
diff --git a/fixture/ListWebACLs.yaml b/fixture/ListWebACLs.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListWebACLs.yaml
diff --git a/fixture/ListWebACLsResponse.proto b/fixture/ListWebACLsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListWebACLsResponse.proto
diff --git a/fixture/UpdateByteMatchSet.yaml b/fixture/UpdateByteMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateByteMatchSet.yaml
diff --git a/fixture/UpdateByteMatchSetResponse.proto b/fixture/UpdateByteMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateByteMatchSetResponse.proto
diff --git a/fixture/UpdateIPSet.yaml b/fixture/UpdateIPSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateIPSet.yaml
diff --git a/fixture/UpdateIPSetResponse.proto b/fixture/UpdateIPSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateIPSetResponse.proto
diff --git a/fixture/UpdateRule.yaml b/fixture/UpdateRule.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateRule.yaml
diff --git a/fixture/UpdateRuleResponse.proto b/fixture/UpdateRuleResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateRuleResponse.proto
diff --git a/fixture/UpdateSqlInjectionMatchSet.yaml b/fixture/UpdateSqlInjectionMatchSet.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateSqlInjectionMatchSet.yaml
diff --git a/fixture/UpdateSqlInjectionMatchSetResponse.proto b/fixture/UpdateSqlInjectionMatchSetResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateSqlInjectionMatchSetResponse.proto
diff --git a/fixture/UpdateWebACL.yaml b/fixture/UpdateWebACL.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateWebACL.yaml
diff --git a/fixture/UpdateWebACLResponse.proto b/fixture/UpdateWebACLResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateWebACLResponse.proto
diff --git a/gen/Network/AWS/WAF.hs b/gen/Network/AWS/WAF.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF.hs
@@ -0,0 +1,411 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports    #-}
+{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- This is the /AWS WAF API Reference/. This guide is for developers who
+-- need detailed information about the AWS WAF API actions, data types, and
+-- errors. For detailed information about AWS WAF features and an overview
+-- of how to use the AWS WAF API, see the
+-- <http://docs.aws.amazon.com/waf/latest/dev/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/Welcome.html AWS API Reference>
+module Network.AWS.WAF
+    (
+    -- * Service Configuration
+      wAF
+
+    -- * Errors
+    -- $errors
+
+    -- ** WAFInvalidAccountException
+    , _WAFInvalidAccountException
+
+    -- ** WAFReferencedItemException
+    , _WAFReferencedItemException
+
+    -- ** WAFInvalidOperationException
+    , _WAFInvalidOperationException
+
+    -- ** WAFNonexistentItemException
+    , _WAFNonexistentItemException
+
+    -- ** WAFInvalidParameterException
+    , _WAFInvalidParameterException
+
+    -- ** WAFLimitsExceededException
+    , _WAFLimitsExceededException
+
+    -- ** WAFStaleDataException
+    , _WAFStaleDataException
+
+    -- ** WAFInternalErrorException
+    , _WAFInternalErrorException
+
+    -- ** WAFNonexistentContainerException
+    , _WAFNonexistentContainerException
+
+    -- ** WAFDisallowedNameException
+    , _WAFDisallowedNameException
+
+    -- ** WAFNonEmptyEntityException
+    , _WAFNonEmptyEntityException
+
+    -- * Waiters
+    -- $waiters
+
+    -- * Operations
+    -- $operations
+
+    -- ** UpdateRule
+    , module Network.AWS.WAF.UpdateRule
+
+    -- ** DeleteRule
+    , module Network.AWS.WAF.DeleteRule
+
+    -- ** CreateIPSet
+    , module Network.AWS.WAF.CreateIPSet
+
+    -- ** GetChangeTokenStatus
+    , module Network.AWS.WAF.GetChangeTokenStatus
+
+    -- ** DeleteWebACL
+    , module Network.AWS.WAF.DeleteWebACL
+
+    -- ** UpdateWebACL
+    , module Network.AWS.WAF.UpdateWebACL
+
+    -- ** ListWebACLs
+    , module Network.AWS.WAF.ListWebACLs
+
+    -- ** ListRules
+    , module Network.AWS.WAF.ListRules
+
+    -- ** CreateRule
+    , module Network.AWS.WAF.CreateRule
+
+    -- ** CreateWebACL
+    , module Network.AWS.WAF.CreateWebACL
+
+    -- ** ListByteMatchSets
+    , module Network.AWS.WAF.ListByteMatchSets
+
+    -- ** GetIPSet
+    , module Network.AWS.WAF.GetIPSet
+
+    -- ** GetWebACL
+    , module Network.AWS.WAF.GetWebACL
+
+    -- ** GetRule
+    , module Network.AWS.WAF.GetRule
+
+    -- ** GetChangeToken
+    , module Network.AWS.WAF.GetChangeToken
+
+    -- ** GetSampledRequests
+    , module Network.AWS.WAF.GetSampledRequests
+
+    -- ** GetSqlInjectionMatchSet
+    , module Network.AWS.WAF.GetSqlInjectionMatchSet
+
+    -- ** CreateSqlInjectionMatchSet
+    , module Network.AWS.WAF.CreateSqlInjectionMatchSet
+
+    -- ** CreateByteMatchSet
+    , module Network.AWS.WAF.CreateByteMatchSet
+
+    -- ** UpdateByteMatchSet
+    , module Network.AWS.WAF.UpdateByteMatchSet
+
+    -- ** DeleteByteMatchSet
+    , module Network.AWS.WAF.DeleteByteMatchSet
+
+    -- ** DeleteIPSet
+    , module Network.AWS.WAF.DeleteIPSet
+
+    -- ** UpdateIPSet
+    , module Network.AWS.WAF.UpdateIPSet
+
+    -- ** ListIPSets
+    , module Network.AWS.WAF.ListIPSets
+
+    -- ** GetByteMatchSet
+    , module Network.AWS.WAF.GetByteMatchSet
+
+    -- ** ListSqlInjectionMatchSets
+    , module Network.AWS.WAF.ListSqlInjectionMatchSets
+
+    -- ** DeleteSqlInjectionMatchSet
+    , module Network.AWS.WAF.DeleteSqlInjectionMatchSet
+
+    -- ** UpdateSqlInjectionMatchSet
+    , module Network.AWS.WAF.UpdateSqlInjectionMatchSet
+
+    -- * Types
+
+    -- ** ChangeAction
+    , ChangeAction (..)
+
+    -- ** ChangeTokenStatus
+    , ChangeTokenStatus (..)
+
+    -- ** IPSetDescriptorType
+    , IPSetDescriptorType (..)
+
+    -- ** MatchFieldType
+    , MatchFieldType (..)
+
+    -- ** PositionalConstraint
+    , PositionalConstraint (..)
+
+    -- ** PredicateType
+    , PredicateType (..)
+
+    -- ** TextTransformation
+    , TextTransformation (..)
+
+    -- ** WafActionType
+    , WafActionType (..)
+
+    -- ** ActivatedRule
+    , ActivatedRule
+    , activatedRule
+    , arPriority
+    , arRuleId
+    , arAction
+
+    -- ** ByteMatchSet
+    , ByteMatchSet
+    , byteMatchSet
+    , bmsName
+    , bmsByteMatchSetId
+    , bmsByteMatchTuples
+
+    -- ** ByteMatchSetSummary
+    , ByteMatchSetSummary
+    , byteMatchSetSummary
+    , bmssByteMatchSetId
+    , bmssName
+
+    -- ** ByteMatchSetUpdate
+    , ByteMatchSetUpdate
+    , byteMatchSetUpdate
+    , bmsuAction
+    , bmsuByteMatchTuple
+
+    -- ** ByteMatchTuple
+    , ByteMatchTuple
+    , byteMatchTuple
+    , bmtFieldToMatch
+    , bmtTargetString
+    , bmtTextTransformation
+    , bmtPositionalConstraint
+
+    -- ** FieldToMatch
+    , FieldToMatch
+    , fieldToMatch
+    , ftmData
+    , ftmType
+
+    -- ** HTTPHeader
+    , HTTPHeader
+    , hTTPHeader
+    , httphValue
+    , httphName
+
+    -- ** HTTPRequest
+    , HTTPRequest
+    , hTTPRequest
+    , httprHTTPVersion
+    , httprCountry
+    , httprURI
+    , httprHeaders
+    , httprMethod
+    , httprClientIP
+
+    -- ** IPSet
+    , IPSet
+    , ipSet
+    , isName
+    , isIPSetId
+    , isIPSetDescriptors
+
+    -- ** IPSetDescriptor
+    , IPSetDescriptor
+    , ipSetDescriptor
+    , isdType
+    , isdValue
+
+    -- ** IPSetSummary
+    , IPSetSummary
+    , ipSetSummary
+    , issIPSetId
+    , issName
+
+    -- ** IPSetUpdate
+    , IPSetUpdate
+    , ipSetUpdate
+    , isuAction
+    , isuIPSetDescriptor
+
+    -- ** Predicate
+    , Predicate
+    , predicate
+    , pNegated
+    , pType
+    , pDataId
+
+    -- ** Rule
+    , Rule
+    , rule
+    , rMetricName
+    , rName
+    , rRuleId
+    , rPredicates
+
+    -- ** RuleSummary
+    , RuleSummary
+    , ruleSummary
+    , rsRuleId
+    , rsName
+
+    -- ** RuleUpdate
+    , RuleUpdate
+    , ruleUpdate
+    , ruAction
+    , ruPredicate
+
+    -- ** SampledHTTPRequest
+    , SampledHTTPRequest
+    , sampledHTTPRequest
+    , shttprAction
+    , shttprTimestamp
+    , shttprRequest
+    , shttprWeight
+
+    -- ** SqlInjectionMatchSet
+    , SqlInjectionMatchSet
+    , sqlInjectionMatchSet
+    , simsName
+    , simsSqlInjectionMatchSetId
+    , simsSqlInjectionMatchTuples
+
+    -- ** SqlInjectionMatchSetSummary
+    , SqlInjectionMatchSetSummary
+    , sqlInjectionMatchSetSummary
+    , simssSqlInjectionMatchSetId
+    , simssName
+
+    -- ** SqlInjectionMatchSetUpdate
+    , SqlInjectionMatchSetUpdate
+    , sqlInjectionMatchSetUpdate
+    , simsuAction
+    , simsuSqlInjectionMatchTuple
+
+    -- ** SqlInjectionMatchTuple
+    , SqlInjectionMatchTuple
+    , sqlInjectionMatchTuple
+    , simtFieldToMatch
+    , simtTextTransformation
+
+    -- ** TimeWindow
+    , TimeWindow
+    , timeWindow
+    , twStartTime
+    , twEndTime
+
+    -- ** WafAction
+    , WafAction
+    , wafAction
+    , waType
+
+    -- ** WebACL
+    , WebACL
+    , webACL
+    , waMetricName
+    , waName
+    , waWebACLId
+    , waDefaultAction
+    , waRules
+
+    -- ** WebACLSummary
+    , WebACLSummary
+    , webACLSummary
+    , wasWebACLId
+    , wasName
+
+    -- ** WebACLUpdate
+    , WebACLUpdate
+    , webACLUpdate
+    , wauAction
+    , wauActivatedRule
+    ) where
+
+import           Network.AWS.WAF.CreateByteMatchSet
+import           Network.AWS.WAF.CreateIPSet
+import           Network.AWS.WAF.CreateRule
+import           Network.AWS.WAF.CreateSqlInjectionMatchSet
+import           Network.AWS.WAF.CreateWebACL
+import           Network.AWS.WAF.DeleteByteMatchSet
+import           Network.AWS.WAF.DeleteIPSet
+import           Network.AWS.WAF.DeleteRule
+import           Network.AWS.WAF.DeleteSqlInjectionMatchSet
+import           Network.AWS.WAF.DeleteWebACL
+import           Network.AWS.WAF.GetByteMatchSet
+import           Network.AWS.WAF.GetChangeToken
+import           Network.AWS.WAF.GetChangeTokenStatus
+import           Network.AWS.WAF.GetIPSet
+import           Network.AWS.WAF.GetRule
+import           Network.AWS.WAF.GetSampledRequests
+import           Network.AWS.WAF.GetSqlInjectionMatchSet
+import           Network.AWS.WAF.GetWebACL
+import           Network.AWS.WAF.ListByteMatchSets
+import           Network.AWS.WAF.ListIPSets
+import           Network.AWS.WAF.ListRules
+import           Network.AWS.WAF.ListSqlInjectionMatchSets
+import           Network.AWS.WAF.ListWebACLs
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.UpdateByteMatchSet
+import           Network.AWS.WAF.UpdateIPSet
+import           Network.AWS.WAF.UpdateRule
+import           Network.AWS.WAF.UpdateSqlInjectionMatchSet
+import           Network.AWS.WAF.UpdateWebACL
+import           Network.AWS.WAF.Waiters
+
+{- $errors
+Error matchers are designed for use with the functions provided by
+<http://hackage.haskell.org/package/lens/docs/Control-Exception-Lens.html Control.Exception.Lens>.
+This allows catching (and rethrowing) service specific errors returned
+by 'WAF'.
+-}
+
+{- $operations
+Some AWS operations return results that are incomplete and require subsequent
+requests in order to obtain the entire result set. The process of sending
+subsequent requests to continue where a previous request left off is called
+pagination. For example, the 'ListObjects' operation of Amazon S3 returns up to
+1000 objects at a time, and you must send subsequent requests with the
+appropriate Marker in order to retrieve the next page of results.
+
+Operations that have an 'AWSPager' instance can transparently perform subsequent
+requests, correctly setting Markers and other request facets to iterate through
+the entire result set of a truncated API operation. Operations which support
+this have an additional note in the documentation.
+
+Many operations have the ability to filter results on the server side. See the
+individual operation parameters for details.
+-}
+
+{- $waiters
+Waiters poll by repeatedly sending a request until some remote success condition
+configured by the 'Wait' specification is fulfilled. The 'Wait' specification
+determines how many attempts should be made, in addition to delay and retry strategies.
+-}
diff --git a/gen/Network/AWS/WAF/CreateByteMatchSet.hs b/gen/Network/AWS/WAF/CreateByteMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/CreateByteMatchSet.hs
@@ -0,0 +1,171 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.CreateByteMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Creates a 'ByteMatchSet'. You then use UpdateByteMatchSet to identify
+-- the part of a web request that you want AWS WAF to inspect, such as the
+-- values of the 'User-Agent' header or the query string. For example, you
+-- can create a 'ByteMatchSet' that matches any requests with 'User-Agent'
+-- headers that contain the string 'BadBot'. You can then configure AWS WAF
+-- to reject those requests.
+--
+-- To create and configure a 'ByteMatchSet', perform the following steps:
+--
+-- 1.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'CreateByteMatchSet' request.
+-- 2.  Submit a 'CreateByteMatchSet' request.
+-- 3.  Use 'GetChangeToken' to get the change token that you provide in the
+--     'ChangeToken' parameter of an 'UpdateByteMatchSet' request.
+-- 4.  Submit an UpdateByteMatchSet request to specify the part of the
+--     request that you want AWS WAF to inspect (for example, the header or
+--     the URI) and the value that you want AWS WAF to watch for.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_CreateByteMatchSet.html AWS API Reference> for CreateByteMatchSet.
+module Network.AWS.WAF.CreateByteMatchSet
+    (
+    -- * Creating a Request
+      createByteMatchSet
+    , CreateByteMatchSet
+    -- * Request Lenses
+    , cbmsName
+    , cbmsChangeToken
+
+    -- * Destructuring the Response
+    , createByteMatchSetResponse
+    , CreateByteMatchSetResponse
+    -- * Response Lenses
+    , cbmsrsByteMatchSet
+    , cbmsrsChangeToken
+    , cbmsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'createByteMatchSet' smart constructor.
+data CreateByteMatchSet = CreateByteMatchSet'
+    { _cbmsName        :: !Text
+    , _cbmsChangeToken :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateByteMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'cbmsName'
+--
+-- * 'cbmsChangeToken'
+createByteMatchSet
+    :: Text -- ^ 'cbmsName'
+    -> Text -- ^ 'cbmsChangeToken'
+    -> CreateByteMatchSet
+createByteMatchSet pName_ pChangeToken_ =
+    CreateByteMatchSet'
+    { _cbmsName = pName_
+    , _cbmsChangeToken = pChangeToken_
+    }
+
+-- | A friendly name or description of the ByteMatchSet. You can\'t change
+-- 'Name' after you create a 'ByteMatchSet'.
+cbmsName :: Lens' CreateByteMatchSet Text
+cbmsName = lens _cbmsName (\ s a -> s{_cbmsName = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+cbmsChangeToken :: Lens' CreateByteMatchSet Text
+cbmsChangeToken = lens _cbmsChangeToken (\ s a -> s{_cbmsChangeToken = a});
+
+instance AWSRequest CreateByteMatchSet where
+        type Rs CreateByteMatchSet =
+             CreateByteMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 CreateByteMatchSetResponse' <$>
+                   (x .?> "ByteMatchSet") <*> (x .?> "ChangeToken") <*>
+                     (pure (fromEnum s)))
+
+instance ToHeaders CreateByteMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.CreateByteMatchSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON CreateByteMatchSet where
+        toJSON CreateByteMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just ("Name" .= _cbmsName),
+                  Just ("ChangeToken" .= _cbmsChangeToken)])
+
+instance ToPath CreateByteMatchSet where
+        toPath = const "/"
+
+instance ToQuery CreateByteMatchSet where
+        toQuery = const mempty
+
+-- | /See:/ 'createByteMatchSetResponse' smart constructor.
+data CreateByteMatchSetResponse = CreateByteMatchSetResponse'
+    { _cbmsrsByteMatchSet   :: !(Maybe ByteMatchSet)
+    , _cbmsrsChangeToken    :: !(Maybe Text)
+    , _cbmsrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateByteMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'cbmsrsByteMatchSet'
+--
+-- * 'cbmsrsChangeToken'
+--
+-- * 'cbmsrsResponseStatus'
+createByteMatchSetResponse
+    :: Int -- ^ 'cbmsrsResponseStatus'
+    -> CreateByteMatchSetResponse
+createByteMatchSetResponse pResponseStatus_ =
+    CreateByteMatchSetResponse'
+    { _cbmsrsByteMatchSet = Nothing
+    , _cbmsrsChangeToken = Nothing
+    , _cbmsrsResponseStatus = pResponseStatus_
+    }
+
+-- | A ByteMatchSet that contains no 'ByteMatchTuple' objects.
+cbmsrsByteMatchSet :: Lens' CreateByteMatchSetResponse (Maybe ByteMatchSet)
+cbmsrsByteMatchSet = lens _cbmsrsByteMatchSet (\ s a -> s{_cbmsrsByteMatchSet = a});
+
+-- | The 'ChangeToken' that you used to submit the 'CreateByteMatchSet'
+-- request. You can also use this value to query the status of the request.
+-- For more information, see GetChangeTokenStatus.
+cbmsrsChangeToken :: Lens' CreateByteMatchSetResponse (Maybe Text)
+cbmsrsChangeToken = lens _cbmsrsChangeToken (\ s a -> s{_cbmsrsChangeToken = a});
+
+-- | The response status code.
+cbmsrsResponseStatus :: Lens' CreateByteMatchSetResponse Int
+cbmsrsResponseStatus = lens _cbmsrsResponseStatus (\ s a -> s{_cbmsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/CreateIPSet.hs b/gen/Network/AWS/WAF/CreateIPSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/CreateIPSet.hs
@@ -0,0 +1,169 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.CreateIPSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Creates an IPSet, which you use to specify which web requests you want
+-- to allow or block based on the IP addresses that the requests originate
+-- from. For example, if you\'re receiving a lot of requests from one or
+-- more individual IP addresses or one or more ranges of IP addresses and
+-- you want to block the requests, you can create an 'IPSet' that contains
+-- those IP addresses and then configure AWS WAF to block the requests.
+--
+-- To create and configure an 'IPSet', perform the following steps:
+--
+-- 1.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'CreateIPSet' request.
+-- 2.  Submit a 'CreateIPSet' request.
+-- 3.  Use 'GetChangeToken' to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateIPSet request.
+-- 4.  Submit an 'UpdateIPSet' request to specify the IP addresses that you
+--     want AWS WAF to watch for.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_CreateIPSet.html AWS API Reference> for CreateIPSet.
+module Network.AWS.WAF.CreateIPSet
+    (
+    -- * Creating a Request
+      createIPSet
+    , CreateIPSet
+    -- * Request Lenses
+    , cisName
+    , cisChangeToken
+
+    -- * Destructuring the Response
+    , createIPSetResponse
+    , CreateIPSetResponse
+    -- * Response Lenses
+    , cisrsChangeToken
+    , cisrsIPSet
+    , cisrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'createIPSet' smart constructor.
+data CreateIPSet = CreateIPSet'
+    { _cisName        :: !Text
+    , _cisChangeToken :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateIPSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'cisName'
+--
+-- * 'cisChangeToken'
+createIPSet
+    :: Text -- ^ 'cisName'
+    -> Text -- ^ 'cisChangeToken'
+    -> CreateIPSet
+createIPSet pName_ pChangeToken_ =
+    CreateIPSet'
+    { _cisName = pName_
+    , _cisChangeToken = pChangeToken_
+    }
+
+-- | A friendly name or description of the IPSet. You can\'t change 'Name'
+-- after you create the 'IPSet'.
+cisName :: Lens' CreateIPSet Text
+cisName = lens _cisName (\ s a -> s{_cisName = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+cisChangeToken :: Lens' CreateIPSet Text
+cisChangeToken = lens _cisChangeToken (\ s a -> s{_cisChangeToken = a});
+
+instance AWSRequest CreateIPSet where
+        type Rs CreateIPSet = CreateIPSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 CreateIPSetResponse' <$>
+                   (x .?> "ChangeToken") <*> (x .?> "IPSet") <*>
+                     (pure (fromEnum s)))
+
+instance ToHeaders CreateIPSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.CreateIPSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON CreateIPSet where
+        toJSON CreateIPSet'{..}
+          = object
+              (catMaybes
+                 [Just ("Name" .= _cisName),
+                  Just ("ChangeToken" .= _cisChangeToken)])
+
+instance ToPath CreateIPSet where
+        toPath = const "/"
+
+instance ToQuery CreateIPSet where
+        toQuery = const mempty
+
+-- | /See:/ 'createIPSetResponse' smart constructor.
+data CreateIPSetResponse = CreateIPSetResponse'
+    { _cisrsChangeToken    :: !(Maybe Text)
+    , _cisrsIPSet          :: !(Maybe IPSet)
+    , _cisrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateIPSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'cisrsChangeToken'
+--
+-- * 'cisrsIPSet'
+--
+-- * 'cisrsResponseStatus'
+createIPSetResponse
+    :: Int -- ^ 'cisrsResponseStatus'
+    -> CreateIPSetResponse
+createIPSetResponse pResponseStatus_ =
+    CreateIPSetResponse'
+    { _cisrsChangeToken = Nothing
+    , _cisrsIPSet = Nothing
+    , _cisrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'CreateIPSet' request. You
+-- can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+cisrsChangeToken :: Lens' CreateIPSetResponse (Maybe Text)
+cisrsChangeToken = lens _cisrsChangeToken (\ s a -> s{_cisrsChangeToken = a});
+
+-- | The IPSet returned in the 'CreateIPSet' response.
+cisrsIPSet :: Lens' CreateIPSetResponse (Maybe IPSet)
+cisrsIPSet = lens _cisrsIPSet (\ s a -> s{_cisrsIPSet = a});
+
+-- | The response status code.
+cisrsResponseStatus :: Lens' CreateIPSetResponse Int
+cisrsResponseStatus = lens _cisrsResponseStatus (\ s a -> s{_cisrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/CreateRule.hs b/gen/Network/AWS/WAF/CreateRule.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/CreateRule.hs
@@ -0,0 +1,195 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.CreateRule
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Creates a 'Rule', which contains the 'IPSet' objects, 'ByteMatchSet'
+-- objects, and other predicates that identify the requests that you want
+-- to block. If you add more than one predicate to a 'Rule', a request must
+-- match all of the specifications to be allowed or blocked. For example,
+-- suppose you add the following to a 'Rule':
+--
+-- -   An 'IPSet' that matches the IP address '192.0.2.44\/32'
+-- -   A 'ByteMatchSet' that matches 'BadBot' in the 'User-Agent' header
+--
+-- You then add the 'Rule' to a 'WebACL' and specify that you want to
+-- blocks requests that satisfy the 'Rule'. For a request to be blocked, it
+-- must come from the IP address 192.0.2.44 /and/ the 'User-Agent' header
+-- in the request must contain the value 'BadBot'.
+--
+-- To create and configure a 'Rule', perform the following steps:
+--
+-- 1.  Create and update the predicates that you want to include in the
+--     'Rule'. For more information, see CreateByteMatchSet, CreateIPSet,
+--     and CreateSqlInjectionMatchSet.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'CreateRule' request.
+-- 3.  Submit a 'CreateRule' request.
+-- 4.  Use 'GetChangeToken' to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateRule request.
+-- 5.  Submit an 'UpdateRule' request to specify the predicates that you
+--     want to include in the 'Rule'.
+-- 6.  Create and update a 'WebACL' that contains the 'Rule'. For more
+--     information, see CreateWebACL.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_CreateRule.html AWS API Reference> for CreateRule.
+module Network.AWS.WAF.CreateRule
+    (
+    -- * Creating a Request
+      createRule
+    , CreateRule
+    -- * Request Lenses
+    , crName
+    , crMetricName
+    , crChangeToken
+
+    -- * Destructuring the Response
+    , createRuleResponse
+    , CreateRuleResponse
+    -- * Response Lenses
+    , crrsRule
+    , crrsChangeToken
+    , crrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'createRule' smart constructor.
+data CreateRule = CreateRule'
+    { _crName        :: !Text
+    , _crMetricName  :: !Text
+    , _crChangeToken :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateRule' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'crName'
+--
+-- * 'crMetricName'
+--
+-- * 'crChangeToken'
+createRule
+    :: Text -- ^ 'crName'
+    -> Text -- ^ 'crMetricName'
+    -> Text -- ^ 'crChangeToken'
+    -> CreateRule
+createRule pName_ pMetricName_ pChangeToken_ =
+    CreateRule'
+    { _crName = pName_
+    , _crMetricName = pMetricName_
+    , _crChangeToken = pChangeToken_
+    }
+
+-- | A friendly name or description of the Rule. You can\'t change the name
+-- of a 'Rule' after you create it.
+crName :: Lens' CreateRule Text
+crName = lens _crName (\ s a -> s{_crName = a});
+
+-- | A friendly name or description for the metrics for this 'Rule'. The name
+-- can contain only alphanumeric characters (A-Z, a-z, 0-9); the name
+-- can\'t contain whitespace. You can\'t change the name of the metric
+-- after you create the 'Rule'.
+crMetricName :: Lens' CreateRule Text
+crMetricName = lens _crMetricName (\ s a -> s{_crMetricName = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+crChangeToken :: Lens' CreateRule Text
+crChangeToken = lens _crChangeToken (\ s a -> s{_crChangeToken = a});
+
+instance AWSRequest CreateRule where
+        type Rs CreateRule = CreateRuleResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 CreateRuleResponse' <$>
+                   (x .?> "Rule") <*> (x .?> "ChangeToken") <*>
+                     (pure (fromEnum s)))
+
+instance ToHeaders CreateRule where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.CreateRule" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON CreateRule where
+        toJSON CreateRule'{..}
+          = object
+              (catMaybes
+                 [Just ("Name" .= _crName),
+                  Just ("MetricName" .= _crMetricName),
+                  Just ("ChangeToken" .= _crChangeToken)])
+
+instance ToPath CreateRule where
+        toPath = const "/"
+
+instance ToQuery CreateRule where
+        toQuery = const mempty
+
+-- | /See:/ 'createRuleResponse' smart constructor.
+data CreateRuleResponse = CreateRuleResponse'
+    { _crrsRule           :: !(Maybe Rule)
+    , _crrsChangeToken    :: !(Maybe Text)
+    , _crrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateRuleResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'crrsRule'
+--
+-- * 'crrsChangeToken'
+--
+-- * 'crrsResponseStatus'
+createRuleResponse
+    :: Int -- ^ 'crrsResponseStatus'
+    -> CreateRuleResponse
+createRuleResponse pResponseStatus_ =
+    CreateRuleResponse'
+    { _crrsRule = Nothing
+    , _crrsChangeToken = Nothing
+    , _crrsResponseStatus = pResponseStatus_
+    }
+
+-- | The Rule returned in the 'CreateRule' response.
+crrsRule :: Lens' CreateRuleResponse (Maybe Rule)
+crrsRule = lens _crrsRule (\ s a -> s{_crrsRule = a});
+
+-- | The 'ChangeToken' that you used to submit the 'CreateRule' request. You
+-- can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+crrsChangeToken :: Lens' CreateRuleResponse (Maybe Text)
+crrsChangeToken = lens _crrsChangeToken (\ s a -> s{_crrsChangeToken = a});
+
+-- | The response status code.
+crrsResponseStatus :: Lens' CreateRuleResponse Int
+crrsResponseStatus = lens _crrsResponseStatus (\ s a -> s{_crrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/CreateSqlInjectionMatchSet.hs b/gen/Network/AWS/WAF/CreateSqlInjectionMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/CreateSqlInjectionMatchSet.hs
@@ -0,0 +1,178 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.CreateSqlInjectionMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Creates a SqlInjectionMatchSet, which you use to allow, block, or count
+-- requests that contain snippets of SQL code in a specified part of web
+-- requests. AWS WAF searches for character sequences that are likely to be
+-- malicious strings.
+--
+-- To create and configure a 'SqlInjectionMatchSet', perform the following
+-- steps:
+--
+-- 1.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'CreateSqlInjectionMatchSet' request.
+-- 2.  Submit a 'CreateSqlInjectionMatchSet' request.
+-- 3.  Use 'GetChangeToken' to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateSqlInjectionMatchSet request.
+-- 4.  Submit an UpdateSqlInjectionMatchSet request to specify the parts of
+--     web requests in which you want to allow, block, or count malicious
+--     SQL code.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_CreateSqlInjectionMatchSet.html AWS API Reference> for CreateSqlInjectionMatchSet.
+module Network.AWS.WAF.CreateSqlInjectionMatchSet
+    (
+    -- * Creating a Request
+      createSqlInjectionMatchSet
+    , CreateSqlInjectionMatchSet
+    -- * Request Lenses
+    , csimsName
+    , csimsChangeToken
+
+    -- * Destructuring the Response
+    , createSqlInjectionMatchSetResponse
+    , CreateSqlInjectionMatchSetResponse
+    -- * Response Lenses
+    , csimsrsSqlInjectionMatchSet
+    , csimsrsChangeToken
+    , csimsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | A request to create a SqlInjectionMatchSet.
+--
+-- /See:/ 'createSqlInjectionMatchSet' smart constructor.
+data CreateSqlInjectionMatchSet = CreateSqlInjectionMatchSet'
+    { _csimsName        :: !Text
+    , _csimsChangeToken :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateSqlInjectionMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'csimsName'
+--
+-- * 'csimsChangeToken'
+createSqlInjectionMatchSet
+    :: Text -- ^ 'csimsName'
+    -> Text -- ^ 'csimsChangeToken'
+    -> CreateSqlInjectionMatchSet
+createSqlInjectionMatchSet pName_ pChangeToken_ =
+    CreateSqlInjectionMatchSet'
+    { _csimsName = pName_
+    , _csimsChangeToken = pChangeToken_
+    }
+
+-- | A friendly name or description for the SqlInjectionMatchSet that you\'re
+-- creating. You can\'t change 'Name' after you create the
+-- 'SqlInjectionMatchSet'.
+csimsName :: Lens' CreateSqlInjectionMatchSet Text
+csimsName = lens _csimsName (\ s a -> s{_csimsName = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+csimsChangeToken :: Lens' CreateSqlInjectionMatchSet Text
+csimsChangeToken = lens _csimsChangeToken (\ s a -> s{_csimsChangeToken = a});
+
+instance AWSRequest CreateSqlInjectionMatchSet where
+        type Rs CreateSqlInjectionMatchSet =
+             CreateSqlInjectionMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 CreateSqlInjectionMatchSetResponse' <$>
+                   (x .?> "SqlInjectionMatchSet") <*>
+                     (x .?> "ChangeToken")
+                     <*> (pure (fromEnum s)))
+
+instance ToHeaders CreateSqlInjectionMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.CreateSqlInjectionMatchSet" ::
+                       ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON CreateSqlInjectionMatchSet where
+        toJSON CreateSqlInjectionMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just ("Name" .= _csimsName),
+                  Just ("ChangeToken" .= _csimsChangeToken)])
+
+instance ToPath CreateSqlInjectionMatchSet where
+        toPath = const "/"
+
+instance ToQuery CreateSqlInjectionMatchSet where
+        toQuery = const mempty
+
+-- | The response to a 'CreateSqlInjectionMatchSet' request.
+--
+-- /See:/ 'createSqlInjectionMatchSetResponse' smart constructor.
+data CreateSqlInjectionMatchSetResponse = CreateSqlInjectionMatchSetResponse'
+    { _csimsrsSqlInjectionMatchSet :: !(Maybe SqlInjectionMatchSet)
+    , _csimsrsChangeToken          :: !(Maybe Text)
+    , _csimsrsResponseStatus       :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateSqlInjectionMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'csimsrsSqlInjectionMatchSet'
+--
+-- * 'csimsrsChangeToken'
+--
+-- * 'csimsrsResponseStatus'
+createSqlInjectionMatchSetResponse
+    :: Int -- ^ 'csimsrsResponseStatus'
+    -> CreateSqlInjectionMatchSetResponse
+createSqlInjectionMatchSetResponse pResponseStatus_ =
+    CreateSqlInjectionMatchSetResponse'
+    { _csimsrsSqlInjectionMatchSet = Nothing
+    , _csimsrsChangeToken = Nothing
+    , _csimsrsResponseStatus = pResponseStatus_
+    }
+
+-- | A SqlInjectionMatchSet.
+csimsrsSqlInjectionMatchSet :: Lens' CreateSqlInjectionMatchSetResponse (Maybe SqlInjectionMatchSet)
+csimsrsSqlInjectionMatchSet = lens _csimsrsSqlInjectionMatchSet (\ s a -> s{_csimsrsSqlInjectionMatchSet = a});
+
+-- | The 'ChangeToken' that you used to submit the
+-- 'CreateSqlInjectionMatchSet' request. You can also use this value to
+-- query the status of the request. For more information, see
+-- GetChangeTokenStatus.
+csimsrsChangeToken :: Lens' CreateSqlInjectionMatchSetResponse (Maybe Text)
+csimsrsChangeToken = lens _csimsrsChangeToken (\ s a -> s{_csimsrsChangeToken = a});
+
+-- | The response status code.
+csimsrsResponseStatus :: Lens' CreateSqlInjectionMatchSetResponse Int
+csimsrsResponseStatus = lens _csimsrsResponseStatus (\ s a -> s{_csimsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/CreateWebACL.hs b/gen/Network/AWS/WAF/CreateWebACL.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/CreateWebACL.hs
@@ -0,0 +1,204 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.CreateWebACL
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Creates a 'WebACL', which contains the 'Rules' that identify the
+-- CloudFront web requests that you want to allow, block, or count. AWS WAF
+-- evaluates 'Rules' in order based on the value of 'Priority' for each
+-- 'Rule'.
+--
+-- You also specify a default action, either 'ALLOW' or 'BLOCK'. If a web
+-- request doesn\'t match any of the 'Rules' in a 'WebACL', AWS WAF
+-- responds to the request with the default action.
+--
+-- To create and configure a 'WebACL', perform the following steps:
+--
+-- 1.  Create and update the 'ByteMatchSet' objects and other predicates
+--     that you want to include in 'Rules'. For more information, see
+--     CreateByteMatchSet, UpdateByteMatchSet, CreateIPSet, UpdateIPSet,
+--     CreateSqlInjectionMatchSet, and UpdateSqlInjectionMatchSet.
+-- 2.  Create and update the 'Rules' that you want to include in the
+--     'WebACL'. For more information, see CreateRule and UpdateRule.
+-- 3.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'CreateWebACL' request.
+-- 4.  Submit a 'CreateWebACL' request.
+-- 5.  Use 'GetChangeToken' to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateWebACL request.
+-- 6.  Submit an UpdateWebACL request to specify the 'Rules' that you want
+--     to include in the 'WebACL', to specify the default action, and to
+--     associate the 'WebACL' with a CloudFront distribution.
+--
+-- For more information about how to use the AWS WAF API, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_CreateWebACL.html AWS API Reference> for CreateWebACL.
+module Network.AWS.WAF.CreateWebACL
+    (
+    -- * Creating a Request
+      createWebACL
+    , CreateWebACL
+    -- * Request Lenses
+    , cwaName
+    , cwaMetricName
+    , cwaDefaultAction
+    , cwaChangeToken
+
+    -- * Destructuring the Response
+    , createWebACLResponse
+    , CreateWebACLResponse
+    -- * Response Lenses
+    , cwarsWebACL
+    , cwarsChangeToken
+    , cwarsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'createWebACL' smart constructor.
+data CreateWebACL = CreateWebACL'
+    { _cwaName          :: !Text
+    , _cwaMetricName    :: !Text
+    , _cwaDefaultAction :: !WafAction
+    , _cwaChangeToken   :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateWebACL' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'cwaName'
+--
+-- * 'cwaMetricName'
+--
+-- * 'cwaDefaultAction'
+--
+-- * 'cwaChangeToken'
+createWebACL
+    :: Text -- ^ 'cwaName'
+    -> Text -- ^ 'cwaMetricName'
+    -> WafAction -- ^ 'cwaDefaultAction'
+    -> Text -- ^ 'cwaChangeToken'
+    -> CreateWebACL
+createWebACL pName_ pMetricName_ pDefaultAction_ pChangeToken_ =
+    CreateWebACL'
+    { _cwaName = pName_
+    , _cwaMetricName = pMetricName_
+    , _cwaDefaultAction = pDefaultAction_
+    , _cwaChangeToken = pChangeToken_
+    }
+
+-- | A friendly name or description of the WebACL. You can\'t change 'Name'
+-- after you create the 'WebACL'.
+cwaName :: Lens' CreateWebACL Text
+cwaName = lens _cwaName (\ s a -> s{_cwaName = a});
+
+-- | A friendly name or description for the metrics for this 'WebACL'. The
+-- name can contain only alphanumeric characters (A-Z, a-z, 0-9); the name
+-- can\'t contain whitespace. You can\'t change 'MetricName' after you
+-- create the 'WebACL'.
+cwaMetricName :: Lens' CreateWebACL Text
+cwaMetricName = lens _cwaMetricName (\ s a -> s{_cwaMetricName = a});
+
+-- | The action that you want AWS WAF to take when a request doesn\'t match
+-- the criteria specified in any of the 'Rule' objects that are associated
+-- with the 'WebACL'.
+cwaDefaultAction :: Lens' CreateWebACL WafAction
+cwaDefaultAction = lens _cwaDefaultAction (\ s a -> s{_cwaDefaultAction = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+cwaChangeToken :: Lens' CreateWebACL Text
+cwaChangeToken = lens _cwaChangeToken (\ s a -> s{_cwaChangeToken = a});
+
+instance AWSRequest CreateWebACL where
+        type Rs CreateWebACL = CreateWebACLResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 CreateWebACLResponse' <$>
+                   (x .?> "WebACL") <*> (x .?> "ChangeToken") <*>
+                     (pure (fromEnum s)))
+
+instance ToHeaders CreateWebACL where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.CreateWebACL" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON CreateWebACL where
+        toJSON CreateWebACL'{..}
+          = object
+              (catMaybes
+                 [Just ("Name" .= _cwaName),
+                  Just ("MetricName" .= _cwaMetricName),
+                  Just ("DefaultAction" .= _cwaDefaultAction),
+                  Just ("ChangeToken" .= _cwaChangeToken)])
+
+instance ToPath CreateWebACL where
+        toPath = const "/"
+
+instance ToQuery CreateWebACL where
+        toQuery = const mempty
+
+-- | /See:/ 'createWebACLResponse' smart constructor.
+data CreateWebACLResponse = CreateWebACLResponse'
+    { _cwarsWebACL         :: !(Maybe WebACL)
+    , _cwarsChangeToken    :: !(Maybe Text)
+    , _cwarsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'CreateWebACLResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'cwarsWebACL'
+--
+-- * 'cwarsChangeToken'
+--
+-- * 'cwarsResponseStatus'
+createWebACLResponse
+    :: Int -- ^ 'cwarsResponseStatus'
+    -> CreateWebACLResponse
+createWebACLResponse pResponseStatus_ =
+    CreateWebACLResponse'
+    { _cwarsWebACL = Nothing
+    , _cwarsChangeToken = Nothing
+    , _cwarsResponseStatus = pResponseStatus_
+    }
+
+-- | The WebACL returned in the 'CreateWebACL' response.
+cwarsWebACL :: Lens' CreateWebACLResponse (Maybe WebACL)
+cwarsWebACL = lens _cwarsWebACL (\ s a -> s{_cwarsWebACL = a});
+
+-- | The 'ChangeToken' that you used to submit the 'CreateWebACL' request.
+-- You can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+cwarsChangeToken :: Lens' CreateWebACLResponse (Maybe Text)
+cwarsChangeToken = lens _cwarsChangeToken (\ s a -> s{_cwarsChangeToken = a});
+
+-- | The response status code.
+cwarsResponseStatus :: Lens' CreateWebACLResponse Int
+cwarsResponseStatus = lens _cwarsResponseStatus (\ s a -> s{_cwarsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/DeleteByteMatchSet.hs b/gen/Network/AWS/WAF/DeleteByteMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/DeleteByteMatchSet.hs
@@ -0,0 +1,155 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.DeleteByteMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Permanently deletes a ByteMatchSet. You can\'t delete a 'ByteMatchSet'
+-- if it\'s still used in any 'Rules' or if it still includes any
+-- ByteMatchTuple objects (any filters).
+--
+-- If you just want to remove a 'ByteMatchSet' from a 'Rule', use
+-- UpdateRule.
+--
+-- To permanently delete a 'ByteMatchSet', perform the following steps:
+--
+-- 1.  Update the 'ByteMatchSet' to remove filters, if any. For more
+--     information, see UpdateByteMatchSet.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'DeleteByteMatchSet' request.
+-- 3.  Submit a 'DeleteByteMatchSet' request.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_DeleteByteMatchSet.html AWS API Reference> for DeleteByteMatchSet.
+module Network.AWS.WAF.DeleteByteMatchSet
+    (
+    -- * Creating a Request
+      deleteByteMatchSet
+    , DeleteByteMatchSet
+    -- * Request Lenses
+    , dbmsByteMatchSetId
+    , dbmsChangeToken
+
+    -- * Destructuring the Response
+    , deleteByteMatchSetResponse
+    , DeleteByteMatchSetResponse
+    -- * Response Lenses
+    , dbmsrsChangeToken
+    , dbmsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'deleteByteMatchSet' smart constructor.
+data DeleteByteMatchSet = DeleteByteMatchSet'
+    { _dbmsByteMatchSetId :: !Text
+    , _dbmsChangeToken    :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteByteMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'dbmsByteMatchSetId'
+--
+-- * 'dbmsChangeToken'
+deleteByteMatchSet
+    :: Text -- ^ 'dbmsByteMatchSetId'
+    -> Text -- ^ 'dbmsChangeToken'
+    -> DeleteByteMatchSet
+deleteByteMatchSet pByteMatchSetId_ pChangeToken_ =
+    DeleteByteMatchSet'
+    { _dbmsByteMatchSetId = pByteMatchSetId_
+    , _dbmsChangeToken = pChangeToken_
+    }
+
+-- | The 'ByteMatchSetId' of the ByteMatchSet that you want to delete.
+-- 'ByteMatchSetId' is returned by CreateByteMatchSet and by
+-- ListByteMatchSets.
+dbmsByteMatchSetId :: Lens' DeleteByteMatchSet Text
+dbmsByteMatchSetId = lens _dbmsByteMatchSetId (\ s a -> s{_dbmsByteMatchSetId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+dbmsChangeToken :: Lens' DeleteByteMatchSet Text
+dbmsChangeToken = lens _dbmsChangeToken (\ s a -> s{_dbmsChangeToken = a});
+
+instance AWSRequest DeleteByteMatchSet where
+        type Rs DeleteByteMatchSet =
+             DeleteByteMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 DeleteByteMatchSetResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders DeleteByteMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.DeleteByteMatchSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON DeleteByteMatchSet where
+        toJSON DeleteByteMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just ("ByteMatchSetId" .= _dbmsByteMatchSetId),
+                  Just ("ChangeToken" .= _dbmsChangeToken)])
+
+instance ToPath DeleteByteMatchSet where
+        toPath = const "/"
+
+instance ToQuery DeleteByteMatchSet where
+        toQuery = const mempty
+
+-- | /See:/ 'deleteByteMatchSetResponse' smart constructor.
+data DeleteByteMatchSetResponse = DeleteByteMatchSetResponse'
+    { _dbmsrsChangeToken    :: !(Maybe Text)
+    , _dbmsrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteByteMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'dbmsrsChangeToken'
+--
+-- * 'dbmsrsResponseStatus'
+deleteByteMatchSetResponse
+    :: Int -- ^ 'dbmsrsResponseStatus'
+    -> DeleteByteMatchSetResponse
+deleteByteMatchSetResponse pResponseStatus_ =
+    DeleteByteMatchSetResponse'
+    { _dbmsrsChangeToken = Nothing
+    , _dbmsrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'DeleteByteMatchSet'
+-- request. You can also use this value to query the status of the request.
+-- For more information, see GetChangeTokenStatus.
+dbmsrsChangeToken :: Lens' DeleteByteMatchSetResponse (Maybe Text)
+dbmsrsChangeToken = lens _dbmsrsChangeToken (\ s a -> s{_dbmsrsChangeToken = a});
+
+-- | The response status code.
+dbmsrsResponseStatus :: Lens' DeleteByteMatchSetResponse Int
+dbmsrsResponseStatus = lens _dbmsrsResponseStatus (\ s a -> s{_dbmsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/DeleteIPSet.hs b/gen/Network/AWS/WAF/DeleteIPSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/DeleteIPSet.hs
@@ -0,0 +1,152 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.DeleteIPSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Permanently deletes an IPSet. You can\'t delete an 'IPSet' if it\'s
+-- still used in any 'Rules' or if it still includes any IP addresses.
+--
+-- If you just want to remove an 'IPSet' from a 'Rule', use UpdateRule.
+--
+-- To permanently delete an 'IPSet' from AWS WAF, perform the following
+-- steps:
+--
+-- 1.  Update the 'IPSet' to remove IP address ranges, if any. For more
+--     information, see UpdateIPSet.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'DeleteIPSet' request.
+-- 3.  Submit a 'DeleteIPSet' request.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_DeleteIPSet.html AWS API Reference> for DeleteIPSet.
+module Network.AWS.WAF.DeleteIPSet
+    (
+    -- * Creating a Request
+      deleteIPSet
+    , DeleteIPSet
+    -- * Request Lenses
+    , disIPSetId
+    , disChangeToken
+
+    -- * Destructuring the Response
+    , deleteIPSetResponse
+    , DeleteIPSetResponse
+    -- * Response Lenses
+    , disrsChangeToken
+    , disrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'deleteIPSet' smart constructor.
+data DeleteIPSet = DeleteIPSet'
+    { _disIPSetId     :: !Text
+    , _disChangeToken :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteIPSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'disIPSetId'
+--
+-- * 'disChangeToken'
+deleteIPSet
+    :: Text -- ^ 'disIPSetId'
+    -> Text -- ^ 'disChangeToken'
+    -> DeleteIPSet
+deleteIPSet pIPSetId_ pChangeToken_ =
+    DeleteIPSet'
+    { _disIPSetId = pIPSetId_
+    , _disChangeToken = pChangeToken_
+    }
+
+-- | The 'IPSetId' of the IPSet that you want to delete. 'IPSetId' is
+-- returned by CreateIPSet and by ListIPSets.
+disIPSetId :: Lens' DeleteIPSet Text
+disIPSetId = lens _disIPSetId (\ s a -> s{_disIPSetId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+disChangeToken :: Lens' DeleteIPSet Text
+disChangeToken = lens _disChangeToken (\ s a -> s{_disChangeToken = a});
+
+instance AWSRequest DeleteIPSet where
+        type Rs DeleteIPSet = DeleteIPSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 DeleteIPSetResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders DeleteIPSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.DeleteIPSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON DeleteIPSet where
+        toJSON DeleteIPSet'{..}
+          = object
+              (catMaybes
+                 [Just ("IPSetId" .= _disIPSetId),
+                  Just ("ChangeToken" .= _disChangeToken)])
+
+instance ToPath DeleteIPSet where
+        toPath = const "/"
+
+instance ToQuery DeleteIPSet where
+        toQuery = const mempty
+
+-- | /See:/ 'deleteIPSetResponse' smart constructor.
+data DeleteIPSetResponse = DeleteIPSetResponse'
+    { _disrsChangeToken    :: !(Maybe Text)
+    , _disrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteIPSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'disrsChangeToken'
+--
+-- * 'disrsResponseStatus'
+deleteIPSetResponse
+    :: Int -- ^ 'disrsResponseStatus'
+    -> DeleteIPSetResponse
+deleteIPSetResponse pResponseStatus_ =
+    DeleteIPSetResponse'
+    { _disrsChangeToken = Nothing
+    , _disrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'DeleteIPSet' request. You
+-- can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+disrsChangeToken :: Lens' DeleteIPSetResponse (Maybe Text)
+disrsChangeToken = lens _disrsChangeToken (\ s a -> s{_disrsChangeToken = a});
+
+-- | The response status code.
+disrsResponseStatus :: Lens' DeleteIPSetResponse Int
+disrsResponseStatus = lens _disrsResponseStatus (\ s a -> s{_disrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/DeleteRule.hs b/gen/Network/AWS/WAF/DeleteRule.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/DeleteRule.hs
@@ -0,0 +1,153 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.DeleteRule
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Permanently deletes a Rule. You can\'t delete a 'Rule' if it\'s still
+-- used in any 'WebACL' objects or if it still includes any predicates,
+-- such as 'ByteMatchSet' objects.
+--
+-- If you just want to remove a 'Rule' from a 'WebACL', use UpdateWebACL.
+--
+-- To permanently delete a 'Rule' from AWS WAF, perform the following
+-- steps:
+--
+-- 1.  Update the 'Rule' to remove predicates, if any. For more
+--     information, see UpdateRule.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'DeleteRule' request.
+-- 3.  Submit a 'DeleteRule' request.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_DeleteRule.html AWS API Reference> for DeleteRule.
+module Network.AWS.WAF.DeleteRule
+    (
+    -- * Creating a Request
+      deleteRule
+    , DeleteRule
+    -- * Request Lenses
+    , drRuleId
+    , drChangeToken
+
+    -- * Destructuring the Response
+    , deleteRuleResponse
+    , DeleteRuleResponse
+    -- * Response Lenses
+    , drrsChangeToken
+    , drrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'deleteRule' smart constructor.
+data DeleteRule = DeleteRule'
+    { _drRuleId      :: !Text
+    , _drChangeToken :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteRule' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'drRuleId'
+--
+-- * 'drChangeToken'
+deleteRule
+    :: Text -- ^ 'drRuleId'
+    -> Text -- ^ 'drChangeToken'
+    -> DeleteRule
+deleteRule pRuleId_ pChangeToken_ =
+    DeleteRule'
+    { _drRuleId = pRuleId_
+    , _drChangeToken = pChangeToken_
+    }
+
+-- | The 'RuleId' of the Rule that you want to delete. 'RuleId' is returned
+-- by CreateRule and by ListRules.
+drRuleId :: Lens' DeleteRule Text
+drRuleId = lens _drRuleId (\ s a -> s{_drRuleId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+drChangeToken :: Lens' DeleteRule Text
+drChangeToken = lens _drChangeToken (\ s a -> s{_drChangeToken = a});
+
+instance AWSRequest DeleteRule where
+        type Rs DeleteRule = DeleteRuleResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 DeleteRuleResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders DeleteRule where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.DeleteRule" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON DeleteRule where
+        toJSON DeleteRule'{..}
+          = object
+              (catMaybes
+                 [Just ("RuleId" .= _drRuleId),
+                  Just ("ChangeToken" .= _drChangeToken)])
+
+instance ToPath DeleteRule where
+        toPath = const "/"
+
+instance ToQuery DeleteRule where
+        toQuery = const mempty
+
+-- | /See:/ 'deleteRuleResponse' smart constructor.
+data DeleteRuleResponse = DeleteRuleResponse'
+    { _drrsChangeToken    :: !(Maybe Text)
+    , _drrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteRuleResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'drrsChangeToken'
+--
+-- * 'drrsResponseStatus'
+deleteRuleResponse
+    :: Int -- ^ 'drrsResponseStatus'
+    -> DeleteRuleResponse
+deleteRuleResponse pResponseStatus_ =
+    DeleteRuleResponse'
+    { _drrsChangeToken = Nothing
+    , _drrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'DeleteRule' request. You
+-- can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+drrsChangeToken :: Lens' DeleteRuleResponse (Maybe Text)
+drrsChangeToken = lens _drrsChangeToken (\ s a -> s{_drrsChangeToken = a});
+
+-- | The response status code.
+drrsResponseStatus :: Lens' DeleteRuleResponse Int
+drrsResponseStatus = lens _drrsResponseStatus (\ s a -> s{_drrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/DeleteSqlInjectionMatchSet.hs b/gen/Network/AWS/WAF/DeleteSqlInjectionMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/DeleteSqlInjectionMatchSet.hs
@@ -0,0 +1,164 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.DeleteSqlInjectionMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Permanently deletes a SqlInjectionMatchSet. You can\'t delete a
+-- 'SqlInjectionMatchSet' if it\'s still used in any 'Rules' or if it still
+-- contains any SqlInjectionMatchTuple objects.
+--
+-- If you just want to remove a 'SqlInjectionMatchSet' from a 'Rule', use
+-- UpdateRule.
+--
+-- To permanently delete a 'SqlInjectionMatchSet' from AWS WAF, perform the
+-- following steps:
+--
+-- 1.  Update the 'SqlInjectionMatchSet' to remove filters, if any. For
+--     more information, see UpdateSqlInjectionMatchSet.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'DeleteSqlInjectionMatchSet' request.
+-- 3.  Submit a 'DeleteSqlInjectionMatchSet' request.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_DeleteSqlInjectionMatchSet.html AWS API Reference> for DeleteSqlInjectionMatchSet.
+module Network.AWS.WAF.DeleteSqlInjectionMatchSet
+    (
+    -- * Creating a Request
+      deleteSqlInjectionMatchSet
+    , DeleteSqlInjectionMatchSet
+    -- * Request Lenses
+    , dsimsSqlInjectionMatchSetId
+    , dsimsChangeToken
+
+    -- * Destructuring the Response
+    , deleteSqlInjectionMatchSetResponse
+    , DeleteSqlInjectionMatchSetResponse
+    -- * Response Lenses
+    , dsimsrsChangeToken
+    , dsimsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | A request to delete a SqlInjectionMatchSet from AWS WAF.
+--
+-- /See:/ 'deleteSqlInjectionMatchSet' smart constructor.
+data DeleteSqlInjectionMatchSet = DeleteSqlInjectionMatchSet'
+    { _dsimsSqlInjectionMatchSetId :: !Text
+    , _dsimsChangeToken            :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteSqlInjectionMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'dsimsSqlInjectionMatchSetId'
+--
+-- * 'dsimsChangeToken'
+deleteSqlInjectionMatchSet
+    :: Text -- ^ 'dsimsSqlInjectionMatchSetId'
+    -> Text -- ^ 'dsimsChangeToken'
+    -> DeleteSqlInjectionMatchSet
+deleteSqlInjectionMatchSet pSqlInjectionMatchSetId_ pChangeToken_ =
+    DeleteSqlInjectionMatchSet'
+    { _dsimsSqlInjectionMatchSetId = pSqlInjectionMatchSetId_
+    , _dsimsChangeToken = pChangeToken_
+    }
+
+-- | The 'SqlInjectionMatchSetId' of the SqlInjectionMatchSet that you want
+-- to delete. 'SqlInjectionMatchSetId' is returned by
+-- CreateSqlInjectionMatchSet and by ListSqlInjectionMatchSets.
+dsimsSqlInjectionMatchSetId :: Lens' DeleteSqlInjectionMatchSet Text
+dsimsSqlInjectionMatchSetId = lens _dsimsSqlInjectionMatchSetId (\ s a -> s{_dsimsSqlInjectionMatchSetId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+dsimsChangeToken :: Lens' DeleteSqlInjectionMatchSet Text
+dsimsChangeToken = lens _dsimsChangeToken (\ s a -> s{_dsimsChangeToken = a});
+
+instance AWSRequest DeleteSqlInjectionMatchSet where
+        type Rs DeleteSqlInjectionMatchSet =
+             DeleteSqlInjectionMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 DeleteSqlInjectionMatchSetResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders DeleteSqlInjectionMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.DeleteSqlInjectionMatchSet" ::
+                       ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON DeleteSqlInjectionMatchSet where
+        toJSON DeleteSqlInjectionMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just
+                    ("SqlInjectionMatchSetId" .=
+                       _dsimsSqlInjectionMatchSetId),
+                  Just ("ChangeToken" .= _dsimsChangeToken)])
+
+instance ToPath DeleteSqlInjectionMatchSet where
+        toPath = const "/"
+
+instance ToQuery DeleteSqlInjectionMatchSet where
+        toQuery = const mempty
+
+-- | The response to a request to delete a SqlInjectionMatchSet from AWS WAF.
+--
+-- /See:/ 'deleteSqlInjectionMatchSetResponse' smart constructor.
+data DeleteSqlInjectionMatchSetResponse = DeleteSqlInjectionMatchSetResponse'
+    { _dsimsrsChangeToken    :: !(Maybe Text)
+    , _dsimsrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteSqlInjectionMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'dsimsrsChangeToken'
+--
+-- * 'dsimsrsResponseStatus'
+deleteSqlInjectionMatchSetResponse
+    :: Int -- ^ 'dsimsrsResponseStatus'
+    -> DeleteSqlInjectionMatchSetResponse
+deleteSqlInjectionMatchSetResponse pResponseStatus_ =
+    DeleteSqlInjectionMatchSetResponse'
+    { _dsimsrsChangeToken = Nothing
+    , _dsimsrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the
+-- 'DeleteSqlInjectionMatchSet' request. You can also use this value to
+-- query the status of the request. For more information, see
+-- GetChangeTokenStatus.
+dsimsrsChangeToken :: Lens' DeleteSqlInjectionMatchSetResponse (Maybe Text)
+dsimsrsChangeToken = lens _dsimsrsChangeToken (\ s a -> s{_dsimsrsChangeToken = a});
+
+-- | The response status code.
+dsimsrsResponseStatus :: Lens' DeleteSqlInjectionMatchSetResponse Int
+dsimsrsResponseStatus = lens _dsimsrsResponseStatus (\ s a -> s{_dsimsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/DeleteWebACL.hs b/gen/Network/AWS/WAF/DeleteWebACL.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/DeleteWebACL.hs
@@ -0,0 +1,149 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.DeleteWebACL
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Permanently deletes a WebACL. You can\'t delete a 'WebACL' if it still
+-- contains any 'Rules'.
+--
+-- To delete a 'WebACL', perform the following steps:
+--
+-- 1.  Update the 'WebACL' to remove 'Rules', if any. For more information,
+--     see UpdateWebACL.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of a 'DeleteWebACL' request.
+-- 3.  Submit a 'DeleteWebACL' request.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_DeleteWebACL.html AWS API Reference> for DeleteWebACL.
+module Network.AWS.WAF.DeleteWebACL
+    (
+    -- * Creating a Request
+      deleteWebACL
+    , DeleteWebACL
+    -- * Request Lenses
+    , dwaWebACLId
+    , dwaChangeToken
+
+    -- * Destructuring the Response
+    , deleteWebACLResponse
+    , DeleteWebACLResponse
+    -- * Response Lenses
+    , dwarsChangeToken
+    , dwarsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'deleteWebACL' smart constructor.
+data DeleteWebACL = DeleteWebACL'
+    { _dwaWebACLId    :: !Text
+    , _dwaChangeToken :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteWebACL' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'dwaWebACLId'
+--
+-- * 'dwaChangeToken'
+deleteWebACL
+    :: Text -- ^ 'dwaWebACLId'
+    -> Text -- ^ 'dwaChangeToken'
+    -> DeleteWebACL
+deleteWebACL pWebACLId_ pChangeToken_ =
+    DeleteWebACL'
+    { _dwaWebACLId = pWebACLId_
+    , _dwaChangeToken = pChangeToken_
+    }
+
+-- | The 'WebACLId' of the WebACL that you want to delete. 'WebACLId' is
+-- returned by CreateWebACL and by ListWebACLs.
+dwaWebACLId :: Lens' DeleteWebACL Text
+dwaWebACLId = lens _dwaWebACLId (\ s a -> s{_dwaWebACLId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+dwaChangeToken :: Lens' DeleteWebACL Text
+dwaChangeToken = lens _dwaChangeToken (\ s a -> s{_dwaChangeToken = a});
+
+instance AWSRequest DeleteWebACL where
+        type Rs DeleteWebACL = DeleteWebACLResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 DeleteWebACLResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders DeleteWebACL where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.DeleteWebACL" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON DeleteWebACL where
+        toJSON DeleteWebACL'{..}
+          = object
+              (catMaybes
+                 [Just ("WebACLId" .= _dwaWebACLId),
+                  Just ("ChangeToken" .= _dwaChangeToken)])
+
+instance ToPath DeleteWebACL where
+        toPath = const "/"
+
+instance ToQuery DeleteWebACL where
+        toQuery = const mempty
+
+-- | /See:/ 'deleteWebACLResponse' smart constructor.
+data DeleteWebACLResponse = DeleteWebACLResponse'
+    { _dwarsChangeToken    :: !(Maybe Text)
+    , _dwarsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'DeleteWebACLResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'dwarsChangeToken'
+--
+-- * 'dwarsResponseStatus'
+deleteWebACLResponse
+    :: Int -- ^ 'dwarsResponseStatus'
+    -> DeleteWebACLResponse
+deleteWebACLResponse pResponseStatus_ =
+    DeleteWebACLResponse'
+    { _dwarsChangeToken = Nothing
+    , _dwarsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'DeleteWebACL' request.
+-- You can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+dwarsChangeToken :: Lens' DeleteWebACLResponse (Maybe Text)
+dwarsChangeToken = lens _dwarsChangeToken (\ s a -> s{_dwarsChangeToken = a});
+
+-- | The response status code.
+dwarsResponseStatus :: Lens' DeleteWebACLResponse Int
+dwarsResponseStatus = lens _dwarsResponseStatus (\ s a -> s{_dwarsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetByteMatchSet.hs b/gen/Network/AWS/WAF/GetByteMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetByteMatchSet.hs
@@ -0,0 +1,137 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetByteMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns the ByteMatchSet specified by 'ByteMatchSetId'.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetByteMatchSet.html AWS API Reference> for GetByteMatchSet.
+module Network.AWS.WAF.GetByteMatchSet
+    (
+    -- * Creating a Request
+      getByteMatchSet
+    , GetByteMatchSet
+    -- * Request Lenses
+    , gbmsByteMatchSetId
+
+    -- * Destructuring the Response
+    , getByteMatchSetResponse
+    , GetByteMatchSetResponse
+    -- * Response Lenses
+    , gbmsrsByteMatchSet
+    , gbmsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'getByteMatchSet' smart constructor.
+newtype GetByteMatchSet = GetByteMatchSet'
+    { _gbmsByteMatchSetId :: Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetByteMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gbmsByteMatchSetId'
+getByteMatchSet
+    :: Text -- ^ 'gbmsByteMatchSetId'
+    -> GetByteMatchSet
+getByteMatchSet pByteMatchSetId_ =
+    GetByteMatchSet'
+    { _gbmsByteMatchSetId = pByteMatchSetId_
+    }
+
+-- | The 'ByteMatchSetId' of the ByteMatchSet that you want to get.
+-- 'ByteMatchSetId' is returned by CreateByteMatchSet and by
+-- ListByteMatchSets.
+gbmsByteMatchSetId :: Lens' GetByteMatchSet Text
+gbmsByteMatchSetId = lens _gbmsByteMatchSetId (\ s a -> s{_gbmsByteMatchSetId = a});
+
+instance AWSRequest GetByteMatchSet where
+        type Rs GetByteMatchSet = GetByteMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetByteMatchSetResponse' <$>
+                   (x .?> "ByteMatchSet") <*> (pure (fromEnum s)))
+
+instance ToHeaders GetByteMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetByteMatchSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetByteMatchSet where
+        toJSON GetByteMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just ("ByteMatchSetId" .= _gbmsByteMatchSetId)])
+
+instance ToPath GetByteMatchSet where
+        toPath = const "/"
+
+instance ToQuery GetByteMatchSet where
+        toQuery = const mempty
+
+-- | /See:/ 'getByteMatchSetResponse' smart constructor.
+data GetByteMatchSetResponse = GetByteMatchSetResponse'
+    { _gbmsrsByteMatchSet   :: !(Maybe ByteMatchSet)
+    , _gbmsrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetByteMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gbmsrsByteMatchSet'
+--
+-- * 'gbmsrsResponseStatus'
+getByteMatchSetResponse
+    :: Int -- ^ 'gbmsrsResponseStatus'
+    -> GetByteMatchSetResponse
+getByteMatchSetResponse pResponseStatus_ =
+    GetByteMatchSetResponse'
+    { _gbmsrsByteMatchSet = Nothing
+    , _gbmsrsResponseStatus = pResponseStatus_
+    }
+
+-- | Information about the ByteMatchSet that you specified in the
+-- 'GetByteMatchSet' request. For more information, see the following
+-- topics:
+--
+-- -   ByteMatchSet: Contains 'ByteMatchSetId', 'ByteMatchTuples', and
+--     'Name'
+-- -   'ByteMatchTuples': Contains an array of ByteMatchTuple objects. Each
+--     'ByteMatchTuple' object contains FieldToMatch,
+--     'PositionalConstraint', 'TargetString', and 'TextTransformation'
+-- -   FieldToMatch: Contains 'Data' and 'Type'
+gbmsrsByteMatchSet :: Lens' GetByteMatchSetResponse (Maybe ByteMatchSet)
+gbmsrsByteMatchSet = lens _gbmsrsByteMatchSet (\ s a -> s{_gbmsrsByteMatchSet = a});
+
+-- | The response status code.
+gbmsrsResponseStatus :: Lens' GetByteMatchSetResponse Int
+gbmsrsResponseStatus = lens _gbmsrsResponseStatus (\ s a -> s{_gbmsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetChangeToken.hs b/gen/Network/AWS/WAF/GetChangeToken.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetChangeToken.hs
@@ -0,0 +1,125 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetChangeToken
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- When you want to create, update, or delete AWS WAF objects, get a change
+-- token and include the change token in the create, update, or delete
+-- request. Change tokens ensure that your application doesn\'t submit
+-- conflicting requests to AWS WAF.
+--
+-- Each create, update, or delete request must use a unique change token.
+-- If your application submits a 'GetChangeToken' request and then submits
+-- a second 'GetChangeToken' request before submitting a create, update, or
+-- delete request, the second 'GetChangeToken' request returns the same
+-- value as the first 'GetChangeToken' request.
+--
+-- When you use a change token in a create, update, or delete request, the
+-- status of the change token changes to 'PENDING', which indicates that
+-- AWS WAF is propagating the change to all AWS WAF servers. Use
+-- 'GetChangeTokenStatus' to determine the status of your change token.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetChangeToken.html AWS API Reference> for GetChangeToken.
+module Network.AWS.WAF.GetChangeToken
+    (
+    -- * Creating a Request
+      getChangeToken
+    , GetChangeToken
+
+    -- * Destructuring the Response
+    , getChangeTokenResponse
+    , GetChangeTokenResponse
+    -- * Response Lenses
+    , gctrsChangeToken
+    , gctrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'getChangeToken' smart constructor.
+data GetChangeToken =
+    GetChangeToken'
+    deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetChangeToken' with the minimum fields required to make a request.
+--
+getChangeToken
+    :: GetChangeToken
+getChangeToken = GetChangeToken'
+
+instance AWSRequest GetChangeToken where
+        type Rs GetChangeToken = GetChangeTokenResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetChangeTokenResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders GetChangeToken where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetChangeToken" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetChangeToken where
+        toJSON = const (Object mempty)
+
+instance ToPath GetChangeToken where
+        toPath = const "/"
+
+instance ToQuery GetChangeToken where
+        toQuery = const mempty
+
+-- | /See:/ 'getChangeTokenResponse' smart constructor.
+data GetChangeTokenResponse = GetChangeTokenResponse'
+    { _gctrsChangeToken    :: !(Maybe Text)
+    , _gctrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetChangeTokenResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gctrsChangeToken'
+--
+-- * 'gctrsResponseStatus'
+getChangeTokenResponse
+    :: Int -- ^ 'gctrsResponseStatus'
+    -> GetChangeTokenResponse
+getChangeTokenResponse pResponseStatus_ =
+    GetChangeTokenResponse'
+    { _gctrsChangeToken = Nothing
+    , _gctrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used in the request. Use this value in a
+-- 'GetChangeTokenStatus' request to get the current status of the request.
+gctrsChangeToken :: Lens' GetChangeTokenResponse (Maybe Text)
+gctrsChangeToken = lens _gctrsChangeToken (\ s a -> s{_gctrsChangeToken = a});
+
+-- | The response status code.
+gctrsResponseStatus :: Lens' GetChangeTokenResponse Int
+gctrsResponseStatus = lens _gctrsResponseStatus (\ s a -> s{_gctrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetChangeTokenStatus.hs b/gen/Network/AWS/WAF/GetChangeTokenStatus.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetChangeTokenStatus.hs
@@ -0,0 +1,137 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetChangeTokenStatus
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns the status of a 'ChangeToken' that you got by calling
+-- GetChangeToken. 'ChangeTokenStatus' is one of the following values:
+--
+-- -   'PROVISIONED': You requested the change token by calling
+--     'GetChangeToken', but you haven\'t used it yet in a call to create,
+--     update, or delete an AWS WAF object.
+-- -   'PENDING': AWS WAF is propagating the create, update, or delete
+--     request to all AWS WAF servers.
+-- -   'IN_SYNC': Propagation is complete.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetChangeTokenStatus.html AWS API Reference> for GetChangeTokenStatus.
+module Network.AWS.WAF.GetChangeTokenStatus
+    (
+    -- * Creating a Request
+      getChangeTokenStatus
+    , GetChangeTokenStatus
+    -- * Request Lenses
+    , gctsChangeToken
+
+    -- * Destructuring the Response
+    , getChangeTokenStatusResponse
+    , GetChangeTokenStatusResponse
+    -- * Response Lenses
+    , gctsrsChangeTokenStatus
+    , gctsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'getChangeTokenStatus' smart constructor.
+newtype GetChangeTokenStatus = GetChangeTokenStatus'
+    { _gctsChangeToken :: Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetChangeTokenStatus' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gctsChangeToken'
+getChangeTokenStatus
+    :: Text -- ^ 'gctsChangeToken'
+    -> GetChangeTokenStatus
+getChangeTokenStatus pChangeToken_ =
+    GetChangeTokenStatus'
+    { _gctsChangeToken = pChangeToken_
+    }
+
+-- | The change token for which you want to get the status. This change token
+-- was previously returned in the 'GetChangeToken' response.
+gctsChangeToken :: Lens' GetChangeTokenStatus Text
+gctsChangeToken = lens _gctsChangeToken (\ s a -> s{_gctsChangeToken = a});
+
+instance AWSRequest GetChangeTokenStatus where
+        type Rs GetChangeTokenStatus =
+             GetChangeTokenStatusResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetChangeTokenStatusResponse' <$>
+                   (x .?> "ChangeTokenStatus") <*> (pure (fromEnum s)))
+
+instance ToHeaders GetChangeTokenStatus where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetChangeTokenStatus" ::
+                       ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetChangeTokenStatus where
+        toJSON GetChangeTokenStatus'{..}
+          = object
+              (catMaybes
+                 [Just ("ChangeToken" .= _gctsChangeToken)])
+
+instance ToPath GetChangeTokenStatus where
+        toPath = const "/"
+
+instance ToQuery GetChangeTokenStatus where
+        toQuery = const mempty
+
+-- | /See:/ 'getChangeTokenStatusResponse' smart constructor.
+data GetChangeTokenStatusResponse = GetChangeTokenStatusResponse'
+    { _gctsrsChangeTokenStatus :: !(Maybe ChangeTokenStatus)
+    , _gctsrsResponseStatus    :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetChangeTokenStatusResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gctsrsChangeTokenStatus'
+--
+-- * 'gctsrsResponseStatus'
+getChangeTokenStatusResponse
+    :: Int -- ^ 'gctsrsResponseStatus'
+    -> GetChangeTokenStatusResponse
+getChangeTokenStatusResponse pResponseStatus_ =
+    GetChangeTokenStatusResponse'
+    { _gctsrsChangeTokenStatus = Nothing
+    , _gctsrsResponseStatus = pResponseStatus_
+    }
+
+-- | The status of the change token.
+gctsrsChangeTokenStatus :: Lens' GetChangeTokenStatusResponse (Maybe ChangeTokenStatus)
+gctsrsChangeTokenStatus = lens _gctsrsChangeTokenStatus (\ s a -> s{_gctsrsChangeTokenStatus = a});
+
+-- | The response status code.
+gctsrsResponseStatus :: Lens' GetChangeTokenStatusResponse Int
+gctsrsResponseStatus = lens _gctsrsResponseStatus (\ s a -> s{_gctsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetIPSet.hs b/gen/Network/AWS/WAF/GetIPSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetIPSet.hs
@@ -0,0 +1,131 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetIPSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns the IPSet that is specified by 'IPSetId'.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetIPSet.html AWS API Reference> for GetIPSet.
+module Network.AWS.WAF.GetIPSet
+    (
+    -- * Creating a Request
+      getIPSet
+    , GetIPSet
+    -- * Request Lenses
+    , gisIPSetId
+
+    -- * Destructuring the Response
+    , getIPSetResponse
+    , GetIPSetResponse
+    -- * Response Lenses
+    , gisrsIPSet
+    , gisrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'getIPSet' smart constructor.
+newtype GetIPSet = GetIPSet'
+    { _gisIPSetId :: Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetIPSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gisIPSetId'
+getIPSet
+    :: Text -- ^ 'gisIPSetId'
+    -> GetIPSet
+getIPSet pIPSetId_ =
+    GetIPSet'
+    { _gisIPSetId = pIPSetId_
+    }
+
+-- | The 'IPSetId' of the IPSet that you want to get. 'IPSetId' is returned
+-- by CreateIPSet and by ListIPSets.
+gisIPSetId :: Lens' GetIPSet Text
+gisIPSetId = lens _gisIPSetId (\ s a -> s{_gisIPSetId = a});
+
+instance AWSRequest GetIPSet where
+        type Rs GetIPSet = GetIPSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetIPSetResponse' <$>
+                   (x .?> "IPSet") <*> (pure (fromEnum s)))
+
+instance ToHeaders GetIPSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetIPSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetIPSet where
+        toJSON GetIPSet'{..}
+          = object
+              (catMaybes [Just ("IPSetId" .= _gisIPSetId)])
+
+instance ToPath GetIPSet where
+        toPath = const "/"
+
+instance ToQuery GetIPSet where
+        toQuery = const mempty
+
+-- | /See:/ 'getIPSetResponse' smart constructor.
+data GetIPSetResponse = GetIPSetResponse'
+    { _gisrsIPSet          :: !(Maybe IPSet)
+    , _gisrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetIPSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gisrsIPSet'
+--
+-- * 'gisrsResponseStatus'
+getIPSetResponse
+    :: Int -- ^ 'gisrsResponseStatus'
+    -> GetIPSetResponse
+getIPSetResponse pResponseStatus_ =
+    GetIPSetResponse'
+    { _gisrsIPSet = Nothing
+    , _gisrsResponseStatus = pResponseStatus_
+    }
+
+-- | Information about the IPSet that you specified in the 'GetIPSet'
+-- request. For more information, see the following topics:
+--
+-- -   IPSet: Contains 'IPSetDescriptors', 'IPSetId', and 'Name'
+-- -   'IPSetDescriptors': Contains an array of IPSetDescriptor objects.
+--     Each 'IPSetDescriptor' object contains 'Type' and 'Value'
+gisrsIPSet :: Lens' GetIPSetResponse (Maybe IPSet)
+gisrsIPSet = lens _gisrsIPSet (\ s a -> s{_gisrsIPSet = a});
+
+-- | The response status code.
+gisrsResponseStatus :: Lens' GetIPSetResponse Int
+gisrsResponseStatus = lens _gisrsResponseStatus (\ s a -> s{_gisrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetRule.hs b/gen/Network/AWS/WAF/GetRule.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetRule.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetRule
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns the Rule that is specified by the 'RuleId' that you included in
+-- the 'GetRule' request.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetRule.html AWS API Reference> for GetRule.
+module Network.AWS.WAF.GetRule
+    (
+    -- * Creating a Request
+      getRule
+    , GetRule
+    -- * Request Lenses
+    , grRuleId
+
+    -- * Destructuring the Response
+    , getRuleResponse
+    , GetRuleResponse
+    -- * Response Lenses
+    , grrsRule
+    , grrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'getRule' smart constructor.
+newtype GetRule = GetRule'
+    { _grRuleId :: Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetRule' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'grRuleId'
+getRule
+    :: Text -- ^ 'grRuleId'
+    -> GetRule
+getRule pRuleId_ =
+    GetRule'
+    { _grRuleId = pRuleId_
+    }
+
+-- | The 'RuleId' of the Rule that you want to get. 'RuleId' is returned by
+-- CreateRule and by ListRules.
+grRuleId :: Lens' GetRule Text
+grRuleId = lens _grRuleId (\ s a -> s{_grRuleId = a});
+
+instance AWSRequest GetRule where
+        type Rs GetRule = GetRuleResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetRuleResponse' <$>
+                   (x .?> "Rule") <*> (pure (fromEnum s)))
+
+instance ToHeaders GetRule where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetRule" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetRule where
+        toJSON GetRule'{..}
+          = object (catMaybes [Just ("RuleId" .= _grRuleId)])
+
+instance ToPath GetRule where
+        toPath = const "/"
+
+instance ToQuery GetRule where
+        toQuery = const mempty
+
+-- | /See:/ 'getRuleResponse' smart constructor.
+data GetRuleResponse = GetRuleResponse'
+    { _grrsRule           :: !(Maybe Rule)
+    , _grrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetRuleResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'grrsRule'
+--
+-- * 'grrsResponseStatus'
+getRuleResponse
+    :: Int -- ^ 'grrsResponseStatus'
+    -> GetRuleResponse
+getRuleResponse pResponseStatus_ =
+    GetRuleResponse'
+    { _grrsRule = Nothing
+    , _grrsResponseStatus = pResponseStatus_
+    }
+
+-- | Information about the Rule that you specified in the 'GetRule' request.
+-- For more information, see the following topics:
+--
+-- -   Rule: Contains 'MetricName', 'Name', an array of 'Predicate'
+--     objects, and 'RuleId'
+-- -   Predicate: Each 'Predicate' object contains 'DataId', 'Negated', and
+--     'Type'
+grrsRule :: Lens' GetRuleResponse (Maybe Rule)
+grrsRule = lens _grrsRule (\ s a -> s{_grrsRule = a});
+
+-- | The response status code.
+grrsResponseStatus :: Lens' GetRuleResponse Int
+grrsResponseStatus = lens _grrsResponseStatus (\ s a -> s{_grrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetSampledRequests.hs b/gen/Network/AWS/WAF/GetSampledRequests.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetSampledRequests.hs
@@ -0,0 +1,213 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetSampledRequests
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Gets detailed information about a specified number of requests--a
+-- sample--that AWS WAF randomly selects from among the first 5,000
+-- requests that your AWS resource received during a time range that you
+-- choose. You can specify a sample size of up to 100 requests, and you can
+-- specify any time range in the previous three hours.
+--
+-- 'GetSampledRequests' returns a time range, which is usually the time
+-- range that you specified. However, if your resource (such as a
+-- CloudFront distribution) received 5,000 requests before the specified
+-- time range elapsed, 'GetSampledRequests' returns an updated time range.
+-- This new time range indicates the actual period during which AWS WAF
+-- selected the requests in the sample.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetSampledRequests.html AWS API Reference> for GetSampledRequests.
+module Network.AWS.WAF.GetSampledRequests
+    (
+    -- * Creating a Request
+      getSampledRequests
+    , GetSampledRequests
+    -- * Request Lenses
+    , gsrWebACLId
+    , gsrRuleId
+    , gsrTimeWindow
+    , gsrMaxItems
+
+    -- * Destructuring the Response
+    , getSampledRequestsResponse
+    , GetSampledRequestsResponse
+    -- * Response Lenses
+    , gsrrsSampledRequests
+    , gsrrsPopulationSize
+    , gsrrsTimeWindow
+    , gsrrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'getSampledRequests' smart constructor.
+data GetSampledRequests = GetSampledRequests'
+    { _gsrWebACLId   :: !Text
+    , _gsrRuleId     :: !Text
+    , _gsrTimeWindow :: !TimeWindow
+    , _gsrMaxItems   :: !Nat
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetSampledRequests' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gsrWebACLId'
+--
+-- * 'gsrRuleId'
+--
+-- * 'gsrTimeWindow'
+--
+-- * 'gsrMaxItems'
+getSampledRequests
+    :: Text -- ^ 'gsrWebACLId'
+    -> Text -- ^ 'gsrRuleId'
+    -> TimeWindow -- ^ 'gsrTimeWindow'
+    -> Natural -- ^ 'gsrMaxItems'
+    -> GetSampledRequests
+getSampledRequests pWebACLId_ pRuleId_ pTimeWindow_ pMaxItems_ =
+    GetSampledRequests'
+    { _gsrWebACLId = pWebACLId_
+    , _gsrRuleId = pRuleId_
+    , _gsrTimeWindow = pTimeWindow_
+    , _gsrMaxItems = _Nat # pMaxItems_
+    }
+
+-- | The 'WebACLId' of the 'WebACL' for which you want 'GetSampledRequests'
+-- to return a sample of requests.
+gsrWebACLId :: Lens' GetSampledRequests Text
+gsrWebACLId = lens _gsrWebACLId (\ s a -> s{_gsrWebACLId = a});
+
+-- | 'RuleId' is one of two values:
+--
+-- -   The 'RuleId' of the 'Rule' for which you want 'GetSampledRequests'
+--     to return a sample of requests.
+-- -   'Default_Action', which causes 'GetSampledRequests' to return a
+--     sample of the requests that didn\'t match any of the rules in the
+--     specified 'WebACL'.
+gsrRuleId :: Lens' GetSampledRequests Text
+gsrRuleId = lens _gsrRuleId (\ s a -> s{_gsrRuleId = a});
+
+-- | The start date and time and the end date and time of the range for which
+-- you want 'GetSampledRequests' to return a sample of requests. Specify
+-- the date and time in Unix time format (in seconds). You can specify any
+-- time range in the previous three hours.
+gsrTimeWindow :: Lens' GetSampledRequests TimeWindow
+gsrTimeWindow = lens _gsrTimeWindow (\ s a -> s{_gsrTimeWindow = a});
+
+-- | The number of requests that you want AWS WAF to return from among the
+-- first 5,000 requests that your AWS resource received during the time
+-- range. If your resource received fewer requests than the value of
+-- 'MaxItems', 'GetSampledRequests' returns information about all of them.
+gsrMaxItems :: Lens' GetSampledRequests Natural
+gsrMaxItems = lens _gsrMaxItems (\ s a -> s{_gsrMaxItems = a}) . _Nat;
+
+instance AWSRequest GetSampledRequests where
+        type Rs GetSampledRequests =
+             GetSampledRequestsResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetSampledRequestsResponse' <$>
+                   (x .?> "SampledRequests" .!@ mempty) <*>
+                     (x .?> "PopulationSize")
+                     <*> (x .?> "TimeWindow")
+                     <*> (pure (fromEnum s)))
+
+instance ToHeaders GetSampledRequests where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetSampledRequests" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetSampledRequests where
+        toJSON GetSampledRequests'{..}
+          = object
+              (catMaybes
+                 [Just ("WebAclId" .= _gsrWebACLId),
+                  Just ("RuleId" .= _gsrRuleId),
+                  Just ("TimeWindow" .= _gsrTimeWindow),
+                  Just ("MaxItems" .= _gsrMaxItems)])
+
+instance ToPath GetSampledRequests where
+        toPath = const "/"
+
+instance ToQuery GetSampledRequests where
+        toQuery = const mempty
+
+-- | /See:/ 'getSampledRequestsResponse' smart constructor.
+data GetSampledRequestsResponse = GetSampledRequestsResponse'
+    { _gsrrsSampledRequests :: !(Maybe [SampledHTTPRequest])
+    , _gsrrsPopulationSize  :: !(Maybe Integer)
+    , _gsrrsTimeWindow      :: !(Maybe TimeWindow)
+    , _gsrrsResponseStatus  :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetSampledRequestsResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gsrrsSampledRequests'
+--
+-- * 'gsrrsPopulationSize'
+--
+-- * 'gsrrsTimeWindow'
+--
+-- * 'gsrrsResponseStatus'
+getSampledRequestsResponse
+    :: Int -- ^ 'gsrrsResponseStatus'
+    -> GetSampledRequestsResponse
+getSampledRequestsResponse pResponseStatus_ =
+    GetSampledRequestsResponse'
+    { _gsrrsSampledRequests = Nothing
+    , _gsrrsPopulationSize = Nothing
+    , _gsrrsTimeWindow = Nothing
+    , _gsrrsResponseStatus = pResponseStatus_
+    }
+
+-- | A complex type that contains detailed information about each of the
+-- requests in the sample.
+gsrrsSampledRequests :: Lens' GetSampledRequestsResponse [SampledHTTPRequest]
+gsrrsSampledRequests = lens _gsrrsSampledRequests (\ s a -> s{_gsrrsSampledRequests = a}) . _Default . _Coerce;
+
+-- | The total number of requests from which 'GetSampledRequests' got a
+-- sample of 'MaxItems' requests. If 'PopulationSize' is less than
+-- 'MaxItems', the sample includes every request that your AWS resource
+-- received during the specified time range.
+gsrrsPopulationSize :: Lens' GetSampledRequestsResponse (Maybe Integer)
+gsrrsPopulationSize = lens _gsrrsPopulationSize (\ s a -> s{_gsrrsPopulationSize = a});
+
+-- | Usually, 'TimeWindow' is the time range that you specified in the
+-- 'GetSampledRequests' request. However, if your AWS resource received
+-- more than 5,000 requests during the time range that you specified in the
+-- request, 'GetSampledRequests' returns the time range for the first 5,000
+-- requests.
+gsrrsTimeWindow :: Lens' GetSampledRequestsResponse (Maybe TimeWindow)
+gsrrsTimeWindow = lens _gsrrsTimeWindow (\ s a -> s{_gsrrsTimeWindow = a});
+
+-- | The response status code.
+gsrrsResponseStatus :: Lens' GetSampledRequestsResponse Int
+gsrrsResponseStatus = lens _gsrrsResponseStatus (\ s a -> s{_gsrrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetSqlInjectionMatchSet.hs b/gen/Network/AWS/WAF/GetSqlInjectionMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetSqlInjectionMatchSet.hs
@@ -0,0 +1,146 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetSqlInjectionMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns the SqlInjectionMatchSet that is specified by
+-- 'SqlInjectionMatchSetId'.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetSqlInjectionMatchSet.html AWS API Reference> for GetSqlInjectionMatchSet.
+module Network.AWS.WAF.GetSqlInjectionMatchSet
+    (
+    -- * Creating a Request
+      getSqlInjectionMatchSet
+    , GetSqlInjectionMatchSet
+    -- * Request Lenses
+    , gsimsSqlInjectionMatchSetId
+
+    -- * Destructuring the Response
+    , getSqlInjectionMatchSetResponse
+    , GetSqlInjectionMatchSetResponse
+    -- * Response Lenses
+    , gsimsrsSqlInjectionMatchSet
+    , gsimsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | A request to get a SqlInjectionMatchSet.
+--
+-- /See:/ 'getSqlInjectionMatchSet' smart constructor.
+newtype GetSqlInjectionMatchSet = GetSqlInjectionMatchSet'
+    { _gsimsSqlInjectionMatchSetId :: Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetSqlInjectionMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gsimsSqlInjectionMatchSetId'
+getSqlInjectionMatchSet
+    :: Text -- ^ 'gsimsSqlInjectionMatchSetId'
+    -> GetSqlInjectionMatchSet
+getSqlInjectionMatchSet pSqlInjectionMatchSetId_ =
+    GetSqlInjectionMatchSet'
+    { _gsimsSqlInjectionMatchSetId = pSqlInjectionMatchSetId_
+    }
+
+-- | The 'SqlInjectionMatchSetId' of the SqlInjectionMatchSet that you want
+-- to get. 'SqlInjectionMatchSetId' is returned by
+-- CreateSqlInjectionMatchSet and by ListSqlInjectionMatchSets.
+gsimsSqlInjectionMatchSetId :: Lens' GetSqlInjectionMatchSet Text
+gsimsSqlInjectionMatchSetId = lens _gsimsSqlInjectionMatchSetId (\ s a -> s{_gsimsSqlInjectionMatchSetId = a});
+
+instance AWSRequest GetSqlInjectionMatchSet where
+        type Rs GetSqlInjectionMatchSet =
+             GetSqlInjectionMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetSqlInjectionMatchSetResponse' <$>
+                   (x .?> "SqlInjectionMatchSet") <*>
+                     (pure (fromEnum s)))
+
+instance ToHeaders GetSqlInjectionMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetSqlInjectionMatchSet" ::
+                       ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetSqlInjectionMatchSet where
+        toJSON GetSqlInjectionMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just
+                    ("SqlInjectionMatchSetId" .=
+                       _gsimsSqlInjectionMatchSetId)])
+
+instance ToPath GetSqlInjectionMatchSet where
+        toPath = const "/"
+
+instance ToQuery GetSqlInjectionMatchSet where
+        toQuery = const mempty
+
+-- | The response to a GetSqlInjectionMatchSet request.
+--
+-- /See:/ 'getSqlInjectionMatchSetResponse' smart constructor.
+data GetSqlInjectionMatchSetResponse = GetSqlInjectionMatchSetResponse'
+    { _gsimsrsSqlInjectionMatchSet :: !(Maybe SqlInjectionMatchSet)
+    , _gsimsrsResponseStatus       :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetSqlInjectionMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gsimsrsSqlInjectionMatchSet'
+--
+-- * 'gsimsrsResponseStatus'
+getSqlInjectionMatchSetResponse
+    :: Int -- ^ 'gsimsrsResponseStatus'
+    -> GetSqlInjectionMatchSetResponse
+getSqlInjectionMatchSetResponse pResponseStatus_ =
+    GetSqlInjectionMatchSetResponse'
+    { _gsimsrsSqlInjectionMatchSet = Nothing
+    , _gsimsrsResponseStatus = pResponseStatus_
+    }
+
+-- | Information about the SqlInjectionMatchSet that you specified in the
+-- 'GetSqlInjectionMatchSet' request. For more information, see the
+-- following topics:
+--
+-- -   SqlInjectionMatchSet: Contains 'Name', 'SqlInjectionMatchSetId', and
+--     an array of 'SqlInjectionMatchTuple' objects
+-- -   SqlInjectionMatchTuple: Each 'SqlInjectionMatchTuple' object
+--     contains 'FieldToMatch' and 'TextTransformation'
+-- -   FieldToMatch: Contains 'Data' and 'Type'
+gsimsrsSqlInjectionMatchSet :: Lens' GetSqlInjectionMatchSetResponse (Maybe SqlInjectionMatchSet)
+gsimsrsSqlInjectionMatchSet = lens _gsimsrsSqlInjectionMatchSet (\ s a -> s{_gsimsrsSqlInjectionMatchSet = a});
+
+-- | The response status code.
+gsimsrsResponseStatus :: Lens' GetSqlInjectionMatchSetResponse Int
+gsimsrsResponseStatus = lens _gsimsrsResponseStatus (\ s a -> s{_gsimsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/GetWebACL.hs b/gen/Network/AWS/WAF/GetWebACL.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/GetWebACL.hs
@@ -0,0 +1,134 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.GetWebACL
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns the WebACL that is specified by 'WebACLId'.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_GetWebACL.html AWS API Reference> for GetWebACL.
+module Network.AWS.WAF.GetWebACL
+    (
+    -- * Creating a Request
+      getWebACL
+    , GetWebACL
+    -- * Request Lenses
+    , gwaWebACLId
+
+    -- * Destructuring the Response
+    , getWebACLResponse
+    , GetWebACLResponse
+    -- * Response Lenses
+    , gwarsWebACL
+    , gwarsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'getWebACL' smart constructor.
+newtype GetWebACL = GetWebACL'
+    { _gwaWebACLId :: Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetWebACL' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gwaWebACLId'
+getWebACL
+    :: Text -- ^ 'gwaWebACLId'
+    -> GetWebACL
+getWebACL pWebACLId_ =
+    GetWebACL'
+    { _gwaWebACLId = pWebACLId_
+    }
+
+-- | The 'WebACLId' of the WebACL that you want to get. 'WebACLId' is
+-- returned by CreateWebACL and by ListWebACLs.
+gwaWebACLId :: Lens' GetWebACL Text
+gwaWebACLId = lens _gwaWebACLId (\ s a -> s{_gwaWebACLId = a});
+
+instance AWSRequest GetWebACL where
+        type Rs GetWebACL = GetWebACLResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 GetWebACLResponse' <$>
+                   (x .?> "WebACL") <*> (pure (fromEnum s)))
+
+instance ToHeaders GetWebACL where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.GetWebACL" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON GetWebACL where
+        toJSON GetWebACL'{..}
+          = object
+              (catMaybes [Just ("WebACLId" .= _gwaWebACLId)])
+
+instance ToPath GetWebACL where
+        toPath = const "/"
+
+instance ToQuery GetWebACL where
+        toQuery = const mempty
+
+-- | /See:/ 'getWebACLResponse' smart constructor.
+data GetWebACLResponse = GetWebACLResponse'
+    { _gwarsWebACL         :: !(Maybe WebACL)
+    , _gwarsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'GetWebACLResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'gwarsWebACL'
+--
+-- * 'gwarsResponseStatus'
+getWebACLResponse
+    :: Int -- ^ 'gwarsResponseStatus'
+    -> GetWebACLResponse
+getWebACLResponse pResponseStatus_ =
+    GetWebACLResponse'
+    { _gwarsWebACL = Nothing
+    , _gwarsResponseStatus = pResponseStatus_
+    }
+
+-- | Information about the WebACL that you specified in the 'GetWebACL'
+-- request. For more information, see the following topics:
+--
+-- -   WebACL: Contains 'DefaultAction', 'MetricName', 'Name', an array of
+--     'Rule' objects, and 'WebACLId'
+-- -   'DefaultAction' (Data type is WafAction): Contains 'Type'
+-- -   'Rules': Contains an array of 'ActivatedRule' objects, which contain
+--     'Action', 'Priority', and 'RuleId'
+-- -   'Action': Contains 'Type'
+gwarsWebACL :: Lens' GetWebACLResponse (Maybe WebACL)
+gwarsWebACL = lens _gwarsWebACL (\ s a -> s{_gwarsWebACL = a});
+
+-- | The response status code.
+gwarsResponseStatus :: Lens' GetWebACLResponse Int
+gwarsResponseStatus = lens _gwarsResponseStatus (\ s a -> s{_gwarsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/ListByteMatchSets.hs b/gen/Network/AWS/WAF/ListByteMatchSets.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/ListByteMatchSets.hs
@@ -0,0 +1,159 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.ListByteMatchSets
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns an array of ByteMatchSetSummary objects.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_ListByteMatchSets.html AWS API Reference> for ListByteMatchSets.
+module Network.AWS.WAF.ListByteMatchSets
+    (
+    -- * Creating a Request
+      listByteMatchSets
+    , ListByteMatchSets
+    -- * Request Lenses
+    , lbmsNextMarker
+    , lbmsLimit
+
+    -- * Destructuring the Response
+    , listByteMatchSetsResponse
+    , ListByteMatchSetsResponse
+    -- * Response Lenses
+    , lbmsrsByteMatchSets
+    , lbmsrsNextMarker
+    , lbmsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'listByteMatchSets' smart constructor.
+data ListByteMatchSets = ListByteMatchSets'
+    { _lbmsNextMarker :: !(Maybe Text)
+    , _lbmsLimit      :: !Nat
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListByteMatchSets' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lbmsNextMarker'
+--
+-- * 'lbmsLimit'
+listByteMatchSets
+    :: Natural -- ^ 'lbmsLimit'
+    -> ListByteMatchSets
+listByteMatchSets pLimit_ =
+    ListByteMatchSets'
+    { _lbmsNextMarker = Nothing
+    , _lbmsLimit = _Nat # pLimit_
+    }
+
+-- | If you specify a value for 'Limit' and you have more 'ByteMatchSets'
+-- than the value of 'Limit', AWS WAF returns a 'NextMarker' value in the
+-- response that allows you to list another group of 'ByteMatchSets'. For
+-- the second and subsequent 'ListByteMatchSets' requests, specify the
+-- value of 'NextMarker' from the previous response to get information
+-- about another batch of 'ByteMatchSets'.
+lbmsNextMarker :: Lens' ListByteMatchSets (Maybe Text)
+lbmsNextMarker = lens _lbmsNextMarker (\ s a -> s{_lbmsNextMarker = a});
+
+-- | Specifies the number of 'ByteMatchSet' objects that you want AWS WAF to
+-- return for this request. If you have more 'ByteMatchSets' objects than
+-- the number you specify for 'Limit', the response includes a 'NextMarker'
+-- value that you can use to get another batch of 'ByteMatchSet' objects.
+lbmsLimit :: Lens' ListByteMatchSets Natural
+lbmsLimit = lens _lbmsLimit (\ s a -> s{_lbmsLimit = a}) . _Nat;
+
+instance AWSRequest ListByteMatchSets where
+        type Rs ListByteMatchSets = ListByteMatchSetsResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 ListByteMatchSetsResponse' <$>
+                   (x .?> "ByteMatchSets" .!@ mempty) <*>
+                     (x .?> "NextMarker")
+                     <*> (pure (fromEnum s)))
+
+instance ToHeaders ListByteMatchSets where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.ListByteMatchSets" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON ListByteMatchSets where
+        toJSON ListByteMatchSets'{..}
+          = object
+              (catMaybes
+                 [("NextMarker" .=) <$> _lbmsNextMarker,
+                  Just ("Limit" .= _lbmsLimit)])
+
+instance ToPath ListByteMatchSets where
+        toPath = const "/"
+
+instance ToQuery ListByteMatchSets where
+        toQuery = const mempty
+
+-- | /See:/ 'listByteMatchSetsResponse' smart constructor.
+data ListByteMatchSetsResponse = ListByteMatchSetsResponse'
+    { _lbmsrsByteMatchSets  :: !(Maybe [ByteMatchSetSummary])
+    , _lbmsrsNextMarker     :: !(Maybe Text)
+    , _lbmsrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListByteMatchSetsResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lbmsrsByteMatchSets'
+--
+-- * 'lbmsrsNextMarker'
+--
+-- * 'lbmsrsResponseStatus'
+listByteMatchSetsResponse
+    :: Int -- ^ 'lbmsrsResponseStatus'
+    -> ListByteMatchSetsResponse
+listByteMatchSetsResponse pResponseStatus_ =
+    ListByteMatchSetsResponse'
+    { _lbmsrsByteMatchSets = Nothing
+    , _lbmsrsNextMarker = Nothing
+    , _lbmsrsResponseStatus = pResponseStatus_
+    }
+
+-- | An array of ByteMatchSetSummary objects.
+lbmsrsByteMatchSets :: Lens' ListByteMatchSetsResponse [ByteMatchSetSummary]
+lbmsrsByteMatchSets = lens _lbmsrsByteMatchSets (\ s a -> s{_lbmsrsByteMatchSets = a}) . _Default . _Coerce;
+
+-- | If you have more 'ByteMatchSet' objects than the number that you
+-- specified for 'Limit' in the request, the response includes a
+-- 'NextMarker' value. To list more 'ByteMatchSet' objects, submit another
+-- 'ListByteMatchSets' request, and specify the 'NextMarker' value from the
+-- response in the 'NextMarker' value in the next request.
+lbmsrsNextMarker :: Lens' ListByteMatchSetsResponse (Maybe Text)
+lbmsrsNextMarker = lens _lbmsrsNextMarker (\ s a -> s{_lbmsrsNextMarker = a});
+
+-- | The response status code.
+lbmsrsResponseStatus :: Lens' ListByteMatchSetsResponse Int
+lbmsrsResponseStatus = lens _lbmsrsResponseStatus (\ s a -> s{_lbmsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/ListIPSets.hs b/gen/Network/AWS/WAF/ListIPSets.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/ListIPSets.hs
@@ -0,0 +1,158 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.ListIPSets
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns an array of IPSetSummary objects in the response.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_ListIPSets.html AWS API Reference> for ListIPSets.
+module Network.AWS.WAF.ListIPSets
+    (
+    -- * Creating a Request
+      listIPSets
+    , ListIPSets
+    -- * Request Lenses
+    , lisNextMarker
+    , lisLimit
+
+    -- * Destructuring the Response
+    , listIPSetsResponse
+    , ListIPSetsResponse
+    -- * Response Lenses
+    , lisrsNextMarker
+    , lisrsIPSets
+    , lisrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'listIPSets' smart constructor.
+data ListIPSets = ListIPSets'
+    { _lisNextMarker :: !(Maybe Text)
+    , _lisLimit      :: !Nat
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListIPSets' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lisNextMarker'
+--
+-- * 'lisLimit'
+listIPSets
+    :: Natural -- ^ 'lisLimit'
+    -> ListIPSets
+listIPSets pLimit_ =
+    ListIPSets'
+    { _lisNextMarker = Nothing
+    , _lisLimit = _Nat # pLimit_
+    }
+
+-- | If you specify a value for 'Limit' and you have more 'IPSets' than the
+-- value of 'Limit', AWS WAF returns a 'NextMarker' value in the response
+-- that allows you to list another group of 'IPSets'. For the second and
+-- subsequent 'ListIPSets' requests, specify the value of 'NextMarker' from
+-- the previous response to get information about another batch of
+-- 'ByteMatchSets'.
+lisNextMarker :: Lens' ListIPSets (Maybe Text)
+lisNextMarker = lens _lisNextMarker (\ s a -> s{_lisNextMarker = a});
+
+-- | Specifies the number of 'IPSet' objects that you want AWS WAF to return
+-- for this request. If you have more 'IPSet' objects than the number you
+-- specify for 'Limit', the response includes a 'NextMarker' value that you
+-- can use to get another batch of 'IPSet' objects.
+lisLimit :: Lens' ListIPSets Natural
+lisLimit = lens _lisLimit (\ s a -> s{_lisLimit = a}) . _Nat;
+
+instance AWSRequest ListIPSets where
+        type Rs ListIPSets = ListIPSetsResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 ListIPSetsResponse' <$>
+                   (x .?> "NextMarker") <*> (x .?> "IPSets" .!@ mempty)
+                     <*> (pure (fromEnum s)))
+
+instance ToHeaders ListIPSets where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.ListIPSets" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON ListIPSets where
+        toJSON ListIPSets'{..}
+          = object
+              (catMaybes
+                 [("NextMarker" .=) <$> _lisNextMarker,
+                  Just ("Limit" .= _lisLimit)])
+
+instance ToPath ListIPSets where
+        toPath = const "/"
+
+instance ToQuery ListIPSets where
+        toQuery = const mempty
+
+-- | /See:/ 'listIPSetsResponse' smart constructor.
+data ListIPSetsResponse = ListIPSetsResponse'
+    { _lisrsNextMarker     :: !(Maybe Text)
+    , _lisrsIPSets         :: !(Maybe [IPSetSummary])
+    , _lisrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListIPSetsResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lisrsNextMarker'
+--
+-- * 'lisrsIPSets'
+--
+-- * 'lisrsResponseStatus'
+listIPSetsResponse
+    :: Int -- ^ 'lisrsResponseStatus'
+    -> ListIPSetsResponse
+listIPSetsResponse pResponseStatus_ =
+    ListIPSetsResponse'
+    { _lisrsNextMarker = Nothing
+    , _lisrsIPSets = Nothing
+    , _lisrsResponseStatus = pResponseStatus_
+    }
+
+-- | If you have more 'IPSet' objects than the number that you specified for
+-- 'Limit' in the request, the response includes a 'NextMarker' value. To
+-- list more 'IPSet' objects, submit another 'ListIPSets' request, and
+-- specify the 'NextMarker' value from the response in the 'NextMarker'
+-- value in the next request.
+lisrsNextMarker :: Lens' ListIPSetsResponse (Maybe Text)
+lisrsNextMarker = lens _lisrsNextMarker (\ s a -> s{_lisrsNextMarker = a});
+
+-- | An array of IPSetSummary objects.
+lisrsIPSets :: Lens' ListIPSetsResponse [IPSetSummary]
+lisrsIPSets = lens _lisrsIPSets (\ s a -> s{_lisrsIPSets = a}) . _Default . _Coerce;
+
+-- | The response status code.
+lisrsResponseStatus :: Lens' ListIPSetsResponse Int
+lisrsResponseStatus = lens _lisrsResponseStatus (\ s a -> s{_lisrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/ListRules.hs b/gen/Network/AWS/WAF/ListRules.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/ListRules.hs
@@ -0,0 +1,157 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.ListRules
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns an array of RuleSummary objects.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_ListRules.html AWS API Reference> for ListRules.
+module Network.AWS.WAF.ListRules
+    (
+    -- * Creating a Request
+      listRules
+    , ListRules
+    -- * Request Lenses
+    , lrNextMarker
+    , lrLimit
+
+    -- * Destructuring the Response
+    , listRulesResponse
+    , ListRulesResponse
+    -- * Response Lenses
+    , lrrsRules
+    , lrrsNextMarker
+    , lrrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'listRules' smart constructor.
+data ListRules = ListRules'
+    { _lrNextMarker :: !(Maybe Text)
+    , _lrLimit      :: !Nat
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListRules' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lrNextMarker'
+--
+-- * 'lrLimit'
+listRules
+    :: Natural -- ^ 'lrLimit'
+    -> ListRules
+listRules pLimit_ =
+    ListRules'
+    { _lrNextMarker = Nothing
+    , _lrLimit = _Nat # pLimit_
+    }
+
+-- | If you specify a value for 'Limit' and you have more 'Rules' than the
+-- value of 'Limit', AWS WAF returns a 'NextMarker' value in the response
+-- that allows you to list another group of 'Rules'. For the second and
+-- subsequent 'ListRules' requests, specify the value of 'NextMarker' from
+-- the previous response to get information about another batch of 'Rules'.
+lrNextMarker :: Lens' ListRules (Maybe Text)
+lrNextMarker = lens _lrNextMarker (\ s a -> s{_lrNextMarker = a});
+
+-- | Specifies the number of 'Rules' that you want AWS WAF to return for this
+-- request. If you have more 'Rules' than the number that you specify for
+-- 'Limit', the response includes a 'NextMarker' value that you can use to
+-- get another batch of 'Rules'.
+lrLimit :: Lens' ListRules Natural
+lrLimit = lens _lrLimit (\ s a -> s{_lrLimit = a}) . _Nat;
+
+instance AWSRequest ListRules where
+        type Rs ListRules = ListRulesResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 ListRulesResponse' <$>
+                   (x .?> "Rules" .!@ mempty) <*> (x .?> "NextMarker")
+                     <*> (pure (fromEnum s)))
+
+instance ToHeaders ListRules where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.ListRules" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON ListRules where
+        toJSON ListRules'{..}
+          = object
+              (catMaybes
+                 [("NextMarker" .=) <$> _lrNextMarker,
+                  Just ("Limit" .= _lrLimit)])
+
+instance ToPath ListRules where
+        toPath = const "/"
+
+instance ToQuery ListRules where
+        toQuery = const mempty
+
+-- | /See:/ 'listRulesResponse' smart constructor.
+data ListRulesResponse = ListRulesResponse'
+    { _lrrsRules          :: !(Maybe [RuleSummary])
+    , _lrrsNextMarker     :: !(Maybe Text)
+    , _lrrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListRulesResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lrrsRules'
+--
+-- * 'lrrsNextMarker'
+--
+-- * 'lrrsResponseStatus'
+listRulesResponse
+    :: Int -- ^ 'lrrsResponseStatus'
+    -> ListRulesResponse
+listRulesResponse pResponseStatus_ =
+    ListRulesResponse'
+    { _lrrsRules = Nothing
+    , _lrrsNextMarker = Nothing
+    , _lrrsResponseStatus = pResponseStatus_
+    }
+
+-- | An array of RuleSummary objects.
+lrrsRules :: Lens' ListRulesResponse [RuleSummary]
+lrrsRules = lens _lrrsRules (\ s a -> s{_lrrsRules = a}) . _Default . _Coerce;
+
+-- | If you have more 'Rules' than the number that you specified for 'Limit'
+-- in the request, the response includes a 'NextMarker' value. To list more
+-- 'Rules', submit another 'ListRules' request, and specify the
+-- 'NextMarker' value from the response in the 'NextMarker' value in the
+-- next request.
+lrrsNextMarker :: Lens' ListRulesResponse (Maybe Text)
+lrrsNextMarker = lens _lrrsNextMarker (\ s a -> s{_lrrsNextMarker = a});
+
+-- | The response status code.
+lrrsResponseStatus :: Lens' ListRulesResponse Int
+lrrsResponseStatus = lens _lrrsResponseStatus (\ s a -> s{_lrrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/ListSqlInjectionMatchSets.hs b/gen/Network/AWS/WAF/ListSqlInjectionMatchSets.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/ListSqlInjectionMatchSets.hs
@@ -0,0 +1,168 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.ListSqlInjectionMatchSets
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns an array of SqlInjectionMatchSet objects.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_ListSqlInjectionMatchSets.html AWS API Reference> for ListSqlInjectionMatchSets.
+module Network.AWS.WAF.ListSqlInjectionMatchSets
+    (
+    -- * Creating a Request
+      listSqlInjectionMatchSets
+    , ListSqlInjectionMatchSets
+    -- * Request Lenses
+    , lsimsNextMarker
+    , lsimsLimit
+
+    -- * Destructuring the Response
+    , listSqlInjectionMatchSetsResponse
+    , ListSqlInjectionMatchSetsResponse
+    -- * Response Lenses
+    , lsimsrsNextMarker
+    , lsimsrsSqlInjectionMatchSets
+    , lsimsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | A request to list the SqlInjectionMatchSet objects created by the
+-- current AWS account.
+--
+-- /See:/ 'listSqlInjectionMatchSets' smart constructor.
+data ListSqlInjectionMatchSets = ListSqlInjectionMatchSets'
+    { _lsimsNextMarker :: !(Maybe Text)
+    , _lsimsLimit      :: !Nat
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListSqlInjectionMatchSets' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lsimsNextMarker'
+--
+-- * 'lsimsLimit'
+listSqlInjectionMatchSets
+    :: Natural -- ^ 'lsimsLimit'
+    -> ListSqlInjectionMatchSets
+listSqlInjectionMatchSets pLimit_ =
+    ListSqlInjectionMatchSets'
+    { _lsimsNextMarker = Nothing
+    , _lsimsLimit = _Nat # pLimit_
+    }
+
+-- | If you specify a value for 'Limit' and you have more
+-- SqlInjectionMatchSet objects than the value of 'Limit', AWS WAF returns
+-- a 'NextMarker' value in the response that allows you to list another
+-- group of 'SqlInjectionMatchSets'. For the second and subsequent
+-- 'ListSqlInjectionMatchSets' requests, specify the value of 'NextMarker'
+-- from the previous response to get information about another batch of
+-- 'SqlInjectionMatchSets'.
+lsimsNextMarker :: Lens' ListSqlInjectionMatchSets (Maybe Text)
+lsimsNextMarker = lens _lsimsNextMarker (\ s a -> s{_lsimsNextMarker = a});
+
+-- | Specifies the number of SqlInjectionMatchSet objects that you want AWS
+-- WAF to return for this request. If you have more 'SqlInjectionMatchSet'
+-- objects than the number you specify for 'Limit', the response includes a
+-- 'NextMarker' value that you can use to get another batch of 'Rules'.
+lsimsLimit :: Lens' ListSqlInjectionMatchSets Natural
+lsimsLimit = lens _lsimsLimit (\ s a -> s{_lsimsLimit = a}) . _Nat;
+
+instance AWSRequest ListSqlInjectionMatchSets where
+        type Rs ListSqlInjectionMatchSets =
+             ListSqlInjectionMatchSetsResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 ListSqlInjectionMatchSetsResponse' <$>
+                   (x .?> "NextMarker") <*>
+                     (x .?> "SqlInjectionMatchSets" .!@ mempty)
+                     <*> (pure (fromEnum s)))
+
+instance ToHeaders ListSqlInjectionMatchSets where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.ListSqlInjectionMatchSets" ::
+                       ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON ListSqlInjectionMatchSets where
+        toJSON ListSqlInjectionMatchSets'{..}
+          = object
+              (catMaybes
+                 [("NextMarker" .=) <$> _lsimsNextMarker,
+                  Just ("Limit" .= _lsimsLimit)])
+
+instance ToPath ListSqlInjectionMatchSets where
+        toPath = const "/"
+
+instance ToQuery ListSqlInjectionMatchSets where
+        toQuery = const mempty
+
+-- | The response to a ListSqlInjectionMatchSets request.
+--
+-- /See:/ 'listSqlInjectionMatchSetsResponse' smart constructor.
+data ListSqlInjectionMatchSetsResponse = ListSqlInjectionMatchSetsResponse'
+    { _lsimsrsNextMarker            :: !(Maybe Text)
+    , _lsimsrsSqlInjectionMatchSets :: !(Maybe [SqlInjectionMatchSetSummary])
+    , _lsimsrsResponseStatus        :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListSqlInjectionMatchSetsResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lsimsrsNextMarker'
+--
+-- * 'lsimsrsSqlInjectionMatchSets'
+--
+-- * 'lsimsrsResponseStatus'
+listSqlInjectionMatchSetsResponse
+    :: Int -- ^ 'lsimsrsResponseStatus'
+    -> ListSqlInjectionMatchSetsResponse
+listSqlInjectionMatchSetsResponse pResponseStatus_ =
+    ListSqlInjectionMatchSetsResponse'
+    { _lsimsrsNextMarker = Nothing
+    , _lsimsrsSqlInjectionMatchSets = Nothing
+    , _lsimsrsResponseStatus = pResponseStatus_
+    }
+
+-- | If you have more SqlInjectionMatchSet objects than the number that you
+-- specified for 'Limit' in the request, the response includes a
+-- 'NextMarker' value. To list more 'SqlInjectionMatchSet' objects, submit
+-- another 'ListSqlInjectionMatchSets' request, and specify the
+-- 'NextMarker' value from the response in the 'NextMarker' value in the
+-- next request.
+lsimsrsNextMarker :: Lens' ListSqlInjectionMatchSetsResponse (Maybe Text)
+lsimsrsNextMarker = lens _lsimsrsNextMarker (\ s a -> s{_lsimsrsNextMarker = a});
+
+-- | An array of SqlInjectionMatchSetSummary objects.
+lsimsrsSqlInjectionMatchSets :: Lens' ListSqlInjectionMatchSetsResponse [SqlInjectionMatchSetSummary]
+lsimsrsSqlInjectionMatchSets = lens _lsimsrsSqlInjectionMatchSets (\ s a -> s{_lsimsrsSqlInjectionMatchSets = a}) . _Default . _Coerce;
+
+-- | The response status code.
+lsimsrsResponseStatus :: Lens' ListSqlInjectionMatchSetsResponse Int
+lsimsrsResponseStatus = lens _lsimsrsResponseStatus (\ s a -> s{_lsimsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/ListWebACLs.hs b/gen/Network/AWS/WAF/ListWebACLs.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/ListWebACLs.hs
@@ -0,0 +1,158 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.ListWebACLs
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns an array of WebACLSummary objects in the response.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_ListWebACLs.html AWS API Reference> for ListWebACLs.
+module Network.AWS.WAF.ListWebACLs
+    (
+    -- * Creating a Request
+      listWebACLs
+    , ListWebACLs
+    -- * Request Lenses
+    , lwaNextMarker
+    , lwaLimit
+
+    -- * Destructuring the Response
+    , listWebACLsResponse
+    , ListWebACLsResponse
+    -- * Response Lenses
+    , lwarsWebACLs
+    , lwarsNextMarker
+    , lwarsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'listWebACLs' smart constructor.
+data ListWebACLs = ListWebACLs'
+    { _lwaNextMarker :: !(Maybe Text)
+    , _lwaLimit      :: !Nat
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListWebACLs' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lwaNextMarker'
+--
+-- * 'lwaLimit'
+listWebACLs
+    :: Natural -- ^ 'lwaLimit'
+    -> ListWebACLs
+listWebACLs pLimit_ =
+    ListWebACLs'
+    { _lwaNextMarker = Nothing
+    , _lwaLimit = _Nat # pLimit_
+    }
+
+-- | If you specify a value for 'Limit' and you have more 'WebACL' objects
+-- than the number that you specify for 'Limit', AWS WAF returns a
+-- 'NextMarker' value in the response that allows you to list another group
+-- of 'WebACL' objects. For the second and subsequent 'ListWebACLs'
+-- requests, specify the value of 'NextMarker' from the previous response
+-- to get information about another batch of 'WebACL' objects.
+lwaNextMarker :: Lens' ListWebACLs (Maybe Text)
+lwaNextMarker = lens _lwaNextMarker (\ s a -> s{_lwaNextMarker = a});
+
+-- | Specifies the number of 'WebACL' objects that you want AWS WAF to return
+-- for this request. If you have more 'WebACL' objects than the number that
+-- you specify for 'Limit', the response includes a 'NextMarker' value that
+-- you can use to get another batch of 'WebACL' objects.
+lwaLimit :: Lens' ListWebACLs Natural
+lwaLimit = lens _lwaLimit (\ s a -> s{_lwaLimit = a}) . _Nat;
+
+instance AWSRequest ListWebACLs where
+        type Rs ListWebACLs = ListWebACLsResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 ListWebACLsResponse' <$>
+                   (x .?> "WebACLs" .!@ mempty) <*> (x .?> "NextMarker")
+                     <*> (pure (fromEnum s)))
+
+instance ToHeaders ListWebACLs where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.ListWebACLs" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON ListWebACLs where
+        toJSON ListWebACLs'{..}
+          = object
+              (catMaybes
+                 [("NextMarker" .=) <$> _lwaNextMarker,
+                  Just ("Limit" .= _lwaLimit)])
+
+instance ToPath ListWebACLs where
+        toPath = const "/"
+
+instance ToQuery ListWebACLs where
+        toQuery = const mempty
+
+-- | /See:/ 'listWebACLsResponse' smart constructor.
+data ListWebACLsResponse = ListWebACLsResponse'
+    { _lwarsWebACLs        :: !(Maybe [WebACLSummary])
+    , _lwarsNextMarker     :: !(Maybe Text)
+    , _lwarsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ListWebACLsResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'lwarsWebACLs'
+--
+-- * 'lwarsNextMarker'
+--
+-- * 'lwarsResponseStatus'
+listWebACLsResponse
+    :: Int -- ^ 'lwarsResponseStatus'
+    -> ListWebACLsResponse
+listWebACLsResponse pResponseStatus_ =
+    ListWebACLsResponse'
+    { _lwarsWebACLs = Nothing
+    , _lwarsNextMarker = Nothing
+    , _lwarsResponseStatus = pResponseStatus_
+    }
+
+-- | An array of WebACLSummary objects.
+lwarsWebACLs :: Lens' ListWebACLsResponse [WebACLSummary]
+lwarsWebACLs = lens _lwarsWebACLs (\ s a -> s{_lwarsWebACLs = a}) . _Default . _Coerce;
+
+-- | If you have more 'WebACL' objects than the number that you specified for
+-- 'Limit' in the request, the response includes a 'NextMarker' value. To
+-- list more 'WebACL' objects, submit another 'ListWebACLs' request, and
+-- specify the 'NextMarker' value from the response in the 'NextMarker'
+-- value in the next request.
+lwarsNextMarker :: Lens' ListWebACLsResponse (Maybe Text)
+lwarsNextMarker = lens _lwarsNextMarker (\ s a -> s{_lwarsNextMarker = a});
+
+-- | The response status code.
+lwarsResponseStatus :: Lens' ListWebACLsResponse Int
+lwarsResponseStatus = lens _lwarsResponseStatus (\ s a -> s{_lwarsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/Types.hs b/gen/Network/AWS/WAF/Types.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/Types.hs
@@ -0,0 +1,376 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.Types
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+module Network.AWS.WAF.Types
+    (
+    -- * Service Configuration
+      wAF
+
+    -- * Errors
+    , _WAFInvalidAccountException
+    , _WAFReferencedItemException
+    , _WAFInvalidOperationException
+    , _WAFNonexistentItemException
+    , _WAFInvalidParameterException
+    , _WAFLimitsExceededException
+    , _WAFStaleDataException
+    , _WAFInternalErrorException
+    , _WAFNonexistentContainerException
+    , _WAFDisallowedNameException
+    , _WAFNonEmptyEntityException
+
+    -- * ChangeAction
+    , ChangeAction (..)
+
+    -- * ChangeTokenStatus
+    , ChangeTokenStatus (..)
+
+    -- * IPSetDescriptorType
+    , IPSetDescriptorType (..)
+
+    -- * MatchFieldType
+    , MatchFieldType (..)
+
+    -- * PositionalConstraint
+    , PositionalConstraint (..)
+
+    -- * PredicateType
+    , PredicateType (..)
+
+    -- * TextTransformation
+    , TextTransformation (..)
+
+    -- * WafActionType
+    , WafActionType (..)
+
+    -- * ActivatedRule
+    , ActivatedRule
+    , activatedRule
+    , arPriority
+    , arRuleId
+    , arAction
+
+    -- * ByteMatchSet
+    , ByteMatchSet
+    , byteMatchSet
+    , bmsName
+    , bmsByteMatchSetId
+    , bmsByteMatchTuples
+
+    -- * ByteMatchSetSummary
+    , ByteMatchSetSummary
+    , byteMatchSetSummary
+    , bmssByteMatchSetId
+    , bmssName
+
+    -- * ByteMatchSetUpdate
+    , ByteMatchSetUpdate
+    , byteMatchSetUpdate
+    , bmsuAction
+    , bmsuByteMatchTuple
+
+    -- * ByteMatchTuple
+    , ByteMatchTuple
+    , byteMatchTuple
+    , bmtFieldToMatch
+    , bmtTargetString
+    , bmtTextTransformation
+    , bmtPositionalConstraint
+
+    -- * FieldToMatch
+    , FieldToMatch
+    , fieldToMatch
+    , ftmData
+    , ftmType
+
+    -- * HTTPHeader
+    , HTTPHeader
+    , hTTPHeader
+    , httphValue
+    , httphName
+
+    -- * HTTPRequest
+    , HTTPRequest
+    , hTTPRequest
+    , httprHTTPVersion
+    , httprCountry
+    , httprURI
+    , httprHeaders
+    , httprMethod
+    , httprClientIP
+
+    -- * IPSet
+    , IPSet
+    , ipSet
+    , isName
+    , isIPSetId
+    , isIPSetDescriptors
+
+    -- * IPSetDescriptor
+    , IPSetDescriptor
+    , ipSetDescriptor
+    , isdType
+    , isdValue
+
+    -- * IPSetSummary
+    , IPSetSummary
+    , ipSetSummary
+    , issIPSetId
+    , issName
+
+    -- * IPSetUpdate
+    , IPSetUpdate
+    , ipSetUpdate
+    , isuAction
+    , isuIPSetDescriptor
+
+    -- * Predicate
+    , Predicate
+    , predicate
+    , pNegated
+    , pType
+    , pDataId
+
+    -- * Rule
+    , Rule
+    , rule
+    , rMetricName
+    , rName
+    , rRuleId
+    , rPredicates
+
+    -- * RuleSummary
+    , RuleSummary
+    , ruleSummary
+    , rsRuleId
+    , rsName
+
+    -- * RuleUpdate
+    , RuleUpdate
+    , ruleUpdate
+    , ruAction
+    , ruPredicate
+
+    -- * SampledHTTPRequest
+    , SampledHTTPRequest
+    , sampledHTTPRequest
+    , shttprAction
+    , shttprTimestamp
+    , shttprRequest
+    , shttprWeight
+
+    -- * SqlInjectionMatchSet
+    , SqlInjectionMatchSet
+    , sqlInjectionMatchSet
+    , simsName
+    , simsSqlInjectionMatchSetId
+    , simsSqlInjectionMatchTuples
+
+    -- * SqlInjectionMatchSetSummary
+    , SqlInjectionMatchSetSummary
+    , sqlInjectionMatchSetSummary
+    , simssSqlInjectionMatchSetId
+    , simssName
+
+    -- * SqlInjectionMatchSetUpdate
+    , SqlInjectionMatchSetUpdate
+    , sqlInjectionMatchSetUpdate
+    , simsuAction
+    , simsuSqlInjectionMatchTuple
+
+    -- * SqlInjectionMatchTuple
+    , SqlInjectionMatchTuple
+    , sqlInjectionMatchTuple
+    , simtFieldToMatch
+    , simtTextTransformation
+
+    -- * TimeWindow
+    , TimeWindow
+    , timeWindow
+    , twStartTime
+    , twEndTime
+
+    -- * WafAction
+    , WafAction
+    , wafAction
+    , waType
+
+    -- * WebACL
+    , WebACL
+    , webACL
+    , waMetricName
+    , waName
+    , waWebACLId
+    , waDefaultAction
+    , waRules
+
+    -- * WebACLSummary
+    , WebACLSummary
+    , webACLSummary
+    , wasWebACLId
+    , wasName
+
+    -- * WebACLUpdate
+    , WebACLUpdate
+    , webACLUpdate
+    , wauAction
+    , wauActivatedRule
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Sign.V4
+import           Network.AWS.WAF.Types.Product
+import           Network.AWS.WAF.Types.Sum
+
+-- | API version '2015-08-24' of the Amazon WAF SDK configuration.
+wAF :: Service
+wAF =
+    Service
+    { _svcAbbrev = "WAF"
+    , _svcSigner = v4
+    , _svcPrefix = "waf"
+    , _svcVersion = "2015-08-24"
+    , _svcEndpoint = defaultEndpoint wAF
+    , _svcTimeout = Just 70
+    , _svcCheck = statusSuccess
+    , _svcError = parseJSONError
+    , _svcRetry = retry
+    }
+  where
+    retry =
+        Exponential
+        { _retryBase = 5.0e-2
+        , _retryGrowth = 2
+        , _retryAttempts = 5
+        , _retryCheck = check
+        }
+    check e
+      | has (hasCode "ThrottlingException" . hasStatus 400) e =
+          Just "throttling_exception"
+      | has (hasCode "Throttling" . hasStatus 400) e = Just "throttling"
+      | has (hasStatus 503) e = Just "service_unavailable"
+      | has (hasStatus 500) e = Just "general_server_error"
+      | has (hasStatus 509) e = Just "limit_exceeded"
+      | otherwise = Nothing
+
+-- | The operation failed because you tried to create, update, or delete an
+-- object by using an invalid account identifier.
+_WAFInvalidAccountException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFInvalidAccountException =
+    _ServiceError . hasCode "WAFInvalidAccountException"
+
+-- | The operation failed because you tried to delete an object that is still
+-- in use. For example:
+--
+-- -   You tried to delete a 'ByteMatchSet' that is still referenced by a
+--     'Rule'.
+-- -   You tried to delete a 'Rule' that is still referenced by a 'WebACL'.
+_WAFReferencedItemException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFReferencedItemException =
+    _ServiceError . hasCode "WAFReferencedItemException"
+
+-- | The operation failed because there was nothing to do. For example:
+--
+-- -   You tried to remove a 'Rule' from a 'WebACL', but the 'Rule' isn\'t
+--     in the specified 'WebACL'.
+-- -   You tried to remove an IP address from an 'IPSet', but the IP
+--     address isn\'t in the specified 'IPSet'.
+-- -   You tried to remove a 'ByteMatchTuple' from a 'ByteMatchSet', but
+--     the 'ByteMatchTuple' isn\'t in the specified 'WebACL'.
+-- -   You tried to add a 'Rule' to a 'WebACL', but the 'Rule' already
+--     exists in the specified 'WebACL'.
+-- -   You tried to add an IP address to an 'IPSet', but the IP address
+--     already exists in the specified 'IPSet'.
+-- -   You tried to add a 'ByteMatchTuple' to a 'ByteMatchSet', but the
+--     'ByteMatchTuple' already exists in the specified 'WebACL'.
+_WAFInvalidOperationException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFInvalidOperationException =
+    _ServiceError . hasCode "WAFInvalidOperationException"
+
+-- | The operation failed because the referenced object doesn\'t exist.
+_WAFNonexistentItemException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFNonexistentItemException =
+    _ServiceError . hasCode "WAFNonexistentItemException"
+
+-- | The operation failed because AWS WAF didn\'t recognize a parameter in
+-- the request. For example:
+--
+-- -   You specified an invalid parameter name.
+-- -   You specified an invalid value.
+-- -   You tried to update an object ('ByteMatchSet', 'IPSet', 'Rule', or
+--     'WebACL') using an action other than 'INSERT' or 'DELETE'.
+-- -   You tried to create a 'WebACL' with a 'DefaultAction' 'Type' other
+--     than 'ALLOW', 'BLOCK', or 'COUNT'.
+-- -   You tried to update a 'WebACL' with a 'WafAction' 'Type' other than
+--     'ALLOW', 'BLOCK', or 'COUNT'.
+-- -   You tried to update a 'ByteMatchSet' with a 'FieldToMatch' 'Type'
+--     other than HEADER, QUERY_STRING, or URI.
+-- -   You tried to update a 'ByteMatchSet' with a 'Field' of 'HEADER' but
+--     no value for 'Data'.
+_WAFInvalidParameterException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFInvalidParameterException =
+    _ServiceError . hasCode "WAFInvalidParameterException"
+
+-- | The operation exceeds a resource limit, for example, the maximum number
+-- of 'WebACL' objects that you can create for an AWS account. For more
+-- information, see
+-- <http://docs.aws.amazon.com/waf/latest/DeveloperGuide/limits.html Limits>
+-- in the /AWS WAF Developer Guide/.
+_WAFLimitsExceededException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFLimitsExceededException =
+    _ServiceError . hasCode "WAFLimitsExceededException"
+
+-- | The operation failed because you tried to create, update, or delete an
+-- object by using a change token that has already been used.
+_WAFStaleDataException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFStaleDataException = _ServiceError . hasCode "WAFStaleDataException"
+
+-- | The operation failed because of a system problem, even though the
+-- request was valid. Retry your request.
+_WAFInternalErrorException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFInternalErrorException =
+    _ServiceError . hasCode "WAFInternalErrorException"
+
+-- | The operation failed because you tried to add an object to or delete an
+-- object from another object that doesn\'t exist. For example:
+--
+-- -   You tried to add a 'Rule' to or delete a 'Rule' from a 'WebACL' that
+--     doesn\'t exist.
+-- -   You tried to add a 'ByteMatchSet' to or delete a 'ByteMatchSet' from
+--     a 'Rule' that doesn\'t exist.
+-- -   You tried to add an IP address to or delete an IP address from an
+--     'IPSet' that doesn\'t exist.
+-- -   You tried to add a 'ByteMatchTuple' to or delete a 'ByteMatchTuple'
+--     from a 'ByteMatchSet' that doesn\'t exist.
+_WAFNonexistentContainerException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFNonexistentContainerException =
+    _ServiceError . hasCode "WAFNonexistentContainerException"
+
+-- | The name specified is invalid.
+_WAFDisallowedNameException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFDisallowedNameException =
+    _ServiceError . hasCode "WAFDisallowedNameException"
+
+-- | The operation failed because you tried to delete an object that isn\'t
+-- empty. For example:
+--
+-- -   You tried to delete a 'WebACL' that still contains one or more
+--     'Rule' objects.
+-- -   You tried to delete a 'Rule' that still contains one or more
+--     'ByteMatchSet' objects or other predicates.
+-- -   You tried to delete a 'ByteMatchSet' that contains one or more
+--     'ByteMatchTuple' objects.
+-- -   You tried to delete an 'IPSet' that references one or more IP
+--     addresses.
+_WAFNonEmptyEntityException :: AsError a => Getting (First ServiceError) a ServiceError
+_WAFNonEmptyEntityException =
+    _ServiceError . hasCode "WAFNonEmptyEntityException"
diff --git a/gen/Network/AWS/WAF/Types/Product.hs b/gen/Network/AWS/WAF/Types/Product.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/Types/Product.hs
@@ -0,0 +1,1735 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.Types.Product
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+module Network.AWS.WAF.Types.Product where
+
+import           Network.AWS.Prelude
+import           Network.AWS.WAF.Types.Sum
+
+-- | The 'ActivatedRule' object in an UpdateWebACL request specifies a 'Rule'
+-- that you want to insert or delete, the priority of the 'Rule' in the
+-- 'WebACL', and the action that you want AWS WAF to take when a web
+-- request matches the 'Rule' ('ALLOW', 'BLOCK', or 'COUNT').
+--
+-- To specify whether to insert or delete a 'Rule', use the 'Action'
+-- parameter in the WebACLUpdate data type.
+--
+-- /See:/ 'activatedRule' smart constructor.
+data ActivatedRule = ActivatedRule'
+    { _arPriority :: !Int
+    , _arRuleId   :: !Text
+    , _arAction   :: !WafAction
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ActivatedRule' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'arPriority'
+--
+-- * 'arRuleId'
+--
+-- * 'arAction'
+activatedRule
+    :: Int -- ^ 'arPriority'
+    -> Text -- ^ 'arRuleId'
+    -> WafAction -- ^ 'arAction'
+    -> ActivatedRule
+activatedRule pPriority_ pRuleId_ pAction_ =
+    ActivatedRule'
+    { _arPriority = pPriority_
+    , _arRuleId = pRuleId_
+    , _arAction = pAction_
+    }
+
+-- | Specifies the order in which the 'Rules' in a 'WebACL' are evaluated.
+-- Rules with a lower value for 'Priority' are evaluated before 'Rules'
+-- with a higher value. The value must be a unique integer. If you add
+-- multiple 'Rules' to a 'WebACL', the values don\'t need to be
+-- consecutive.
+arPriority :: Lens' ActivatedRule Int
+arPriority = lens _arPriority (\ s a -> s{_arPriority = a});
+
+-- | The 'RuleId' for a 'Rule'. You use 'RuleId' to get more information
+-- about a 'Rule' (see GetRule), update a 'Rule' (see UpdateRule), insert a
+-- 'Rule' into a 'WebACL' or delete a one from a 'WebACL' (see
+-- UpdateWebACL), or delete a 'Rule' from AWS WAF (see DeleteRule).
+--
+-- 'RuleId' is returned by CreateRule and by ListRules.
+arRuleId :: Lens' ActivatedRule Text
+arRuleId = lens _arRuleId (\ s a -> s{_arRuleId = a});
+
+-- | Specifies the action that CloudFront or AWS WAF takes when a web request
+-- matches the conditions in the 'Rule'. Valid values for 'Action' include
+-- the following:
+--
+-- -   'ALLOW': CloudFront responds with the requested object.
+-- -   'BLOCK': CloudFront responds with an HTTP 403 (Forbidden) status
+--     code.
+-- -   'COUNT': AWS WAF increments a counter of requests that match the
+--     conditions in the rule and then continues to inspect the web request
+--     based on the remaining rules in the web ACL.
+arAction :: Lens' ActivatedRule WafAction
+arAction = lens _arAction (\ s a -> s{_arAction = a});
+
+instance FromJSON ActivatedRule where
+        parseJSON
+          = withObject "ActivatedRule"
+              (\ x ->
+                 ActivatedRule' <$>
+                   (x .: "Priority") <*> (x .: "RuleId") <*>
+                     (x .: "Action"))
+
+instance ToJSON ActivatedRule where
+        toJSON ActivatedRule'{..}
+          = object
+              (catMaybes
+                 [Just ("Priority" .= _arPriority),
+                  Just ("RuleId" .= _arRuleId),
+                  Just ("Action" .= _arAction)])
+
+-- | In a GetByteMatchSet request, 'ByteMatchSet' is a complex type that
+-- contains the 'ByteMatchSetId' and 'Name' of a 'ByteMatchSet', and the
+-- values that you specified when you updated the 'ByteMatchSet'.
+--
+-- A complex type that contains 'ByteMatchTuple' objects, which specify the
+-- parts of web requests that you want AWS WAF to inspect and the values
+-- that you want AWS WAF to search for. If a 'ByteMatchSet' contains more
+-- than one 'ByteMatchTuple' object, a request needs to match the settings
+-- in only one 'ByteMatchTuple' to be considered a match.
+--
+-- /See:/ 'byteMatchSet' smart constructor.
+data ByteMatchSet = ByteMatchSet'
+    { _bmsName            :: !(Maybe Text)
+    , _bmsByteMatchSetId  :: !Text
+    , _bmsByteMatchTuples :: ![ByteMatchTuple]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ByteMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'bmsName'
+--
+-- * 'bmsByteMatchSetId'
+--
+-- * 'bmsByteMatchTuples'
+byteMatchSet
+    :: Text -- ^ 'bmsByteMatchSetId'
+    -> ByteMatchSet
+byteMatchSet pByteMatchSetId_ =
+    ByteMatchSet'
+    { _bmsName = Nothing
+    , _bmsByteMatchSetId = pByteMatchSetId_
+    , _bmsByteMatchTuples = mempty
+    }
+
+-- | A friendly name or description of the ByteMatchSet. You can\'t change
+-- 'Name' after you create a 'ByteMatchSet'.
+bmsName :: Lens' ByteMatchSet (Maybe Text)
+bmsName = lens _bmsName (\ s a -> s{_bmsName = a});
+
+-- | The 'ByteMatchSetId' for a 'ByteMatchSet'. You use 'ByteMatchSetId' to
+-- get information about a 'ByteMatchSet' (see GetByteMatchSet), update a
+-- 'ByteMatchSet' (see UpdateByteMatchSet, insert a 'ByteMatchSet' into a
+-- 'Rule' or delete one from a 'Rule' (see UpdateRule), and delete a
+-- 'ByteMatchSet' from AWS WAF (see DeleteByteMatchSet).
+--
+-- 'ByteMatchSetId' is returned by CreateByteMatchSet and by
+-- ListByteMatchSets.
+bmsByteMatchSetId :: Lens' ByteMatchSet Text
+bmsByteMatchSetId = lens _bmsByteMatchSetId (\ s a -> s{_bmsByteMatchSetId = a});
+
+-- | Specifies the bytes (typically a string that corresponds with ASCII
+-- characters) that you want AWS WAF to search for in web requests, the
+-- location in requests that you want AWS WAF to search, and other
+-- settings.
+bmsByteMatchTuples :: Lens' ByteMatchSet [ByteMatchTuple]
+bmsByteMatchTuples = lens _bmsByteMatchTuples (\ s a -> s{_bmsByteMatchTuples = a}) . _Coerce;
+
+instance FromJSON ByteMatchSet where
+        parseJSON
+          = withObject "ByteMatchSet"
+              (\ x ->
+                 ByteMatchSet' <$>
+                   (x .:? "Name") <*> (x .: "ByteMatchSetId") <*>
+                     (x .:? "ByteMatchTuples" .!= mempty))
+
+-- | Returned by ListByteMatchSets. Each 'ByteMatchSetSummary' object
+-- includes the 'Name' and 'ByteMatchSetId' for one ByteMatchSet.
+--
+-- /See:/ 'byteMatchSetSummary' smart constructor.
+data ByteMatchSetSummary = ByteMatchSetSummary'
+    { _bmssByteMatchSetId :: !Text
+    , _bmssName           :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ByteMatchSetSummary' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'bmssByteMatchSetId'
+--
+-- * 'bmssName'
+byteMatchSetSummary
+    :: Text -- ^ 'bmssByteMatchSetId'
+    -> Text -- ^ 'bmssName'
+    -> ByteMatchSetSummary
+byteMatchSetSummary pByteMatchSetId_ pName_ =
+    ByteMatchSetSummary'
+    { _bmssByteMatchSetId = pByteMatchSetId_
+    , _bmssName = pName_
+    }
+
+-- | The 'ByteMatchSetId' for a 'ByteMatchSet'. You use 'ByteMatchSetId' to
+-- get information about a 'ByteMatchSet', update a 'ByteMatchSet', remove
+-- a 'ByteMatchSet' from a 'Rule', and delete a 'ByteMatchSet' from AWS
+-- WAF.
+--
+-- 'ByteMatchSetId' is returned by CreateByteMatchSet and by
+-- ListByteMatchSets.
+bmssByteMatchSetId :: Lens' ByteMatchSetSummary Text
+bmssByteMatchSetId = lens _bmssByteMatchSetId (\ s a -> s{_bmssByteMatchSetId = a});
+
+-- | A friendly name or description of the ByteMatchSet. You can\'t change
+-- 'Name' after you create a 'ByteMatchSet'.
+bmssName :: Lens' ByteMatchSetSummary Text
+bmssName = lens _bmssName (\ s a -> s{_bmssName = a});
+
+instance FromJSON ByteMatchSetSummary where
+        parseJSON
+          = withObject "ByteMatchSetSummary"
+              (\ x ->
+                 ByteMatchSetSummary' <$>
+                   (x .: "ByteMatchSetId") <*> (x .: "Name"))
+
+-- | In an UpdateByteMatchSet request, 'ByteMatchSetUpdate' specifies whether
+-- to insert or delete a ByteMatchTuple and includes the settings for the
+-- 'ByteMatchTuple'.
+--
+-- /See:/ 'byteMatchSetUpdate' smart constructor.
+data ByteMatchSetUpdate = ByteMatchSetUpdate'
+    { _bmsuAction         :: !ChangeAction
+    , _bmsuByteMatchTuple :: !ByteMatchTuple
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ByteMatchSetUpdate' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'bmsuAction'
+--
+-- * 'bmsuByteMatchTuple'
+byteMatchSetUpdate
+    :: ChangeAction -- ^ 'bmsuAction'
+    -> ByteMatchTuple -- ^ 'bmsuByteMatchTuple'
+    -> ByteMatchSetUpdate
+byteMatchSetUpdate pAction_ pByteMatchTuple_ =
+    ByteMatchSetUpdate'
+    { _bmsuAction = pAction_
+    , _bmsuByteMatchTuple = pByteMatchTuple_
+    }
+
+-- | Specifies whether to insert or delete a ByteMatchTuple.
+bmsuAction :: Lens' ByteMatchSetUpdate ChangeAction
+bmsuAction = lens _bmsuAction (\ s a -> s{_bmsuAction = a});
+
+-- | Information about the part of a web request that you want AWS WAF to
+-- inspect and the value that you want AWS WAF to search for. If you
+-- specify 'DELETE' for the value of 'Action', the 'ByteMatchTuple' values
+-- must exactly match the values in the 'ByteMatchTuple' that you want to
+-- delete from the 'ByteMatchSet'.
+bmsuByteMatchTuple :: Lens' ByteMatchSetUpdate ByteMatchTuple
+bmsuByteMatchTuple = lens _bmsuByteMatchTuple (\ s a -> s{_bmsuByteMatchTuple = a});
+
+instance ToJSON ByteMatchSetUpdate where
+        toJSON ByteMatchSetUpdate'{..}
+          = object
+              (catMaybes
+                 [Just ("Action" .= _bmsuAction),
+                  Just ("ByteMatchTuple" .= _bmsuByteMatchTuple)])
+
+-- | The bytes (typically a string that corresponds with ASCII characters)
+-- that you want AWS WAF to search for in web requests, the location in
+-- requests that you want AWS WAF to search, and other settings.
+--
+-- /See:/ 'byteMatchTuple' smart constructor.
+data ByteMatchTuple = ByteMatchTuple'
+    { _bmtFieldToMatch         :: !FieldToMatch
+    , _bmtTargetString         :: !Base64
+    , _bmtTextTransformation   :: !TextTransformation
+    , _bmtPositionalConstraint :: !PositionalConstraint
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'ByteMatchTuple' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'bmtFieldToMatch'
+--
+-- * 'bmtTargetString'
+--
+-- * 'bmtTextTransformation'
+--
+-- * 'bmtPositionalConstraint'
+byteMatchTuple
+    :: FieldToMatch -- ^ 'bmtFieldToMatch'
+    -> ByteString -- ^ 'bmtTargetString'
+    -> TextTransformation -- ^ 'bmtTextTransformation'
+    -> PositionalConstraint -- ^ 'bmtPositionalConstraint'
+    -> ByteMatchTuple
+byteMatchTuple pFieldToMatch_ pTargetString_ pTextTransformation_ pPositionalConstraint_ =
+    ByteMatchTuple'
+    { _bmtFieldToMatch = pFieldToMatch_
+    , _bmtTargetString = _Base64 # pTargetString_
+    , _bmtTextTransformation = pTextTransformation_
+    , _bmtPositionalConstraint = pPositionalConstraint_
+    }
+
+-- | The part of a web request that you want AWS WAF to search, such as a
+-- specified header or a query string. For more information, see
+-- FieldToMatch.
+bmtFieldToMatch :: Lens' ByteMatchTuple FieldToMatch
+bmtFieldToMatch = lens _bmtFieldToMatch (\ s a -> s{_bmtFieldToMatch = a});
+
+-- | The value that you want AWS WAF to search for. AWS WAF searches for the
+-- specified string in the part of web requests that you specified in
+-- 'FieldToMatch'. The maximum length of the value is 50 bytes.
+--
+-- Valid values depend on the values that you specified for 'FieldToMatch':
+--
+-- -   'HEADER': The value that you want AWS WAF to search for in the
+--     request header that you specified in FieldToMatch, for example, the
+--     value of the 'User-Agent' or 'Referer' header.
+-- -   'METHOD': The HTTP method, which indicates the type of operation
+--     specified in the request. CloudFront supports the following methods:
+--     'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', and 'PUT'.
+-- -   'QUERY_STRING': The value that you want AWS WAF to search for in the
+--     query string, which is the part of a URL that appears after a '?'
+--     character.
+-- -   'URI': The value that you want AWS WAF to search for in the part of
+--     a URL that identifies a resource, for example,
+--     '\/images\/daily-ad.jpg'.
+--
+-- If 'TargetString' includes alphabetic characters A-Z and a-z, note that
+-- the value is case sensitive.
+--
+-- __If you\'re using the AWS WAF API__
+--
+-- Specify a base64-encoded version of the value. The maximum length of the
+-- value before you base64-encode it is 50 bytes.
+--
+-- For example, suppose the value of 'Type' is 'HEADER' and the value of
+-- 'Data' is 'User-Agent'. If you want to search the 'User-Agent' header
+-- for the value 'BadBot', you base64-encode 'BadBot' using MIME base64
+-- encoding and include the resulting value, 'QmFkQm90', in the value of
+-- 'TargetString'.
+--
+-- __If you\'re using the AWS CLI or one of the AWS SDKs__
+--
+-- The value that you want AWS WAF to search for. The SDK automatically
+-- base64 encodes the value.
+--
+-- /Note:/ This 'Lens' automatically encodes and decodes Base64 data,
+-- despite what the AWS documentation might say.
+-- The underlying isomorphism will encode to Base64 representation during
+-- serialisation, and decode from Base64 representation during deserialisation.
+-- This 'Lens' accepts and returns only raw unencoded data.
+bmtTargetString :: Lens' ByteMatchTuple ByteString
+bmtTargetString = lens _bmtTargetString (\ s a -> s{_bmtTargetString = a}) . _Base64;
+
+-- | Text transformations eliminate some of the unusual formatting that
+-- attackers use in web requests in an effort to bypass AWS WAF. If you
+-- specify a transformation, AWS WAF performs the transformation on
+-- 'TargetString' before inspecting a request for a match.
+--
+-- __CMD_LINE__
+--
+-- When you\'re concerned that attackers are injecting an operating system
+-- commandline command and using unusual formatting to disguise some or all
+-- of the command, use this option to perform the following
+-- transformations:
+--
+-- -   Delete the following characters: \\ \" \' ^
+-- -   Delete spaces before the following characters: \/ (
+-- -   Replace the following characters with a space: , ;
+-- -   Replace multiple spaces with one space
+-- -   Convert uppercase letters (A-Z) to lowercase (a-z)
+--
+-- __COMPRESS_WHITE_SPACE__
+--
+-- Use this option to replace the following characters with a space
+-- character (decimal 32):
+--
+-- -   \\f, formfeed, decimal 12
+-- -   \\t, tab, decimal 9
+-- -   \\n, newline, decimal 10
+-- -   \\r, carriage return, decimal 13
+-- -   \\v, vertical tab, decimal 11
+-- -   non-breaking space, decimal 160
+--
+-- 'COMPRESS_WHITE_SPACE' also replaces multiple spaces with one space.
+--
+-- __HTML_ENTITY_DECODE__
+--
+-- Use this option to replace HTML-encoded characters with unencoded
+-- characters. 'HTML_ENTITY_DECODE' performs the following operations:
+--
+-- -   Replaces '(ampersand)quot;' with '\"'
+-- -   Replaces '(ampersand)nbsp;' with a non-breaking space, decimal 160
+-- -   Replaces '(ampersand)lt;' with a \"less than\" symbol
+-- -   Replaces '(ampersand)gt;' with '>'
+-- -   Replaces characters that are represented in hexadecimal format,
+--     '(ampersand)#xhhhh;', with the corresponding characters
+-- -   Replaces characters that are represented in decimal format,
+--     '(ampersand)#nnnn;', with the corresponding characters
+--
+-- __LOWERCASE__
+--
+-- Use this option to convert uppercase letters (A-Z) to lowercase (a-z).
+--
+-- __URL_DECODE__
+--
+-- Use this option to decode a URL-encoded value.
+--
+-- __NONE__
+--
+-- Specify 'NONE' if you don\'t want to perform any text transformations.
+bmtTextTransformation :: Lens' ByteMatchTuple TextTransformation
+bmtTextTransformation = lens _bmtTextTransformation (\ s a -> s{_bmtTextTransformation = a});
+
+-- | Within the portion of a web request that you want to search (for
+-- example, in the query string, if any), specify where you want AWS WAF to
+-- search. Valid values include the following:
+--
+-- __CONTAINS__
+--
+-- The specified part of the web request must include the value of
+-- 'TargetString', but the location doesn\'t matter.
+--
+-- __CONTAINS_WORD__
+--
+-- The specified part of the web request must include the value of
+-- 'TargetString', and 'TargetString' must contain only alphanumeric
+-- characters or underscore (A-Z, a-z, 0-9, or _). In addition,
+-- 'TargetString' must be a word, which means one of the following:
+--
+-- -   'TargetString' exactly matches the value of the specified part of
+--     the web request, such as the value of a header.
+-- -   'TargetString' is at the beginning of the specified part of the web
+--     request and is followed by a character other than an alphanumeric
+--     character or underscore (_), for example, 'BadBot;'.
+-- -   'TargetString' is at the end of the specified part of the web
+--     request and is preceded by a character other than an alphanumeric
+--     character or underscore (_), for example, ';BadBot'.
+-- -   'TargetString' is in the middle of the specified part of the web
+--     request and is preceded and followed by characters other than
+--     alphanumeric characters or underscore (_), for example, '-BadBot;'.
+--
+-- __EXACTLY__
+--
+-- The value of the specified part of the web request must exactly match
+-- the value of 'TargetString'.
+--
+-- __STARTS_WITH__
+--
+-- The value of 'TargetString' must appear at the beginning of the
+-- specified part of the web request.
+--
+-- __ENDS_WITH__
+--
+-- The value of 'TargetString' must appear at the end of the specified part
+-- of the web request.
+bmtPositionalConstraint :: Lens' ByteMatchTuple PositionalConstraint
+bmtPositionalConstraint = lens _bmtPositionalConstraint (\ s a -> s{_bmtPositionalConstraint = a});
+
+instance FromJSON ByteMatchTuple where
+        parseJSON
+          = withObject "ByteMatchTuple"
+              (\ x ->
+                 ByteMatchTuple' <$>
+                   (x .: "FieldToMatch") <*> (x .: "TargetString") <*>
+                     (x .: "TextTransformation")
+                     <*> (x .: "PositionalConstraint"))
+
+instance ToJSON ByteMatchTuple where
+        toJSON ByteMatchTuple'{..}
+          = object
+              (catMaybes
+                 [Just ("FieldToMatch" .= _bmtFieldToMatch),
+                  Just ("TargetString" .= _bmtTargetString),
+                  Just
+                    ("TextTransformation" .= _bmtTextTransformation),
+                  Just
+                    ("PositionalConstraint" .=
+                       _bmtPositionalConstraint)])
+
+-- | Specifies where in a web request to look for 'TargetString'.
+--
+-- /See:/ 'fieldToMatch' smart constructor.
+data FieldToMatch = FieldToMatch'
+    { _ftmData :: !(Maybe Text)
+    , _ftmType :: !MatchFieldType
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'FieldToMatch' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'ftmData'
+--
+-- * 'ftmType'
+fieldToMatch
+    :: MatchFieldType -- ^ 'ftmType'
+    -> FieldToMatch
+fieldToMatch pType_ =
+    FieldToMatch'
+    { _ftmData = Nothing
+    , _ftmType = pType_
+    }
+
+-- | When the value of 'Type' is 'HEADER', enter the name of the header that
+-- you want AWS WAF to search, for example, 'User-Agent' or 'Referer'. If
+-- the value of 'Type' is any other value, omit 'Data'.
+--
+-- The name of the header is not case sensitive.
+ftmData :: Lens' FieldToMatch (Maybe Text)
+ftmData = lens _ftmData (\ s a -> s{_ftmData = a});
+
+-- | The part of the web request that you want AWS WAF to search for a
+-- specified string. Parts of a request that you can search include the
+-- following:
+--
+-- -   'HEADER': A specified request header, for example, the value of the
+--     'User-Agent' or 'Referer' header. If you choose 'HEADER' for the
+--     type, specify the name of the header in 'Data'.
+-- -   'METHOD': The HTTP method, which indicated the type of operation
+--     that the request is asking the origin to perform. Amazon CloudFront
+--     supports the following methods: 'DELETE', 'GET', 'HEAD', 'OPTIONS',
+--     'PATCH', 'POST', and 'PUT'.
+-- -   'QUERY_STRING': A query string, which is the part of a URL that
+--     appears after a '?' character, if any.
+-- -   'URI': The part of a web request that identifies a resource, for
+--     example, '\/images\/daily-ad.jpg'.
+ftmType :: Lens' FieldToMatch MatchFieldType
+ftmType = lens _ftmType (\ s a -> s{_ftmType = a});
+
+instance FromJSON FieldToMatch where
+        parseJSON
+          = withObject "FieldToMatch"
+              (\ x ->
+                 FieldToMatch' <$> (x .:? "Data") <*> (x .: "Type"))
+
+instance ToJSON FieldToMatch where
+        toJSON FieldToMatch'{..}
+          = object
+              (catMaybes
+                 [("Data" .=) <$> _ftmData,
+                  Just ("Type" .= _ftmType)])
+
+-- | The response from a GetSampledRequests request includes an 'HTTPHeader'
+-- complex type that appears as 'Headers' in the response syntax.
+-- 'HTTPHeader' contains the names and values of all of the headers that
+-- appear in one of the web requests that were returned by
+-- 'GetSampledRequests'.
+--
+-- /See:/ 'hTTPHeader' smart constructor.
+data HTTPHeader = HTTPHeader'
+    { _httphValue :: !(Maybe Text)
+    , _httphName  :: !(Maybe Text)
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'HTTPHeader' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'httphValue'
+--
+-- * 'httphName'
+hTTPHeader
+    :: HTTPHeader
+hTTPHeader =
+    HTTPHeader'
+    { _httphValue = Nothing
+    , _httphName = Nothing
+    }
+
+-- | The value of one of the headers in the sampled web request.
+httphValue :: Lens' HTTPHeader (Maybe Text)
+httphValue = lens _httphValue (\ s a -> s{_httphValue = a});
+
+-- | The name of one of the headers in the sampled web request.
+httphName :: Lens' HTTPHeader (Maybe Text)
+httphName = lens _httphName (\ s a -> s{_httphName = a});
+
+instance FromJSON HTTPHeader where
+        parseJSON
+          = withObject "HTTPHeader"
+              (\ x ->
+                 HTTPHeader' <$> (x .:? "Value") <*> (x .:? "Name"))
+
+-- | The response from a GetSampledRequests request includes an 'HTTPRequest'
+-- complex type that appears as 'Request' in the response syntax.
+-- 'HTTPRequest' contains information about one of the web requests that
+-- were returned by 'GetSampledRequests'.
+--
+-- /See:/ 'hTTPRequest' smart constructor.
+data HTTPRequest = HTTPRequest'
+    { _httprHTTPVersion :: !(Maybe Text)
+    , _httprCountry     :: !(Maybe Text)
+    , _httprURI         :: !(Maybe Text)
+    , _httprHeaders     :: !(Maybe [HTTPHeader])
+    , _httprMethod      :: !(Maybe Text)
+    , _httprClientIP    :: !(Maybe Text)
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'HTTPRequest' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'httprHTTPVersion'
+--
+-- * 'httprCountry'
+--
+-- * 'httprURI'
+--
+-- * 'httprHeaders'
+--
+-- * 'httprMethod'
+--
+-- * 'httprClientIP'
+hTTPRequest
+    :: HTTPRequest
+hTTPRequest =
+    HTTPRequest'
+    { _httprHTTPVersion = Nothing
+    , _httprCountry = Nothing
+    , _httprURI = Nothing
+    , _httprHeaders = Nothing
+    , _httprMethod = Nothing
+    , _httprClientIP = Nothing
+    }
+
+-- | The HTTP version specified in the sampled web request, for example,
+-- 'HTTP\/1.1'.
+httprHTTPVersion :: Lens' HTTPRequest (Maybe Text)
+httprHTTPVersion = lens _httprHTTPVersion (\ s a -> s{_httprHTTPVersion = a});
+
+-- | The two-letter country code for the country that the request originated
+-- from. For a current list of country codes, see the Wikipedia entry
+-- <https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2>.
+httprCountry :: Lens' HTTPRequest (Maybe Text)
+httprCountry = lens _httprCountry (\ s a -> s{_httprCountry = a});
+
+-- | The part of a web request that identifies the resource, for example,
+-- '\/images\/daily-ad.jpg'.
+httprURI :: Lens' HTTPRequest (Maybe Text)
+httprURI = lens _httprURI (\ s a -> s{_httprURI = a});
+
+-- | A complex type that contains two values for each header in the sampled
+-- web request: the name of the header and the value of the header.
+httprHeaders :: Lens' HTTPRequest [HTTPHeader]
+httprHeaders = lens _httprHeaders (\ s a -> s{_httprHeaders = a}) . _Default . _Coerce;
+
+-- | The HTTP method specified in the sampled web request. CloudFront
+-- supports the following methods: 'DELETE', 'GET', 'HEAD', 'OPTIONS',
+-- 'PATCH', 'POST', and 'PUT'.
+httprMethod :: Lens' HTTPRequest (Maybe Text)
+httprMethod = lens _httprMethod (\ s a -> s{_httprMethod = a});
+
+-- | The IP address that the request originated from. If the 'WebACL' is
+-- associated with a CloudFront distribution, this is the value of one of
+-- the following fields in CloudFront access logs:
+--
+-- -   'c-ip', if the viewer did not use an HTTP proxy or a load balancer
+--     to send the request
+-- -   'x-forwarded-for', if the viewer did use an HTTP proxy or a load
+--     balancer to send the request
+httprClientIP :: Lens' HTTPRequest (Maybe Text)
+httprClientIP = lens _httprClientIP (\ s a -> s{_httprClientIP = a});
+
+instance FromJSON HTTPRequest where
+        parseJSON
+          = withObject "HTTPRequest"
+              (\ x ->
+                 HTTPRequest' <$>
+                   (x .:? "HTTPVersion") <*> (x .:? "Country") <*>
+                     (x .:? "URI")
+                     <*> (x .:? "Headers" .!= mempty)
+                     <*> (x .:? "Method")
+                     <*> (x .:? "ClientIP"))
+
+-- | Contains one or more IP addresses or blocks of IP addresses specified in
+-- Classless Inter-Domain Routing (CIDR) notation. To specify an individual
+-- IP address, you specify the four-part IP address followed by a '\/32',
+-- for example, 192.0.2.0\/31. To block a range of IP addresses, you can
+-- specify a '\/24', a '\/16', or a '\/8' CIDR. For more information about
+-- CIDR notation, perform an Internet search on 'cidr notation'.
+--
+-- /See:/ 'ipSet' smart constructor.
+data IPSet = IPSet'
+    { _isName             :: !(Maybe Text)
+    , _isIPSetId          :: !Text
+    , _isIPSetDescriptors :: ![IPSetDescriptor]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'IPSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'isName'
+--
+-- * 'isIPSetId'
+--
+-- * 'isIPSetDescriptors'
+ipSet
+    :: Text -- ^ 'isIPSetId'
+    -> IPSet
+ipSet pIPSetId_ =
+    IPSet'
+    { _isName = Nothing
+    , _isIPSetId = pIPSetId_
+    , _isIPSetDescriptors = mempty
+    }
+
+-- | A friendly name or description of the IPSet. You can\'t change the name
+-- of an 'IPSet' after you create it.
+isName :: Lens' IPSet (Maybe Text)
+isName = lens _isName (\ s a -> s{_isName = a});
+
+-- | The 'IPSetId' for an 'IPSet'. You use 'IPSetId' to get information about
+-- an 'IPSet' (see GetIPSet), update an 'IPSet' (see UpdateIPSet), insert
+-- an 'IPSet' into a 'Rule' or delete one from a 'Rule' (see UpdateRule),
+-- and delete an 'IPSet' from AWS WAF (see DeleteIPSet).
+--
+-- 'IPSetId' is returned by CreateIPSet and by ListIPSets.
+isIPSetId :: Lens' IPSet Text
+isIPSetId = lens _isIPSetId (\ s a -> s{_isIPSetId = a});
+
+-- | The IP address type ('IPV4') and the IP address range (in CIDR notation)
+-- that web requests originate from. If the 'WebACL' is associated with a
+-- CloudFront distribution, this is the value of one of the following
+-- fields in CloudFront access logs:
+--
+-- -   'c-ip', if the viewer did not use an HTTP proxy or a load balancer
+--     to send the request
+-- -   'x-forwarded-for', if the viewer did use an HTTP proxy or a load
+--     balancer to send the request
+isIPSetDescriptors :: Lens' IPSet [IPSetDescriptor]
+isIPSetDescriptors = lens _isIPSetDescriptors (\ s a -> s{_isIPSetDescriptors = a}) . _Coerce;
+
+instance FromJSON IPSet where
+        parseJSON
+          = withObject "IPSet"
+              (\ x ->
+                 IPSet' <$>
+                   (x .:? "Name") <*> (x .: "IPSetId") <*>
+                     (x .:? "IPSetDescriptors" .!= mempty))
+
+-- | Specifies the IP address type ('IPV4') and the IP address range (in CIDR
+-- format) that web requests originate from.
+--
+-- /See:/ 'ipSetDescriptor' smart constructor.
+data IPSetDescriptor = IPSetDescriptor'
+    { _isdType  :: !IPSetDescriptorType
+    , _isdValue :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'IPSetDescriptor' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'isdType'
+--
+-- * 'isdValue'
+ipSetDescriptor
+    :: IPSetDescriptorType -- ^ 'isdType'
+    -> Text -- ^ 'isdValue'
+    -> IPSetDescriptor
+ipSetDescriptor pType_ pValue_ =
+    IPSetDescriptor'
+    { _isdType = pType_
+    , _isdValue = pValue_
+    }
+
+-- | Specify 'IPV4'.
+isdType :: Lens' IPSetDescriptor IPSetDescriptorType
+isdType = lens _isdType (\ s a -> s{_isdType = a});
+
+-- | Specify an IPv4 address by using CIDR notation. For example:
+--
+-- -   To configure AWS WAF to allow, block, or count requests that
+--     originated from the IP address 192.0.2.44, specify '192.0.2.44\/32'.
+-- -   To configure AWS WAF to allow, block, or count requests that
+--     originated from IP addresses from 192.0.2.0 to 192.0.2.255, specify
+--     '192.0.2.0\/24'.
+--
+-- AWS WAF supports only \/8, \/16, \/24, and \/32 IP addresses.
+--
+-- For more information about CIDR notation, see the Wikipedia entry
+-- <https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing Classless Inter-Domain Routing>.
+isdValue :: Lens' IPSetDescriptor Text
+isdValue = lens _isdValue (\ s a -> s{_isdValue = a});
+
+instance FromJSON IPSetDescriptor where
+        parseJSON
+          = withObject "IPSetDescriptor"
+              (\ x ->
+                 IPSetDescriptor' <$>
+                   (x .: "Type") <*> (x .: "Value"))
+
+instance ToJSON IPSetDescriptor where
+        toJSON IPSetDescriptor'{..}
+          = object
+              (catMaybes
+                 [Just ("Type" .= _isdType),
+                  Just ("Value" .= _isdValue)])
+
+-- | Contains the identifier and the name of the 'IPSet'.
+--
+-- /See:/ 'ipSetSummary' smart constructor.
+data IPSetSummary = IPSetSummary'
+    { _issIPSetId :: !Text
+    , _issName    :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'IPSetSummary' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'issIPSetId'
+--
+-- * 'issName'
+ipSetSummary
+    :: Text -- ^ 'issIPSetId'
+    -> Text -- ^ 'issName'
+    -> IPSetSummary
+ipSetSummary pIPSetId_ pName_ =
+    IPSetSummary'
+    { _issIPSetId = pIPSetId_
+    , _issName = pName_
+    }
+
+-- | The 'IPSetId' for an IPSet. You can use 'IPSetId' in a GetIPSet request
+-- to get detailed information about an IPSet.
+issIPSetId :: Lens' IPSetSummary Text
+issIPSetId = lens _issIPSetId (\ s a -> s{_issIPSetId = a});
+
+-- | A friendly name or description of the IPSet. You can\'t change the name
+-- of an 'IPSet' after you create it.
+issName :: Lens' IPSetSummary Text
+issName = lens _issName (\ s a -> s{_issName = a});
+
+instance FromJSON IPSetSummary where
+        parseJSON
+          = withObject "IPSetSummary"
+              (\ x ->
+                 IPSetSummary' <$> (x .: "IPSetId") <*> (x .: "Name"))
+
+-- | Specifies the type of update to perform to an IPSet with UpdateIPSet.
+--
+-- /See:/ 'ipSetUpdate' smart constructor.
+data IPSetUpdate = IPSetUpdate'
+    { _isuAction          :: !ChangeAction
+    , _isuIPSetDescriptor :: !IPSetDescriptor
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'IPSetUpdate' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'isuAction'
+--
+-- * 'isuIPSetDescriptor'
+ipSetUpdate
+    :: ChangeAction -- ^ 'isuAction'
+    -> IPSetDescriptor -- ^ 'isuIPSetDescriptor'
+    -> IPSetUpdate
+ipSetUpdate pAction_ pIPSetDescriptor_ =
+    IPSetUpdate'
+    { _isuAction = pAction_
+    , _isuIPSetDescriptor = pIPSetDescriptor_
+    }
+
+-- | Specifies whether to insert or delete an IP address with UpdateIPSet.
+isuAction :: Lens' IPSetUpdate ChangeAction
+isuAction = lens _isuAction (\ s a -> s{_isuAction = a});
+
+-- | The IP address type ('IPV4') and the IP address range (in CIDR notation)
+-- that web requests originate from.
+isuIPSetDescriptor :: Lens' IPSetUpdate IPSetDescriptor
+isuIPSetDescriptor = lens _isuIPSetDescriptor (\ s a -> s{_isuIPSetDescriptor = a});
+
+instance ToJSON IPSetUpdate where
+        toJSON IPSetUpdate'{..}
+          = object
+              (catMaybes
+                 [Just ("Action" .= _isuAction),
+                  Just ("IPSetDescriptor" .= _isuIPSetDescriptor)])
+
+-- | Specifies the ByteMatchSet, IPSet, and SqlInjectionMatchSet objects that
+-- you want to add to a 'Rule' and, for each object, indicates whether you
+-- want to negate the settings, for example, requests that do NOT originate
+-- from the IP address 192.0.2.44.
+--
+-- /See:/ 'predicate' smart constructor.
+data Predicate = Predicate'
+    { _pNegated :: !Bool
+    , _pType    :: !PredicateType
+    , _pDataId  :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'Predicate' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'pNegated'
+--
+-- * 'pType'
+--
+-- * 'pDataId'
+predicate
+    :: Bool -- ^ 'pNegated'
+    -> PredicateType -- ^ 'pType'
+    -> Text -- ^ 'pDataId'
+    -> Predicate
+predicate pNegated_ pType_ pDataId_ =
+    Predicate'
+    { _pNegated = pNegated_
+    , _pType = pType_
+    , _pDataId = pDataId_
+    }
+
+-- | Set 'Negated' to 'False' if you want AWS WAF to allow, block, or count
+-- requests based on the settings in the specified ByteMatchSet, IPSet, or
+-- SqlInjectionMatchSet. For example, if an 'IPSet' includes the IP address
+-- '192.0.2.44', AWS WAF will allow or block requests based on that IP
+-- address.
+--
+-- Set 'Negated' to 'True' if you want AWS WAF to allow or block a request
+-- based on the negation of the settings in the ByteMatchSet, IPSet, or
+-- SqlInjectionMatchSet. For example, if an 'IPSet' includes the IP address
+-- '192.0.2.44', AWS WAF will allow, block, or count requests based on all
+-- IP addresses /except/ '192.0.2.44'.
+pNegated :: Lens' Predicate Bool
+pNegated = lens _pNegated (\ s a -> s{_pNegated = a});
+
+-- | The type of predicate in a 'Rule', such as 'ByteMatchSet' or 'IPSet'.
+pType :: Lens' Predicate PredicateType
+pType = lens _pType (\ s a -> s{_pType = a});
+
+-- | A unique identifier for a predicate in a 'Rule', such as
+-- 'ByteMatchSetId' or 'IPSetId'. The ID is returned by the corresponding
+-- 'Create' or 'List' command.
+pDataId :: Lens' Predicate Text
+pDataId = lens _pDataId (\ s a -> s{_pDataId = a});
+
+instance FromJSON Predicate where
+        parseJSON
+          = withObject "Predicate"
+              (\ x ->
+                 Predicate' <$>
+                   (x .: "Negated") <*> (x .: "Type") <*>
+                     (x .: "DataId"))
+
+instance ToJSON Predicate where
+        toJSON Predicate'{..}
+          = object
+              (catMaybes
+                 [Just ("Negated" .= _pNegated),
+                  Just ("Type" .= _pType),
+                  Just ("DataId" .= _pDataId)])
+
+-- | A combination of ByteMatchSet, IPSet, and\/or SqlInjectionMatchSet
+-- objects that identify the web requests that you want to allow, block, or
+-- count. For example, you might create a 'Rule' that includes the
+-- following predicates:
+--
+-- -   An 'IPSet' that causes AWS WAF to search for web requests that
+--     originate from the IP address '192.0.2.44'
+-- -   A 'ByteMatchSet' that causes AWS WAF to search for web requests for
+--     which the value of the 'User-Agent' header is 'BadBot'.
+--
+-- To match the settings in this 'Rule', a request must originate from
+-- '192.0.2.44' AND include a 'User-Agent' header for which the value is
+-- 'BadBot'.
+--
+-- /See:/ 'rule' smart constructor.
+data Rule = Rule'
+    { _rMetricName :: !(Maybe Text)
+    , _rName       :: !(Maybe Text)
+    , _rRuleId     :: !Text
+    , _rPredicates :: ![Predicate]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'Rule' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'rMetricName'
+--
+-- * 'rName'
+--
+-- * 'rRuleId'
+--
+-- * 'rPredicates'
+rule
+    :: Text -- ^ 'rRuleId'
+    -> Rule
+rule pRuleId_ =
+    Rule'
+    { _rMetricName = Nothing
+    , _rName = Nothing
+    , _rRuleId = pRuleId_
+    , _rPredicates = mempty
+    }
+
+-- | Undocumented member.
+rMetricName :: Lens' Rule (Maybe Text)
+rMetricName = lens _rMetricName (\ s a -> s{_rMetricName = a});
+
+-- | The friendly name or description for the 'Rule'. You can\'t change the
+-- name of a 'Rule' after you create it.
+rName :: Lens' Rule (Maybe Text)
+rName = lens _rName (\ s a -> s{_rName = a});
+
+-- | A unique identifier for a 'Rule'. You use 'RuleId' to get more
+-- information about a 'Rule' (see GetRule), update a 'Rule' (see
+-- UpdateRule), insert a 'Rule' into a 'WebACL' or delete a one from a
+-- 'WebACL' (see UpdateWebACL), or delete a 'Rule' from AWS WAF (see
+-- DeleteRule).
+--
+-- 'RuleId' is returned by CreateRule and by ListRules.
+rRuleId :: Lens' Rule Text
+rRuleId = lens _rRuleId (\ s a -> s{_rRuleId = a});
+
+-- | The 'Predicates' object contains one 'Predicate' element for each
+-- ByteMatchSet, IPSet, or SqlInjectionMatchSet object that you want to
+-- include in a 'Rule'.
+rPredicates :: Lens' Rule [Predicate]
+rPredicates = lens _rPredicates (\ s a -> s{_rPredicates = a}) . _Coerce;
+
+instance FromJSON Rule where
+        parseJSON
+          = withObject "Rule"
+              (\ x ->
+                 Rule' <$>
+                   (x .:? "MetricName") <*> (x .:? "Name") <*>
+                     (x .: "RuleId")
+                     <*> (x .:? "Predicates" .!= mempty))
+
+-- | Contains the identifier and the friendly name or description of the
+-- 'Rule'.
+--
+-- /See:/ 'ruleSummary' smart constructor.
+data RuleSummary = RuleSummary'
+    { _rsRuleId :: !Text
+    , _rsName   :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'RuleSummary' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'rsRuleId'
+--
+-- * 'rsName'
+ruleSummary
+    :: Text -- ^ 'rsRuleId'
+    -> Text -- ^ 'rsName'
+    -> RuleSummary
+ruleSummary pRuleId_ pName_ =
+    RuleSummary'
+    { _rsRuleId = pRuleId_
+    , _rsName = pName_
+    }
+
+-- | A unique identifier for a 'Rule'. You use 'RuleId' to get more
+-- information about a 'Rule' (see GetRule), update a 'Rule' (see
+-- UpdateRule), insert a 'Rule' into a 'WebACL' or delete one from a
+-- 'WebACL' (see UpdateWebACL), or delete a 'Rule' from AWS WAF (see
+-- DeleteRule).
+--
+-- 'RuleId' is returned by CreateRule and by ListRules.
+rsRuleId :: Lens' RuleSummary Text
+rsRuleId = lens _rsRuleId (\ s a -> s{_rsRuleId = a});
+
+-- | A friendly name or description of the Rule. You can\'t change the name
+-- of a 'Rule' after you create it.
+rsName :: Lens' RuleSummary Text
+rsName = lens _rsName (\ s a -> s{_rsName = a});
+
+instance FromJSON RuleSummary where
+        parseJSON
+          = withObject "RuleSummary"
+              (\ x ->
+                 RuleSummary' <$> (x .: "RuleId") <*> (x .: "Name"))
+
+-- | Specifies a 'Predicate' (such as an 'IPSet') and indicates whether you
+-- want to add it to a 'Rule' or delete it from a 'Rule'.
+--
+-- /See:/ 'ruleUpdate' smart constructor.
+data RuleUpdate = RuleUpdate'
+    { _ruAction    :: !ChangeAction
+    , _ruPredicate :: !Predicate
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'RuleUpdate' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'ruAction'
+--
+-- * 'ruPredicate'
+ruleUpdate
+    :: ChangeAction -- ^ 'ruAction'
+    -> Predicate -- ^ 'ruPredicate'
+    -> RuleUpdate
+ruleUpdate pAction_ pPredicate_ =
+    RuleUpdate'
+    { _ruAction = pAction_
+    , _ruPredicate = pPredicate_
+    }
+
+-- | Specify 'INSERT' to add a 'Predicate' to a 'Rule'. Use 'DELETE' to
+-- remove a 'Predicate' from a 'Rule'.
+ruAction :: Lens' RuleUpdate ChangeAction
+ruAction = lens _ruAction (\ s a -> s{_ruAction = a});
+
+-- | The ID of the 'Predicate' (such as an 'IPSet') that you want to add to a
+-- 'Rule'.
+ruPredicate :: Lens' RuleUpdate Predicate
+ruPredicate = lens _ruPredicate (\ s a -> s{_ruPredicate = a});
+
+instance ToJSON RuleUpdate where
+        toJSON RuleUpdate'{..}
+          = object
+              (catMaybes
+                 [Just ("Action" .= _ruAction),
+                  Just ("Predicate" .= _ruPredicate)])
+
+-- | The response from a GetSampledRequests request includes a
+-- 'SampledHTTPRequests' complex type that appears as 'SampledRequests' in
+-- the response syntax. 'SampledHTTPRequests' contains one
+-- 'SampledHTTPRequest' object for each web request that is returned by
+-- 'GetSampledRequests'.
+--
+-- /See:/ 'sampledHTTPRequest' smart constructor.
+data SampledHTTPRequest = SampledHTTPRequest'
+    { _shttprAction    :: !(Maybe Text)
+    , _shttprTimestamp :: !(Maybe POSIX)
+    , _shttprRequest   :: !HTTPRequest
+    , _shttprWeight    :: !Nat
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'SampledHTTPRequest' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'shttprAction'
+--
+-- * 'shttprTimestamp'
+--
+-- * 'shttprRequest'
+--
+-- * 'shttprWeight'
+sampledHTTPRequest
+    :: HTTPRequest -- ^ 'shttprRequest'
+    -> Natural -- ^ 'shttprWeight'
+    -> SampledHTTPRequest
+sampledHTTPRequest pRequest_ pWeight_ =
+    SampledHTTPRequest'
+    { _shttprAction = Nothing
+    , _shttprTimestamp = Nothing
+    , _shttprRequest = pRequest_
+    , _shttprWeight = _Nat # pWeight_
+    }
+
+-- | The action for the 'Rule' that the request matched: 'ALLOW', 'BLOCK', or
+-- 'COUNT'.
+shttprAction :: Lens' SampledHTTPRequest (Maybe Text)
+shttprAction = lens _shttprAction (\ s a -> s{_shttprAction = a});
+
+-- | The time at which AWS WAF received the request from your AWS resource,
+-- in Unix time format (in seconds).
+shttprTimestamp :: Lens' SampledHTTPRequest (Maybe UTCTime)
+shttprTimestamp = lens _shttprTimestamp (\ s a -> s{_shttprTimestamp = a}) . mapping _Time;
+
+-- | A complex type that contains detailed information about the request.
+shttprRequest :: Lens' SampledHTTPRequest HTTPRequest
+shttprRequest = lens _shttprRequest (\ s a -> s{_shttprRequest = a});
+
+-- | A value that indicates how one result in the response relates
+-- proportionally to other results in the response. A result that has a
+-- weight of '2' represents roughly twice as many CloudFront web requests
+-- as a result that has a weight of '1'.
+shttprWeight :: Lens' SampledHTTPRequest Natural
+shttprWeight = lens _shttprWeight (\ s a -> s{_shttprWeight = a}) . _Nat;
+
+instance FromJSON SampledHTTPRequest where
+        parseJSON
+          = withObject "SampledHTTPRequest"
+              (\ x ->
+                 SampledHTTPRequest' <$>
+                   (x .:? "Action") <*> (x .:? "Timestamp") <*>
+                     (x .: "Request")
+                     <*> (x .: "Weight"))
+
+-- | A complex type that contains 'SqlInjectionMatchTuple' objects, which
+-- specify the parts of web requests that you want AWS WAF to inspect for
+-- snippets of malicious SQL code and, if you want AWS WAF to inspect a
+-- header, the name of the header. If a 'SqlInjectionMatchSet' contains
+-- more than one 'SqlInjectionMatchTuple' object, a request needs to
+-- include snippets of SQL code in only one of the specified parts of the
+-- request to be considered a match.
+--
+-- /See:/ 'sqlInjectionMatchSet' smart constructor.
+data SqlInjectionMatchSet = SqlInjectionMatchSet'
+    { _simsName                    :: !(Maybe Text)
+    , _simsSqlInjectionMatchSetId  :: !Text
+    , _simsSqlInjectionMatchTuples :: ![SqlInjectionMatchTuple]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'SqlInjectionMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'simsName'
+--
+-- * 'simsSqlInjectionMatchSetId'
+--
+-- * 'simsSqlInjectionMatchTuples'
+sqlInjectionMatchSet
+    :: Text -- ^ 'simsSqlInjectionMatchSetId'
+    -> SqlInjectionMatchSet
+sqlInjectionMatchSet pSqlInjectionMatchSetId_ =
+    SqlInjectionMatchSet'
+    { _simsName = Nothing
+    , _simsSqlInjectionMatchSetId = pSqlInjectionMatchSetId_
+    , _simsSqlInjectionMatchTuples = mempty
+    }
+
+-- | The name, if any, of the 'SqlInjectionMatchSet'.
+simsName :: Lens' SqlInjectionMatchSet (Maybe Text)
+simsName = lens _simsName (\ s a -> s{_simsName = a});
+
+-- | A unique identifier for a 'SqlInjectionMatchSet'. You use
+-- 'SqlInjectionMatchSetId' to get information about a
+-- 'SqlInjectionMatchSet' (see GetSqlInjectionMatchSet), update a
+-- 'SqlInjectionMatchSet' (see UpdateSqlInjectionMatchSet, insert a
+-- 'SqlInjectionMatchSet' into a 'Rule' or delete one from a 'Rule' (see
+-- UpdateRule), and delete a 'SqlInjectionMatchSet' from AWS WAF (see
+-- DeleteByteMatchSet).
+--
+-- 'SqlInjectionMatchSetId' is returned by CreateSqlInjectionMatchSet and
+-- by ListSqlInjectionMatchSets.
+simsSqlInjectionMatchSetId :: Lens' SqlInjectionMatchSet Text
+simsSqlInjectionMatchSetId = lens _simsSqlInjectionMatchSetId (\ s a -> s{_simsSqlInjectionMatchSetId = a});
+
+-- | Specifies the parts of web requests that you want to inspect for
+-- snippets of malicious SQL code.
+simsSqlInjectionMatchTuples :: Lens' SqlInjectionMatchSet [SqlInjectionMatchTuple]
+simsSqlInjectionMatchTuples = lens _simsSqlInjectionMatchTuples (\ s a -> s{_simsSqlInjectionMatchTuples = a}) . _Coerce;
+
+instance FromJSON SqlInjectionMatchSet where
+        parseJSON
+          = withObject "SqlInjectionMatchSet"
+              (\ x ->
+                 SqlInjectionMatchSet' <$>
+                   (x .:? "Name") <*> (x .: "SqlInjectionMatchSetId")
+                     <*> (x .:? "SqlInjectionMatchTuples" .!= mempty))
+
+-- | The 'Id' and 'Name' of a 'SqlInjectionMatchSet'.
+--
+-- /See:/ 'sqlInjectionMatchSetSummary' smart constructor.
+data SqlInjectionMatchSetSummary = SqlInjectionMatchSetSummary'
+    { _simssSqlInjectionMatchSetId :: !Text
+    , _simssName                   :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'SqlInjectionMatchSetSummary' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'simssSqlInjectionMatchSetId'
+--
+-- * 'simssName'
+sqlInjectionMatchSetSummary
+    :: Text -- ^ 'simssSqlInjectionMatchSetId'
+    -> Text -- ^ 'simssName'
+    -> SqlInjectionMatchSetSummary
+sqlInjectionMatchSetSummary pSqlInjectionMatchSetId_ pName_ =
+    SqlInjectionMatchSetSummary'
+    { _simssSqlInjectionMatchSetId = pSqlInjectionMatchSetId_
+    , _simssName = pName_
+    }
+
+-- | A unique identifier for a 'SqlInjectionMatchSet'. You use
+-- 'SqlInjectionMatchSetId' to get information about a
+-- 'SqlInjectionMatchSet' (see GetSqlInjectionMatchSet), update a
+-- 'SqlInjectionMatchSet' (see UpdateSqlInjectionMatchSet, insert a
+-- 'SqlInjectionMatchSet' into a 'Rule' or delete one from a 'Rule' (see
+-- UpdateRule), and delete a 'SqlInjectionMatchSet' from AWS WAF (see
+-- DeleteByteMatchSet).
+--
+-- 'SqlInjectionMatchSetId' is returned by CreateSqlInjectionMatchSet and
+-- by ListSqlInjectionMatchSets.
+simssSqlInjectionMatchSetId :: Lens' SqlInjectionMatchSetSummary Text
+simssSqlInjectionMatchSetId = lens _simssSqlInjectionMatchSetId (\ s a -> s{_simssSqlInjectionMatchSetId = a});
+
+-- | The name of the 'SqlInjectionMatchSet', if any, specified by 'Id'.
+simssName :: Lens' SqlInjectionMatchSetSummary Text
+simssName = lens _simssName (\ s a -> s{_simssName = a});
+
+instance FromJSON SqlInjectionMatchSetSummary where
+        parseJSON
+          = withObject "SqlInjectionMatchSetSummary"
+              (\ x ->
+                 SqlInjectionMatchSetSummary' <$>
+                   (x .: "SqlInjectionMatchSetId") <*> (x .: "Name"))
+
+-- | Specifies the part of a web request that you want to inspect for
+-- snippets of malicious SQL code and indicates whether you want to add the
+-- specification to a SqlInjectionMatchSet or delete it from a
+-- 'SqlInjectionMatchSet'.
+--
+-- /See:/ 'sqlInjectionMatchSetUpdate' smart constructor.
+data SqlInjectionMatchSetUpdate = SqlInjectionMatchSetUpdate'
+    { _simsuAction                 :: !ChangeAction
+    , _simsuSqlInjectionMatchTuple :: !SqlInjectionMatchTuple
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'SqlInjectionMatchSetUpdate' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'simsuAction'
+--
+-- * 'simsuSqlInjectionMatchTuple'
+sqlInjectionMatchSetUpdate
+    :: ChangeAction -- ^ 'simsuAction'
+    -> SqlInjectionMatchTuple -- ^ 'simsuSqlInjectionMatchTuple'
+    -> SqlInjectionMatchSetUpdate
+sqlInjectionMatchSetUpdate pAction_ pSqlInjectionMatchTuple_ =
+    SqlInjectionMatchSetUpdate'
+    { _simsuAction = pAction_
+    , _simsuSqlInjectionMatchTuple = pSqlInjectionMatchTuple_
+    }
+
+-- | Specify 'INSERT' to add a SqlInjectionMatchSetUpdate to a
+-- SqlInjectionMatchSet. Use 'DELETE' to remove a
+-- 'SqlInjectionMatchSetUpdate' from a 'SqlInjectionMatchSet'.
+simsuAction :: Lens' SqlInjectionMatchSetUpdate ChangeAction
+simsuAction = lens _simsuAction (\ s a -> s{_simsuAction = a});
+
+-- | Specifies the part of a web request that you want AWS WAF to inspect for
+-- snippets of malicious SQL code and, if you want AWS WAF to inspect a
+-- header, the name of the header.
+simsuSqlInjectionMatchTuple :: Lens' SqlInjectionMatchSetUpdate SqlInjectionMatchTuple
+simsuSqlInjectionMatchTuple = lens _simsuSqlInjectionMatchTuple (\ s a -> s{_simsuSqlInjectionMatchTuple = a});
+
+instance ToJSON SqlInjectionMatchSetUpdate where
+        toJSON SqlInjectionMatchSetUpdate'{..}
+          = object
+              (catMaybes
+                 [Just ("Action" .= _simsuAction),
+                  Just
+                    ("SqlInjectionMatchTuple" .=
+                       _simsuSqlInjectionMatchTuple)])
+
+-- | Specifies the part of a web request that you want AWS WAF to inspect for
+-- snippets of malicious SQL code and, if you want AWS WAF to inspect a
+-- header, the name of the header.
+--
+-- /See:/ 'sqlInjectionMatchTuple' smart constructor.
+data SqlInjectionMatchTuple = SqlInjectionMatchTuple'
+    { _simtFieldToMatch       :: !FieldToMatch
+    , _simtTextTransformation :: !TextTransformation
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'SqlInjectionMatchTuple' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'simtFieldToMatch'
+--
+-- * 'simtTextTransformation'
+sqlInjectionMatchTuple
+    :: FieldToMatch -- ^ 'simtFieldToMatch'
+    -> TextTransformation -- ^ 'simtTextTransformation'
+    -> SqlInjectionMatchTuple
+sqlInjectionMatchTuple pFieldToMatch_ pTextTransformation_ =
+    SqlInjectionMatchTuple'
+    { _simtFieldToMatch = pFieldToMatch_
+    , _simtTextTransformation = pTextTransformation_
+    }
+
+-- | Undocumented member.
+simtFieldToMatch :: Lens' SqlInjectionMatchTuple FieldToMatch
+simtFieldToMatch = lens _simtFieldToMatch (\ s a -> s{_simtFieldToMatch = a});
+
+-- | Text transformations eliminate some of the unusual formatting that
+-- attackers use in web requests in an effort to bypass AWS WAF. If you
+-- specify a transformation, AWS WAF performs the transformation on
+-- 'TargetString' before inspecting a request for a match.
+--
+-- __CMD_LINE__
+--
+-- When you\'re concerned that attackers are injecting an operating system
+-- commandline command and using unusual formatting to disguise some or all
+-- of the command, use this option to perform the following
+-- transformations:
+--
+-- -   Delete the following characters: \\ \" \' ^
+-- -   Delete spaces before the following characters: \/ (
+-- -   Replace the following characters with a space: , ;
+-- -   Replace multiple spaces with one space
+-- -   Convert uppercase letters (A-Z) to lowercase (a-z)
+--
+-- __COMPRESS_WHITE_SPACE__
+--
+-- Use this option to replace the following characters with a space
+-- character (decimal 32):
+--
+-- -   \\f, formfeed, decimal 12
+-- -   \\t, tab, decimal 9
+-- -   \\n, newline, decimal 10
+-- -   \\r, carriage return, decimal 13
+-- -   \\v, vertical tab, decimal 11
+-- -   non-breaking space, decimal 160
+--
+-- 'COMPRESS_WHITE_SPACE' also replaces multiple spaces with one space.
+--
+-- __HTML_ENTITY_DECODE__
+--
+-- Use this option to replace HTML-encoded characters with unencoded
+-- characters. 'HTML_ENTITY_DECODE' performs the following operations:
+--
+-- -   Replaces '(ampersand)quot;' with '\"'
+-- -   Replaces '(ampersand)nbsp;' with a non-breaking space, decimal 160
+-- -   Replaces '(ampersand)lt;' with a \"less than\" symbol
+-- -   Replaces '(ampersand)gt;' with '>'
+-- -   Replaces characters that are represented in hexadecimal format,
+--     '(ampersand)#xhhhh;', with the corresponding characters
+-- -   Replaces characters that are represented in decimal format,
+--     '(ampersand)#nnnn;', with the corresponding characters
+--
+-- __LOWERCASE__
+--
+-- Use this option to convert uppercase letters (A-Z) to lowercase (a-z).
+--
+-- __URL_DECODE__
+--
+-- Use this option to decode a URL-encoded value.
+--
+-- __NONE__
+--
+-- Specify 'NONE' if you don\'t want to perform any text transformations.
+simtTextTransformation :: Lens' SqlInjectionMatchTuple TextTransformation
+simtTextTransformation = lens _simtTextTransformation (\ s a -> s{_simtTextTransformation = a});
+
+instance FromJSON SqlInjectionMatchTuple where
+        parseJSON
+          = withObject "SqlInjectionMatchTuple"
+              (\ x ->
+                 SqlInjectionMatchTuple' <$>
+                   (x .: "FieldToMatch") <*>
+                     (x .: "TextTransformation"))
+
+instance ToJSON SqlInjectionMatchTuple where
+        toJSON SqlInjectionMatchTuple'{..}
+          = object
+              (catMaybes
+                 [Just ("FieldToMatch" .= _simtFieldToMatch),
+                  Just
+                    ("TextTransformation" .= _simtTextTransformation)])
+
+-- | In a GetSampledRequests request, the 'StartTime' and 'EndTime' objects
+-- specify the time range for which you want AWS WAF to return a sample of
+-- web requests.
+--
+-- In a GetSampledRequests response, the 'StartTime' and 'EndTime' objects
+-- specify the time range for which AWS WAF actually returned a sample of
+-- web requests. AWS WAF gets the specified number of requests from among
+-- the first 5,000 requests that your AWS resource receives during the
+-- specified time period. If your resource receives more than 5,000
+-- requests during that period, AWS WAF stops sampling after the 5,000th
+-- request. In that case, 'EndTime' is the time that AWS WAF received the
+-- 5,000th request.
+--
+-- /See:/ 'timeWindow' smart constructor.
+data TimeWindow = TimeWindow'
+    { _twStartTime :: !POSIX
+    , _twEndTime   :: !POSIX
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'TimeWindow' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'twStartTime'
+--
+-- * 'twEndTime'
+timeWindow
+    :: UTCTime -- ^ 'twStartTime'
+    -> UTCTime -- ^ 'twEndTime'
+    -> TimeWindow
+timeWindow pStartTime_ pEndTime_ =
+    TimeWindow'
+    { _twStartTime = _Time # pStartTime_
+    , _twEndTime = _Time # pEndTime_
+    }
+
+-- | The beginning of the time range from which you want 'GetSampledRequests'
+-- to return a sample of the requests that your AWS resource received. You
+-- can specify any time range in the previous three hours.
+twStartTime :: Lens' TimeWindow UTCTime
+twStartTime = lens _twStartTime (\ s a -> s{_twStartTime = a}) . _Time;
+
+-- | The end of the time range from which you want 'GetSampledRequests' to
+-- return a sample of the requests that your AWS resource received. You can
+-- specify any time range in the previous three hours.
+twEndTime :: Lens' TimeWindow UTCTime
+twEndTime = lens _twEndTime (\ s a -> s{_twEndTime = a}) . _Time;
+
+instance FromJSON TimeWindow where
+        parseJSON
+          = withObject "TimeWindow"
+              (\ x ->
+                 TimeWindow' <$>
+                   (x .: "StartTime") <*> (x .: "EndTime"))
+
+instance ToJSON TimeWindow where
+        toJSON TimeWindow'{..}
+          = object
+              (catMaybes
+                 [Just ("StartTime" .= _twStartTime),
+                  Just ("EndTime" .= _twEndTime)])
+
+-- | For the action that is associated with a rule in a 'WebACL', specifies
+-- the action that you want AWS WAF to perform when a web request matches
+-- all of the conditions in a rule. For the default action in a 'WebACL',
+-- specifies the action that you want AWS WAF to take when a web request
+-- doesn\'t match all of the conditions in any of the rules in a 'WebACL'.
+--
+-- /See:/ 'wafAction' smart constructor.
+newtype WafAction = WafAction'
+    { _waType :: WafActionType
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'WafAction' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'waType'
+wafAction
+    :: WafActionType -- ^ 'waType'
+    -> WafAction
+wafAction pType_ =
+    WafAction'
+    { _waType = pType_
+    }
+
+-- | Specifies how you want AWS WAF to respond to requests that match the
+-- settings in a 'Rule'. Valid settings include the following:
+--
+-- -   'ALLOW': AWS WAF allows requests
+-- -   'BLOCK': AWS WAF blocks requests
+-- -   'COUNT': AWS WAF increments a counter of the requests that match all
+--     of the conditions in the rule. AWS WAF then continues to inspect the
+--     web request based on the remaining rules in the web ACL. You can\'t
+--     specify 'COUNT' for the default action for a 'WebACL'.
+waType :: Lens' WafAction WafActionType
+waType = lens _waType (\ s a -> s{_waType = a});
+
+instance FromJSON WafAction where
+        parseJSON
+          = withObject "WafAction"
+              (\ x -> WafAction' <$> (x .: "Type"))
+
+instance ToJSON WafAction where
+        toJSON WafAction'{..}
+          = object (catMaybes [Just ("Type" .= _waType)])
+
+-- | Contains the 'Rules' that identify the requests that you want to allow,
+-- block, or count. In a 'WebACL', you also specify a default action
+-- ('ALLOW' or 'BLOCK'), and the action for each 'Rule' that you add to a
+-- 'WebACL', for example, block requests from specified IP addresses or
+-- block requests from specified referrers. You also associate the 'WebACL'
+-- with a CloudFront distribution to identify the requests that you want
+-- AWS WAF to filter. If you add more than one 'Rule' to a 'WebACL', a
+-- request needs to match only one of the specifications to be allowed,
+-- blocked, or counted. For more information, see UpdateWebACL.
+--
+-- /See:/ 'webACL' smart constructor.
+data WebACL = WebACL'
+    { _waMetricName    :: !(Maybe Text)
+    , _waName          :: !(Maybe Text)
+    , _waWebACLId      :: !Text
+    , _waDefaultAction :: !WafAction
+    , _waRules         :: ![ActivatedRule]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'WebACL' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'waMetricName'
+--
+-- * 'waName'
+--
+-- * 'waWebACLId'
+--
+-- * 'waDefaultAction'
+--
+-- * 'waRules'
+webACL
+    :: Text -- ^ 'waWebACLId'
+    -> WafAction -- ^ 'waDefaultAction'
+    -> WebACL
+webACL pWebACLId_ pDefaultAction_ =
+    WebACL'
+    { _waMetricName = Nothing
+    , _waName = Nothing
+    , _waWebACLId = pWebACLId_
+    , _waDefaultAction = pDefaultAction_
+    , _waRules = mempty
+    }
+
+-- | Undocumented member.
+waMetricName :: Lens' WebACL (Maybe Text)
+waMetricName = lens _waMetricName (\ s a -> s{_waMetricName = a});
+
+-- | A friendly name or description of the 'WebACL'. You can\'t change the
+-- name of a 'WebACL' after you create it.
+waName :: Lens' WebACL (Maybe Text)
+waName = lens _waName (\ s a -> s{_waName = a});
+
+-- | A unique identifier for a 'WebACL'. You use 'WebACLId' to get
+-- information about a 'WebACL' (see GetWebACL), update a 'WebACL' (see
+-- UpdateWebACL, and delete a 'WebACL' from AWS WAF (see DeleteWebACL).
+--
+-- 'WebACLId' is returned by CreateWebACL and by ListWebACLs.
+waWebACLId :: Lens' WebACL Text
+waWebACLId = lens _waWebACLId (\ s a -> s{_waWebACLId = a});
+
+-- | The action to perform if none of the 'Rules' contained in the 'WebACL'
+-- match. The action is specified by the WafAction object.
+waDefaultAction :: Lens' WebACL WafAction
+waDefaultAction = lens _waDefaultAction (\ s a -> s{_waDefaultAction = a});
+
+-- | An array that contains the action for each 'Rule' in a 'WebACL', the
+-- priority of the 'Rule', and the ID of the 'Rule'.
+waRules :: Lens' WebACL [ActivatedRule]
+waRules = lens _waRules (\ s a -> s{_waRules = a}) . _Coerce;
+
+instance FromJSON WebACL where
+        parseJSON
+          = withObject "WebACL"
+              (\ x ->
+                 WebACL' <$>
+                   (x .:? "MetricName") <*> (x .:? "Name") <*>
+                     (x .: "WebACLId")
+                     <*> (x .: "DefaultAction")
+                     <*> (x .:? "Rules" .!= mempty))
+
+-- | Contains the identifier and the name or description of the WebACL.
+--
+-- /See:/ 'webACLSummary' smart constructor.
+data WebACLSummary = WebACLSummary'
+    { _wasWebACLId :: !Text
+    , _wasName     :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'WebACLSummary' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'wasWebACLId'
+--
+-- * 'wasName'
+webACLSummary
+    :: Text -- ^ 'wasWebACLId'
+    -> Text -- ^ 'wasName'
+    -> WebACLSummary
+webACLSummary pWebACLId_ pName_ =
+    WebACLSummary'
+    { _wasWebACLId = pWebACLId_
+    , _wasName = pName_
+    }
+
+-- | A unique identifier for a 'WebACL'. You use 'WebACLId' to get
+-- information about a 'WebACL' (see GetWebACL), update a 'WebACL' (see
+-- UpdateWebACL, and delete a 'WebACL' from AWS WAF (see DeleteWebACL).
+--
+-- 'WebACLId' is returned by CreateWebACL and by ListWebACLs.
+wasWebACLId :: Lens' WebACLSummary Text
+wasWebACLId = lens _wasWebACLId (\ s a -> s{_wasWebACLId = a});
+
+-- | A friendly name or description of the WebACL. You can\'t change the name
+-- of a 'WebACL' after you create it.
+wasName :: Lens' WebACLSummary Text
+wasName = lens _wasName (\ s a -> s{_wasName = a});
+
+instance FromJSON WebACLSummary where
+        parseJSON
+          = withObject "WebACLSummary"
+              (\ x ->
+                 WebACLSummary' <$>
+                   (x .: "WebACLId") <*> (x .: "Name"))
+
+-- | Specifies whether to insert a 'Rule' into or delete a 'Rule' from a
+-- 'WebACL'.
+--
+-- /See:/ 'webACLUpdate' smart constructor.
+data WebACLUpdate = WebACLUpdate'
+    { _wauAction        :: !ChangeAction
+    , _wauActivatedRule :: !ActivatedRule
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'WebACLUpdate' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'wauAction'
+--
+-- * 'wauActivatedRule'
+webACLUpdate
+    :: ChangeAction -- ^ 'wauAction'
+    -> ActivatedRule -- ^ 'wauActivatedRule'
+    -> WebACLUpdate
+webACLUpdate pAction_ pActivatedRule_ =
+    WebACLUpdate'
+    { _wauAction = pAction_
+    , _wauActivatedRule = pActivatedRule_
+    }
+
+-- | Specifies whether to insert a 'Rule' into or delete a 'Rule' from a
+-- 'WebACL'.
+wauAction :: Lens' WebACLUpdate ChangeAction
+wauAction = lens _wauAction (\ s a -> s{_wauAction = a});
+
+-- | Undocumented member.
+wauActivatedRule :: Lens' WebACLUpdate ActivatedRule
+wauActivatedRule = lens _wauActivatedRule (\ s a -> s{_wauActivatedRule = a});
+
+instance ToJSON WebACLUpdate where
+        toJSON WebACLUpdate'{..}
+          = object
+              (catMaybes
+                 [Just ("Action" .= _wauAction),
+                  Just ("ActivatedRule" .= _wauActivatedRule)])
diff --git a/gen/Network/AWS/WAF/Types/Sum.hs b/gen/Network/AWS/WAF/Types/Sum.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/Types/Sum.hs
@@ -0,0 +1,271 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE LambdaCase         #-}
+{-# LANGUAGE OverloadedStrings  #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.Types.Sum
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+module Network.AWS.WAF.Types.Sum where
+
+import           Network.AWS.Prelude
+
+data ChangeAction
+    = Delete
+    | Insert
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText ChangeAction where
+    parser = takeLowerText >>= \case
+        "delete" -> pure Delete
+        "insert" -> pure Insert
+        e -> fromTextError $ "Failure parsing ChangeAction from value: '" <> e
+           <> "'. Accepted values: DELETE, INSERT"
+
+instance ToText ChangeAction where
+    toText = \case
+        Delete -> "DELETE"
+        Insert -> "INSERT"
+
+instance Hashable     ChangeAction
+instance ToByteString ChangeAction
+instance ToQuery      ChangeAction
+instance ToHeader     ChangeAction
+
+instance ToJSON ChangeAction where
+    toJSON = toJSONText
+
+data ChangeTokenStatus
+    = Insync
+    | Pending
+    | Provisioned
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText ChangeTokenStatus where
+    parser = takeLowerText >>= \case
+        "insync" -> pure Insync
+        "pending" -> pure Pending
+        "provisioned" -> pure Provisioned
+        e -> fromTextError $ "Failure parsing ChangeTokenStatus from value: '" <> e
+           <> "'. Accepted values: INSYNC, PENDING, PROVISIONED"
+
+instance ToText ChangeTokenStatus where
+    toText = \case
+        Insync -> "INSYNC"
+        Pending -> "PENDING"
+        Provisioned -> "PROVISIONED"
+
+instance Hashable     ChangeTokenStatus
+instance ToByteString ChangeTokenStatus
+instance ToQuery      ChangeTokenStatus
+instance ToHeader     ChangeTokenStatus
+
+instance FromJSON ChangeTokenStatus where
+    parseJSON = parseJSONText "ChangeTokenStatus"
+
+data IPSetDescriptorType =
+    IPV4
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText IPSetDescriptorType where
+    parser = takeLowerText >>= \case
+        "ipv4" -> pure IPV4
+        e -> fromTextError $ "Failure parsing IPSetDescriptorType from value: '" <> e
+           <> "'. Accepted values: IPV4"
+
+instance ToText IPSetDescriptorType where
+    toText = \case
+        IPV4 -> "IPV4"
+
+instance Hashable     IPSetDescriptorType
+instance ToByteString IPSetDescriptorType
+instance ToQuery      IPSetDescriptorType
+instance ToHeader     IPSetDescriptorType
+
+instance ToJSON IPSetDescriptorType where
+    toJSON = toJSONText
+
+instance FromJSON IPSetDescriptorType where
+    parseJSON = parseJSONText "IPSetDescriptorType"
+
+data MatchFieldType
+    = Header
+    | Method
+    | QueryString
+    | URI
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText MatchFieldType where
+    parser = takeLowerText >>= \case
+        "header" -> pure Header
+        "method" -> pure Method
+        "query_string" -> pure QueryString
+        "uri" -> pure URI
+        e -> fromTextError $ "Failure parsing MatchFieldType from value: '" <> e
+           <> "'. Accepted values: HEADER, METHOD, QUERY_STRING, URI"
+
+instance ToText MatchFieldType where
+    toText = \case
+        Header -> "HEADER"
+        Method -> "METHOD"
+        QueryString -> "QUERY_STRING"
+        URI -> "URI"
+
+instance Hashable     MatchFieldType
+instance ToByteString MatchFieldType
+instance ToQuery      MatchFieldType
+instance ToHeader     MatchFieldType
+
+instance ToJSON MatchFieldType where
+    toJSON = toJSONText
+
+instance FromJSON MatchFieldType where
+    parseJSON = parseJSONText "MatchFieldType"
+
+data PositionalConstraint
+    = Contains
+    | ContainsWord
+    | EndsWith
+    | Exactly
+    | StartsWith
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText PositionalConstraint where
+    parser = takeLowerText >>= \case
+        "contains" -> pure Contains
+        "contains_word" -> pure ContainsWord
+        "ends_with" -> pure EndsWith
+        "exactly" -> pure Exactly
+        "starts_with" -> pure StartsWith
+        e -> fromTextError $ "Failure parsing PositionalConstraint from value: '" <> e
+           <> "'. Accepted values: CONTAINS, CONTAINS_WORD, ENDS_WITH, EXACTLY, STARTS_WITH"
+
+instance ToText PositionalConstraint where
+    toText = \case
+        Contains -> "CONTAINS"
+        ContainsWord -> "CONTAINS_WORD"
+        EndsWith -> "ENDS_WITH"
+        Exactly -> "EXACTLY"
+        StartsWith -> "STARTS_WITH"
+
+instance Hashable     PositionalConstraint
+instance ToByteString PositionalConstraint
+instance ToQuery      PositionalConstraint
+instance ToHeader     PositionalConstraint
+
+instance ToJSON PositionalConstraint where
+    toJSON = toJSONText
+
+instance FromJSON PositionalConstraint where
+    parseJSON = parseJSONText "PositionalConstraint"
+
+data PredicateType
+    = ByteMatch
+    | IPMatch
+    | SqlInjectionMatch
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText PredicateType where
+    parser = takeLowerText >>= \case
+        "bytematch" -> pure ByteMatch
+        "ipmatch" -> pure IPMatch
+        "sqlinjectionmatch" -> pure SqlInjectionMatch
+        e -> fromTextError $ "Failure parsing PredicateType from value: '" <> e
+           <> "'. Accepted values: ByteMatch, IPMatch, SqlInjectionMatch"
+
+instance ToText PredicateType where
+    toText = \case
+        ByteMatch -> "ByteMatch"
+        IPMatch -> "IPMatch"
+        SqlInjectionMatch -> "SqlInjectionMatch"
+
+instance Hashable     PredicateType
+instance ToByteString PredicateType
+instance ToQuery      PredicateType
+instance ToHeader     PredicateType
+
+instance ToJSON PredicateType where
+    toJSON = toJSONText
+
+instance FromJSON PredicateType where
+    parseJSON = parseJSONText "PredicateType"
+
+data TextTransformation
+    = CmdLine
+    | CompressWhiteSpace
+    | HTMLEntityDecode
+    | Lowercase
+    | None
+    | URLDecode
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText TextTransformation where
+    parser = takeLowerText >>= \case
+        "cmd_line" -> pure CmdLine
+        "compress_white_space" -> pure CompressWhiteSpace
+        "html_entity_decode" -> pure HTMLEntityDecode
+        "lowercase" -> pure Lowercase
+        "none" -> pure None
+        "url_decode" -> pure URLDecode
+        e -> fromTextError $ "Failure parsing TextTransformation from value: '" <> e
+           <> "'. Accepted values: CMD_LINE, COMPRESS_WHITE_SPACE, HTML_ENTITY_DECODE, LOWERCASE, NONE, URL_DECODE"
+
+instance ToText TextTransformation where
+    toText = \case
+        CmdLine -> "CMD_LINE"
+        CompressWhiteSpace -> "COMPRESS_WHITE_SPACE"
+        HTMLEntityDecode -> "HTML_ENTITY_DECODE"
+        Lowercase -> "LOWERCASE"
+        None -> "NONE"
+        URLDecode -> "URL_DECODE"
+
+instance Hashable     TextTransformation
+instance ToByteString TextTransformation
+instance ToQuery      TextTransformation
+instance ToHeader     TextTransformation
+
+instance ToJSON TextTransformation where
+    toJSON = toJSONText
+
+instance FromJSON TextTransformation where
+    parseJSON = parseJSONText "TextTransformation"
+
+data WafActionType
+    = Allow
+    | Block
+    | Count
+    deriving (Eq,Ord,Read,Show,Enum,Data,Typeable,Generic)
+
+instance FromText WafActionType where
+    parser = takeLowerText >>= \case
+        "allow" -> pure Allow
+        "block" -> pure Block
+        "count" -> pure Count
+        e -> fromTextError $ "Failure parsing WafActionType from value: '" <> e
+           <> "'. Accepted values: ALLOW, BLOCK, COUNT"
+
+instance ToText WafActionType where
+    toText = \case
+        Allow -> "ALLOW"
+        Block -> "BLOCK"
+        Count -> "COUNT"
+
+instance Hashable     WafActionType
+instance ToByteString WafActionType
+instance ToQuery      WafActionType
+instance ToHeader     WafActionType
+
+instance ToJSON WafActionType where
+    toJSON = toJSONText
+
+instance FromJSON WafActionType where
+    parseJSON = parseJSONText "WafActionType"
diff --git a/gen/Network/AWS/WAF/UpdateByteMatchSet.hs b/gen/Network/AWS/WAF/UpdateByteMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/UpdateByteMatchSet.hs
@@ -0,0 +1,193 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.UpdateByteMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Inserts or deletes ByteMatchTuple objects (filters) in a ByteMatchSet.
+-- For each 'ByteMatchTuple' object, you specify the following values:
+--
+-- -   Whether to insert or delete the object from the array. If you want
+--     to change a 'ByteMatchSetUpdate' object, you delete the existing
+--     object and add a new one.
+-- -   The part of a web request that you want AWS WAF to inspect, such as
+--     a query string or the value of the 'User-Agent' header.
+-- -   The bytes (typically a string that corresponds with ASCII
+--     characters) that you want AWS WAF to look for. For more information,
+--     including how you specify the values for the AWS WAF API and the AWS
+--     CLI or SDKs, see 'TargetString' in the ByteMatchTuple data type.
+-- -   Where to look, such as at the beginning or the end of a query
+--     string.
+-- -   Whether to perform any conversions on the request, such as
+--     converting it to lowercase, before inspecting it for the specified
+--     string.
+--
+-- For example, you can add a 'ByteMatchSetUpdate' object that matches web
+-- requests in which 'User-Agent' headers contain the string 'BadBot'. You
+-- can then configure AWS WAF to block those requests.
+--
+-- To create and configure a 'ByteMatchSet', perform the following steps:
+--
+-- 1.  Create a 'ByteMatchSet.' For more information, see
+--     CreateByteMatchSet.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of an 'UpdateByteMatchSet' request.
+-- 3.  Submit an 'UpdateByteMatchSet' request to specify the part of the
+--     request that you want AWS WAF to inspect (for example, the header or
+--     the URI) and the value that you want AWS WAF to watch for.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_UpdateByteMatchSet.html AWS API Reference> for UpdateByteMatchSet.
+module Network.AWS.WAF.UpdateByteMatchSet
+    (
+    -- * Creating a Request
+      updateByteMatchSet
+    , UpdateByteMatchSet
+    -- * Request Lenses
+    , ubmsByteMatchSetId
+    , ubmsChangeToken
+    , ubmsUpdates
+
+    -- * Destructuring the Response
+    , updateByteMatchSetResponse
+    , UpdateByteMatchSetResponse
+    -- * Response Lenses
+    , ubmsrsChangeToken
+    , ubmsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'updateByteMatchSet' smart constructor.
+data UpdateByteMatchSet = UpdateByteMatchSet'
+    { _ubmsByteMatchSetId :: !Text
+    , _ubmsChangeToken    :: !Text
+    , _ubmsUpdates        :: ![ByteMatchSetUpdate]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateByteMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'ubmsByteMatchSetId'
+--
+-- * 'ubmsChangeToken'
+--
+-- * 'ubmsUpdates'
+updateByteMatchSet
+    :: Text -- ^ 'ubmsByteMatchSetId'
+    -> Text -- ^ 'ubmsChangeToken'
+    -> UpdateByteMatchSet
+updateByteMatchSet pByteMatchSetId_ pChangeToken_ =
+    UpdateByteMatchSet'
+    { _ubmsByteMatchSetId = pByteMatchSetId_
+    , _ubmsChangeToken = pChangeToken_
+    , _ubmsUpdates = mempty
+    }
+
+-- | The 'ByteMatchSetId' of the ByteMatchSet that you want to update.
+-- 'ByteMatchSetId' is returned by CreateByteMatchSet and by
+-- ListByteMatchSets.
+ubmsByteMatchSetId :: Lens' UpdateByteMatchSet Text
+ubmsByteMatchSetId = lens _ubmsByteMatchSetId (\ s a -> s{_ubmsByteMatchSetId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+ubmsChangeToken :: Lens' UpdateByteMatchSet Text
+ubmsChangeToken = lens _ubmsChangeToken (\ s a -> s{_ubmsChangeToken = a});
+
+-- | An array of 'ByteMatchSetUpdate' objects that you want to insert into or
+-- delete from a ByteMatchSet. For more information, see the applicable
+-- data types:
+--
+-- -   ByteMatchSetUpdate: Contains 'Action' and 'ByteMatchTuple'
+-- -   ByteMatchTuple: Contains 'FieldToMatch', 'PositionalConstraint',
+--     'TargetString', and 'TextTransformation'
+-- -   FieldToMatch: Contains 'Data' and 'Type'
+ubmsUpdates :: Lens' UpdateByteMatchSet [ByteMatchSetUpdate]
+ubmsUpdates = lens _ubmsUpdates (\ s a -> s{_ubmsUpdates = a}) . _Coerce;
+
+instance AWSRequest UpdateByteMatchSet where
+        type Rs UpdateByteMatchSet =
+             UpdateByteMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 UpdateByteMatchSetResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders UpdateByteMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.UpdateByteMatchSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON UpdateByteMatchSet where
+        toJSON UpdateByteMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just ("ByteMatchSetId" .= _ubmsByteMatchSetId),
+                  Just ("ChangeToken" .= _ubmsChangeToken),
+                  Just ("Updates" .= _ubmsUpdates)])
+
+instance ToPath UpdateByteMatchSet where
+        toPath = const "/"
+
+instance ToQuery UpdateByteMatchSet where
+        toQuery = const mempty
+
+-- | /See:/ 'updateByteMatchSetResponse' smart constructor.
+data UpdateByteMatchSetResponse = UpdateByteMatchSetResponse'
+    { _ubmsrsChangeToken    :: !(Maybe Text)
+    , _ubmsrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateByteMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'ubmsrsChangeToken'
+--
+-- * 'ubmsrsResponseStatus'
+updateByteMatchSetResponse
+    :: Int -- ^ 'ubmsrsResponseStatus'
+    -> UpdateByteMatchSetResponse
+updateByteMatchSetResponse pResponseStatus_ =
+    UpdateByteMatchSetResponse'
+    { _ubmsrsChangeToken = Nothing
+    , _ubmsrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'UpdateByteMatchSet'
+-- request. You can also use this value to query the status of the request.
+-- For more information, see GetChangeTokenStatus.
+ubmsrsChangeToken :: Lens' UpdateByteMatchSetResponse (Maybe Text)
+ubmsrsChangeToken = lens _ubmsrsChangeToken (\ s a -> s{_ubmsrsChangeToken = a});
+
+-- | The response status code.
+ubmsrsResponseStatus :: Lens' UpdateByteMatchSetResponse Int
+ubmsrsResponseStatus = lens _ubmsrsResponseStatus (\ s a -> s{_ubmsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/UpdateIPSet.hs b/gen/Network/AWS/WAF/UpdateIPSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/UpdateIPSet.hs
@@ -0,0 +1,191 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.UpdateIPSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Inserts or deletes IPSetDescriptor objects in an 'IPSet'. For each
+-- 'IPSetDescriptor' object, you specify the following values:
+--
+-- -   Whether to insert or delete the object from the array. If you want
+--     to change an 'IPSetDescriptor' object, you delete the existing
+--     object and add a new one.
+-- -   The IP address version, 'IPv4'.
+-- -   The IP address in CIDR notation, for example, '192.0.2.0\/24' (for
+--     the range of IP addresses from '192.0.2.0' to '192.0.2.255') or
+--     '192.0.2.44\/32' (for the individual IP address '192.0.2.44').
+--
+-- AWS WAF supports \/8, \/16, \/24, and \/32 IP address ranges. For more
+-- information about CIDR notation, see the Wikipedia entry
+-- <https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing Classless Inter-Domain Routing>.
+--
+-- You use an 'IPSet' to specify which web requests you want to allow or
+-- block based on the IP addresses that the requests originated from. For
+-- example, if you\'re receiving a lot of requests from one or a small
+-- number of IP addresses and you want to block the requests, you can
+-- create an 'IPSet' that specifies those IP addresses, and then configure
+-- AWS WAF to block the requests.
+--
+-- To create and configure an 'IPSet', perform the following steps:
+--
+-- 1.  Submit a CreateIPSet request.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateIPSet request.
+-- 3.  Submit an 'UpdateIPSet' request to specify the IP addresses that you
+--     want AWS WAF to watch for.
+--
+-- When you update an 'IPSet', you specify the IP addresses that you want
+-- to add and\/or the IP addresses that you want to delete. If you want to
+-- change an IP address, you delete the existing IP address and add the new
+-- one.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_UpdateIPSet.html AWS API Reference> for UpdateIPSet.
+module Network.AWS.WAF.UpdateIPSet
+    (
+    -- * Creating a Request
+      updateIPSet
+    , UpdateIPSet
+    -- * Request Lenses
+    , uisIPSetId
+    , uisChangeToken
+    , uisUpdates
+
+    -- * Destructuring the Response
+    , updateIPSetResponse
+    , UpdateIPSetResponse
+    -- * Response Lenses
+    , uisrsChangeToken
+    , uisrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'updateIPSet' smart constructor.
+data UpdateIPSet = UpdateIPSet'
+    { _uisIPSetId     :: !Text
+    , _uisChangeToken :: !Text
+    , _uisUpdates     :: ![IPSetUpdate]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateIPSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'uisIPSetId'
+--
+-- * 'uisChangeToken'
+--
+-- * 'uisUpdates'
+updateIPSet
+    :: Text -- ^ 'uisIPSetId'
+    -> Text -- ^ 'uisChangeToken'
+    -> UpdateIPSet
+updateIPSet pIPSetId_ pChangeToken_ =
+    UpdateIPSet'
+    { _uisIPSetId = pIPSetId_
+    , _uisChangeToken = pChangeToken_
+    , _uisUpdates = mempty
+    }
+
+-- | The 'IPSetId' of the IPSet that you want to update. 'IPSetId' is
+-- returned by CreateIPSet and by ListIPSets.
+uisIPSetId :: Lens' UpdateIPSet Text
+uisIPSetId = lens _uisIPSetId (\ s a -> s{_uisIPSetId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+uisChangeToken :: Lens' UpdateIPSet Text
+uisChangeToken = lens _uisChangeToken (\ s a -> s{_uisChangeToken = a});
+
+-- | An array of 'IPSetUpdate' objects that you want to insert into or delete
+-- from an IPSet. For more information, see the applicable data types:
+--
+-- -   IPSetUpdate: Contains 'Action' and 'IPSetDescriptor'
+-- -   IPSetDescriptor: Contains 'Type' and 'Value'
+uisUpdates :: Lens' UpdateIPSet [IPSetUpdate]
+uisUpdates = lens _uisUpdates (\ s a -> s{_uisUpdates = a}) . _Coerce;
+
+instance AWSRequest UpdateIPSet where
+        type Rs UpdateIPSet = UpdateIPSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 UpdateIPSetResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders UpdateIPSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.UpdateIPSet" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON UpdateIPSet where
+        toJSON UpdateIPSet'{..}
+          = object
+              (catMaybes
+                 [Just ("IPSetId" .= _uisIPSetId),
+                  Just ("ChangeToken" .= _uisChangeToken),
+                  Just ("Updates" .= _uisUpdates)])
+
+instance ToPath UpdateIPSet where
+        toPath = const "/"
+
+instance ToQuery UpdateIPSet where
+        toQuery = const mempty
+
+-- | /See:/ 'updateIPSetResponse' smart constructor.
+data UpdateIPSetResponse = UpdateIPSetResponse'
+    { _uisrsChangeToken    :: !(Maybe Text)
+    , _uisrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateIPSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'uisrsChangeToken'
+--
+-- * 'uisrsResponseStatus'
+updateIPSetResponse
+    :: Int -- ^ 'uisrsResponseStatus'
+    -> UpdateIPSetResponse
+updateIPSetResponse pResponseStatus_ =
+    UpdateIPSetResponse'
+    { _uisrsChangeToken = Nothing
+    , _uisrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'UpdateIPSet' request. You
+-- can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+uisrsChangeToken :: Lens' UpdateIPSetResponse (Maybe Text)
+uisrsChangeToken = lens _uisrsChangeToken (\ s a -> s{_uisrsChangeToken = a});
+
+-- | The response status code.
+uisrsResponseStatus :: Lens' UpdateIPSetResponse Int
+uisrsResponseStatus = lens _uisrsResponseStatus (\ s a -> s{_uisrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/UpdateRule.hs b/gen/Network/AWS/WAF/UpdateRule.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/UpdateRule.hs
@@ -0,0 +1,187 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.UpdateRule
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Inserts or deletes Predicate objects in a 'Rule'. Each 'Predicate'
+-- object identifies a predicate, such as a ByteMatchSet or an IPSet, that
+-- specifies the web requests that you want to allow, block, or count. If
+-- you add more than one predicate to a 'Rule', a request must match all of
+-- the specifications to be allowed, blocked, or counted. For example,
+-- suppose you add the following to a 'Rule':
+--
+-- -   A 'ByteMatchSet' that matches the value 'BadBot' in the 'User-Agent'
+--     header
+-- -   An 'IPSet' that matches the IP address '192.0.2.44'
+--
+-- You then add the 'Rule' to a 'WebACL' and specify that you want to block
+-- requests that satisfy the 'Rule'. For a request to be blocked, the
+-- 'User-Agent' header in the request must contain the value 'BadBot' /and/
+-- the request must originate from the IP address 192.0.2.44.
+--
+-- To create and configure a 'Rule', perform the following steps:
+--
+-- 1.  Create and update the predicates that you want to include in the
+--     'Rule'.
+-- 2.  Create the 'Rule'. See CreateRule.
+-- 3.  Use 'GetChangeToken' to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateRule request.
+-- 4.  Submit an 'UpdateRule' request to add predicates to the 'Rule'.
+-- 5.  Create and update a 'WebACL' that contains the 'Rule'. See
+--     CreateWebACL.
+--
+-- If you want to replace one 'ByteMatchSet' or 'IPSet' with another, you
+-- delete the existing one and add the new one.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_UpdateRule.html AWS API Reference> for UpdateRule.
+module Network.AWS.WAF.UpdateRule
+    (
+    -- * Creating a Request
+      updateRule
+    , UpdateRule
+    -- * Request Lenses
+    , urRuleId
+    , urChangeToken
+    , urUpdates
+
+    -- * Destructuring the Response
+    , updateRuleResponse
+    , UpdateRuleResponse
+    -- * Response Lenses
+    , urrsChangeToken
+    , urrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'updateRule' smart constructor.
+data UpdateRule = UpdateRule'
+    { _urRuleId      :: !Text
+    , _urChangeToken :: !Text
+    , _urUpdates     :: ![RuleUpdate]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateRule' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'urRuleId'
+--
+-- * 'urChangeToken'
+--
+-- * 'urUpdates'
+updateRule
+    :: Text -- ^ 'urRuleId'
+    -> Text -- ^ 'urChangeToken'
+    -> UpdateRule
+updateRule pRuleId_ pChangeToken_ =
+    UpdateRule'
+    { _urRuleId = pRuleId_
+    , _urChangeToken = pChangeToken_
+    , _urUpdates = mempty
+    }
+
+-- | The 'RuleId' of the 'Rule' that you want to update. 'RuleId' is returned
+-- by 'CreateRule' and by ListRules.
+urRuleId :: Lens' UpdateRule Text
+urRuleId = lens _urRuleId (\ s a -> s{_urRuleId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+urChangeToken :: Lens' UpdateRule Text
+urChangeToken = lens _urChangeToken (\ s a -> s{_urChangeToken = a});
+
+-- | An array of 'RuleUpdate' objects that you want to insert into or delete
+-- from a Rule. For more information, see the applicable data types:
+--
+-- -   RuleUpdate: Contains 'Action' and 'Predicate'
+-- -   Predicate: Contains 'DataId', 'Negated', and 'Type'
+-- -   FieldToMatch: Contains 'Data' and 'Type'
+urUpdates :: Lens' UpdateRule [RuleUpdate]
+urUpdates = lens _urUpdates (\ s a -> s{_urUpdates = a}) . _Coerce;
+
+instance AWSRequest UpdateRule where
+        type Rs UpdateRule = UpdateRuleResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 UpdateRuleResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders UpdateRule where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.UpdateRule" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON UpdateRule where
+        toJSON UpdateRule'{..}
+          = object
+              (catMaybes
+                 [Just ("RuleId" .= _urRuleId),
+                  Just ("ChangeToken" .= _urChangeToken),
+                  Just ("Updates" .= _urUpdates)])
+
+instance ToPath UpdateRule where
+        toPath = const "/"
+
+instance ToQuery UpdateRule where
+        toQuery = const mempty
+
+-- | /See:/ 'updateRuleResponse' smart constructor.
+data UpdateRuleResponse = UpdateRuleResponse'
+    { _urrsChangeToken    :: !(Maybe Text)
+    , _urrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateRuleResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'urrsChangeToken'
+--
+-- * 'urrsResponseStatus'
+updateRuleResponse
+    :: Int -- ^ 'urrsResponseStatus'
+    -> UpdateRuleResponse
+updateRuleResponse pResponseStatus_ =
+    UpdateRuleResponse'
+    { _urrsChangeToken = Nothing
+    , _urrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'UpdateRule' request. You
+-- can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+urrsChangeToken :: Lens' UpdateRuleResponse (Maybe Text)
+urrsChangeToken = lens _urrsChangeToken (\ s a -> s{_urrsChangeToken = a});
+
+-- | The response status code.
+urrsResponseStatus :: Lens' UpdateRuleResponse Int
+urrsResponseStatus = lens _urrsResponseStatus (\ s a -> s{_urrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/UpdateSqlInjectionMatchSet.hs b/gen/Network/AWS/WAF/UpdateSqlInjectionMatchSet.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/UpdateSqlInjectionMatchSet.hs
@@ -0,0 +1,201 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.UpdateSqlInjectionMatchSet
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Inserts or deletes SqlInjectionMatchTuple objects (filters) in a
+-- SqlInjectionMatchSet. For each 'SqlInjectionMatchTuple' object, you
+-- specify the following values:
+--
+-- -   'Action': Whether to insert the object into or delete the object
+--     from the array. To change a 'SqlInjectionMatchTuple', you delete the
+--     existing object and add a new one.
+-- -   'FieldToMatch': The part of web requests that you want AWS WAF to
+--     inspect and, if you want AWS WAF to inspect a header, the name of
+--     the header.
+-- -   'TextTransformation': Which text transformation, if any, to perform
+--     on the web request before inspecting the request for snippets of
+--     malicious SQL code.
+--
+-- You use 'SqlInjectionMatchSet' objects to specify which CloudFront
+-- requests you want to allow, block, or count. For example, if you\'re
+-- receiving requests that contain snippets of SQL code in the query string
+-- and you want to block the requests, you can create a
+-- 'SqlInjectionMatchSet' with the applicable settings, and then configure
+-- AWS WAF to block the requests.
+--
+-- To create and configure a 'SqlInjectionMatchSet', perform the following
+-- steps:
+--
+-- 1.  Submit a CreateSqlInjectionMatchSet request.
+-- 2.  Use GetChangeToken to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateIPSet request.
+-- 3.  Submit an 'UpdateSqlInjectionMatchSet' request to specify the parts
+--     of web requests that you want AWS WAF to inspect for snippets of SQL
+--     code.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_UpdateSqlInjectionMatchSet.html AWS API Reference> for UpdateSqlInjectionMatchSet.
+module Network.AWS.WAF.UpdateSqlInjectionMatchSet
+    (
+    -- * Creating a Request
+      updateSqlInjectionMatchSet
+    , UpdateSqlInjectionMatchSet
+    -- * Request Lenses
+    , usimsSqlInjectionMatchSetId
+    , usimsChangeToken
+    , usimsUpdates
+
+    -- * Destructuring the Response
+    , updateSqlInjectionMatchSetResponse
+    , UpdateSqlInjectionMatchSetResponse
+    -- * Response Lenses
+    , usimsrsChangeToken
+    , usimsrsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | A request to update a SqlInjectionMatchSet.
+--
+-- /See:/ 'updateSqlInjectionMatchSet' smart constructor.
+data UpdateSqlInjectionMatchSet = UpdateSqlInjectionMatchSet'
+    { _usimsSqlInjectionMatchSetId :: !Text
+    , _usimsChangeToken            :: !Text
+    , _usimsUpdates                :: ![SqlInjectionMatchSetUpdate]
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateSqlInjectionMatchSet' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'usimsSqlInjectionMatchSetId'
+--
+-- * 'usimsChangeToken'
+--
+-- * 'usimsUpdates'
+updateSqlInjectionMatchSet
+    :: Text -- ^ 'usimsSqlInjectionMatchSetId'
+    -> Text -- ^ 'usimsChangeToken'
+    -> UpdateSqlInjectionMatchSet
+updateSqlInjectionMatchSet pSqlInjectionMatchSetId_ pChangeToken_ =
+    UpdateSqlInjectionMatchSet'
+    { _usimsSqlInjectionMatchSetId = pSqlInjectionMatchSetId_
+    , _usimsChangeToken = pChangeToken_
+    , _usimsUpdates = mempty
+    }
+
+-- | The 'SqlInjectionMatchSetId' of the 'SqlInjectionMatchSet' that you want
+-- to update. 'SqlInjectionMatchSetId' is returned by
+-- CreateSqlInjectionMatchSet and by ListSqlInjectionMatchSets.
+usimsSqlInjectionMatchSetId :: Lens' UpdateSqlInjectionMatchSet Text
+usimsSqlInjectionMatchSetId = lens _usimsSqlInjectionMatchSetId (\ s a -> s{_usimsSqlInjectionMatchSetId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+usimsChangeToken :: Lens' UpdateSqlInjectionMatchSet Text
+usimsChangeToken = lens _usimsChangeToken (\ s a -> s{_usimsChangeToken = a});
+
+-- | An array of 'SqlInjectionMatchSetUpdate' objects that you want to insert
+-- into or delete from a SqlInjectionMatchSet. For more information, see
+-- the applicable data types:
+--
+-- -   SqlInjectionMatchSetUpdate: Contains 'Action' and
+--     'SqlInjectionMatchTuple'
+-- -   SqlInjectionMatchTuple: Contains 'FieldToMatch' and
+--     'TextTransformation'
+-- -   FieldToMatch: Contains 'Data' and 'Type'
+usimsUpdates :: Lens' UpdateSqlInjectionMatchSet [SqlInjectionMatchSetUpdate]
+usimsUpdates = lens _usimsUpdates (\ s a -> s{_usimsUpdates = a}) . _Coerce;
+
+instance AWSRequest UpdateSqlInjectionMatchSet where
+        type Rs UpdateSqlInjectionMatchSet =
+             UpdateSqlInjectionMatchSetResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 UpdateSqlInjectionMatchSetResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders UpdateSqlInjectionMatchSet where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.UpdateSqlInjectionMatchSet" ::
+                       ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON UpdateSqlInjectionMatchSet where
+        toJSON UpdateSqlInjectionMatchSet'{..}
+          = object
+              (catMaybes
+                 [Just
+                    ("SqlInjectionMatchSetId" .=
+                       _usimsSqlInjectionMatchSetId),
+                  Just ("ChangeToken" .= _usimsChangeToken),
+                  Just ("Updates" .= _usimsUpdates)])
+
+instance ToPath UpdateSqlInjectionMatchSet where
+        toPath = const "/"
+
+instance ToQuery UpdateSqlInjectionMatchSet where
+        toQuery = const mempty
+
+-- | The response to an UpdateSqlInjectionMatchSets request.
+--
+-- /See:/ 'updateSqlInjectionMatchSetResponse' smart constructor.
+data UpdateSqlInjectionMatchSetResponse = UpdateSqlInjectionMatchSetResponse'
+    { _usimsrsChangeToken    :: !(Maybe Text)
+    , _usimsrsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateSqlInjectionMatchSetResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'usimsrsChangeToken'
+--
+-- * 'usimsrsResponseStatus'
+updateSqlInjectionMatchSetResponse
+    :: Int -- ^ 'usimsrsResponseStatus'
+    -> UpdateSqlInjectionMatchSetResponse
+updateSqlInjectionMatchSetResponse pResponseStatus_ =
+    UpdateSqlInjectionMatchSetResponse'
+    { _usimsrsChangeToken = Nothing
+    , _usimsrsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the
+-- 'UpdateSqlInjectionMatchSet' request. You can also use this value to
+-- query the status of the request. For more information, see
+-- GetChangeTokenStatus.
+usimsrsChangeToken :: Lens' UpdateSqlInjectionMatchSetResponse (Maybe Text)
+usimsrsChangeToken = lens _usimsrsChangeToken (\ s a -> s{_usimsrsChangeToken = a});
+
+-- | The response status code.
+usimsrsResponseStatus :: Lens' UpdateSqlInjectionMatchSetResponse Int
+usimsrsResponseStatus = lens _usimsrsResponseStatus (\ s a -> s{_usimsrsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/UpdateWebACL.hs b/gen/Network/AWS/WAF/UpdateWebACL.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/UpdateWebACL.hs
@@ -0,0 +1,209 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE TypeFamilies       #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.UpdateWebACL
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Inserts or deletes ActivatedRule objects in a 'WebACL'. Each 'Rule'
+-- identifies web requests that you want to allow, block, or count. When
+-- you update a 'WebACL', you specify the following values:
+--
+-- -   A default action for the 'WebACL', either 'ALLOW' or 'BLOCK'. AWS
+--     WAF performs the default action if a request doesn\'t match the
+--     criteria in any of the 'Rules' in a 'WebACL'.
+-- -   The 'Rules' that you want to add and\/or delete. If you want to
+--     replace one 'Rule' with another, you delete the existing 'Rule' and
+--     add the new one.
+-- -   For each 'Rule', whether you want AWS WAF to allow requests, block
+--     requests, or count requests that match the conditions in the 'Rule'.
+-- -   The order in which you want AWS WAF to evaluate the 'Rules' in a
+--     'WebACL'. If you add more than one 'Rule' to a 'WebACL', AWS WAF
+--     evaluates each request against the 'Rules' in order based on the
+--     value of 'Priority'. (The 'Rule' that has the lowest value for
+--     'Priority' is evaluated first.) When a web request matches all of
+--     the predicates (such as 'ByteMatchSets' and 'IPSets') in a 'Rule',
+--     AWS WAF immediately takes the corresponding action, allow or block,
+--     and doesn\'t evaluate the request against the remaining 'Rules' in
+--     the 'WebACL', if any.
+-- -   The CloudFront distribution that you want to associate with the
+--     'WebACL'.
+--
+-- To create and configure a 'WebACL', perform the following steps:
+--
+-- 1.  Create and update the predicates that you want to include in
+--     'Rules'. For more information, see CreateByteMatchSet,
+--     UpdateByteMatchSet, CreateIPSet, UpdateIPSet,
+--     CreateSqlInjectionMatchSet, and UpdateSqlInjectionMatchSet.
+-- 2.  Create and update the 'Rules' that you want to include in the
+--     'WebACL'. For more information, see CreateRule and UpdateRule.
+-- 3.  Create a 'WebACL'. See CreateWebACL.
+-- 4.  Use 'GetChangeToken' to get the change token that you provide in the
+--     'ChangeToken' parameter of an UpdateWebACL request.
+-- 5.  Submit an 'UpdateWebACL' request to specify the 'Rules' that you
+--     want to include in the 'WebACL', to specify the default action, and
+--     to associate the 'WebACL' with a CloudFront distribution.
+--
+-- For more information about how to use the AWS WAF API to allow or block
+-- HTTP requests, see the
+-- <http://docs.aws.amazon.com/waf/latest/developerguide/ AWS WAF Developer Guide>.
+--
+-- /See:/ <http://docs.aws.amazon.com/waf/latest/APIReference/API_UpdateWebACL.html AWS API Reference> for UpdateWebACL.
+module Network.AWS.WAF.UpdateWebACL
+    (
+    -- * Creating a Request
+      updateWebACL
+    , UpdateWebACL
+    -- * Request Lenses
+    , uwaUpdates
+    , uwaDefaultAction
+    , uwaWebACLId
+    , uwaChangeToken
+
+    -- * Destructuring the Response
+    , updateWebACLResponse
+    , UpdateWebACLResponse
+    -- * Response Lenses
+    , uwarsChangeToken
+    , uwarsResponseStatus
+    ) where
+
+import           Network.AWS.Prelude
+import           Network.AWS.Request
+import           Network.AWS.Response
+import           Network.AWS.WAF.Types
+import           Network.AWS.WAF.Types.Product
+
+-- | /See:/ 'updateWebACL' smart constructor.
+data UpdateWebACL = UpdateWebACL'
+    { _uwaUpdates       :: !(Maybe [WebACLUpdate])
+    , _uwaDefaultAction :: !(Maybe WafAction)
+    , _uwaWebACLId      :: !Text
+    , _uwaChangeToken   :: !Text
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateWebACL' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'uwaUpdates'
+--
+-- * 'uwaDefaultAction'
+--
+-- * 'uwaWebACLId'
+--
+-- * 'uwaChangeToken'
+updateWebACL
+    :: Text -- ^ 'uwaWebACLId'
+    -> Text -- ^ 'uwaChangeToken'
+    -> UpdateWebACL
+updateWebACL pWebACLId_ pChangeToken_ =
+    UpdateWebACL'
+    { _uwaUpdates = Nothing
+    , _uwaDefaultAction = Nothing
+    , _uwaWebACLId = pWebACLId_
+    , _uwaChangeToken = pChangeToken_
+    }
+
+-- | An array of updates to make to the WebACL.
+--
+-- An array of 'WebACLUpdate' objects that you want to insert into or
+-- delete from a WebACL. For more information, see the applicable data
+-- types:
+--
+-- -   WebACLUpdate: Contains 'Action' and 'ActivatedRule'
+-- -   ActivatedRule: Contains 'Action', 'Priority', and 'RuleId'
+-- -   WafAction: Contains 'Type'
+uwaUpdates :: Lens' UpdateWebACL [WebACLUpdate]
+uwaUpdates = lens _uwaUpdates (\ s a -> s{_uwaUpdates = a}) . _Default . _Coerce;
+
+-- | Undocumented member.
+uwaDefaultAction :: Lens' UpdateWebACL (Maybe WafAction)
+uwaDefaultAction = lens _uwaDefaultAction (\ s a -> s{_uwaDefaultAction = a});
+
+-- | The 'WebACLId' of the WebACL that you want to update. 'WebACLId' is
+-- returned by CreateWebACL and by ListWebACLs.
+uwaWebACLId :: Lens' UpdateWebACL Text
+uwaWebACLId = lens _uwaWebACLId (\ s a -> s{_uwaWebACLId = a});
+
+-- | The value returned by the most recent call to GetChangeToken.
+uwaChangeToken :: Lens' UpdateWebACL Text
+uwaChangeToken = lens _uwaChangeToken (\ s a -> s{_uwaChangeToken = a});
+
+instance AWSRequest UpdateWebACL where
+        type Rs UpdateWebACL = UpdateWebACLResponse
+        request = postJSON wAF
+        response
+          = receiveJSON
+              (\ s h x ->
+                 UpdateWebACLResponse' <$>
+                   (x .?> "ChangeToken") <*> (pure (fromEnum s)))
+
+instance ToHeaders UpdateWebACL where
+        toHeaders
+          = const
+              (mconcat
+                 ["X-Amz-Target" =#
+                    ("AWSWAF_20150824.UpdateWebACL" :: ByteString),
+                  "Content-Type" =#
+                    ("application/x-amz-json-1.1" :: ByteString)])
+
+instance ToJSON UpdateWebACL where
+        toJSON UpdateWebACL'{..}
+          = object
+              (catMaybes
+                 [("Updates" .=) <$> _uwaUpdates,
+                  ("DefaultAction" .=) <$> _uwaDefaultAction,
+                  Just ("WebACLId" .= _uwaWebACLId),
+                  Just ("ChangeToken" .= _uwaChangeToken)])
+
+instance ToPath UpdateWebACL where
+        toPath = const "/"
+
+instance ToQuery UpdateWebACL where
+        toQuery = const mempty
+
+-- | /See:/ 'updateWebACLResponse' smart constructor.
+data UpdateWebACLResponse = UpdateWebACLResponse'
+    { _uwarsChangeToken    :: !(Maybe Text)
+    , _uwarsResponseStatus :: !Int
+    } deriving (Eq,Read,Show,Data,Typeable,Generic)
+
+-- | Creates a value of 'UpdateWebACLResponse' with the minimum fields required to make a request.
+--
+-- Use one of the following lenses to modify other fields as desired:
+--
+-- * 'uwarsChangeToken'
+--
+-- * 'uwarsResponseStatus'
+updateWebACLResponse
+    :: Int -- ^ 'uwarsResponseStatus'
+    -> UpdateWebACLResponse
+updateWebACLResponse pResponseStatus_ =
+    UpdateWebACLResponse'
+    { _uwarsChangeToken = Nothing
+    , _uwarsResponseStatus = pResponseStatus_
+    }
+
+-- | The 'ChangeToken' that you used to submit the 'UpdateWebACL' request.
+-- You can also use this value to query the status of the request. For more
+-- information, see GetChangeTokenStatus.
+uwarsChangeToken :: Lens' UpdateWebACLResponse (Maybe Text)
+uwarsChangeToken = lens _uwarsChangeToken (\ s a -> s{_uwarsChangeToken = a});
+
+-- | The response status code.
+uwarsResponseStatus :: Lens' UpdateWebACLResponse Int
+uwarsResponseStatus = lens _uwarsResponseStatus (\ s a -> s{_uwarsResponseStatus = a});
diff --git a/gen/Network/AWS/WAF/Waiters.hs b/gen/Network/AWS/WAF/Waiters.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/WAF/Waiters.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TypeFamilies      #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Network.AWS.WAF.Waiters
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+module Network.AWS.WAF.Waiters where
+
+import           Network.AWS.Prelude
+import           Network.AWS.WAF.Types
+import           Network.AWS.Waiter
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,21 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- |
+-- Module      : Main
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+module Main (main) where
+
+import Test.Tasty
+import Test.AWS.WAF
+import Test.AWS.WAF.Internal
+
+main :: IO ()
+main = defaultMain $ testGroup "WAF"
+    [ testGroup "tests"    tests
+    , testGroup "fixtures" fixtures
+    ]
diff --git a/test/Test/AWS/Gen/WAF.hs b/test/Test/AWS/Gen/WAF.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/AWS/Gen/WAF.hs
@@ -0,0 +1,543 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-orphans        #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Test.AWS.Gen.WAF
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+module Test.AWS.Gen.WAF where
+
+import Data.Proxy
+import Test.AWS.Fixture
+import Test.AWS.Prelude
+import Test.Tasty
+import Network.AWS.WAF
+import Test.AWS.WAF.Internal
+
+-- Auto-generated: the actual test selection needs to be manually placed into
+-- the top-level so that real test data can be incrementally added.
+--
+-- This commented snippet is what the entire set should look like:
+
+-- fixtures :: TestTree
+-- fixtures =
+--     [ testGroup "request"
+--         [ testUpdateRule $
+--             updateRule
+--
+--         , testDeleteRule $
+--             deleteRule
+--
+--         , testCreateIPSet $
+--             createIPSet
+--
+--         , testGetChangeTokenStatus $
+--             getChangeTokenStatus
+--
+--         , testDeleteWebACL $
+--             deleteWebACL
+--
+--         , testUpdateWebACL $
+--             updateWebACL
+--
+--         , testListWebACLs $
+--             listWebACLs
+--
+--         , testListRules $
+--             listRules
+--
+--         , testCreateRule $
+--             createRule
+--
+--         , testCreateWebACL $
+--             createWebACL
+--
+--         , testListByteMatchSets $
+--             listByteMatchSets
+--
+--         , testGetIPSet $
+--             getIPSet
+--
+--         , testGetWebACL $
+--             getWebACL
+--
+--         , testGetRule $
+--             getRule
+--
+--         , testGetChangeToken $
+--             getChangeToken
+--
+--         , testGetSampledRequests $
+--             getSampledRequests
+--
+--         , testGetSqlInjectionMatchSet $
+--             getSqlInjectionMatchSet
+--
+--         , testCreateSqlInjectionMatchSet $
+--             createSqlInjectionMatchSet
+--
+--         , testCreateByteMatchSet $
+--             createByteMatchSet
+--
+--         , testUpdateByteMatchSet $
+--             updateByteMatchSet
+--
+--         , testDeleteByteMatchSet $
+--             deleteByteMatchSet
+--
+--         , testDeleteIPSet $
+--             deleteIPSet
+--
+--         , testUpdateIPSet $
+--             updateIPSet
+--
+--         , testListIPSets $
+--             listIPSets
+--
+--         , testGetByteMatchSet $
+--             getByteMatchSet
+--
+--         , testListSqlInjectionMatchSets $
+--             listSqlInjectionMatchSets
+--
+--         , testDeleteSqlInjectionMatchSet $
+--             deleteSqlInjectionMatchSet
+--
+--         , testUpdateSqlInjectionMatchSet $
+--             updateSqlInjectionMatchSet
+--
+--           ]
+
+--     , testGroup "response"
+--         [ testUpdateRuleResponse $
+--             updateRuleResponse
+--
+--         , testDeleteRuleResponse $
+--             deleteRuleResponse
+--
+--         , testCreateIPSetResponse $
+--             createIPSetResponse
+--
+--         , testGetChangeTokenStatusResponse $
+--             getChangeTokenStatusResponse
+--
+--         , testDeleteWebACLResponse $
+--             deleteWebACLResponse
+--
+--         , testUpdateWebACLResponse $
+--             updateWebACLResponse
+--
+--         , testListWebACLsResponse $
+--             listWebACLsResponse
+--
+--         , testListRulesResponse $
+--             listRulesResponse
+--
+--         , testCreateRuleResponse $
+--             createRuleResponse
+--
+--         , testCreateWebACLResponse $
+--             createWebACLResponse
+--
+--         , testListByteMatchSetsResponse $
+--             listByteMatchSetsResponse
+--
+--         , testGetIPSetResponse $
+--             getIPSetResponse
+--
+--         , testGetWebACLResponse $
+--             getWebACLResponse
+--
+--         , testGetRuleResponse $
+--             getRuleResponse
+--
+--         , testGetChangeTokenResponse $
+--             getChangeTokenResponse
+--
+--         , testGetSampledRequestsResponse $
+--             getSampledRequestsResponse
+--
+--         , testGetSqlInjectionMatchSetResponse $
+--             getSqlInjectionMatchSetResponse
+--
+--         , testCreateSqlInjectionMatchSetResponse $
+--             createSqlInjectionMatchSetResponse
+--
+--         , testCreateByteMatchSetResponse $
+--             createByteMatchSetResponse
+--
+--         , testUpdateByteMatchSetResponse $
+--             updateByteMatchSetResponse
+--
+--         , testDeleteByteMatchSetResponse $
+--             deleteByteMatchSetResponse
+--
+--         , testDeleteIPSetResponse $
+--             deleteIPSetResponse
+--
+--         , testUpdateIPSetResponse $
+--             updateIPSetResponse
+--
+--         , testListIPSetsResponse $
+--             listIPSetsResponse
+--
+--         , testGetByteMatchSetResponse $
+--             getByteMatchSetResponse
+--
+--         , testListSqlInjectionMatchSetsResponse $
+--             listSqlInjectionMatchSetsResponse
+--
+--         , testDeleteSqlInjectionMatchSetResponse $
+--             deleteSqlInjectionMatchSetResponse
+--
+--         , testUpdateSqlInjectionMatchSetResponse $
+--             updateSqlInjectionMatchSetResponse
+--
+--           ]
+--     ]
+
+-- Requests
+
+testUpdateRule :: UpdateRule -> TestTree
+testUpdateRule = req
+    "UpdateRule"
+    "fixture/UpdateRule.yaml"
+
+testDeleteRule :: DeleteRule -> TestTree
+testDeleteRule = req
+    "DeleteRule"
+    "fixture/DeleteRule.yaml"
+
+testCreateIPSet :: CreateIPSet -> TestTree
+testCreateIPSet = req
+    "CreateIPSet"
+    "fixture/CreateIPSet.yaml"
+
+testGetChangeTokenStatus :: GetChangeTokenStatus -> TestTree
+testGetChangeTokenStatus = req
+    "GetChangeTokenStatus"
+    "fixture/GetChangeTokenStatus.yaml"
+
+testDeleteWebACL :: DeleteWebACL -> TestTree
+testDeleteWebACL = req
+    "DeleteWebACL"
+    "fixture/DeleteWebACL.yaml"
+
+testUpdateWebACL :: UpdateWebACL -> TestTree
+testUpdateWebACL = req
+    "UpdateWebACL"
+    "fixture/UpdateWebACL.yaml"
+
+testListWebACLs :: ListWebACLs -> TestTree
+testListWebACLs = req
+    "ListWebACLs"
+    "fixture/ListWebACLs.yaml"
+
+testListRules :: ListRules -> TestTree
+testListRules = req
+    "ListRules"
+    "fixture/ListRules.yaml"
+
+testCreateRule :: CreateRule -> TestTree
+testCreateRule = req
+    "CreateRule"
+    "fixture/CreateRule.yaml"
+
+testCreateWebACL :: CreateWebACL -> TestTree
+testCreateWebACL = req
+    "CreateWebACL"
+    "fixture/CreateWebACL.yaml"
+
+testListByteMatchSets :: ListByteMatchSets -> TestTree
+testListByteMatchSets = req
+    "ListByteMatchSets"
+    "fixture/ListByteMatchSets.yaml"
+
+testGetIPSet :: GetIPSet -> TestTree
+testGetIPSet = req
+    "GetIPSet"
+    "fixture/GetIPSet.yaml"
+
+testGetWebACL :: GetWebACL -> TestTree
+testGetWebACL = req
+    "GetWebACL"
+    "fixture/GetWebACL.yaml"
+
+testGetRule :: GetRule -> TestTree
+testGetRule = req
+    "GetRule"
+    "fixture/GetRule.yaml"
+
+testGetChangeToken :: GetChangeToken -> TestTree
+testGetChangeToken = req
+    "GetChangeToken"
+    "fixture/GetChangeToken.yaml"
+
+testGetSampledRequests :: GetSampledRequests -> TestTree
+testGetSampledRequests = req
+    "GetSampledRequests"
+    "fixture/GetSampledRequests.yaml"
+
+testGetSqlInjectionMatchSet :: GetSqlInjectionMatchSet -> TestTree
+testGetSqlInjectionMatchSet = req
+    "GetSqlInjectionMatchSet"
+    "fixture/GetSqlInjectionMatchSet.yaml"
+
+testCreateSqlInjectionMatchSet :: CreateSqlInjectionMatchSet -> TestTree
+testCreateSqlInjectionMatchSet = req
+    "CreateSqlInjectionMatchSet"
+    "fixture/CreateSqlInjectionMatchSet.yaml"
+
+testCreateByteMatchSet :: CreateByteMatchSet -> TestTree
+testCreateByteMatchSet = req
+    "CreateByteMatchSet"
+    "fixture/CreateByteMatchSet.yaml"
+
+testUpdateByteMatchSet :: UpdateByteMatchSet -> TestTree
+testUpdateByteMatchSet = req
+    "UpdateByteMatchSet"
+    "fixture/UpdateByteMatchSet.yaml"
+
+testDeleteByteMatchSet :: DeleteByteMatchSet -> TestTree
+testDeleteByteMatchSet = req
+    "DeleteByteMatchSet"
+    "fixture/DeleteByteMatchSet.yaml"
+
+testDeleteIPSet :: DeleteIPSet -> TestTree
+testDeleteIPSet = req
+    "DeleteIPSet"
+    "fixture/DeleteIPSet.yaml"
+
+testUpdateIPSet :: UpdateIPSet -> TestTree
+testUpdateIPSet = req
+    "UpdateIPSet"
+    "fixture/UpdateIPSet.yaml"
+
+testListIPSets :: ListIPSets -> TestTree
+testListIPSets = req
+    "ListIPSets"
+    "fixture/ListIPSets.yaml"
+
+testGetByteMatchSet :: GetByteMatchSet -> TestTree
+testGetByteMatchSet = req
+    "GetByteMatchSet"
+    "fixture/GetByteMatchSet.yaml"
+
+testListSqlInjectionMatchSets :: ListSqlInjectionMatchSets -> TestTree
+testListSqlInjectionMatchSets = req
+    "ListSqlInjectionMatchSets"
+    "fixture/ListSqlInjectionMatchSets.yaml"
+
+testDeleteSqlInjectionMatchSet :: DeleteSqlInjectionMatchSet -> TestTree
+testDeleteSqlInjectionMatchSet = req
+    "DeleteSqlInjectionMatchSet"
+    "fixture/DeleteSqlInjectionMatchSet.yaml"
+
+testUpdateSqlInjectionMatchSet :: UpdateSqlInjectionMatchSet -> TestTree
+testUpdateSqlInjectionMatchSet = req
+    "UpdateSqlInjectionMatchSet"
+    "fixture/UpdateSqlInjectionMatchSet.yaml"
+
+-- Responses
+
+testUpdateRuleResponse :: UpdateRuleResponse -> TestTree
+testUpdateRuleResponse = res
+    "UpdateRuleResponse"
+    "fixture/UpdateRuleResponse.proto"
+    wAF
+    (Proxy :: Proxy UpdateRule)
+
+testDeleteRuleResponse :: DeleteRuleResponse -> TestTree
+testDeleteRuleResponse = res
+    "DeleteRuleResponse"
+    "fixture/DeleteRuleResponse.proto"
+    wAF
+    (Proxy :: Proxy DeleteRule)
+
+testCreateIPSetResponse :: CreateIPSetResponse -> TestTree
+testCreateIPSetResponse = res
+    "CreateIPSetResponse"
+    "fixture/CreateIPSetResponse.proto"
+    wAF
+    (Proxy :: Proxy CreateIPSet)
+
+testGetChangeTokenStatusResponse :: GetChangeTokenStatusResponse -> TestTree
+testGetChangeTokenStatusResponse = res
+    "GetChangeTokenStatusResponse"
+    "fixture/GetChangeTokenStatusResponse.proto"
+    wAF
+    (Proxy :: Proxy GetChangeTokenStatus)
+
+testDeleteWebACLResponse :: DeleteWebACLResponse -> TestTree
+testDeleteWebACLResponse = res
+    "DeleteWebACLResponse"
+    "fixture/DeleteWebACLResponse.proto"
+    wAF
+    (Proxy :: Proxy DeleteWebACL)
+
+testUpdateWebACLResponse :: UpdateWebACLResponse -> TestTree
+testUpdateWebACLResponse = res
+    "UpdateWebACLResponse"
+    "fixture/UpdateWebACLResponse.proto"
+    wAF
+    (Proxy :: Proxy UpdateWebACL)
+
+testListWebACLsResponse :: ListWebACLsResponse -> TestTree
+testListWebACLsResponse = res
+    "ListWebACLsResponse"
+    "fixture/ListWebACLsResponse.proto"
+    wAF
+    (Proxy :: Proxy ListWebACLs)
+
+testListRulesResponse :: ListRulesResponse -> TestTree
+testListRulesResponse = res
+    "ListRulesResponse"
+    "fixture/ListRulesResponse.proto"
+    wAF
+    (Proxy :: Proxy ListRules)
+
+testCreateRuleResponse :: CreateRuleResponse -> TestTree
+testCreateRuleResponse = res
+    "CreateRuleResponse"
+    "fixture/CreateRuleResponse.proto"
+    wAF
+    (Proxy :: Proxy CreateRule)
+
+testCreateWebACLResponse :: CreateWebACLResponse -> TestTree
+testCreateWebACLResponse = res
+    "CreateWebACLResponse"
+    "fixture/CreateWebACLResponse.proto"
+    wAF
+    (Proxy :: Proxy CreateWebACL)
+
+testListByteMatchSetsResponse :: ListByteMatchSetsResponse -> TestTree
+testListByteMatchSetsResponse = res
+    "ListByteMatchSetsResponse"
+    "fixture/ListByteMatchSetsResponse.proto"
+    wAF
+    (Proxy :: Proxy ListByteMatchSets)
+
+testGetIPSetResponse :: GetIPSetResponse -> TestTree
+testGetIPSetResponse = res
+    "GetIPSetResponse"
+    "fixture/GetIPSetResponse.proto"
+    wAF
+    (Proxy :: Proxy GetIPSet)
+
+testGetWebACLResponse :: GetWebACLResponse -> TestTree
+testGetWebACLResponse = res
+    "GetWebACLResponse"
+    "fixture/GetWebACLResponse.proto"
+    wAF
+    (Proxy :: Proxy GetWebACL)
+
+testGetRuleResponse :: GetRuleResponse -> TestTree
+testGetRuleResponse = res
+    "GetRuleResponse"
+    "fixture/GetRuleResponse.proto"
+    wAF
+    (Proxy :: Proxy GetRule)
+
+testGetChangeTokenResponse :: GetChangeTokenResponse -> TestTree
+testGetChangeTokenResponse = res
+    "GetChangeTokenResponse"
+    "fixture/GetChangeTokenResponse.proto"
+    wAF
+    (Proxy :: Proxy GetChangeToken)
+
+testGetSampledRequestsResponse :: GetSampledRequestsResponse -> TestTree
+testGetSampledRequestsResponse = res
+    "GetSampledRequestsResponse"
+    "fixture/GetSampledRequestsResponse.proto"
+    wAF
+    (Proxy :: Proxy GetSampledRequests)
+
+testGetSqlInjectionMatchSetResponse :: GetSqlInjectionMatchSetResponse -> TestTree
+testGetSqlInjectionMatchSetResponse = res
+    "GetSqlInjectionMatchSetResponse"
+    "fixture/GetSqlInjectionMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy GetSqlInjectionMatchSet)
+
+testCreateSqlInjectionMatchSetResponse :: CreateSqlInjectionMatchSetResponse -> TestTree
+testCreateSqlInjectionMatchSetResponse = res
+    "CreateSqlInjectionMatchSetResponse"
+    "fixture/CreateSqlInjectionMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy CreateSqlInjectionMatchSet)
+
+testCreateByteMatchSetResponse :: CreateByteMatchSetResponse -> TestTree
+testCreateByteMatchSetResponse = res
+    "CreateByteMatchSetResponse"
+    "fixture/CreateByteMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy CreateByteMatchSet)
+
+testUpdateByteMatchSetResponse :: UpdateByteMatchSetResponse -> TestTree
+testUpdateByteMatchSetResponse = res
+    "UpdateByteMatchSetResponse"
+    "fixture/UpdateByteMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy UpdateByteMatchSet)
+
+testDeleteByteMatchSetResponse :: DeleteByteMatchSetResponse -> TestTree
+testDeleteByteMatchSetResponse = res
+    "DeleteByteMatchSetResponse"
+    "fixture/DeleteByteMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy DeleteByteMatchSet)
+
+testDeleteIPSetResponse :: DeleteIPSetResponse -> TestTree
+testDeleteIPSetResponse = res
+    "DeleteIPSetResponse"
+    "fixture/DeleteIPSetResponse.proto"
+    wAF
+    (Proxy :: Proxy DeleteIPSet)
+
+testUpdateIPSetResponse :: UpdateIPSetResponse -> TestTree
+testUpdateIPSetResponse = res
+    "UpdateIPSetResponse"
+    "fixture/UpdateIPSetResponse.proto"
+    wAF
+    (Proxy :: Proxy UpdateIPSet)
+
+testListIPSetsResponse :: ListIPSetsResponse -> TestTree
+testListIPSetsResponse = res
+    "ListIPSetsResponse"
+    "fixture/ListIPSetsResponse.proto"
+    wAF
+    (Proxy :: Proxy ListIPSets)
+
+testGetByteMatchSetResponse :: GetByteMatchSetResponse -> TestTree
+testGetByteMatchSetResponse = res
+    "GetByteMatchSetResponse"
+    "fixture/GetByteMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy GetByteMatchSet)
+
+testListSqlInjectionMatchSetsResponse :: ListSqlInjectionMatchSetsResponse -> TestTree
+testListSqlInjectionMatchSetsResponse = res
+    "ListSqlInjectionMatchSetsResponse"
+    "fixture/ListSqlInjectionMatchSetsResponse.proto"
+    wAF
+    (Proxy :: Proxy ListSqlInjectionMatchSets)
+
+testDeleteSqlInjectionMatchSetResponse :: DeleteSqlInjectionMatchSetResponse -> TestTree
+testDeleteSqlInjectionMatchSetResponse = res
+    "DeleteSqlInjectionMatchSetResponse"
+    "fixture/DeleteSqlInjectionMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy DeleteSqlInjectionMatchSet)
+
+testUpdateSqlInjectionMatchSetResponse :: UpdateSqlInjectionMatchSetResponse -> TestTree
+testUpdateSqlInjectionMatchSetResponse = res
+    "UpdateSqlInjectionMatchSetResponse"
+    "fixture/UpdateSqlInjectionMatchSetResponse.proto"
+    wAF
+    (Proxy :: Proxy UpdateSqlInjectionMatchSet)
diff --git a/test/Test/AWS/WAF.hs b/test/Test/AWS/WAF.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/AWS/WAF.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Test.AWS.WAF
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- 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 Test.AWS.WAF where
+
+import           Test.AWS.Prelude
+
+tests :: [TestTree]
+tests = []
+
+fixtures :: [TestTree]
+fixtures = []
diff --git a/test/Test/AWS/WAF/Internal.hs b/test/Test/AWS/WAF/Internal.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/AWS/WAF/Internal.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Test.AWS.WAF.Internal
+-- Copyright   : (c) 2013-2015 Brendan Hay
+-- 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 Test.AWS.WAF.Internal where
+
+import           Test.AWS.Prelude
