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,44 @@
+# Amazon Elastic Block Store SDK
+
+* [Version](#version)
+* [Description](#description)
+* [Contribute](#contribute)
+* [Licence](#licence)
+
+
+## Version
+ 
+`2.0` - Derived from API version @2019-11-02@ of the AWS service descriptions, licensed under Apache 2.0.
+
+## Description
+
+Documentation is available via [Hackage](http://hackage.haskell.org/package/amazonka-ebs)
+and the [AWS API Reference](https://aws.amazon.com/documentation/).
+
+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, sending requests,
+and receiving responses.
+
+Lenses are used for constructing and manipulating types,
+due to the depth 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).
+
+See [Amazonka.EBS](http://hackage.haskell.org/package/amazonka-ebs/docs/Amazonka-EBS.html)
+or [the AWS documentation](https://aws.amazon.com/documentation/) to get started.
+
+
+## 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-ebs` 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/amazonka-ebs.cabal b/amazonka-ebs.cabal
new file mode 100644
--- /dev/null
+++ b/amazonka-ebs.cabal
@@ -0,0 +1,95 @@
+cabal-version:      2.2
+name:               amazonka-ebs
+version:            2.0
+synopsis:           Amazon Elastic Block Store SDK.
+homepage:           https://github.com/brendanhay/amazonka
+bug-reports:        https://github.com/brendanhay/amazonka/issues
+license:            MPL-2.0
+license-file:       LICENSE
+author:             Brendan Hay
+maintainer:
+  Brendan Hay <brendan.g.hay+amazonka@gmail.com>, Jack Kelly <jack@jackkelly.name>
+
+copyright:          Copyright (c) 2013-2023 Brendan Hay
+category:           AWS
+build-type:         Simple
+extra-source-files:
+  fixture/*.proto
+  fixture/*.yaml
+  README.md
+  src/.gitkeep
+
+description:
+  Derived from API version @2019-11-02@ of the AWS service descriptions, licensed under Apache 2.0.
+  .
+  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, sending requests, and receiving responses.
+  .
+  It is recommended to use generic lenses or optics from packages such as <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify optional fields and deconstruct responses.
+  .
+  Generated lenses can be found in "Amazonka.EBS.Lens" and are
+  suitable for use with a lens package such as <http://hackage.haskell.org/package/lens lens> or <http://hackage.haskell.org/package/lens-family-core lens-family-core>.
+  .
+  See "Amazonka.EBS" and the <https://aws.amazon.com/documentation/ AWS documentation> to get started.
+
+source-repository head
+  type:     git
+  location: git://github.com/brendanhay/amazonka.git
+  subdir:   amazonka-ebs
+
+library
+  default-language: Haskell2010
+  hs-source-dirs:   src gen
+  ghc-options:
+    -Wall -fwarn-incomplete-uni-patterns
+    -fwarn-incomplete-record-updates -funbox-strict-fields
+
+  exposed-modules:
+    Amazonka.EBS
+    Amazonka.EBS.CompleteSnapshot
+    Amazonka.EBS.GetSnapshotBlock
+    Amazonka.EBS.Lens
+    Amazonka.EBS.ListChangedBlocks
+    Amazonka.EBS.ListSnapshotBlocks
+    Amazonka.EBS.PutSnapshotBlock
+    Amazonka.EBS.StartSnapshot
+    Amazonka.EBS.Types
+    Amazonka.EBS.Types.Block
+    Amazonka.EBS.Types.ChangedBlock
+    Amazonka.EBS.Types.ChecksumAggregationMethod
+    Amazonka.EBS.Types.ChecksumAlgorithm
+    Amazonka.EBS.Types.Status
+    Amazonka.EBS.Types.Tag
+    Amazonka.EBS.Waiters
+
+  build-depends:
+    , amazonka-core  >=2.0  && <2.1
+    , base           >=4.12 && <5
+
+test-suite amazonka-ebs-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.Amazonka.EBS
+    Test.Amazonka.EBS.Internal
+    Test.Amazonka.Gen.EBS
+
+  build-depends:
+    , amazonka-core         >=2.0 && <2.1
+    , amazonka-ebs
+    , amazonka-test         >=2.0 && <2.1
+    , base
+    , bytestring
+    , case-insensitive
+    , tasty
+    , tasty-hunit
+    , text
+    , time
+    , unordered-containers
diff --git a/fixture/CompleteSnapshot.yaml b/fixture/CompleteSnapshot.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CompleteSnapshot.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/ebs/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  ebs.us-east-1.amazonaws.com
+  Content-Type:          application/x-www-form-urlencoded; charset=utf-8
+  X-Amz-Content-SHA256:  abcdef
+  X-Amz-Date:            20091028T223200Z
+body:
+  ''
diff --git a/fixture/CompleteSnapshotResponse.proto b/fixture/CompleteSnapshotResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CompleteSnapshotResponse.proto
diff --git a/fixture/GetSnapshotBlock.yaml b/fixture/GetSnapshotBlock.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetSnapshotBlock.yaml
@@ -0,0 +1,10 @@
+---
+method: GET
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/ebs/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  ebs.us-east-1.amazonaws.com
+  Content-Type:          application/x-www-form-urlencoded; charset=utf-8
+  X-Amz-Content-SHA256:  abcdef
+  X-Amz-Date:            20091028T223200Z
+body:
+  ''
diff --git a/fixture/GetSnapshotBlockResponse.proto b/fixture/GetSnapshotBlockResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetSnapshotBlockResponse.proto
diff --git a/fixture/ListChangedBlocks.yaml b/fixture/ListChangedBlocks.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListChangedBlocks.yaml
@@ -0,0 +1,10 @@
+---
+method: GET
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/ebs/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  ebs.us-east-1.amazonaws.com
+  Content-Type:          application/x-www-form-urlencoded; charset=utf-8
+  X-Amz-Content-SHA256:  abcdef
+  X-Amz-Date:            20091028T223200Z
+body:
+  ''
diff --git a/fixture/ListChangedBlocksResponse.proto b/fixture/ListChangedBlocksResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListChangedBlocksResponse.proto
diff --git a/fixture/ListSnapshotBlocks.yaml b/fixture/ListSnapshotBlocks.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListSnapshotBlocks.yaml
@@ -0,0 +1,10 @@
+---
+method: GET
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/ebs/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  ebs.us-east-1.amazonaws.com
+  Content-Type:          application/x-www-form-urlencoded; charset=utf-8
+  X-Amz-Content-SHA256:  abcdef
+  X-Amz-Date:            20091028T223200Z
+body:
+  ''
diff --git a/fixture/ListSnapshotBlocksResponse.proto b/fixture/ListSnapshotBlocksResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListSnapshotBlocksResponse.proto
diff --git a/fixture/PutSnapshotBlock.yaml b/fixture/PutSnapshotBlock.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/PutSnapshotBlock.yaml
@@ -0,0 +1,10 @@
+---
+method: PUT
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/ebs/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  ebs.us-east-1.amazonaws.com
+  Content-Type:          application/x-www-form-urlencoded; charset=utf-8
+  X-Amz-Content-SHA256:  abcdef
+  X-Amz-Date:            20091028T223200Z
+body:
+  ''
diff --git a/fixture/PutSnapshotBlockResponse.proto b/fixture/PutSnapshotBlockResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/PutSnapshotBlockResponse.proto
diff --git a/fixture/StartSnapshot.yaml b/fixture/StartSnapshot.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/StartSnapshot.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/ebs/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  ebs.us-east-1.amazonaws.com
+  Content-Type:          application/x-www-form-urlencoded; charset=utf-8
+  X-Amz-Content-SHA256:  abcdef
+  X-Amz-Date:            20091028T223200Z
+body:
+  ''
diff --git a/fixture/StartSnapshotResponse.proto b/fixture/StartSnapshotResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/StartSnapshotResponse.proto
diff --git a/gen/Amazonka/EBS.hs b/gen/Amazonka/EBS.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS.hs
@@ -0,0 +1,175 @@
+{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- |
+-- Module      : Amazonka.EBS
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Derived from API version @2019-11-02@ of the AWS service descriptions, licensed under Apache 2.0.
+--
+-- You can use the Amazon Elastic Block Store (Amazon EBS) direct APIs to
+-- create Amazon EBS snapshots, write data directly to your snapshots, read
+-- data on your snapshots, and identify the differences or changes between
+-- two snapshots. If you’re an independent software vendor (ISV) who offers
+-- backup services for Amazon EBS, the EBS direct APIs make it more
+-- efficient and cost-effective to track incremental changes on your Amazon
+-- EBS volumes through snapshots. This can be done without having to create
+-- new volumes from snapshots, and then use Amazon Elastic Compute Cloud
+-- (Amazon EC2) instances to compare the differences.
+--
+-- You can create incremental snapshots directly from data on-premises into
+-- volumes and the cloud to use for quick disaster recovery. With the
+-- ability to write and read snapshots, you can write your on-premises data
+-- to an snapshot during a disaster. Then after recovery, you can restore
+-- it back to Amazon Web Services or on-premises from the snapshot. You no
+-- longer need to build and maintain complex mechanisms to copy data to and
+-- from Amazon EBS.
+--
+-- This API reference provides detailed information about the actions, data
+-- types, parameters, and errors of the EBS direct APIs. For more
+-- information about the elements that make up the EBS direct APIs, and
+-- examples of how to use them effectively, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html Accessing the Contents of an Amazon EBS Snapshot>
+-- in the /Amazon Elastic Compute Cloud User Guide/. For more information
+-- about the supported Amazon Web Services Regions, endpoints, and service
+-- quotas for the EBS direct APIs, see
+-- <https://docs.aws.amazon.com/general/latest/gr/ebs-service.html Amazon Elastic Block Store Endpoints and Quotas>
+-- in the /Amazon Web Services General Reference/.
+module Amazonka.EBS
+  ( -- * Service Configuration
+    defaultService,
+
+    -- * Errors
+    -- $errors
+
+    -- ** AccessDeniedException
+    _AccessDeniedException,
+
+    -- ** ConcurrentLimitExceededException
+    _ConcurrentLimitExceededException,
+
+    -- ** ConflictException
+    _ConflictException,
+
+    -- ** InternalServerException
+    _InternalServerException,
+
+    -- ** RequestThrottledException
+    _RequestThrottledException,
+
+    -- ** ResourceNotFoundException
+    _ResourceNotFoundException,
+
+    -- ** ServiceQuotaExceededException
+    _ServiceQuotaExceededException,
+
+    -- ** ValidationException
+    _ValidationException,
+
+    -- * Waiters
+    -- $waiters
+
+    -- * Operations
+    -- $operations
+
+    -- ** CompleteSnapshot
+    CompleteSnapshot (CompleteSnapshot'),
+    newCompleteSnapshot,
+    CompleteSnapshotResponse (CompleteSnapshotResponse'),
+    newCompleteSnapshotResponse,
+
+    -- ** GetSnapshotBlock
+    GetSnapshotBlock (GetSnapshotBlock'),
+    newGetSnapshotBlock,
+    GetSnapshotBlockResponse (GetSnapshotBlockResponse'),
+    newGetSnapshotBlockResponse,
+
+    -- ** ListChangedBlocks
+    ListChangedBlocks (ListChangedBlocks'),
+    newListChangedBlocks,
+    ListChangedBlocksResponse (ListChangedBlocksResponse'),
+    newListChangedBlocksResponse,
+
+    -- ** ListSnapshotBlocks
+    ListSnapshotBlocks (ListSnapshotBlocks'),
+    newListSnapshotBlocks,
+    ListSnapshotBlocksResponse (ListSnapshotBlocksResponse'),
+    newListSnapshotBlocksResponse,
+
+    -- ** PutSnapshotBlock
+    PutSnapshotBlock (PutSnapshotBlock'),
+    newPutSnapshotBlock,
+    PutSnapshotBlockResponse (PutSnapshotBlockResponse'),
+    newPutSnapshotBlockResponse,
+
+    -- ** StartSnapshot
+    StartSnapshot (StartSnapshot'),
+    newStartSnapshot,
+    StartSnapshotResponse (StartSnapshotResponse'),
+    newStartSnapshotResponse,
+
+    -- * Types
+
+    -- ** ChecksumAggregationMethod
+    ChecksumAggregationMethod (..),
+
+    -- ** ChecksumAlgorithm
+    ChecksumAlgorithm (..),
+
+    -- ** Status
+    Status (..),
+
+    -- ** Block
+    Block (Block'),
+    newBlock,
+
+    -- ** ChangedBlock
+    ChangedBlock (ChangedBlock'),
+    newChangedBlock,
+
+    -- ** Tag
+    Tag (Tag'),
+    newTag,
+  )
+where
+
+import Amazonka.EBS.CompleteSnapshot
+import Amazonka.EBS.GetSnapshotBlock
+import Amazonka.EBS.Lens
+import Amazonka.EBS.ListChangedBlocks
+import Amazonka.EBS.ListSnapshotBlocks
+import Amazonka.EBS.PutSnapshotBlock
+import Amazonka.EBS.StartSnapshot
+import Amazonka.EBS.Types
+import Amazonka.EBS.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 'EBS'.
+
+-- $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/Amazonka/EBS/CompleteSnapshot.hs b/gen/Amazonka/EBS/CompleteSnapshot.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/CompleteSnapshot.hs
@@ -0,0 +1,244 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.CompleteSnapshot
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Seals and completes the snapshot after all of the required blocks of
+-- data have been written to it. Completing the snapshot changes the status
+-- to @completed@. You cannot write new blocks to a snapshot after it has
+-- been completed.
+module Amazonka.EBS.CompleteSnapshot
+  ( -- * Creating a Request
+    CompleteSnapshot (..),
+    newCompleteSnapshot,
+
+    -- * Request Lenses
+    completeSnapshot_checksum,
+    completeSnapshot_checksumAggregationMethod,
+    completeSnapshot_checksumAlgorithm,
+    completeSnapshot_snapshotId,
+    completeSnapshot_changedBlocksCount,
+
+    -- * Destructuring the Response
+    CompleteSnapshotResponse (..),
+    newCompleteSnapshotResponse,
+
+    -- * Response Lenses
+    completeSnapshotResponse_status,
+    completeSnapshotResponse_httpStatus,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import Amazonka.EBS.Types
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+
+-- | /See:/ 'newCompleteSnapshot' smart constructor.
+data CompleteSnapshot = CompleteSnapshot'
+  { -- | An aggregated Base-64 SHA256 checksum based on the checksums of each
+    -- written block.
+    --
+    -- To generate the aggregated checksum using the linear aggregation method,
+    -- arrange the checksums for each written block in ascending order of their
+    -- block index, concatenate them to form a single string, and then generate
+    -- the checksum on the entire string using the SHA256 algorithm.
+    checksum :: Prelude.Maybe Prelude.Text,
+    -- | The aggregation method used to generate the checksum. Currently, the
+    -- only supported aggregation method is @LINEAR@.
+    checksumAggregationMethod :: Prelude.Maybe ChecksumAggregationMethod,
+    -- | The algorithm used to generate the checksum. Currently, the only
+    -- supported algorithm is @SHA256@.
+    checksumAlgorithm :: Prelude.Maybe ChecksumAlgorithm,
+    -- | The ID of the snapshot.
+    snapshotId :: Prelude.Text,
+    -- | The number of blocks that were written to the snapshot.
+    changedBlocksCount :: Prelude.Natural
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CompleteSnapshot' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'checksum', 'completeSnapshot_checksum' - An aggregated Base-64 SHA256 checksum based on the checksums of each
+-- written block.
+--
+-- To generate the aggregated checksum using the linear aggregation method,
+-- arrange the checksums for each written block in ascending order of their
+-- block index, concatenate them to form a single string, and then generate
+-- the checksum on the entire string using the SHA256 algorithm.
+--
+-- 'checksumAggregationMethod', 'completeSnapshot_checksumAggregationMethod' - The aggregation method used to generate the checksum. Currently, the
+-- only supported aggregation method is @LINEAR@.
+--
+-- 'checksumAlgorithm', 'completeSnapshot_checksumAlgorithm' - The algorithm used to generate the checksum. Currently, the only
+-- supported algorithm is @SHA256@.
+--
+-- 'snapshotId', 'completeSnapshot_snapshotId' - The ID of the snapshot.
+--
+-- 'changedBlocksCount', 'completeSnapshot_changedBlocksCount' - The number of blocks that were written to the snapshot.
+newCompleteSnapshot ::
+  -- | 'snapshotId'
+  Prelude.Text ->
+  -- | 'changedBlocksCount'
+  Prelude.Natural ->
+  CompleteSnapshot
+newCompleteSnapshot pSnapshotId_ pChangedBlocksCount_ =
+  CompleteSnapshot'
+    { checksum = Prelude.Nothing,
+      checksumAggregationMethod = Prelude.Nothing,
+      checksumAlgorithm = Prelude.Nothing,
+      snapshotId = pSnapshotId_,
+      changedBlocksCount = pChangedBlocksCount_
+    }
+
+-- | An aggregated Base-64 SHA256 checksum based on the checksums of each
+-- written block.
+--
+-- To generate the aggregated checksum using the linear aggregation method,
+-- arrange the checksums for each written block in ascending order of their
+-- block index, concatenate them to form a single string, and then generate
+-- the checksum on the entire string using the SHA256 algorithm.
+completeSnapshot_checksum :: Lens.Lens' CompleteSnapshot (Prelude.Maybe Prelude.Text)
+completeSnapshot_checksum = Lens.lens (\CompleteSnapshot' {checksum} -> checksum) (\s@CompleteSnapshot' {} a -> s {checksum = a} :: CompleteSnapshot)
+
+-- | The aggregation method used to generate the checksum. Currently, the
+-- only supported aggregation method is @LINEAR@.
+completeSnapshot_checksumAggregationMethod :: Lens.Lens' CompleteSnapshot (Prelude.Maybe ChecksumAggregationMethod)
+completeSnapshot_checksumAggregationMethod = Lens.lens (\CompleteSnapshot' {checksumAggregationMethod} -> checksumAggregationMethod) (\s@CompleteSnapshot' {} a -> s {checksumAggregationMethod = a} :: CompleteSnapshot)
+
+-- | The algorithm used to generate the checksum. Currently, the only
+-- supported algorithm is @SHA256@.
+completeSnapshot_checksumAlgorithm :: Lens.Lens' CompleteSnapshot (Prelude.Maybe ChecksumAlgorithm)
+completeSnapshot_checksumAlgorithm = Lens.lens (\CompleteSnapshot' {checksumAlgorithm} -> checksumAlgorithm) (\s@CompleteSnapshot' {} a -> s {checksumAlgorithm = a} :: CompleteSnapshot)
+
+-- | The ID of the snapshot.
+completeSnapshot_snapshotId :: Lens.Lens' CompleteSnapshot Prelude.Text
+completeSnapshot_snapshotId = Lens.lens (\CompleteSnapshot' {snapshotId} -> snapshotId) (\s@CompleteSnapshot' {} a -> s {snapshotId = a} :: CompleteSnapshot)
+
+-- | The number of blocks that were written to the snapshot.
+completeSnapshot_changedBlocksCount :: Lens.Lens' CompleteSnapshot Prelude.Natural
+completeSnapshot_changedBlocksCount = Lens.lens (\CompleteSnapshot' {changedBlocksCount} -> changedBlocksCount) (\s@CompleteSnapshot' {} a -> s {changedBlocksCount = a} :: CompleteSnapshot)
+
+instance Core.AWSRequest CompleteSnapshot where
+  type
+    AWSResponse CompleteSnapshot =
+      CompleteSnapshotResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          CompleteSnapshotResponse'
+            Prelude.<$> (x Data..?> "Status")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable CompleteSnapshot where
+  hashWithSalt _salt CompleteSnapshot' {..} =
+    _salt
+      `Prelude.hashWithSalt` checksum
+      `Prelude.hashWithSalt` checksumAggregationMethod
+      `Prelude.hashWithSalt` checksumAlgorithm
+      `Prelude.hashWithSalt` snapshotId
+      `Prelude.hashWithSalt` changedBlocksCount
+
+instance Prelude.NFData CompleteSnapshot where
+  rnf CompleteSnapshot' {..} =
+    Prelude.rnf checksum
+      `Prelude.seq` Prelude.rnf checksumAggregationMethod
+      `Prelude.seq` Prelude.rnf checksumAlgorithm
+      `Prelude.seq` Prelude.rnf snapshotId
+      `Prelude.seq` Prelude.rnf changedBlocksCount
+
+instance Data.ToHeaders CompleteSnapshot where
+  toHeaders CompleteSnapshot' {..} =
+    Prelude.mconcat
+      [ "x-amz-Checksum" Data.=# checksum,
+        "x-amz-Checksum-Aggregation-Method"
+          Data.=# checksumAggregationMethod,
+        "x-amz-Checksum-Algorithm" Data.=# checksumAlgorithm,
+        "x-amz-ChangedBlocksCount"
+          Data.=# changedBlocksCount,
+        "Content-Type"
+          Data.=# ("application/x-amz-json-1.1" :: Prelude.ByteString)
+      ]
+
+instance Data.ToJSON CompleteSnapshot where
+  toJSON = Prelude.const (Data.Object Prelude.mempty)
+
+instance Data.ToPath CompleteSnapshot where
+  toPath CompleteSnapshot' {..} =
+    Prelude.mconcat
+      ["/snapshots/completion/", Data.toBS snapshotId]
+
+instance Data.ToQuery CompleteSnapshot where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newCompleteSnapshotResponse' smart constructor.
+data CompleteSnapshotResponse = CompleteSnapshotResponse'
+  { -- | The status of the snapshot.
+    status :: Prelude.Maybe Status,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CompleteSnapshotResponse' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'status', 'completeSnapshotResponse_status' - The status of the snapshot.
+--
+-- 'httpStatus', 'completeSnapshotResponse_httpStatus' - The response's http status code.
+newCompleteSnapshotResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  CompleteSnapshotResponse
+newCompleteSnapshotResponse pHttpStatus_ =
+  CompleteSnapshotResponse'
+    { status = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | The status of the snapshot.
+completeSnapshotResponse_status :: Lens.Lens' CompleteSnapshotResponse (Prelude.Maybe Status)
+completeSnapshotResponse_status = Lens.lens (\CompleteSnapshotResponse' {status} -> status) (\s@CompleteSnapshotResponse' {} a -> s {status = a} :: CompleteSnapshotResponse)
+
+-- | The response's http status code.
+completeSnapshotResponse_httpStatus :: Lens.Lens' CompleteSnapshotResponse Prelude.Int
+completeSnapshotResponse_httpStatus = Lens.lens (\CompleteSnapshotResponse' {httpStatus} -> httpStatus) (\s@CompleteSnapshotResponse' {} a -> s {httpStatus = a} :: CompleteSnapshotResponse)
+
+instance Prelude.NFData CompleteSnapshotResponse where
+  rnf CompleteSnapshotResponse' {..} =
+    Prelude.rnf status
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/EBS/GetSnapshotBlock.hs b/gen/Amazonka/EBS/GetSnapshotBlock.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/GetSnapshotBlock.hs
@@ -0,0 +1,268 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.GetSnapshotBlock
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns the data in a block in an Amazon Elastic Block Store snapshot.
+module Amazonka.EBS.GetSnapshotBlock
+  ( -- * Creating a Request
+    GetSnapshotBlock (..),
+    newGetSnapshotBlock,
+
+    -- * Request Lenses
+    getSnapshotBlock_snapshotId,
+    getSnapshotBlock_blockIndex,
+    getSnapshotBlock_blockToken,
+
+    -- * Destructuring the Response
+    GetSnapshotBlockResponse (..),
+    newGetSnapshotBlockResponse,
+
+    -- * Response Lenses
+    getSnapshotBlockResponse_checksum,
+    getSnapshotBlockResponse_checksumAlgorithm,
+    getSnapshotBlockResponse_dataLength,
+    getSnapshotBlockResponse_httpStatus,
+    getSnapshotBlockResponse_blockData,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import Amazonka.EBS.Types
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+
+-- | /See:/ 'newGetSnapshotBlock' smart constructor.
+data GetSnapshotBlock = GetSnapshotBlock'
+  { -- | The ID of the snapshot containing the block from which to get data.
+    --
+    -- If the specified snapshot is encrypted, you must have permission to use
+    -- the KMS key that was used to encrypt the snapshot. For more information,
+    -- see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    snapshotId :: Prelude.Text,
+    -- | The block index of the block in which to read the data. A block index is
+    -- a logical index in units of @512@ KiB blocks. To identify the block
+    -- index, divide the logical offset of the data in the logical volume by
+    -- the block size (logical offset of data\/@524288@). The logical offset of
+    -- the data must be @512@ KiB aligned.
+    blockIndex :: Prelude.Natural,
+    -- | The block token of the block from which to get data. You can obtain the
+    -- @BlockToken@ by running the @ListChangedBlocks@ or @ListSnapshotBlocks@
+    -- operations.
+    blockToken :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetSnapshotBlock' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'snapshotId', 'getSnapshotBlock_snapshotId' - The ID of the snapshot containing the block from which to get data.
+--
+-- If the specified snapshot is encrypted, you must have permission to use
+-- the KMS key that was used to encrypt the snapshot. For more information,
+-- see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- 'blockIndex', 'getSnapshotBlock_blockIndex' - The block index of the block in which to read the data. A block index is
+-- a logical index in units of @512@ KiB blocks. To identify the block
+-- index, divide the logical offset of the data in the logical volume by
+-- the block size (logical offset of data\/@524288@). The logical offset of
+-- the data must be @512@ KiB aligned.
+--
+-- 'blockToken', 'getSnapshotBlock_blockToken' - The block token of the block from which to get data. You can obtain the
+-- @BlockToken@ by running the @ListChangedBlocks@ or @ListSnapshotBlocks@
+-- operations.
+newGetSnapshotBlock ::
+  -- | 'snapshotId'
+  Prelude.Text ->
+  -- | 'blockIndex'
+  Prelude.Natural ->
+  -- | 'blockToken'
+  Prelude.Text ->
+  GetSnapshotBlock
+newGetSnapshotBlock
+  pSnapshotId_
+  pBlockIndex_
+  pBlockToken_ =
+    GetSnapshotBlock'
+      { snapshotId = pSnapshotId_,
+        blockIndex = pBlockIndex_,
+        blockToken = pBlockToken_
+      }
+
+-- | The ID of the snapshot containing the block from which to get data.
+--
+-- If the specified snapshot is encrypted, you must have permission to use
+-- the KMS key that was used to encrypt the snapshot. For more information,
+-- see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+getSnapshotBlock_snapshotId :: Lens.Lens' GetSnapshotBlock Prelude.Text
+getSnapshotBlock_snapshotId = Lens.lens (\GetSnapshotBlock' {snapshotId} -> snapshotId) (\s@GetSnapshotBlock' {} a -> s {snapshotId = a} :: GetSnapshotBlock)
+
+-- | The block index of the block in which to read the data. A block index is
+-- a logical index in units of @512@ KiB blocks. To identify the block
+-- index, divide the logical offset of the data in the logical volume by
+-- the block size (logical offset of data\/@524288@). The logical offset of
+-- the data must be @512@ KiB aligned.
+getSnapshotBlock_blockIndex :: Lens.Lens' GetSnapshotBlock Prelude.Natural
+getSnapshotBlock_blockIndex = Lens.lens (\GetSnapshotBlock' {blockIndex} -> blockIndex) (\s@GetSnapshotBlock' {} a -> s {blockIndex = a} :: GetSnapshotBlock)
+
+-- | The block token of the block from which to get data. You can obtain the
+-- @BlockToken@ by running the @ListChangedBlocks@ or @ListSnapshotBlocks@
+-- operations.
+getSnapshotBlock_blockToken :: Lens.Lens' GetSnapshotBlock Prelude.Text
+getSnapshotBlock_blockToken = Lens.lens (\GetSnapshotBlock' {blockToken} -> blockToken) (\s@GetSnapshotBlock' {} a -> s {blockToken = a} :: GetSnapshotBlock)
+
+instance Core.AWSRequest GetSnapshotBlock where
+  type
+    AWSResponse GetSnapshotBlock =
+      GetSnapshotBlockResponse
+  request overrides =
+    Request.get (overrides defaultService)
+  response =
+    Response.receiveBody
+      ( \s h x ->
+          GetSnapshotBlockResponse'
+            Prelude.<$> (h Data..#? "x-amz-Checksum")
+            Prelude.<*> (h Data..#? "x-amz-Checksum-Algorithm")
+            Prelude.<*> (h Data..#? "x-amz-Data-Length")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+            Prelude.<*> (Prelude.pure x)
+      )
+
+instance Prelude.Hashable GetSnapshotBlock where
+  hashWithSalt _salt GetSnapshotBlock' {..} =
+    _salt
+      `Prelude.hashWithSalt` snapshotId
+      `Prelude.hashWithSalt` blockIndex
+      `Prelude.hashWithSalt` blockToken
+
+instance Prelude.NFData GetSnapshotBlock where
+  rnf GetSnapshotBlock' {..} =
+    Prelude.rnf snapshotId
+      `Prelude.seq` Prelude.rnf blockIndex
+      `Prelude.seq` Prelude.rnf blockToken
+
+instance Data.ToHeaders GetSnapshotBlock where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath GetSnapshotBlock where
+  toPath GetSnapshotBlock' {..} =
+    Prelude.mconcat
+      [ "/snapshots/",
+        Data.toBS snapshotId,
+        "/blocks/",
+        Data.toBS blockIndex
+      ]
+
+instance Data.ToQuery GetSnapshotBlock where
+  toQuery GetSnapshotBlock' {..} =
+    Prelude.mconcat ["blockToken" Data.=: blockToken]
+
+-- | /See:/ 'newGetSnapshotBlockResponse' smart constructor.
+data GetSnapshotBlockResponse = GetSnapshotBlockResponse'
+  { -- | The checksum generated for the block, which is Base64 encoded.
+    checksum :: Prelude.Maybe Prelude.Text,
+    -- | The algorithm used to generate the checksum for the block, such as
+    -- SHA256.
+    checksumAlgorithm :: Prelude.Maybe ChecksumAlgorithm,
+    -- | The size of the data in the block.
+    dataLength :: Prelude.Maybe Prelude.Int,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int,
+    -- | The data content of the block.
+    blockData :: Data.ResponseBody
+  }
+  deriving (Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetSnapshotBlockResponse' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'checksum', 'getSnapshotBlockResponse_checksum' - The checksum generated for the block, which is Base64 encoded.
+--
+-- 'checksumAlgorithm', 'getSnapshotBlockResponse_checksumAlgorithm' - The algorithm used to generate the checksum for the block, such as
+-- SHA256.
+--
+-- 'dataLength', 'getSnapshotBlockResponse_dataLength' - The size of the data in the block.
+--
+-- 'httpStatus', 'getSnapshotBlockResponse_httpStatus' - The response's http status code.
+--
+-- 'blockData', 'getSnapshotBlockResponse_blockData' - The data content of the block.
+newGetSnapshotBlockResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  -- | 'blockData'
+  Data.ResponseBody ->
+  GetSnapshotBlockResponse
+newGetSnapshotBlockResponse pHttpStatus_ pBlockData_ =
+  GetSnapshotBlockResponse'
+    { checksum =
+        Prelude.Nothing,
+      checksumAlgorithm = Prelude.Nothing,
+      dataLength = Prelude.Nothing,
+      httpStatus = pHttpStatus_,
+      blockData = pBlockData_
+    }
+
+-- | The checksum generated for the block, which is Base64 encoded.
+getSnapshotBlockResponse_checksum :: Lens.Lens' GetSnapshotBlockResponse (Prelude.Maybe Prelude.Text)
+getSnapshotBlockResponse_checksum = Lens.lens (\GetSnapshotBlockResponse' {checksum} -> checksum) (\s@GetSnapshotBlockResponse' {} a -> s {checksum = a} :: GetSnapshotBlockResponse)
+
+-- | The algorithm used to generate the checksum for the block, such as
+-- SHA256.
+getSnapshotBlockResponse_checksumAlgorithm :: Lens.Lens' GetSnapshotBlockResponse (Prelude.Maybe ChecksumAlgorithm)
+getSnapshotBlockResponse_checksumAlgorithm = Lens.lens (\GetSnapshotBlockResponse' {checksumAlgorithm} -> checksumAlgorithm) (\s@GetSnapshotBlockResponse' {} a -> s {checksumAlgorithm = a} :: GetSnapshotBlockResponse)
+
+-- | The size of the data in the block.
+getSnapshotBlockResponse_dataLength :: Lens.Lens' GetSnapshotBlockResponse (Prelude.Maybe Prelude.Int)
+getSnapshotBlockResponse_dataLength = Lens.lens (\GetSnapshotBlockResponse' {dataLength} -> dataLength) (\s@GetSnapshotBlockResponse' {} a -> s {dataLength = a} :: GetSnapshotBlockResponse)
+
+-- | The response's http status code.
+getSnapshotBlockResponse_httpStatus :: Lens.Lens' GetSnapshotBlockResponse Prelude.Int
+getSnapshotBlockResponse_httpStatus = Lens.lens (\GetSnapshotBlockResponse' {httpStatus} -> httpStatus) (\s@GetSnapshotBlockResponse' {} a -> s {httpStatus = a} :: GetSnapshotBlockResponse)
+
+-- | The data content of the block.
+getSnapshotBlockResponse_blockData :: Lens.Lens' GetSnapshotBlockResponse Data.ResponseBody
+getSnapshotBlockResponse_blockData = Lens.lens (\GetSnapshotBlockResponse' {blockData} -> blockData) (\s@GetSnapshotBlockResponse' {} a -> s {blockData = a} :: GetSnapshotBlockResponse)
diff --git a/gen/Amazonka/EBS/Lens.hs b/gen/Amazonka/EBS/Lens.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Lens.hs
@@ -0,0 +1,119 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Lens
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Lens
+  ( -- * Operations
+
+    -- ** CompleteSnapshot
+    completeSnapshot_checksum,
+    completeSnapshot_checksumAggregationMethod,
+    completeSnapshot_checksumAlgorithm,
+    completeSnapshot_snapshotId,
+    completeSnapshot_changedBlocksCount,
+    completeSnapshotResponse_status,
+    completeSnapshotResponse_httpStatus,
+
+    -- ** GetSnapshotBlock
+    getSnapshotBlock_snapshotId,
+    getSnapshotBlock_blockIndex,
+    getSnapshotBlock_blockToken,
+    getSnapshotBlockResponse_checksum,
+    getSnapshotBlockResponse_checksumAlgorithm,
+    getSnapshotBlockResponse_dataLength,
+    getSnapshotBlockResponse_httpStatus,
+    getSnapshotBlockResponse_blockData,
+
+    -- ** ListChangedBlocks
+    listChangedBlocks_firstSnapshotId,
+    listChangedBlocks_maxResults,
+    listChangedBlocks_nextToken,
+    listChangedBlocks_startingBlockIndex,
+    listChangedBlocks_secondSnapshotId,
+    listChangedBlocksResponse_blockSize,
+    listChangedBlocksResponse_changedBlocks,
+    listChangedBlocksResponse_expiryTime,
+    listChangedBlocksResponse_nextToken,
+    listChangedBlocksResponse_volumeSize,
+    listChangedBlocksResponse_httpStatus,
+
+    -- ** ListSnapshotBlocks
+    listSnapshotBlocks_maxResults,
+    listSnapshotBlocks_nextToken,
+    listSnapshotBlocks_startingBlockIndex,
+    listSnapshotBlocks_snapshotId,
+    listSnapshotBlocksResponse_blockSize,
+    listSnapshotBlocksResponse_blocks,
+    listSnapshotBlocksResponse_expiryTime,
+    listSnapshotBlocksResponse_nextToken,
+    listSnapshotBlocksResponse_volumeSize,
+    listSnapshotBlocksResponse_httpStatus,
+
+    -- ** PutSnapshotBlock
+    putSnapshotBlock_progress,
+    putSnapshotBlock_snapshotId,
+    putSnapshotBlock_blockIndex,
+    putSnapshotBlock_dataLength,
+    putSnapshotBlock_checksum,
+    putSnapshotBlock_checksumAlgorithm,
+    putSnapshotBlock_blockData,
+    putSnapshotBlockResponse_checksum,
+    putSnapshotBlockResponse_checksumAlgorithm,
+    putSnapshotBlockResponse_httpStatus,
+
+    -- ** StartSnapshot
+    startSnapshot_clientToken,
+    startSnapshot_description,
+    startSnapshot_encrypted,
+    startSnapshot_kmsKeyArn,
+    startSnapshot_parentSnapshotId,
+    startSnapshot_tags,
+    startSnapshot_timeout,
+    startSnapshot_volumeSize,
+    startSnapshotResponse_blockSize,
+    startSnapshotResponse_description,
+    startSnapshotResponse_kmsKeyArn,
+    startSnapshotResponse_ownerId,
+    startSnapshotResponse_parentSnapshotId,
+    startSnapshotResponse_snapshotId,
+    startSnapshotResponse_startTime,
+    startSnapshotResponse_status,
+    startSnapshotResponse_tags,
+    startSnapshotResponse_volumeSize,
+    startSnapshotResponse_httpStatus,
+
+    -- * Types
+
+    -- ** Block
+    block_blockIndex,
+    block_blockToken,
+
+    -- ** ChangedBlock
+    changedBlock_blockIndex,
+    changedBlock_firstBlockToken,
+    changedBlock_secondBlockToken,
+
+    -- ** Tag
+    tag_key,
+    tag_value,
+  )
+where
+
+import Amazonka.EBS.CompleteSnapshot
+import Amazonka.EBS.GetSnapshotBlock
+import Amazonka.EBS.ListChangedBlocks
+import Amazonka.EBS.ListSnapshotBlocks
+import Amazonka.EBS.PutSnapshotBlock
+import Amazonka.EBS.StartSnapshot
+import Amazonka.EBS.Types.Block
+import Amazonka.EBS.Types.ChangedBlock
+import Amazonka.EBS.Types.Tag
diff --git a/gen/Amazonka/EBS/ListChangedBlocks.hs b/gen/Amazonka/EBS/ListChangedBlocks.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/ListChangedBlocks.hs
@@ -0,0 +1,337 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.ListChangedBlocks
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns information about the blocks that are different between two
+-- Amazon Elastic Block Store snapshots of the same volume\/snapshot
+-- lineage.
+module Amazonka.EBS.ListChangedBlocks
+  ( -- * Creating a Request
+    ListChangedBlocks (..),
+    newListChangedBlocks,
+
+    -- * Request Lenses
+    listChangedBlocks_firstSnapshotId,
+    listChangedBlocks_maxResults,
+    listChangedBlocks_nextToken,
+    listChangedBlocks_startingBlockIndex,
+    listChangedBlocks_secondSnapshotId,
+
+    -- * Destructuring the Response
+    ListChangedBlocksResponse (..),
+    newListChangedBlocksResponse,
+
+    -- * Response Lenses
+    listChangedBlocksResponse_blockSize,
+    listChangedBlocksResponse_changedBlocks,
+    listChangedBlocksResponse_expiryTime,
+    listChangedBlocksResponse_nextToken,
+    listChangedBlocksResponse_volumeSize,
+    listChangedBlocksResponse_httpStatus,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import Amazonka.EBS.Types
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+
+-- | /See:/ 'newListChangedBlocks' smart constructor.
+data ListChangedBlocks = ListChangedBlocks'
+  { -- | The ID of the first snapshot to use for the comparison.
+    --
+    -- The @FirstSnapshotID@ parameter must be specified with a
+    -- @SecondSnapshotId@ parameter; otherwise, an error occurs.
+    firstSnapshotId :: Prelude.Maybe Prelude.Text,
+    -- | The maximum number of blocks to be returned by the request.
+    --
+    -- Even if additional blocks can be retrieved from the snapshot, the
+    -- request can return less blocks than __MaxResults__ or an empty array of
+    -- blocks.
+    --
+    -- To retrieve the next set of blocks from the snapshot, make another
+    -- request with the returned __NextToken__ value. The value of
+    -- __NextToken__ is @null@ when there are no more blocks to return.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | The token to request the next page of results.
+    --
+    -- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The block index from which the comparison should start.
+    --
+    -- The list in the response will start from this block index or the next
+    -- valid block index in the snapshots.
+    --
+    -- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+    startingBlockIndex :: Prelude.Maybe Prelude.Natural,
+    -- | The ID of the second snapshot to use for the comparison.
+    --
+    -- The @SecondSnapshotId@ parameter must be specified with a
+    -- @FirstSnapshotID@ parameter; otherwise, an error occurs.
+    secondSnapshotId :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListChangedBlocks' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'firstSnapshotId', 'listChangedBlocks_firstSnapshotId' - The ID of the first snapshot to use for the comparison.
+--
+-- The @FirstSnapshotID@ parameter must be specified with a
+-- @SecondSnapshotId@ parameter; otherwise, an error occurs.
+--
+-- 'maxResults', 'listChangedBlocks_maxResults' - The maximum number of blocks to be returned by the request.
+--
+-- Even if additional blocks can be retrieved from the snapshot, the
+-- request can return less blocks than __MaxResults__ or an empty array of
+-- blocks.
+--
+-- To retrieve the next set of blocks from the snapshot, make another
+-- request with the returned __NextToken__ value. The value of
+-- __NextToken__ is @null@ when there are no more blocks to return.
+--
+-- 'nextToken', 'listChangedBlocks_nextToken' - The token to request the next page of results.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+--
+-- 'startingBlockIndex', 'listChangedBlocks_startingBlockIndex' - The block index from which the comparison should start.
+--
+-- The list in the response will start from this block index or the next
+-- valid block index in the snapshots.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+--
+-- 'secondSnapshotId', 'listChangedBlocks_secondSnapshotId' - The ID of the second snapshot to use for the comparison.
+--
+-- The @SecondSnapshotId@ parameter must be specified with a
+-- @FirstSnapshotID@ parameter; otherwise, an error occurs.
+newListChangedBlocks ::
+  -- | 'secondSnapshotId'
+  Prelude.Text ->
+  ListChangedBlocks
+newListChangedBlocks pSecondSnapshotId_ =
+  ListChangedBlocks'
+    { firstSnapshotId =
+        Prelude.Nothing,
+      maxResults = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      startingBlockIndex = Prelude.Nothing,
+      secondSnapshotId = pSecondSnapshotId_
+    }
+
+-- | The ID of the first snapshot to use for the comparison.
+--
+-- The @FirstSnapshotID@ parameter must be specified with a
+-- @SecondSnapshotId@ parameter; otherwise, an error occurs.
+listChangedBlocks_firstSnapshotId :: Lens.Lens' ListChangedBlocks (Prelude.Maybe Prelude.Text)
+listChangedBlocks_firstSnapshotId = Lens.lens (\ListChangedBlocks' {firstSnapshotId} -> firstSnapshotId) (\s@ListChangedBlocks' {} a -> s {firstSnapshotId = a} :: ListChangedBlocks)
+
+-- | The maximum number of blocks to be returned by the request.
+--
+-- Even if additional blocks can be retrieved from the snapshot, the
+-- request can return less blocks than __MaxResults__ or an empty array of
+-- blocks.
+--
+-- To retrieve the next set of blocks from the snapshot, make another
+-- request with the returned __NextToken__ value. The value of
+-- __NextToken__ is @null@ when there are no more blocks to return.
+listChangedBlocks_maxResults :: Lens.Lens' ListChangedBlocks (Prelude.Maybe Prelude.Natural)
+listChangedBlocks_maxResults = Lens.lens (\ListChangedBlocks' {maxResults} -> maxResults) (\s@ListChangedBlocks' {} a -> s {maxResults = a} :: ListChangedBlocks)
+
+-- | The token to request the next page of results.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+listChangedBlocks_nextToken :: Lens.Lens' ListChangedBlocks (Prelude.Maybe Prelude.Text)
+listChangedBlocks_nextToken = Lens.lens (\ListChangedBlocks' {nextToken} -> nextToken) (\s@ListChangedBlocks' {} a -> s {nextToken = a} :: ListChangedBlocks)
+
+-- | The block index from which the comparison should start.
+--
+-- The list in the response will start from this block index or the next
+-- valid block index in the snapshots.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+listChangedBlocks_startingBlockIndex :: Lens.Lens' ListChangedBlocks (Prelude.Maybe Prelude.Natural)
+listChangedBlocks_startingBlockIndex = Lens.lens (\ListChangedBlocks' {startingBlockIndex} -> startingBlockIndex) (\s@ListChangedBlocks' {} a -> s {startingBlockIndex = a} :: ListChangedBlocks)
+
+-- | The ID of the second snapshot to use for the comparison.
+--
+-- The @SecondSnapshotId@ parameter must be specified with a
+-- @FirstSnapshotID@ parameter; otherwise, an error occurs.
+listChangedBlocks_secondSnapshotId :: Lens.Lens' ListChangedBlocks Prelude.Text
+listChangedBlocks_secondSnapshotId = Lens.lens (\ListChangedBlocks' {secondSnapshotId} -> secondSnapshotId) (\s@ListChangedBlocks' {} a -> s {secondSnapshotId = a} :: ListChangedBlocks)
+
+instance Core.AWSRequest ListChangedBlocks where
+  type
+    AWSResponse ListChangedBlocks =
+      ListChangedBlocksResponse
+  request overrides =
+    Request.get (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          ListChangedBlocksResponse'
+            Prelude.<$> (x Data..?> "BlockSize")
+            Prelude.<*> (x Data..?> "ChangedBlocks" Core..!@ Prelude.mempty)
+            Prelude.<*> (x Data..?> "ExpiryTime")
+            Prelude.<*> (x Data..?> "NextToken")
+            Prelude.<*> (x Data..?> "VolumeSize")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable ListChangedBlocks where
+  hashWithSalt _salt ListChangedBlocks' {..} =
+    _salt
+      `Prelude.hashWithSalt` firstSnapshotId
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` nextToken
+      `Prelude.hashWithSalt` startingBlockIndex
+      `Prelude.hashWithSalt` secondSnapshotId
+
+instance Prelude.NFData ListChangedBlocks where
+  rnf ListChangedBlocks' {..} =
+    Prelude.rnf firstSnapshotId
+      `Prelude.seq` Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf startingBlockIndex
+      `Prelude.seq` Prelude.rnf secondSnapshotId
+
+instance Data.ToHeaders ListChangedBlocks where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath ListChangedBlocks where
+  toPath ListChangedBlocks' {..} =
+    Prelude.mconcat
+      [ "/snapshots/",
+        Data.toBS secondSnapshotId,
+        "/changedblocks"
+      ]
+
+instance Data.ToQuery ListChangedBlocks where
+  toQuery ListChangedBlocks' {..} =
+    Prelude.mconcat
+      [ "firstSnapshotId" Data.=: firstSnapshotId,
+        "maxResults" Data.=: maxResults,
+        "pageToken" Data.=: nextToken,
+        "startingBlockIndex" Data.=: startingBlockIndex
+      ]
+
+-- | /See:/ 'newListChangedBlocksResponse' smart constructor.
+data ListChangedBlocksResponse = ListChangedBlocksResponse'
+  { -- | The size of the blocks in the snapshot, in bytes.
+    blockSize :: Prelude.Maybe Prelude.Int,
+    -- | An array of objects containing information about the changed blocks.
+    changedBlocks :: Prelude.Maybe [Data.Sensitive ChangedBlock],
+    -- | The time when the @BlockToken@ expires.
+    expiryTime :: Prelude.Maybe Data.POSIX,
+    -- | The token to use to retrieve the next page of results. This value is
+    -- null when there are no more results to return.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The size of the volume in GB.
+    volumeSize :: Prelude.Maybe Prelude.Natural,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListChangedBlocksResponse' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'blockSize', 'listChangedBlocksResponse_blockSize' - The size of the blocks in the snapshot, in bytes.
+--
+-- 'changedBlocks', 'listChangedBlocksResponse_changedBlocks' - An array of objects containing information about the changed blocks.
+--
+-- 'expiryTime', 'listChangedBlocksResponse_expiryTime' - The time when the @BlockToken@ expires.
+--
+-- 'nextToken', 'listChangedBlocksResponse_nextToken' - The token to use to retrieve the next page of results. This value is
+-- null when there are no more results to return.
+--
+-- 'volumeSize', 'listChangedBlocksResponse_volumeSize' - The size of the volume in GB.
+--
+-- 'httpStatus', 'listChangedBlocksResponse_httpStatus' - The response's http status code.
+newListChangedBlocksResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  ListChangedBlocksResponse
+newListChangedBlocksResponse pHttpStatus_ =
+  ListChangedBlocksResponse'
+    { blockSize =
+        Prelude.Nothing,
+      changedBlocks = Prelude.Nothing,
+      expiryTime = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      volumeSize = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | The size of the blocks in the snapshot, in bytes.
+listChangedBlocksResponse_blockSize :: Lens.Lens' ListChangedBlocksResponse (Prelude.Maybe Prelude.Int)
+listChangedBlocksResponse_blockSize = Lens.lens (\ListChangedBlocksResponse' {blockSize} -> blockSize) (\s@ListChangedBlocksResponse' {} a -> s {blockSize = a} :: ListChangedBlocksResponse)
+
+-- | An array of objects containing information about the changed blocks.
+listChangedBlocksResponse_changedBlocks :: Lens.Lens' ListChangedBlocksResponse (Prelude.Maybe [ChangedBlock])
+listChangedBlocksResponse_changedBlocks = Lens.lens (\ListChangedBlocksResponse' {changedBlocks} -> changedBlocks) (\s@ListChangedBlocksResponse' {} a -> s {changedBlocks = a} :: ListChangedBlocksResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | The time when the @BlockToken@ expires.
+listChangedBlocksResponse_expiryTime :: Lens.Lens' ListChangedBlocksResponse (Prelude.Maybe Prelude.UTCTime)
+listChangedBlocksResponse_expiryTime = Lens.lens (\ListChangedBlocksResponse' {expiryTime} -> expiryTime) (\s@ListChangedBlocksResponse' {} a -> s {expiryTime = a} :: ListChangedBlocksResponse) Prelude.. Lens.mapping Data._Time
+
+-- | The token to use to retrieve the next page of results. This value is
+-- null when there are no more results to return.
+listChangedBlocksResponse_nextToken :: Lens.Lens' ListChangedBlocksResponse (Prelude.Maybe Prelude.Text)
+listChangedBlocksResponse_nextToken = Lens.lens (\ListChangedBlocksResponse' {nextToken} -> nextToken) (\s@ListChangedBlocksResponse' {} a -> s {nextToken = a} :: ListChangedBlocksResponse)
+
+-- | The size of the volume in GB.
+listChangedBlocksResponse_volumeSize :: Lens.Lens' ListChangedBlocksResponse (Prelude.Maybe Prelude.Natural)
+listChangedBlocksResponse_volumeSize = Lens.lens (\ListChangedBlocksResponse' {volumeSize} -> volumeSize) (\s@ListChangedBlocksResponse' {} a -> s {volumeSize = a} :: ListChangedBlocksResponse)
+
+-- | The response's http status code.
+listChangedBlocksResponse_httpStatus :: Lens.Lens' ListChangedBlocksResponse Prelude.Int
+listChangedBlocksResponse_httpStatus = Lens.lens (\ListChangedBlocksResponse' {httpStatus} -> httpStatus) (\s@ListChangedBlocksResponse' {} a -> s {httpStatus = a} :: ListChangedBlocksResponse)
+
+instance Prelude.NFData ListChangedBlocksResponse where
+  rnf ListChangedBlocksResponse' {..} =
+    Prelude.rnf blockSize
+      `Prelude.seq` Prelude.rnf changedBlocks
+      `Prelude.seq` Prelude.rnf expiryTime
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf volumeSize
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/EBS/ListSnapshotBlocks.hs b/gen/Amazonka/EBS/ListSnapshotBlocks.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/ListSnapshotBlocks.hs
@@ -0,0 +1,298 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.ListSnapshotBlocks
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Returns information about the blocks in an Amazon Elastic Block Store
+-- snapshot.
+module Amazonka.EBS.ListSnapshotBlocks
+  ( -- * Creating a Request
+    ListSnapshotBlocks (..),
+    newListSnapshotBlocks,
+
+    -- * Request Lenses
+    listSnapshotBlocks_maxResults,
+    listSnapshotBlocks_nextToken,
+    listSnapshotBlocks_startingBlockIndex,
+    listSnapshotBlocks_snapshotId,
+
+    -- * Destructuring the Response
+    ListSnapshotBlocksResponse (..),
+    newListSnapshotBlocksResponse,
+
+    -- * Response Lenses
+    listSnapshotBlocksResponse_blockSize,
+    listSnapshotBlocksResponse_blocks,
+    listSnapshotBlocksResponse_expiryTime,
+    listSnapshotBlocksResponse_nextToken,
+    listSnapshotBlocksResponse_volumeSize,
+    listSnapshotBlocksResponse_httpStatus,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import Amazonka.EBS.Types
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+
+-- | /See:/ 'newListSnapshotBlocks' smart constructor.
+data ListSnapshotBlocks = ListSnapshotBlocks'
+  { -- | The maximum number of blocks to be returned by the request.
+    --
+    -- Even if additional blocks can be retrieved from the snapshot, the
+    -- request can return less blocks than __MaxResults__ or an empty array of
+    -- blocks.
+    --
+    -- To retrieve the next set of blocks from the snapshot, make another
+    -- request with the returned __NextToken__ value. The value of
+    -- __NextToken__ is @null@ when there are no more blocks to return.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | The token to request the next page of results.
+    --
+    -- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The block index from which the list should start. The list in the
+    -- response will start from this block index or the next valid block index
+    -- in the snapshot.
+    --
+    -- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+    startingBlockIndex :: Prelude.Maybe Prelude.Natural,
+    -- | The ID of the snapshot from which to get block indexes and block tokens.
+    snapshotId :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListSnapshotBlocks' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'maxResults', 'listSnapshotBlocks_maxResults' - The maximum number of blocks to be returned by the request.
+--
+-- Even if additional blocks can be retrieved from the snapshot, the
+-- request can return less blocks than __MaxResults__ or an empty array of
+-- blocks.
+--
+-- To retrieve the next set of blocks from the snapshot, make another
+-- request with the returned __NextToken__ value. The value of
+-- __NextToken__ is @null@ when there are no more blocks to return.
+--
+-- 'nextToken', 'listSnapshotBlocks_nextToken' - The token to request the next page of results.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+--
+-- 'startingBlockIndex', 'listSnapshotBlocks_startingBlockIndex' - The block index from which the list should start. The list in the
+-- response will start from this block index or the next valid block index
+-- in the snapshot.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+--
+-- 'snapshotId', 'listSnapshotBlocks_snapshotId' - The ID of the snapshot from which to get block indexes and block tokens.
+newListSnapshotBlocks ::
+  -- | 'snapshotId'
+  Prelude.Text ->
+  ListSnapshotBlocks
+newListSnapshotBlocks pSnapshotId_ =
+  ListSnapshotBlocks'
+    { maxResults = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      startingBlockIndex = Prelude.Nothing,
+      snapshotId = pSnapshotId_
+    }
+
+-- | The maximum number of blocks to be returned by the request.
+--
+-- Even if additional blocks can be retrieved from the snapshot, the
+-- request can return less blocks than __MaxResults__ or an empty array of
+-- blocks.
+--
+-- To retrieve the next set of blocks from the snapshot, make another
+-- request with the returned __NextToken__ value. The value of
+-- __NextToken__ is @null@ when there are no more blocks to return.
+listSnapshotBlocks_maxResults :: Lens.Lens' ListSnapshotBlocks (Prelude.Maybe Prelude.Natural)
+listSnapshotBlocks_maxResults = Lens.lens (\ListSnapshotBlocks' {maxResults} -> maxResults) (\s@ListSnapshotBlocks' {} a -> s {maxResults = a} :: ListSnapshotBlocks)
+
+-- | The token to request the next page of results.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+listSnapshotBlocks_nextToken :: Lens.Lens' ListSnapshotBlocks (Prelude.Maybe Prelude.Text)
+listSnapshotBlocks_nextToken = Lens.lens (\ListSnapshotBlocks' {nextToken} -> nextToken) (\s@ListSnapshotBlocks' {} a -> s {nextToken = a} :: ListSnapshotBlocks)
+
+-- | The block index from which the list should start. The list in the
+-- response will start from this block index or the next valid block index
+-- in the snapshot.
+--
+-- If you specify __NextToken__, then __StartingBlockIndex__ is ignored.
+listSnapshotBlocks_startingBlockIndex :: Lens.Lens' ListSnapshotBlocks (Prelude.Maybe Prelude.Natural)
+listSnapshotBlocks_startingBlockIndex = Lens.lens (\ListSnapshotBlocks' {startingBlockIndex} -> startingBlockIndex) (\s@ListSnapshotBlocks' {} a -> s {startingBlockIndex = a} :: ListSnapshotBlocks)
+
+-- | The ID of the snapshot from which to get block indexes and block tokens.
+listSnapshotBlocks_snapshotId :: Lens.Lens' ListSnapshotBlocks Prelude.Text
+listSnapshotBlocks_snapshotId = Lens.lens (\ListSnapshotBlocks' {snapshotId} -> snapshotId) (\s@ListSnapshotBlocks' {} a -> s {snapshotId = a} :: ListSnapshotBlocks)
+
+instance Core.AWSRequest ListSnapshotBlocks where
+  type
+    AWSResponse ListSnapshotBlocks =
+      ListSnapshotBlocksResponse
+  request overrides =
+    Request.get (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          ListSnapshotBlocksResponse'
+            Prelude.<$> (x Data..?> "BlockSize")
+            Prelude.<*> (x Data..?> "Blocks" Core..!@ Prelude.mempty)
+            Prelude.<*> (x Data..?> "ExpiryTime")
+            Prelude.<*> (x Data..?> "NextToken")
+            Prelude.<*> (x Data..?> "VolumeSize")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable ListSnapshotBlocks where
+  hashWithSalt _salt ListSnapshotBlocks' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` nextToken
+      `Prelude.hashWithSalt` startingBlockIndex
+      `Prelude.hashWithSalt` snapshotId
+
+instance Prelude.NFData ListSnapshotBlocks where
+  rnf ListSnapshotBlocks' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf startingBlockIndex
+      `Prelude.seq` Prelude.rnf snapshotId
+
+instance Data.ToHeaders ListSnapshotBlocks where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath ListSnapshotBlocks where
+  toPath ListSnapshotBlocks' {..} =
+    Prelude.mconcat
+      ["/snapshots/", Data.toBS snapshotId, "/blocks"]
+
+instance Data.ToQuery ListSnapshotBlocks where
+  toQuery ListSnapshotBlocks' {..} =
+    Prelude.mconcat
+      [ "maxResults" Data.=: maxResults,
+        "pageToken" Data.=: nextToken,
+        "startingBlockIndex" Data.=: startingBlockIndex
+      ]
+
+-- | /See:/ 'newListSnapshotBlocksResponse' smart constructor.
+data ListSnapshotBlocksResponse = ListSnapshotBlocksResponse'
+  { -- | The size of the blocks in the snapshot, in bytes.
+    blockSize :: Prelude.Maybe Prelude.Int,
+    -- | An array of objects containing information about the blocks.
+    blocks :: Prelude.Maybe (Data.Sensitive [Block]),
+    -- | The time when the @BlockToken@ expires.
+    expiryTime :: Prelude.Maybe Data.POSIX,
+    -- | The token to use to retrieve the next page of results. This value is
+    -- null when there are no more results to return.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The size of the volume in GB.
+    volumeSize :: Prelude.Maybe Prelude.Natural,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListSnapshotBlocksResponse' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'blockSize', 'listSnapshotBlocksResponse_blockSize' - The size of the blocks in the snapshot, in bytes.
+--
+-- 'blocks', 'listSnapshotBlocksResponse_blocks' - An array of objects containing information about the blocks.
+--
+-- 'expiryTime', 'listSnapshotBlocksResponse_expiryTime' - The time when the @BlockToken@ expires.
+--
+-- 'nextToken', 'listSnapshotBlocksResponse_nextToken' - The token to use to retrieve the next page of results. This value is
+-- null when there are no more results to return.
+--
+-- 'volumeSize', 'listSnapshotBlocksResponse_volumeSize' - The size of the volume in GB.
+--
+-- 'httpStatus', 'listSnapshotBlocksResponse_httpStatus' - The response's http status code.
+newListSnapshotBlocksResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  ListSnapshotBlocksResponse
+newListSnapshotBlocksResponse pHttpStatus_ =
+  ListSnapshotBlocksResponse'
+    { blockSize =
+        Prelude.Nothing,
+      blocks = Prelude.Nothing,
+      expiryTime = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      volumeSize = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | The size of the blocks in the snapshot, in bytes.
+listSnapshotBlocksResponse_blockSize :: Lens.Lens' ListSnapshotBlocksResponse (Prelude.Maybe Prelude.Int)
+listSnapshotBlocksResponse_blockSize = Lens.lens (\ListSnapshotBlocksResponse' {blockSize} -> blockSize) (\s@ListSnapshotBlocksResponse' {} a -> s {blockSize = a} :: ListSnapshotBlocksResponse)
+
+-- | An array of objects containing information about the blocks.
+listSnapshotBlocksResponse_blocks :: Lens.Lens' ListSnapshotBlocksResponse (Prelude.Maybe [Block])
+listSnapshotBlocksResponse_blocks = Lens.lens (\ListSnapshotBlocksResponse' {blocks} -> blocks) (\s@ListSnapshotBlocksResponse' {} a -> s {blocks = a} :: ListSnapshotBlocksResponse) Prelude.. Lens.mapping (Data._Sensitive Prelude.. Lens.coerced)
+
+-- | The time when the @BlockToken@ expires.
+listSnapshotBlocksResponse_expiryTime :: Lens.Lens' ListSnapshotBlocksResponse (Prelude.Maybe Prelude.UTCTime)
+listSnapshotBlocksResponse_expiryTime = Lens.lens (\ListSnapshotBlocksResponse' {expiryTime} -> expiryTime) (\s@ListSnapshotBlocksResponse' {} a -> s {expiryTime = a} :: ListSnapshotBlocksResponse) Prelude.. Lens.mapping Data._Time
+
+-- | The token to use to retrieve the next page of results. This value is
+-- null when there are no more results to return.
+listSnapshotBlocksResponse_nextToken :: Lens.Lens' ListSnapshotBlocksResponse (Prelude.Maybe Prelude.Text)
+listSnapshotBlocksResponse_nextToken = Lens.lens (\ListSnapshotBlocksResponse' {nextToken} -> nextToken) (\s@ListSnapshotBlocksResponse' {} a -> s {nextToken = a} :: ListSnapshotBlocksResponse)
+
+-- | The size of the volume in GB.
+listSnapshotBlocksResponse_volumeSize :: Lens.Lens' ListSnapshotBlocksResponse (Prelude.Maybe Prelude.Natural)
+listSnapshotBlocksResponse_volumeSize = Lens.lens (\ListSnapshotBlocksResponse' {volumeSize} -> volumeSize) (\s@ListSnapshotBlocksResponse' {} a -> s {volumeSize = a} :: ListSnapshotBlocksResponse)
+
+-- | The response's http status code.
+listSnapshotBlocksResponse_httpStatus :: Lens.Lens' ListSnapshotBlocksResponse Prelude.Int
+listSnapshotBlocksResponse_httpStatus = Lens.lens (\ListSnapshotBlocksResponse' {httpStatus} -> httpStatus) (\s@ListSnapshotBlocksResponse' {} a -> s {httpStatus = a} :: ListSnapshotBlocksResponse)
+
+instance Prelude.NFData ListSnapshotBlocksResponse where
+  rnf ListSnapshotBlocksResponse' {..} =
+    Prelude.rnf blockSize
+      `Prelude.seq` Prelude.rnf blocks
+      `Prelude.seq` Prelude.rnf expiryTime
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf volumeSize
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/EBS/PutSnapshotBlock.hs b/gen/Amazonka/EBS/PutSnapshotBlock.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/PutSnapshotBlock.hs
@@ -0,0 +1,334 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.PutSnapshotBlock
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Writes a block of data to a snapshot. If the specified block contains
+-- data, the existing data is overwritten. The target snapshot must be in
+-- the @pending@ state.
+--
+-- Data written to a snapshot must be aligned with 512-KiB sectors.
+module Amazonka.EBS.PutSnapshotBlock
+  ( -- * Creating a Request
+    PutSnapshotBlock (..),
+    newPutSnapshotBlock,
+
+    -- * Request Lenses
+    putSnapshotBlock_progress,
+    putSnapshotBlock_snapshotId,
+    putSnapshotBlock_blockIndex,
+    putSnapshotBlock_dataLength,
+    putSnapshotBlock_checksum,
+    putSnapshotBlock_checksumAlgorithm,
+    putSnapshotBlock_blockData,
+
+    -- * Destructuring the Response
+    PutSnapshotBlockResponse (..),
+    newPutSnapshotBlockResponse,
+
+    -- * Response Lenses
+    putSnapshotBlockResponse_checksum,
+    putSnapshotBlockResponse_checksumAlgorithm,
+    putSnapshotBlockResponse_httpStatus,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import Amazonka.EBS.Types
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+
+-- | /See:/ 'newPutSnapshotBlock' smart constructor.
+data PutSnapshotBlock = PutSnapshotBlock'
+  { -- | The progress of the write process, as a percentage.
+    progress :: Prelude.Maybe Prelude.Natural,
+    -- | The ID of the snapshot.
+    --
+    -- If the specified snapshot is encrypted, you must have permission to use
+    -- the KMS key that was used to encrypt the snapshot. For more information,
+    -- see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+    -- in the /Amazon Elastic Compute Cloud User Guide/..
+    snapshotId :: Prelude.Text,
+    -- | The block index of the block in which to write the data. A block index
+    -- is a logical index in units of @512@ KiB blocks. To identify the block
+    -- index, divide the logical offset of the data in the logical volume by
+    -- the block size (logical offset of data\/@524288@). The logical offset of
+    -- the data must be @512@ KiB aligned.
+    blockIndex :: Prelude.Natural,
+    -- | The size of the data to write to the block, in bytes. Currently, the
+    -- only supported size is @524288@ bytes.
+    --
+    -- Valid values: @524288@
+    dataLength :: Prelude.Int,
+    -- | A Base64-encoded SHA256 checksum of the data. Only SHA256 checksums are
+    -- supported.
+    checksum :: Prelude.Text,
+    -- | The algorithm used to generate the checksum. Currently, the only
+    -- supported algorithm is @SHA256@.
+    checksumAlgorithm :: ChecksumAlgorithm,
+    -- | The data to write to the block.
+    --
+    -- The block data is not signed as part of the Signature Version 4 signing
+    -- process. As a result, you must generate and provide a Base64-encoded
+    -- SHA256 checksum for the block data using the __x-amz-Checksum__ header.
+    -- Also, you must specify the checksum algorithm using the
+    -- __x-amz-Checksum-Algorithm__ header. The checksum that you provide is
+    -- part of the Signature Version 4 signing process. It is validated against
+    -- a checksum generated by Amazon EBS to ensure the validity and
+    -- authenticity of the data. If the checksums do not correspond, the
+    -- request fails. For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html#ebsapis-using-checksums Using checksums with the EBS direct APIs>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    blockData :: Data.HashedBody
+  }
+  deriving (Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'PutSnapshotBlock' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'progress', 'putSnapshotBlock_progress' - The progress of the write process, as a percentage.
+--
+-- 'snapshotId', 'putSnapshotBlock_snapshotId' - The ID of the snapshot.
+--
+-- If the specified snapshot is encrypted, you must have permission to use
+-- the KMS key that was used to encrypt the snapshot. For more information,
+-- see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/..
+--
+-- 'blockIndex', 'putSnapshotBlock_blockIndex' - The block index of the block in which to write the data. A block index
+-- is a logical index in units of @512@ KiB blocks. To identify the block
+-- index, divide the logical offset of the data in the logical volume by
+-- the block size (logical offset of data\/@524288@). The logical offset of
+-- the data must be @512@ KiB aligned.
+--
+-- 'dataLength', 'putSnapshotBlock_dataLength' - The size of the data to write to the block, in bytes. Currently, the
+-- only supported size is @524288@ bytes.
+--
+-- Valid values: @524288@
+--
+-- 'checksum', 'putSnapshotBlock_checksum' - A Base64-encoded SHA256 checksum of the data. Only SHA256 checksums are
+-- supported.
+--
+-- 'checksumAlgorithm', 'putSnapshotBlock_checksumAlgorithm' - The algorithm used to generate the checksum. Currently, the only
+-- supported algorithm is @SHA256@.
+--
+-- 'blockData', 'putSnapshotBlock_blockData' - The data to write to the block.
+--
+-- The block data is not signed as part of the Signature Version 4 signing
+-- process. As a result, you must generate and provide a Base64-encoded
+-- SHA256 checksum for the block data using the __x-amz-Checksum__ header.
+-- Also, you must specify the checksum algorithm using the
+-- __x-amz-Checksum-Algorithm__ header. The checksum that you provide is
+-- part of the Signature Version 4 signing process. It is validated against
+-- a checksum generated by Amazon EBS to ensure the validity and
+-- authenticity of the data. If the checksums do not correspond, the
+-- request fails. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html#ebsapis-using-checksums Using checksums with the EBS direct APIs>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+newPutSnapshotBlock ::
+  -- | 'snapshotId'
+  Prelude.Text ->
+  -- | 'blockIndex'
+  Prelude.Natural ->
+  -- | 'dataLength'
+  Prelude.Int ->
+  -- | 'checksum'
+  Prelude.Text ->
+  -- | 'checksumAlgorithm'
+  ChecksumAlgorithm ->
+  -- | 'blockData'
+  Data.HashedBody ->
+  PutSnapshotBlock
+newPutSnapshotBlock
+  pSnapshotId_
+  pBlockIndex_
+  pDataLength_
+  pChecksum_
+  pChecksumAlgorithm_
+  pBlockData_ =
+    PutSnapshotBlock'
+      { progress = Prelude.Nothing,
+        snapshotId = pSnapshotId_,
+        blockIndex = pBlockIndex_,
+        dataLength = pDataLength_,
+        checksum = pChecksum_,
+        checksumAlgorithm = pChecksumAlgorithm_,
+        blockData = pBlockData_
+      }
+
+-- | The progress of the write process, as a percentage.
+putSnapshotBlock_progress :: Lens.Lens' PutSnapshotBlock (Prelude.Maybe Prelude.Natural)
+putSnapshotBlock_progress = Lens.lens (\PutSnapshotBlock' {progress} -> progress) (\s@PutSnapshotBlock' {} a -> s {progress = a} :: PutSnapshotBlock)
+
+-- | The ID of the snapshot.
+--
+-- If the specified snapshot is encrypted, you must have permission to use
+-- the KMS key that was used to encrypt the snapshot. For more information,
+-- see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/..
+putSnapshotBlock_snapshotId :: Lens.Lens' PutSnapshotBlock Prelude.Text
+putSnapshotBlock_snapshotId = Lens.lens (\PutSnapshotBlock' {snapshotId} -> snapshotId) (\s@PutSnapshotBlock' {} a -> s {snapshotId = a} :: PutSnapshotBlock)
+
+-- | The block index of the block in which to write the data. A block index
+-- is a logical index in units of @512@ KiB blocks. To identify the block
+-- index, divide the logical offset of the data in the logical volume by
+-- the block size (logical offset of data\/@524288@). The logical offset of
+-- the data must be @512@ KiB aligned.
+putSnapshotBlock_blockIndex :: Lens.Lens' PutSnapshotBlock Prelude.Natural
+putSnapshotBlock_blockIndex = Lens.lens (\PutSnapshotBlock' {blockIndex} -> blockIndex) (\s@PutSnapshotBlock' {} a -> s {blockIndex = a} :: PutSnapshotBlock)
+
+-- | The size of the data to write to the block, in bytes. Currently, the
+-- only supported size is @524288@ bytes.
+--
+-- Valid values: @524288@
+putSnapshotBlock_dataLength :: Lens.Lens' PutSnapshotBlock Prelude.Int
+putSnapshotBlock_dataLength = Lens.lens (\PutSnapshotBlock' {dataLength} -> dataLength) (\s@PutSnapshotBlock' {} a -> s {dataLength = a} :: PutSnapshotBlock)
+
+-- | A Base64-encoded SHA256 checksum of the data. Only SHA256 checksums are
+-- supported.
+putSnapshotBlock_checksum :: Lens.Lens' PutSnapshotBlock Prelude.Text
+putSnapshotBlock_checksum = Lens.lens (\PutSnapshotBlock' {checksum} -> checksum) (\s@PutSnapshotBlock' {} a -> s {checksum = a} :: PutSnapshotBlock)
+
+-- | The algorithm used to generate the checksum. Currently, the only
+-- supported algorithm is @SHA256@.
+putSnapshotBlock_checksumAlgorithm :: Lens.Lens' PutSnapshotBlock ChecksumAlgorithm
+putSnapshotBlock_checksumAlgorithm = Lens.lens (\PutSnapshotBlock' {checksumAlgorithm} -> checksumAlgorithm) (\s@PutSnapshotBlock' {} a -> s {checksumAlgorithm = a} :: PutSnapshotBlock)
+
+-- | The data to write to the block.
+--
+-- The block data is not signed as part of the Signature Version 4 signing
+-- process. As a result, you must generate and provide a Base64-encoded
+-- SHA256 checksum for the block data using the __x-amz-Checksum__ header.
+-- Also, you must specify the checksum algorithm using the
+-- __x-amz-Checksum-Algorithm__ header. The checksum that you provide is
+-- part of the Signature Version 4 signing process. It is validated against
+-- a checksum generated by Amazon EBS to ensure the validity and
+-- authenticity of the data. If the checksums do not correspond, the
+-- request fails. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html#ebsapis-using-checksums Using checksums with the EBS direct APIs>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+putSnapshotBlock_blockData :: Lens.Lens' PutSnapshotBlock Data.HashedBody
+putSnapshotBlock_blockData = Lens.lens (\PutSnapshotBlock' {blockData} -> blockData) (\s@PutSnapshotBlock' {} a -> s {blockData = a} :: PutSnapshotBlock)
+
+instance Core.AWSRequest PutSnapshotBlock where
+  type
+    AWSResponse PutSnapshotBlock =
+      PutSnapshotBlockResponse
+  request overrides =
+    Request.putBody (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          PutSnapshotBlockResponse'
+            Prelude.<$> (h Data..#? "x-amz-Checksum")
+            Prelude.<*> (h Data..#? "x-amz-Checksum-Algorithm")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Data.ToBody PutSnapshotBlock where
+  toBody PutSnapshotBlock' {..} = Data.toBody blockData
+
+instance Data.ToHeaders PutSnapshotBlock where
+  toHeaders PutSnapshotBlock' {..} =
+    Prelude.mconcat
+      [ "x-amz-Progress" Data.=# progress,
+        "x-amz-Data-Length" Data.=# dataLength,
+        "x-amz-Checksum" Data.=# checksum,
+        "x-amz-Checksum-Algorithm" Data.=# checksumAlgorithm,
+        "Content-Type"
+          Data.=# ("application/x-amz-json-1.1" :: Prelude.ByteString)
+      ]
+
+instance Data.ToPath PutSnapshotBlock where
+  toPath PutSnapshotBlock' {..} =
+    Prelude.mconcat
+      [ "/snapshots/",
+        Data.toBS snapshotId,
+        "/blocks/",
+        Data.toBS blockIndex
+      ]
+
+instance Data.ToQuery PutSnapshotBlock where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newPutSnapshotBlockResponse' smart constructor.
+data PutSnapshotBlockResponse = PutSnapshotBlockResponse'
+  { -- | The SHA256 checksum generated for the block data by Amazon EBS.
+    checksum :: Prelude.Maybe Prelude.Text,
+    -- | The algorithm used by Amazon EBS to generate the checksum.
+    checksumAlgorithm :: Prelude.Maybe ChecksumAlgorithm,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'PutSnapshotBlockResponse' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'checksum', 'putSnapshotBlockResponse_checksum' - The SHA256 checksum generated for the block data by Amazon EBS.
+--
+-- 'checksumAlgorithm', 'putSnapshotBlockResponse_checksumAlgorithm' - The algorithm used by Amazon EBS to generate the checksum.
+--
+-- 'httpStatus', 'putSnapshotBlockResponse_httpStatus' - The response's http status code.
+newPutSnapshotBlockResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  PutSnapshotBlockResponse
+newPutSnapshotBlockResponse pHttpStatus_ =
+  PutSnapshotBlockResponse'
+    { checksum =
+        Prelude.Nothing,
+      checksumAlgorithm = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | The SHA256 checksum generated for the block data by Amazon EBS.
+putSnapshotBlockResponse_checksum :: Lens.Lens' PutSnapshotBlockResponse (Prelude.Maybe Prelude.Text)
+putSnapshotBlockResponse_checksum = Lens.lens (\PutSnapshotBlockResponse' {checksum} -> checksum) (\s@PutSnapshotBlockResponse' {} a -> s {checksum = a} :: PutSnapshotBlockResponse)
+
+-- | The algorithm used by Amazon EBS to generate the checksum.
+putSnapshotBlockResponse_checksumAlgorithm :: Lens.Lens' PutSnapshotBlockResponse (Prelude.Maybe ChecksumAlgorithm)
+putSnapshotBlockResponse_checksumAlgorithm = Lens.lens (\PutSnapshotBlockResponse' {checksumAlgorithm} -> checksumAlgorithm) (\s@PutSnapshotBlockResponse' {} a -> s {checksumAlgorithm = a} :: PutSnapshotBlockResponse)
+
+-- | The response's http status code.
+putSnapshotBlockResponse_httpStatus :: Lens.Lens' PutSnapshotBlockResponse Prelude.Int
+putSnapshotBlockResponse_httpStatus = Lens.lens (\PutSnapshotBlockResponse' {httpStatus} -> httpStatus) (\s@PutSnapshotBlockResponse' {} a -> s {httpStatus = a} :: PutSnapshotBlockResponse)
+
+instance Prelude.NFData PutSnapshotBlockResponse where
+  rnf PutSnapshotBlockResponse' {..} =
+    Prelude.rnf checksum
+      `Prelude.seq` Prelude.rnf checksumAlgorithm
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/EBS/StartSnapshot.hs b/gen/Amazonka/EBS/StartSnapshot.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/StartSnapshot.hs
@@ -0,0 +1,598 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.StartSnapshot
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Creates a new Amazon EBS snapshot. The new snapshot enters the @pending@
+-- state after the request completes.
+--
+-- After creating the snapshot, use
+-- <https://docs.aws.amazon.com/ebs/latest/APIReference/API_PutSnapshotBlock.html PutSnapshotBlock>
+-- to write blocks of data to the snapshot.
+module Amazonka.EBS.StartSnapshot
+  ( -- * Creating a Request
+    StartSnapshot (..),
+    newStartSnapshot,
+
+    -- * Request Lenses
+    startSnapshot_clientToken,
+    startSnapshot_description,
+    startSnapshot_encrypted,
+    startSnapshot_kmsKeyArn,
+    startSnapshot_parentSnapshotId,
+    startSnapshot_tags,
+    startSnapshot_timeout,
+    startSnapshot_volumeSize,
+
+    -- * Destructuring the Response
+    StartSnapshotResponse (..),
+    newStartSnapshotResponse,
+
+    -- * Response Lenses
+    startSnapshotResponse_blockSize,
+    startSnapshotResponse_description,
+    startSnapshotResponse_kmsKeyArn,
+    startSnapshotResponse_ownerId,
+    startSnapshotResponse_parentSnapshotId,
+    startSnapshotResponse_snapshotId,
+    startSnapshotResponse_startTime,
+    startSnapshotResponse_status,
+    startSnapshotResponse_tags,
+    startSnapshotResponse_volumeSize,
+    startSnapshotResponse_httpStatus,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import Amazonka.EBS.Types
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+
+-- | /See:/ 'newStartSnapshot' smart constructor.
+data StartSnapshot = StartSnapshot'
+  { -- | A unique, case-sensitive identifier that you provide to ensure the
+    -- idempotency of the request. Idempotency ensures that an API request
+    -- completes only once. With an idempotent request, if the original request
+    -- completes successfully. The subsequent retries with the same client
+    -- token return the result from the original successful request and they
+    -- have no additional effect.
+    --
+    -- If you do not specify a client token, one is automatically generated by
+    -- the Amazon Web Services SDK.
+    --
+    -- For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-direct-api-idempotency.html Idempotency for StartSnapshot API>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    clientToken :: Prelude.Maybe Prelude.Text,
+    -- | A description for the snapshot.
+    description :: Prelude.Maybe Prelude.Text,
+    -- | Indicates whether to encrypt the snapshot.
+    --
+    -- You can\'t specify __Encrypted__ and __ParentSnapshotId__ in the same
+    -- request. If you specify both parameters, the request fails with
+    -- @ValidationException@.
+    --
+    -- The encryption status of the snapshot depends on the values that you
+    -- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+    -- whether your Amazon Web Services account is enabled for
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+    -- For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    --
+    -- To create an encrypted snapshot, you must have permission to use the KMS
+    -- key. For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    encrypted :: Prelude.Maybe Prelude.Bool,
+    -- | The Amazon Resource Name (ARN) of the Key Management Service (KMS) key
+    -- to be used to encrypt the snapshot.
+    --
+    -- The encryption status of the snapshot depends on the values that you
+    -- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+    -- whether your Amazon Web Services account is enabled for
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+    -- For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    --
+    -- To create an encrypted snapshot, you must have permission to use the KMS
+    -- key. For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    kmsKeyArn :: Prelude.Maybe (Data.Sensitive Prelude.Text),
+    -- | The ID of the parent snapshot. If there is no parent snapshot, or if you
+    -- are creating the first snapshot for an on-premises volume, omit this
+    -- parameter.
+    --
+    -- You can\'t specify __ParentSnapshotId__ and __Encrypted__ in the same
+    -- request. If you specify both parameters, the request fails with
+    -- @ValidationException@.
+    --
+    -- The encryption status of the snapshot depends on the values that you
+    -- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+    -- whether your Amazon Web Services account is enabled for
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+    -- For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    --
+    -- If you specify an encrypted parent snapshot, you must have permission to
+    -- use the KMS key that was used to encrypt the parent snapshot. For more
+    -- information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    parentSnapshotId :: Prelude.Maybe Prelude.Text,
+    -- | The tags to apply to the snapshot.
+    tags :: Prelude.Maybe [Tag],
+    -- | The amount of time (in minutes) after which the snapshot is
+    -- automatically cancelled if:
+    --
+    -- -   No blocks are written to the snapshot.
+    --
+    -- -   The snapshot is not completed after writing the last block of data.
+    --
+    -- If no value is specified, the timeout defaults to @60@ minutes.
+    timeout :: Prelude.Maybe Prelude.Natural,
+    -- | The size of the volume, in GiB. The maximum size is @65536@ GiB (64
+    -- TiB).
+    volumeSize :: Prelude.Natural
+  }
+  deriving (Prelude.Eq, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'StartSnapshot' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'clientToken', 'startSnapshot_clientToken' - A unique, case-sensitive identifier that you provide to ensure the
+-- idempotency of the request. Idempotency ensures that an API request
+-- completes only once. With an idempotent request, if the original request
+-- completes successfully. The subsequent retries with the same client
+-- token return the result from the original successful request and they
+-- have no additional effect.
+--
+-- If you do not specify a client token, one is automatically generated by
+-- the Amazon Web Services SDK.
+--
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-direct-api-idempotency.html Idempotency for StartSnapshot API>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- 'description', 'startSnapshot_description' - A description for the snapshot.
+--
+-- 'encrypted', 'startSnapshot_encrypted' - Indicates whether to encrypt the snapshot.
+--
+-- You can\'t specify __Encrypted__ and __ParentSnapshotId__ in the same
+-- request. If you specify both parameters, the request fails with
+-- @ValidationException@.
+--
+-- The encryption status of the snapshot depends on the values that you
+-- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+-- whether your Amazon Web Services account is enabled for
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- To create an encrypted snapshot, you must have permission to use the KMS
+-- key. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- 'kmsKeyArn', 'startSnapshot_kmsKeyArn' - The Amazon Resource Name (ARN) of the Key Management Service (KMS) key
+-- to be used to encrypt the snapshot.
+--
+-- The encryption status of the snapshot depends on the values that you
+-- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+-- whether your Amazon Web Services account is enabled for
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- To create an encrypted snapshot, you must have permission to use the KMS
+-- key. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- 'parentSnapshotId', 'startSnapshot_parentSnapshotId' - The ID of the parent snapshot. If there is no parent snapshot, or if you
+-- are creating the first snapshot for an on-premises volume, omit this
+-- parameter.
+--
+-- You can\'t specify __ParentSnapshotId__ and __Encrypted__ in the same
+-- request. If you specify both parameters, the request fails with
+-- @ValidationException@.
+--
+-- The encryption status of the snapshot depends on the values that you
+-- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+-- whether your Amazon Web Services account is enabled for
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- If you specify an encrypted parent snapshot, you must have permission to
+-- use the KMS key that was used to encrypt the parent snapshot. For more
+-- information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- 'tags', 'startSnapshot_tags' - The tags to apply to the snapshot.
+--
+-- 'timeout', 'startSnapshot_timeout' - The amount of time (in minutes) after which the snapshot is
+-- automatically cancelled if:
+--
+-- -   No blocks are written to the snapshot.
+--
+-- -   The snapshot is not completed after writing the last block of data.
+--
+-- If no value is specified, the timeout defaults to @60@ minutes.
+--
+-- 'volumeSize', 'startSnapshot_volumeSize' - The size of the volume, in GiB. The maximum size is @65536@ GiB (64
+-- TiB).
+newStartSnapshot ::
+  -- | 'volumeSize'
+  Prelude.Natural ->
+  StartSnapshot
+newStartSnapshot pVolumeSize_ =
+  StartSnapshot'
+    { clientToken = Prelude.Nothing,
+      description = Prelude.Nothing,
+      encrypted = Prelude.Nothing,
+      kmsKeyArn = Prelude.Nothing,
+      parentSnapshotId = Prelude.Nothing,
+      tags = Prelude.Nothing,
+      timeout = Prelude.Nothing,
+      volumeSize = pVolumeSize_
+    }
+
+-- | A unique, case-sensitive identifier that you provide to ensure the
+-- idempotency of the request. Idempotency ensures that an API request
+-- completes only once. With an idempotent request, if the original request
+-- completes successfully. The subsequent retries with the same client
+-- token return the result from the original successful request and they
+-- have no additional effect.
+--
+-- If you do not specify a client token, one is automatically generated by
+-- the Amazon Web Services SDK.
+--
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-direct-api-idempotency.html Idempotency for StartSnapshot API>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+startSnapshot_clientToken :: Lens.Lens' StartSnapshot (Prelude.Maybe Prelude.Text)
+startSnapshot_clientToken = Lens.lens (\StartSnapshot' {clientToken} -> clientToken) (\s@StartSnapshot' {} a -> s {clientToken = a} :: StartSnapshot)
+
+-- | A description for the snapshot.
+startSnapshot_description :: Lens.Lens' StartSnapshot (Prelude.Maybe Prelude.Text)
+startSnapshot_description = Lens.lens (\StartSnapshot' {description} -> description) (\s@StartSnapshot' {} a -> s {description = a} :: StartSnapshot)
+
+-- | Indicates whether to encrypt the snapshot.
+--
+-- You can\'t specify __Encrypted__ and __ParentSnapshotId__ in the same
+-- request. If you specify both parameters, the request fails with
+-- @ValidationException@.
+--
+-- The encryption status of the snapshot depends on the values that you
+-- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+-- whether your Amazon Web Services account is enabled for
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- To create an encrypted snapshot, you must have permission to use the KMS
+-- key. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+startSnapshot_encrypted :: Lens.Lens' StartSnapshot (Prelude.Maybe Prelude.Bool)
+startSnapshot_encrypted = Lens.lens (\StartSnapshot' {encrypted} -> encrypted) (\s@StartSnapshot' {} a -> s {encrypted = a} :: StartSnapshot)
+
+-- | The Amazon Resource Name (ARN) of the Key Management Service (KMS) key
+-- to be used to encrypt the snapshot.
+--
+-- The encryption status of the snapshot depends on the values that you
+-- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+-- whether your Amazon Web Services account is enabled for
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- To create an encrypted snapshot, you must have permission to use the KMS
+-- key. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+startSnapshot_kmsKeyArn :: Lens.Lens' StartSnapshot (Prelude.Maybe Prelude.Text)
+startSnapshot_kmsKeyArn = Lens.lens (\StartSnapshot' {kmsKeyArn} -> kmsKeyArn) (\s@StartSnapshot' {} a -> s {kmsKeyArn = a} :: StartSnapshot) Prelude.. Lens.mapping Data._Sensitive
+
+-- | The ID of the parent snapshot. If there is no parent snapshot, or if you
+-- are creating the first snapshot for an on-premises volume, omit this
+-- parameter.
+--
+-- You can\'t specify __ParentSnapshotId__ and __Encrypted__ in the same
+-- request. If you specify both parameters, the request fails with
+-- @ValidationException@.
+--
+-- The encryption status of the snapshot depends on the values that you
+-- specify for __Encrypted__, __KmsKeyArn__, and __ParentSnapshotId__, and
+-- whether your Amazon Web Services account is enabled for
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default encryption by default>.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapis-using-encryption.html Using encryption>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- If you specify an encrypted parent snapshot, you must have permission to
+-- use the KMS key that was used to encrypt the parent snapshot. For more
+-- information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html#ebsapi-kms-permissions Permissions to use Key Management Service keys>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+startSnapshot_parentSnapshotId :: Lens.Lens' StartSnapshot (Prelude.Maybe Prelude.Text)
+startSnapshot_parentSnapshotId = Lens.lens (\StartSnapshot' {parentSnapshotId} -> parentSnapshotId) (\s@StartSnapshot' {} a -> s {parentSnapshotId = a} :: StartSnapshot)
+
+-- | The tags to apply to the snapshot.
+startSnapshot_tags :: Lens.Lens' StartSnapshot (Prelude.Maybe [Tag])
+startSnapshot_tags = Lens.lens (\StartSnapshot' {tags} -> tags) (\s@StartSnapshot' {} a -> s {tags = a} :: StartSnapshot) Prelude.. Lens.mapping Lens.coerced
+
+-- | The amount of time (in minutes) after which the snapshot is
+-- automatically cancelled if:
+--
+-- -   No blocks are written to the snapshot.
+--
+-- -   The snapshot is not completed after writing the last block of data.
+--
+-- If no value is specified, the timeout defaults to @60@ minutes.
+startSnapshot_timeout :: Lens.Lens' StartSnapshot (Prelude.Maybe Prelude.Natural)
+startSnapshot_timeout = Lens.lens (\StartSnapshot' {timeout} -> timeout) (\s@StartSnapshot' {} a -> s {timeout = a} :: StartSnapshot)
+
+-- | The size of the volume, in GiB. The maximum size is @65536@ GiB (64
+-- TiB).
+startSnapshot_volumeSize :: Lens.Lens' StartSnapshot Prelude.Natural
+startSnapshot_volumeSize = Lens.lens (\StartSnapshot' {volumeSize} -> volumeSize) (\s@StartSnapshot' {} a -> s {volumeSize = a} :: StartSnapshot)
+
+instance Core.AWSRequest StartSnapshot where
+  type
+    AWSResponse StartSnapshot =
+      StartSnapshotResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          StartSnapshotResponse'
+            Prelude.<$> (x Data..?> "BlockSize")
+            Prelude.<*> (x Data..?> "Description")
+            Prelude.<*> (x Data..?> "KmsKeyArn")
+            Prelude.<*> (x Data..?> "OwnerId")
+            Prelude.<*> (x Data..?> "ParentSnapshotId")
+            Prelude.<*> (x Data..?> "SnapshotId")
+            Prelude.<*> (x Data..?> "StartTime")
+            Prelude.<*> (x Data..?> "Status")
+            Prelude.<*> (x Data..?> "Tags" Core..!@ Prelude.mempty)
+            Prelude.<*> (x Data..?> "VolumeSize")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable StartSnapshot where
+  hashWithSalt _salt StartSnapshot' {..} =
+    _salt
+      `Prelude.hashWithSalt` clientToken
+      `Prelude.hashWithSalt` description
+      `Prelude.hashWithSalt` encrypted
+      `Prelude.hashWithSalt` kmsKeyArn
+      `Prelude.hashWithSalt` parentSnapshotId
+      `Prelude.hashWithSalt` tags
+      `Prelude.hashWithSalt` timeout
+      `Prelude.hashWithSalt` volumeSize
+
+instance Prelude.NFData StartSnapshot where
+  rnf StartSnapshot' {..} =
+    Prelude.rnf clientToken
+      `Prelude.seq` Prelude.rnf description
+      `Prelude.seq` Prelude.rnf encrypted
+      `Prelude.seq` Prelude.rnf kmsKeyArn
+      `Prelude.seq` Prelude.rnf parentSnapshotId
+      `Prelude.seq` Prelude.rnf tags
+      `Prelude.seq` Prelude.rnf timeout
+      `Prelude.seq` Prelude.rnf volumeSize
+
+instance Data.ToHeaders StartSnapshot where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON StartSnapshot where
+  toJSON StartSnapshot' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("ClientToken" Data..=) Prelude.<$> clientToken,
+            ("Description" Data..=) Prelude.<$> description,
+            ("Encrypted" Data..=) Prelude.<$> encrypted,
+            ("KmsKeyArn" Data..=) Prelude.<$> kmsKeyArn,
+            ("ParentSnapshotId" Data..=)
+              Prelude.<$> parentSnapshotId,
+            ("Tags" Data..=) Prelude.<$> tags,
+            ("Timeout" Data..=) Prelude.<$> timeout,
+            Prelude.Just ("VolumeSize" Data..= volumeSize)
+          ]
+      )
+
+instance Data.ToPath StartSnapshot where
+  toPath = Prelude.const "/snapshots"
+
+instance Data.ToQuery StartSnapshot where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newStartSnapshotResponse' smart constructor.
+data StartSnapshotResponse = StartSnapshotResponse'
+  { -- | The size of the blocks in the snapshot, in bytes.
+    blockSize :: Prelude.Maybe Prelude.Int,
+    -- | The description of the snapshot.
+    description :: Prelude.Maybe Prelude.Text,
+    -- | The Amazon Resource Name (ARN) of the Key Management Service (KMS) key
+    -- used to encrypt the snapshot.
+    kmsKeyArn :: Prelude.Maybe (Data.Sensitive Prelude.Text),
+    -- | The Amazon Web Services account ID of the snapshot owner.
+    ownerId :: Prelude.Maybe Prelude.Text,
+    -- | The ID of the parent snapshot.
+    parentSnapshotId :: Prelude.Maybe Prelude.Text,
+    -- | The ID of the snapshot.
+    snapshotId :: Prelude.Maybe Prelude.Text,
+    -- | The timestamp when the snapshot was created.
+    startTime :: Prelude.Maybe Data.POSIX,
+    -- | The status of the snapshot.
+    status :: Prelude.Maybe Status,
+    -- | The tags applied to the snapshot. You can specify up to 50 tags per
+    -- snapshot. For more information, see
+    -- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html Tagging your Amazon EC2 resources>
+    -- in the /Amazon Elastic Compute Cloud User Guide/.
+    tags :: Prelude.Maybe [Tag],
+    -- | The size of the volume, in GiB.
+    volumeSize :: Prelude.Maybe Prelude.Natural,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'StartSnapshotResponse' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'blockSize', 'startSnapshotResponse_blockSize' - The size of the blocks in the snapshot, in bytes.
+--
+-- 'description', 'startSnapshotResponse_description' - The description of the snapshot.
+--
+-- 'kmsKeyArn', 'startSnapshotResponse_kmsKeyArn' - The Amazon Resource Name (ARN) of the Key Management Service (KMS) key
+-- used to encrypt the snapshot.
+--
+-- 'ownerId', 'startSnapshotResponse_ownerId' - The Amazon Web Services account ID of the snapshot owner.
+--
+-- 'parentSnapshotId', 'startSnapshotResponse_parentSnapshotId' - The ID of the parent snapshot.
+--
+-- 'snapshotId', 'startSnapshotResponse_snapshotId' - The ID of the snapshot.
+--
+-- 'startTime', 'startSnapshotResponse_startTime' - The timestamp when the snapshot was created.
+--
+-- 'status', 'startSnapshotResponse_status' - The status of the snapshot.
+--
+-- 'tags', 'startSnapshotResponse_tags' - The tags applied to the snapshot. You can specify up to 50 tags per
+-- snapshot. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html Tagging your Amazon EC2 resources>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+--
+-- 'volumeSize', 'startSnapshotResponse_volumeSize' - The size of the volume, in GiB.
+--
+-- 'httpStatus', 'startSnapshotResponse_httpStatus' - The response's http status code.
+newStartSnapshotResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  StartSnapshotResponse
+newStartSnapshotResponse pHttpStatus_ =
+  StartSnapshotResponse'
+    { blockSize = Prelude.Nothing,
+      description = Prelude.Nothing,
+      kmsKeyArn = Prelude.Nothing,
+      ownerId = Prelude.Nothing,
+      parentSnapshotId = Prelude.Nothing,
+      snapshotId = Prelude.Nothing,
+      startTime = Prelude.Nothing,
+      status = Prelude.Nothing,
+      tags = Prelude.Nothing,
+      volumeSize = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | The size of the blocks in the snapshot, in bytes.
+startSnapshotResponse_blockSize :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.Int)
+startSnapshotResponse_blockSize = Lens.lens (\StartSnapshotResponse' {blockSize} -> blockSize) (\s@StartSnapshotResponse' {} a -> s {blockSize = a} :: StartSnapshotResponse)
+
+-- | The description of the snapshot.
+startSnapshotResponse_description :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.Text)
+startSnapshotResponse_description = Lens.lens (\StartSnapshotResponse' {description} -> description) (\s@StartSnapshotResponse' {} a -> s {description = a} :: StartSnapshotResponse)
+
+-- | The Amazon Resource Name (ARN) of the Key Management Service (KMS) key
+-- used to encrypt the snapshot.
+startSnapshotResponse_kmsKeyArn :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.Text)
+startSnapshotResponse_kmsKeyArn = Lens.lens (\StartSnapshotResponse' {kmsKeyArn} -> kmsKeyArn) (\s@StartSnapshotResponse' {} a -> s {kmsKeyArn = a} :: StartSnapshotResponse) Prelude.. Lens.mapping Data._Sensitive
+
+-- | The Amazon Web Services account ID of the snapshot owner.
+startSnapshotResponse_ownerId :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.Text)
+startSnapshotResponse_ownerId = Lens.lens (\StartSnapshotResponse' {ownerId} -> ownerId) (\s@StartSnapshotResponse' {} a -> s {ownerId = a} :: StartSnapshotResponse)
+
+-- | The ID of the parent snapshot.
+startSnapshotResponse_parentSnapshotId :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.Text)
+startSnapshotResponse_parentSnapshotId = Lens.lens (\StartSnapshotResponse' {parentSnapshotId} -> parentSnapshotId) (\s@StartSnapshotResponse' {} a -> s {parentSnapshotId = a} :: StartSnapshotResponse)
+
+-- | The ID of the snapshot.
+startSnapshotResponse_snapshotId :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.Text)
+startSnapshotResponse_snapshotId = Lens.lens (\StartSnapshotResponse' {snapshotId} -> snapshotId) (\s@StartSnapshotResponse' {} a -> s {snapshotId = a} :: StartSnapshotResponse)
+
+-- | The timestamp when the snapshot was created.
+startSnapshotResponse_startTime :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.UTCTime)
+startSnapshotResponse_startTime = Lens.lens (\StartSnapshotResponse' {startTime} -> startTime) (\s@StartSnapshotResponse' {} a -> s {startTime = a} :: StartSnapshotResponse) Prelude.. Lens.mapping Data._Time
+
+-- | The status of the snapshot.
+startSnapshotResponse_status :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Status)
+startSnapshotResponse_status = Lens.lens (\StartSnapshotResponse' {status} -> status) (\s@StartSnapshotResponse' {} a -> s {status = a} :: StartSnapshotResponse)
+
+-- | The tags applied to the snapshot. You can specify up to 50 tags per
+-- snapshot. For more information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html Tagging your Amazon EC2 resources>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+startSnapshotResponse_tags :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe [Tag])
+startSnapshotResponse_tags = Lens.lens (\StartSnapshotResponse' {tags} -> tags) (\s@StartSnapshotResponse' {} a -> s {tags = a} :: StartSnapshotResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | The size of the volume, in GiB.
+startSnapshotResponse_volumeSize :: Lens.Lens' StartSnapshotResponse (Prelude.Maybe Prelude.Natural)
+startSnapshotResponse_volumeSize = Lens.lens (\StartSnapshotResponse' {volumeSize} -> volumeSize) (\s@StartSnapshotResponse' {} a -> s {volumeSize = a} :: StartSnapshotResponse)
+
+-- | The response's http status code.
+startSnapshotResponse_httpStatus :: Lens.Lens' StartSnapshotResponse Prelude.Int
+startSnapshotResponse_httpStatus = Lens.lens (\StartSnapshotResponse' {httpStatus} -> httpStatus) (\s@StartSnapshotResponse' {} a -> s {httpStatus = a} :: StartSnapshotResponse)
+
+instance Prelude.NFData StartSnapshotResponse where
+  rnf StartSnapshotResponse' {..} =
+    Prelude.rnf blockSize
+      `Prelude.seq` Prelude.rnf description
+      `Prelude.seq` Prelude.rnf kmsKeyArn
+      `Prelude.seq` Prelude.rnf ownerId
+      `Prelude.seq` Prelude.rnf parentSnapshotId
+      `Prelude.seq` Prelude.rnf snapshotId
+      `Prelude.seq` Prelude.rnf startTime
+      `Prelude.seq` Prelude.rnf status
+      `Prelude.seq` Prelude.rnf tags
+      `Prelude.seq` Prelude.rnf volumeSize
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/EBS/Types.hs b/gen/Amazonka/EBS/Types.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Types.hs
@@ -0,0 +1,208 @@
+{-# LANGUAGE DisambiguateRecordFields #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Types
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Types
+  ( -- * Service Configuration
+    defaultService,
+
+    -- * Errors
+    _AccessDeniedException,
+    _ConcurrentLimitExceededException,
+    _ConflictException,
+    _InternalServerException,
+    _RequestThrottledException,
+    _ResourceNotFoundException,
+    _ServiceQuotaExceededException,
+    _ValidationException,
+
+    -- * ChecksumAggregationMethod
+    ChecksumAggregationMethod (..),
+
+    -- * ChecksumAlgorithm
+    ChecksumAlgorithm (..),
+
+    -- * Status
+    Status (..),
+
+    -- * Block
+    Block (..),
+    newBlock,
+    block_blockIndex,
+    block_blockToken,
+
+    -- * ChangedBlock
+    ChangedBlock (..),
+    newChangedBlock,
+    changedBlock_blockIndex,
+    changedBlock_firstBlockToken,
+    changedBlock_secondBlockToken,
+
+    -- * Tag
+    Tag (..),
+    newTag,
+    tag_key,
+    tag_value,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import Amazonka.EBS.Types.Block
+import Amazonka.EBS.Types.ChangedBlock
+import Amazonka.EBS.Types.ChecksumAggregationMethod
+import Amazonka.EBS.Types.ChecksumAlgorithm
+import Amazonka.EBS.Types.Status
+import Amazonka.EBS.Types.Tag
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Sign.V4 as Sign
+
+-- | API version @2019-11-02@ of the Amazon Elastic Block Store SDK configuration.
+defaultService :: Core.Service
+defaultService =
+  Core.Service
+    { Core.abbrev = "EBS",
+      Core.signer = Sign.v4,
+      Core.endpointPrefix = "ebs",
+      Core.signingName = "ebs",
+      Core.version = "2019-11-02",
+      Core.s3AddressingStyle = Core.S3AddressingStyleAuto,
+      Core.endpoint = Core.defaultEndpoint defaultService,
+      Core.timeout = Prelude.Just 70,
+      Core.check = Core.statusSuccess,
+      Core.error = Core.parseJSONError "EBS",
+      Core.retry = retry
+    }
+  where
+    retry =
+      Core.Exponential
+        { Core.base = 5.0e-2,
+          Core.growth = 2,
+          Core.attempts = 5,
+          Core.check = check
+        }
+    check e
+      | Lens.has (Core.hasStatus 502) e =
+          Prelude.Just "bad_gateway"
+      | Lens.has (Core.hasStatus 504) e =
+          Prelude.Just "gateway_timeout"
+      | Lens.has (Core.hasStatus 500) e =
+          Prelude.Just "general_server_error"
+      | Lens.has (Core.hasStatus 509) e =
+          Prelude.Just "limit_exceeded"
+      | Lens.has
+          ( Core.hasCode "RequestThrottledException"
+              Prelude.. Core.hasStatus 400
+          )
+          e =
+          Prelude.Just "request_throttled_exception"
+      | Lens.has (Core.hasStatus 503) e =
+          Prelude.Just "service_unavailable"
+      | Lens.has
+          ( Core.hasCode "ThrottledException"
+              Prelude.. Core.hasStatus 400
+          )
+          e =
+          Prelude.Just "throttled_exception"
+      | Lens.has
+          ( Core.hasCode "Throttling"
+              Prelude.. Core.hasStatus 400
+          )
+          e =
+          Prelude.Just "throttling"
+      | Lens.has
+          ( Core.hasCode "ThrottlingException"
+              Prelude.. Core.hasStatus 400
+          )
+          e =
+          Prelude.Just "throttling_exception"
+      | Lens.has
+          ( Core.hasCode
+              "ProvisionedThroughputExceededException"
+              Prelude.. Core.hasStatus 400
+          )
+          e =
+          Prelude.Just "throughput_exceeded"
+      | Lens.has (Core.hasStatus 429) e =
+          Prelude.Just "too_many_requests"
+      | Prelude.otherwise = Prelude.Nothing
+
+-- | You do not have sufficient access to perform this action.
+_AccessDeniedException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_AccessDeniedException =
+  Core._MatchServiceError
+    defaultService
+    "AccessDeniedException"
+    Prelude.. Core.hasStatus 403
+
+-- | You have reached the limit for concurrent API requests. For more
+-- information, see
+-- <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-accessing-snapshot.html#ebsapi-performance Optimizing performance of the EBS direct APIs>
+-- in the /Amazon Elastic Compute Cloud User Guide/.
+_ConcurrentLimitExceededException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ConcurrentLimitExceededException =
+  Core._MatchServiceError
+    defaultService
+    "ConcurrentLimitExceededException"
+    Prelude.. Core.hasStatus 400
+
+-- | The request uses the same client token as a previous, but non-identical
+-- request.
+_ConflictException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ConflictException =
+  Core._MatchServiceError
+    defaultService
+    "ConflictException"
+    Prelude.. Core.hasStatus 409
+
+-- | An internal error has occurred.
+_InternalServerException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_InternalServerException =
+  Core._MatchServiceError
+    defaultService
+    "InternalServerException"
+    Prelude.. Core.hasStatus 500
+
+-- | The number of API requests has exceed the maximum allowed API request
+-- throttling limit.
+_RequestThrottledException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_RequestThrottledException =
+  Core._MatchServiceError
+    defaultService
+    "RequestThrottledException"
+    Prelude.. Core.hasStatus 400
+
+-- | The specified resource does not exist.
+_ResourceNotFoundException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ResourceNotFoundException =
+  Core._MatchServiceError
+    defaultService
+    "ResourceNotFoundException"
+    Prelude.. Core.hasStatus 404
+
+-- | Your current service quotas do not allow you to perform this action.
+_ServiceQuotaExceededException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ServiceQuotaExceededException =
+  Core._MatchServiceError
+    defaultService
+    "ServiceQuotaExceededException"
+    Prelude.. Core.hasStatus 402
+
+-- | The input fails to satisfy the constraints of the EBS direct APIs.
+_ValidationException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ValidationException =
+  Core._MatchServiceError
+    defaultService
+    "ValidationException"
+    Prelude.. Core.hasStatus 400
diff --git a/gen/Amazonka/EBS/Types/Block.hs b/gen/Amazonka/EBS/Types/Block.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Types/Block.hs
@@ -0,0 +1,84 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Types.Block
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Types.Block where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+-- | A block of data in an Amazon Elastic Block Store snapshot.
+--
+-- /See:/ 'newBlock' smart constructor.
+data Block = Block'
+  { -- | The block index.
+    blockIndex :: Prelude.Maybe Prelude.Natural,
+    -- | The block token for the block index.
+    blockToken :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'Block' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'blockIndex', 'block_blockIndex' - The block index.
+--
+-- 'blockToken', 'block_blockToken' - The block token for the block index.
+newBlock ::
+  Block
+newBlock =
+  Block'
+    { blockIndex = Prelude.Nothing,
+      blockToken = Prelude.Nothing
+    }
+
+-- | The block index.
+block_blockIndex :: Lens.Lens' Block (Prelude.Maybe Prelude.Natural)
+block_blockIndex = Lens.lens (\Block' {blockIndex} -> blockIndex) (\s@Block' {} a -> s {blockIndex = a} :: Block)
+
+-- | The block token for the block index.
+block_blockToken :: Lens.Lens' Block (Prelude.Maybe Prelude.Text)
+block_blockToken = Lens.lens (\Block' {blockToken} -> blockToken) (\s@Block' {} a -> s {blockToken = a} :: Block)
+
+instance Data.FromJSON Block where
+  parseJSON =
+    Data.withObject
+      "Block"
+      ( \x ->
+          Block'
+            Prelude.<$> (x Data..:? "BlockIndex")
+            Prelude.<*> (x Data..:? "BlockToken")
+      )
+
+instance Prelude.Hashable Block where
+  hashWithSalt _salt Block' {..} =
+    _salt
+      `Prelude.hashWithSalt` blockIndex
+      `Prelude.hashWithSalt` blockToken
+
+instance Prelude.NFData Block where
+  rnf Block' {..} =
+    Prelude.rnf blockIndex
+      `Prelude.seq` Prelude.rnf blockToken
diff --git a/gen/Amazonka/EBS/Types/ChangedBlock.hs b/gen/Amazonka/EBS/Types/ChangedBlock.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Types/ChangedBlock.hs
@@ -0,0 +1,106 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Types.ChangedBlock
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Types.ChangedBlock where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+-- | A block of data in an Amazon Elastic Block Store snapshot that is
+-- different from another snapshot of the same volume\/snapshot lineage.
+--
+-- /See:/ 'newChangedBlock' smart constructor.
+data ChangedBlock = ChangedBlock'
+  { -- | The block index.
+    blockIndex :: Prelude.Maybe Prelude.Natural,
+    -- | The block token for the block index of the @FirstSnapshotId@ specified
+    -- in the @ListChangedBlocks@ operation. This value is absent if the first
+    -- snapshot does not have the changed block that is on the second snapshot.
+    firstBlockToken :: Prelude.Maybe Prelude.Text,
+    -- | The block token for the block index of the @SecondSnapshotId@ specified
+    -- in the @ListChangedBlocks@ operation.
+    secondBlockToken :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ChangedBlock' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'blockIndex', 'changedBlock_blockIndex' - The block index.
+--
+-- 'firstBlockToken', 'changedBlock_firstBlockToken' - The block token for the block index of the @FirstSnapshotId@ specified
+-- in the @ListChangedBlocks@ operation. This value is absent if the first
+-- snapshot does not have the changed block that is on the second snapshot.
+--
+-- 'secondBlockToken', 'changedBlock_secondBlockToken' - The block token for the block index of the @SecondSnapshotId@ specified
+-- in the @ListChangedBlocks@ operation.
+newChangedBlock ::
+  ChangedBlock
+newChangedBlock =
+  ChangedBlock'
+    { blockIndex = Prelude.Nothing,
+      firstBlockToken = Prelude.Nothing,
+      secondBlockToken = Prelude.Nothing
+    }
+
+-- | The block index.
+changedBlock_blockIndex :: Lens.Lens' ChangedBlock (Prelude.Maybe Prelude.Natural)
+changedBlock_blockIndex = Lens.lens (\ChangedBlock' {blockIndex} -> blockIndex) (\s@ChangedBlock' {} a -> s {blockIndex = a} :: ChangedBlock)
+
+-- | The block token for the block index of the @FirstSnapshotId@ specified
+-- in the @ListChangedBlocks@ operation. This value is absent if the first
+-- snapshot does not have the changed block that is on the second snapshot.
+changedBlock_firstBlockToken :: Lens.Lens' ChangedBlock (Prelude.Maybe Prelude.Text)
+changedBlock_firstBlockToken = Lens.lens (\ChangedBlock' {firstBlockToken} -> firstBlockToken) (\s@ChangedBlock' {} a -> s {firstBlockToken = a} :: ChangedBlock)
+
+-- | The block token for the block index of the @SecondSnapshotId@ specified
+-- in the @ListChangedBlocks@ operation.
+changedBlock_secondBlockToken :: Lens.Lens' ChangedBlock (Prelude.Maybe Prelude.Text)
+changedBlock_secondBlockToken = Lens.lens (\ChangedBlock' {secondBlockToken} -> secondBlockToken) (\s@ChangedBlock' {} a -> s {secondBlockToken = a} :: ChangedBlock)
+
+instance Data.FromJSON ChangedBlock where
+  parseJSON =
+    Data.withObject
+      "ChangedBlock"
+      ( \x ->
+          ChangedBlock'
+            Prelude.<$> (x Data..:? "BlockIndex")
+            Prelude.<*> (x Data..:? "FirstBlockToken")
+            Prelude.<*> (x Data..:? "SecondBlockToken")
+      )
+
+instance Prelude.Hashable ChangedBlock where
+  hashWithSalt _salt ChangedBlock' {..} =
+    _salt
+      `Prelude.hashWithSalt` blockIndex
+      `Prelude.hashWithSalt` firstBlockToken
+      `Prelude.hashWithSalt` secondBlockToken
+
+instance Prelude.NFData ChangedBlock where
+  rnf ChangedBlock' {..} =
+    Prelude.rnf blockIndex
+      `Prelude.seq` Prelude.rnf firstBlockToken
+      `Prelude.seq` Prelude.rnf secondBlockToken
diff --git a/gen/Amazonka/EBS/Types/ChecksumAggregationMethod.hs b/gen/Amazonka/EBS/Types/ChecksumAggregationMethod.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Types/ChecksumAggregationMethod.hs
@@ -0,0 +1,66 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Types.ChecksumAggregationMethod
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Types.ChecksumAggregationMethod
+  ( ChecksumAggregationMethod
+      ( ..,
+        ChecksumAggregationMethod_LINEAR
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype ChecksumAggregationMethod = ChecksumAggregationMethod'
+  { fromChecksumAggregationMethod ::
+      Data.Text
+  }
+  deriving stock
+    ( Prelude.Show,
+      Prelude.Read,
+      Prelude.Eq,
+      Prelude.Ord,
+      Prelude.Generic
+    )
+  deriving newtype
+    ( Prelude.Hashable,
+      Prelude.NFData,
+      Data.FromText,
+      Data.ToText,
+      Data.ToByteString,
+      Data.ToLog,
+      Data.ToHeader,
+      Data.ToQuery,
+      Data.FromJSON,
+      Data.FromJSONKey,
+      Data.ToJSON,
+      Data.ToJSONKey,
+      Data.FromXML,
+      Data.ToXML
+    )
+
+pattern ChecksumAggregationMethod_LINEAR :: ChecksumAggregationMethod
+pattern ChecksumAggregationMethod_LINEAR = ChecksumAggregationMethod' "LINEAR"
+
+{-# COMPLETE
+  ChecksumAggregationMethod_LINEAR,
+  ChecksumAggregationMethod'
+  #-}
diff --git a/gen/Amazonka/EBS/Types/ChecksumAlgorithm.hs b/gen/Amazonka/EBS/Types/ChecksumAlgorithm.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Types/ChecksumAlgorithm.hs
@@ -0,0 +1,66 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Types.ChecksumAlgorithm
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Types.ChecksumAlgorithm
+  ( ChecksumAlgorithm
+      ( ..,
+        ChecksumAlgorithm_SHA256
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype ChecksumAlgorithm = ChecksumAlgorithm'
+  { fromChecksumAlgorithm ::
+      Data.Text
+  }
+  deriving stock
+    ( Prelude.Show,
+      Prelude.Read,
+      Prelude.Eq,
+      Prelude.Ord,
+      Prelude.Generic
+    )
+  deriving newtype
+    ( Prelude.Hashable,
+      Prelude.NFData,
+      Data.FromText,
+      Data.ToText,
+      Data.ToByteString,
+      Data.ToLog,
+      Data.ToHeader,
+      Data.ToQuery,
+      Data.FromJSON,
+      Data.FromJSONKey,
+      Data.ToJSON,
+      Data.ToJSONKey,
+      Data.FromXML,
+      Data.ToXML
+    )
+
+pattern ChecksumAlgorithm_SHA256 :: ChecksumAlgorithm
+pattern ChecksumAlgorithm_SHA256 = ChecksumAlgorithm' "SHA256"
+
+{-# COMPLETE
+  ChecksumAlgorithm_SHA256,
+  ChecksumAlgorithm'
+  #-}
diff --git a/gen/Amazonka/EBS/Types/Status.hs b/gen/Amazonka/EBS/Types/Status.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Types/Status.hs
@@ -0,0 +1,73 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Types.Status
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Types.Status
+  ( Status
+      ( ..,
+        Status_Completed,
+        Status_Error,
+        Status_Pending
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype Status = Status' {fromStatus :: Data.Text}
+  deriving stock
+    ( Prelude.Show,
+      Prelude.Read,
+      Prelude.Eq,
+      Prelude.Ord,
+      Prelude.Generic
+    )
+  deriving newtype
+    ( Prelude.Hashable,
+      Prelude.NFData,
+      Data.FromText,
+      Data.ToText,
+      Data.ToByteString,
+      Data.ToLog,
+      Data.ToHeader,
+      Data.ToQuery,
+      Data.FromJSON,
+      Data.FromJSONKey,
+      Data.ToJSON,
+      Data.ToJSONKey,
+      Data.FromXML,
+      Data.ToXML
+    )
+
+pattern Status_Completed :: Status
+pattern Status_Completed = Status' "completed"
+
+pattern Status_Error :: Status
+pattern Status_Error = Status' "error"
+
+pattern Status_Pending :: Status
+pattern Status_Pending = Status' "pending"
+
+{-# COMPLETE
+  Status_Completed,
+  Status_Error,
+  Status_Pending,
+  Status'
+  #-}
diff --git a/gen/Amazonka/EBS/Types/Tag.hs b/gen/Amazonka/EBS/Types/Tag.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Types/Tag.hs
@@ -0,0 +1,92 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_GHC -fno-warn-unused-matches #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Types.Tag
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Types.Tag where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+-- | Describes a tag.
+--
+-- /See:/ 'newTag' smart constructor.
+data Tag = Tag'
+  { -- | The key of the tag.
+    key :: Prelude.Maybe Prelude.Text,
+    -- | The value of the tag.
+    value :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'Tag' with all optional fields omitted.
+--
+-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
+--
+-- The following record fields are available, with the corresponding lenses provided
+-- for backwards compatibility:
+--
+-- 'key', 'tag_key' - The key of the tag.
+--
+-- 'value', 'tag_value' - The value of the tag.
+newTag ::
+  Tag
+newTag =
+  Tag'
+    { key = Prelude.Nothing,
+      value = Prelude.Nothing
+    }
+
+-- | The key of the tag.
+tag_key :: Lens.Lens' Tag (Prelude.Maybe Prelude.Text)
+tag_key = Lens.lens (\Tag' {key} -> key) (\s@Tag' {} a -> s {key = a} :: Tag)
+
+-- | The value of the tag.
+tag_value :: Lens.Lens' Tag (Prelude.Maybe Prelude.Text)
+tag_value = Lens.lens (\Tag' {value} -> value) (\s@Tag' {} a -> s {value = a} :: Tag)
+
+instance Data.FromJSON Tag where
+  parseJSON =
+    Data.withObject
+      "Tag"
+      ( \x ->
+          Tag'
+            Prelude.<$> (x Data..:? "Key")
+            Prelude.<*> (x Data..:? "Value")
+      )
+
+instance Prelude.Hashable Tag where
+  hashWithSalt _salt Tag' {..} =
+    _salt
+      `Prelude.hashWithSalt` key
+      `Prelude.hashWithSalt` value
+
+instance Prelude.NFData Tag where
+  rnf Tag' {..} =
+    Prelude.rnf key `Prelude.seq` Prelude.rnf value
+
+instance Data.ToJSON Tag where
+  toJSON Tag' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("Key" Data..=) Prelude.<$> key,
+            ("Value" Data..=) Prelude.<$> value
+          ]
+      )
diff --git a/gen/Amazonka/EBS/Waiters.hs b/gen/Amazonka/EBS/Waiters.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/EBS/Waiters.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE DisambiguateRecordFields #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Amazonka.EBS.Waiters
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Amazonka.EBS.Waiters where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Data as Data
+import Amazonka.EBS.Lens
+import Amazonka.EBS.Types
+import qualified Amazonka.Prelude as Prelude
diff --git a/src/.gitkeep b/src/.gitkeep
new file mode 100644
--- /dev/null
+++ b/src/.gitkeep
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,23 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- |
+-- Module      : Main
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Main (main) where
+
+import Test.Amazonka.EBS
+import Test.Amazonka.EBS.Internal
+import Test.Tasty
+
+main :: IO ()
+main =
+  defaultMain $
+    testGroup
+      "EBS"
+      [ testGroup "tests" tests,
+        testGroup "fixtures" fixtures
+      ]
diff --git a/test/Test/Amazonka/EBS.hs b/test/Test/Amazonka/EBS.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Amazonka/EBS.hs
@@ -0,0 +1,20 @@
+-- |
+-- Module      : Test.Amazonka.EBS
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Test.Amazonka.EBS
+  ( tests,
+    fixtures,
+  )
+where
+
+import Test.Tasty (TestTree)
+
+tests :: [TestTree]
+tests = []
+
+fixtures :: [TestTree]
+fixtures = []
diff --git a/test/Test/Amazonka/EBS/Internal.hs b/test/Test/Amazonka/EBS/Internal.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Amazonka/EBS/Internal.hs
@@ -0,0 +1,8 @@
+-- |
+-- Module      : Test.Amazonka.EBS.Internal
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Test.Amazonka.EBS.Internal where
diff --git a/test/Test/Amazonka/Gen/EBS.hs b/test/Test/Amazonka/Gen/EBS.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Amazonka/Gen/EBS.hs
@@ -0,0 +1,144 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+-- |
+-- Module      : Test.Amazonka.Gen.EBS
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+module Test.Amazonka.Gen.EBS where
+
+import Amazonka.EBS
+import qualified Data.Proxy as Proxy
+import Test.Amazonka.EBS.Internal
+import Test.Amazonka.Fixture
+import Test.Amazonka.Prelude
+import Test.Tasty
+
+-- 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"
+--         [ requestCompleteSnapshot $
+--             newCompleteSnapshot
+--
+--         , requestGetSnapshotBlock $
+--             newGetSnapshotBlock
+--
+--         , requestListChangedBlocks $
+--             newListChangedBlocks
+--
+--         , requestListSnapshotBlocks $
+--             newListSnapshotBlocks
+--
+--         , requestPutSnapshotBlock $
+--             newPutSnapshotBlock
+--
+--         , requestStartSnapshot $
+--             newStartSnapshot
+--
+--           ]
+
+--     , testGroup "response"
+--         [ responseCompleteSnapshot $
+--             newCompleteSnapshotResponse
+--
+--         , responseGetSnapshotBlock $
+--             newGetSnapshotBlockResponse
+--
+--         , responseListChangedBlocks $
+--             newListChangedBlocksResponse
+--
+--         , responseListSnapshotBlocks $
+--             newListSnapshotBlocksResponse
+--
+--         , responsePutSnapshotBlock $
+--             newPutSnapshotBlockResponse
+--
+--         , responseStartSnapshot $
+--             newStartSnapshotResponse
+--
+--           ]
+--     ]
+
+-- Requests
+
+requestCompleteSnapshot :: CompleteSnapshot -> TestTree
+requestCompleteSnapshot =
+  req
+    "CompleteSnapshot"
+    "fixture/CompleteSnapshot.yaml"
+
+requestGetSnapshotBlock :: GetSnapshotBlock -> TestTree
+requestGetSnapshotBlock =
+  req
+    "GetSnapshotBlock"
+    "fixture/GetSnapshotBlock.yaml"
+
+requestListChangedBlocks :: ListChangedBlocks -> TestTree
+requestListChangedBlocks =
+  req
+    "ListChangedBlocks"
+    "fixture/ListChangedBlocks.yaml"
+
+requestListSnapshotBlocks :: ListSnapshotBlocks -> TestTree
+requestListSnapshotBlocks =
+  req
+    "ListSnapshotBlocks"
+    "fixture/ListSnapshotBlocks.yaml"
+
+requestStartSnapshot :: StartSnapshot -> TestTree
+requestStartSnapshot =
+  req
+    "StartSnapshot"
+    "fixture/StartSnapshot.yaml"
+
+-- Responses
+
+responseCompleteSnapshot :: CompleteSnapshotResponse -> TestTree
+responseCompleteSnapshot =
+  res
+    "CompleteSnapshotResponse"
+    "fixture/CompleteSnapshotResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy CompleteSnapshot)
+
+responseListChangedBlocks :: ListChangedBlocksResponse -> TestTree
+responseListChangedBlocks =
+  res
+    "ListChangedBlocksResponse"
+    "fixture/ListChangedBlocksResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy ListChangedBlocks)
+
+responseListSnapshotBlocks :: ListSnapshotBlocksResponse -> TestTree
+responseListSnapshotBlocks =
+  res
+    "ListSnapshotBlocksResponse"
+    "fixture/ListSnapshotBlocksResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy ListSnapshotBlocks)
+
+responsePutSnapshotBlock :: PutSnapshotBlockResponse -> TestTree
+responsePutSnapshotBlock =
+  res
+    "PutSnapshotBlockResponse"
+    "fixture/PutSnapshotBlockResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy PutSnapshotBlock)
+
+responseStartSnapshot :: StartSnapshotResponse -> TestTree
+responseStartSnapshot =
+  res
+    "StartSnapshotResponse"
+    "fixture/StartSnapshotResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy StartSnapshot)
