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 Synthetics SDK
+
+* [Version](#version)
+* [Description](#description)
+* [Contribute](#contribute)
+* [Licence](#licence)
+
+
+## Version
+ 
+`2.0` - Derived from API version @2017-10-11@ of the AWS service descriptions, licensed under Apache 2.0.
+
+## Description
+
+Documentation is available via [Hackage](http://hackage.haskell.org/package/amazonka-synthetics)
+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.Synthetics](http://hackage.haskell.org/package/amazonka-synthetics/docs/Amazonka-Synthetics.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-synthetics` 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-synthetics.cabal b/amazonka-synthetics.cabal
new file mode 100644
--- /dev/null
+++ b/amazonka-synthetics.cabal
@@ -0,0 +1,133 @@
+cabal-version:      2.2
+name:               amazonka-synthetics
+version:            2.0
+synopsis:           Amazon Synthetics 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 @2017-10-11@ 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.Synthetics.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.Synthetics" 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-synthetics
+
+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.Synthetics
+    Amazonka.Synthetics.AssociateResource
+    Amazonka.Synthetics.CreateCanary
+    Amazonka.Synthetics.CreateGroup
+    Amazonka.Synthetics.DeleteCanary
+    Amazonka.Synthetics.DeleteGroup
+    Amazonka.Synthetics.DescribeCanaries
+    Amazonka.Synthetics.DescribeCanariesLastRun
+    Amazonka.Synthetics.DescribeRuntimeVersions
+    Amazonka.Synthetics.DisassociateResource
+    Amazonka.Synthetics.GetCanary
+    Amazonka.Synthetics.GetCanaryRuns
+    Amazonka.Synthetics.GetGroup
+    Amazonka.Synthetics.Lens
+    Amazonka.Synthetics.ListAssociatedGroups
+    Amazonka.Synthetics.ListGroupResources
+    Amazonka.Synthetics.ListGroups
+    Amazonka.Synthetics.ListTagsForResource
+    Amazonka.Synthetics.StartCanary
+    Amazonka.Synthetics.StopCanary
+    Amazonka.Synthetics.TagResource
+    Amazonka.Synthetics.Types
+    Amazonka.Synthetics.Types.ArtifactConfigInput
+    Amazonka.Synthetics.Types.ArtifactConfigOutput
+    Amazonka.Synthetics.Types.BaseScreenshot
+    Amazonka.Synthetics.Types.Canary
+    Amazonka.Synthetics.Types.CanaryCodeInput
+    Amazonka.Synthetics.Types.CanaryCodeOutput
+    Amazonka.Synthetics.Types.CanaryLastRun
+    Amazonka.Synthetics.Types.CanaryRun
+    Amazonka.Synthetics.Types.CanaryRunConfigInput
+    Amazonka.Synthetics.Types.CanaryRunConfigOutput
+    Amazonka.Synthetics.Types.CanaryRunState
+    Amazonka.Synthetics.Types.CanaryRunStateReasonCode
+    Amazonka.Synthetics.Types.CanaryRunStatus
+    Amazonka.Synthetics.Types.CanaryRunTimeline
+    Amazonka.Synthetics.Types.CanaryScheduleInput
+    Amazonka.Synthetics.Types.CanaryScheduleOutput
+    Amazonka.Synthetics.Types.CanaryState
+    Amazonka.Synthetics.Types.CanaryStateReasonCode
+    Amazonka.Synthetics.Types.CanaryStatus
+    Amazonka.Synthetics.Types.CanaryTimeline
+    Amazonka.Synthetics.Types.EncryptionMode
+    Amazonka.Synthetics.Types.Group
+    Amazonka.Synthetics.Types.GroupSummary
+    Amazonka.Synthetics.Types.RuntimeVersion
+    Amazonka.Synthetics.Types.S3EncryptionConfig
+    Amazonka.Synthetics.Types.VisualReferenceInput
+    Amazonka.Synthetics.Types.VisualReferenceOutput
+    Amazonka.Synthetics.Types.VpcConfigInput
+    Amazonka.Synthetics.Types.VpcConfigOutput
+    Amazonka.Synthetics.UntagResource
+    Amazonka.Synthetics.UpdateCanary
+    Amazonka.Synthetics.Waiters
+
+  build-depends:
+    , amazonka-core  >=2.0  && <2.1
+    , base           >=4.12 && <5
+
+test-suite amazonka-synthetics-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.Gen.Synthetics
+    Test.Amazonka.Synthetics
+    Test.Amazonka.Synthetics.Internal
+
+  build-depends:
+    , amazonka-core         >=2.0 && <2.1
+    , amazonka-synthetics
+    , amazonka-test         >=2.0 && <2.1
+    , base
+    , bytestring
+    , case-insensitive
+    , tasty
+    , tasty-hunit
+    , text
+    , time
+    , unordered-containers
diff --git a/fixture/AssociateResource.yaml b/fixture/AssociateResource.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/AssociateResource.yaml
@@ -0,0 +1,10 @@
+---
+method: PATCH
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/AssociateResourceResponse.proto b/fixture/AssociateResourceResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/AssociateResourceResponse.proto
diff --git a/fixture/CreateCanary.yaml b/fixture/CreateCanary.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CreateCanary.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/CreateCanaryResponse.proto b/fixture/CreateCanaryResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CreateCanaryResponse.proto
diff --git a/fixture/CreateGroup.yaml b/fixture/CreateGroup.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/CreateGroup.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/CreateGroupResponse.proto b/fixture/CreateGroupResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/CreateGroupResponse.proto
diff --git a/fixture/DeleteCanary.yaml b/fixture/DeleteCanary.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteCanary.yaml
@@ -0,0 +1,10 @@
+---
+method: DELETE
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/DeleteCanaryResponse.proto b/fixture/DeleteCanaryResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteCanaryResponse.proto
diff --git a/fixture/DeleteGroup.yaml b/fixture/DeleteGroup.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteGroup.yaml
@@ -0,0 +1,10 @@
+---
+method: DELETE
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/DeleteGroupResponse.proto b/fixture/DeleteGroupResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DeleteGroupResponse.proto
diff --git a/fixture/DescribeCanaries.yaml b/fixture/DescribeCanaries.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DescribeCanaries.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/DescribeCanariesLastRun.yaml b/fixture/DescribeCanariesLastRun.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DescribeCanariesLastRun.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/DescribeCanariesLastRunResponse.proto b/fixture/DescribeCanariesLastRunResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DescribeCanariesLastRunResponse.proto
diff --git a/fixture/DescribeCanariesResponse.proto b/fixture/DescribeCanariesResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DescribeCanariesResponse.proto
diff --git a/fixture/DescribeRuntimeVersions.yaml b/fixture/DescribeRuntimeVersions.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DescribeRuntimeVersions.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/DescribeRuntimeVersionsResponse.proto b/fixture/DescribeRuntimeVersionsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DescribeRuntimeVersionsResponse.proto
diff --git a/fixture/DisassociateResource.yaml b/fixture/DisassociateResource.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/DisassociateResource.yaml
@@ -0,0 +1,10 @@
+---
+method: PATCH
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/DisassociateResourceResponse.proto b/fixture/DisassociateResourceResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/DisassociateResourceResponse.proto
diff --git a/fixture/GetCanary.yaml b/fixture/GetCanary.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetCanary.yaml
@@ -0,0 +1,10 @@
+---
+method: GET
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/GetCanaryResponse.proto b/fixture/GetCanaryResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetCanaryResponse.proto
diff --git a/fixture/GetCanaryRuns.yaml b/fixture/GetCanaryRuns.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetCanaryRuns.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/GetCanaryRunsResponse.proto b/fixture/GetCanaryRunsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetCanaryRunsResponse.proto
diff --git a/fixture/GetGroup.yaml b/fixture/GetGroup.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/GetGroup.yaml
@@ -0,0 +1,10 @@
+---
+method: GET
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/GetGroupResponse.proto b/fixture/GetGroupResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/GetGroupResponse.proto
diff --git a/fixture/ListAssociatedGroups.yaml b/fixture/ListAssociatedGroups.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListAssociatedGroups.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/ListAssociatedGroupsResponse.proto b/fixture/ListAssociatedGroupsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListAssociatedGroupsResponse.proto
diff --git a/fixture/ListGroupResources.yaml b/fixture/ListGroupResources.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListGroupResources.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/ListGroupResourcesResponse.proto b/fixture/ListGroupResourcesResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListGroupResourcesResponse.proto
diff --git a/fixture/ListGroups.yaml b/fixture/ListGroups.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListGroups.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/ListGroupsResponse.proto b/fixture/ListGroupsResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListGroupsResponse.proto
diff --git a/fixture/ListTagsForResource.yaml b/fixture/ListTagsForResource.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/ListTagsForResource.yaml
@@ -0,0 +1,10 @@
+---
+method: GET
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/ListTagsForResourceResponse.proto b/fixture/ListTagsForResourceResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/ListTagsForResourceResponse.proto
diff --git a/fixture/StartCanary.yaml b/fixture/StartCanary.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/StartCanary.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/StartCanaryResponse.proto b/fixture/StartCanaryResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/StartCanaryResponse.proto
diff --git a/fixture/StopCanary.yaml b/fixture/StopCanary.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/StopCanary.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/StopCanaryResponse.proto b/fixture/StopCanaryResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/StopCanaryResponse.proto
diff --git a/fixture/TagResource.yaml b/fixture/TagResource.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/TagResource.yaml
@@ -0,0 +1,10 @@
+---
+method: POST
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/TagResourceResponse.proto b/fixture/TagResourceResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/TagResourceResponse.proto
diff --git a/fixture/UntagResource.yaml b/fixture/UntagResource.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/UntagResource.yaml
@@ -0,0 +1,10 @@
+---
+method: DELETE
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/UntagResourceResponse.proto b/fixture/UntagResourceResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/UntagResourceResponse.proto
diff --git a/fixture/UpdateCanary.yaml b/fixture/UpdateCanary.yaml
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateCanary.yaml
@@ -0,0 +1,10 @@
+---
+method: PATCH
+headers:
+  Authorization:         AWS4-HMAC-SHA256 Credential=access/20091028/us-east-1/synthetics/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=?
+  Host:                  synthetics.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/UpdateCanaryResponse.proto b/fixture/UpdateCanaryResponse.proto
new file mode 100644
--- /dev/null
+++ b/fixture/UpdateCanaryResponse.proto
diff --git a/gen/Amazonka/Synthetics.hs b/gen/Amazonka/Synthetics.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics.hs
@@ -0,0 +1,365 @@
+{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- |
+-- Module      : Amazonka.Synthetics
+-- 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 @2017-10-11@ of the AWS service descriptions, licensed under Apache 2.0.
+--
+-- Amazon CloudWatch Synthetics
+--
+-- You can use Amazon CloudWatch Synthetics to continually monitor your
+-- services. You can create and manage /canaries/, which are modular,
+-- lightweight scripts that monitor your endpoints and APIs from the
+-- outside-in. You can set up your canaries to run 24 hours a day, once per
+-- minute. The canaries help you check the availability and latency of your
+-- web services and troubleshoot anomalies by investigating load time data,
+-- screenshots of the UI, logs, and metrics. The canaries seamlessly
+-- integrate with CloudWatch ServiceLens to help you trace the causes of
+-- impacted nodes in your applications. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ServiceLens.html Using ServiceLens to Monitor the Health of Your Applications>
+-- in the /Amazon CloudWatch User Guide/.
+--
+-- Before you create and manage canaries, be aware of the security
+-- considerations. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html Security Considerations for Synthetics Canaries>.
+module Amazonka.Synthetics
+  ( -- * Service Configuration
+    defaultService,
+
+    -- * Errors
+    -- $errors
+
+    -- ** BadRequestException
+    _BadRequestException,
+
+    -- ** ConflictException
+    _ConflictException,
+
+    -- ** InternalFailureException
+    _InternalFailureException,
+
+    -- ** InternalServerException
+    _InternalServerException,
+
+    -- ** NotFoundException
+    _NotFoundException,
+
+    -- ** RequestEntityTooLargeException
+    _RequestEntityTooLargeException,
+
+    -- ** ResourceNotFoundException
+    _ResourceNotFoundException,
+
+    -- ** ServiceQuotaExceededException
+    _ServiceQuotaExceededException,
+
+    -- ** TooManyRequestsException
+    _TooManyRequestsException,
+
+    -- ** ValidationException
+    _ValidationException,
+
+    -- * Waiters
+    -- $waiters
+
+    -- * Operations
+    -- $operations
+
+    -- ** AssociateResource
+    AssociateResource (AssociateResource'),
+    newAssociateResource,
+    AssociateResourceResponse (AssociateResourceResponse'),
+    newAssociateResourceResponse,
+
+    -- ** CreateCanary
+    CreateCanary (CreateCanary'),
+    newCreateCanary,
+    CreateCanaryResponse (CreateCanaryResponse'),
+    newCreateCanaryResponse,
+
+    -- ** CreateGroup
+    CreateGroup (CreateGroup'),
+    newCreateGroup,
+    CreateGroupResponse (CreateGroupResponse'),
+    newCreateGroupResponse,
+
+    -- ** DeleteCanary
+    DeleteCanary (DeleteCanary'),
+    newDeleteCanary,
+    DeleteCanaryResponse (DeleteCanaryResponse'),
+    newDeleteCanaryResponse,
+
+    -- ** DeleteGroup
+    DeleteGroup (DeleteGroup'),
+    newDeleteGroup,
+    DeleteGroupResponse (DeleteGroupResponse'),
+    newDeleteGroupResponse,
+
+    -- ** DescribeCanaries
+    DescribeCanaries (DescribeCanaries'),
+    newDescribeCanaries,
+    DescribeCanariesResponse (DescribeCanariesResponse'),
+    newDescribeCanariesResponse,
+
+    -- ** DescribeCanariesLastRun
+    DescribeCanariesLastRun (DescribeCanariesLastRun'),
+    newDescribeCanariesLastRun,
+    DescribeCanariesLastRunResponse (DescribeCanariesLastRunResponse'),
+    newDescribeCanariesLastRunResponse,
+
+    -- ** DescribeRuntimeVersions
+    DescribeRuntimeVersions (DescribeRuntimeVersions'),
+    newDescribeRuntimeVersions,
+    DescribeRuntimeVersionsResponse (DescribeRuntimeVersionsResponse'),
+    newDescribeRuntimeVersionsResponse,
+
+    -- ** DisassociateResource
+    DisassociateResource (DisassociateResource'),
+    newDisassociateResource,
+    DisassociateResourceResponse (DisassociateResourceResponse'),
+    newDisassociateResourceResponse,
+
+    -- ** GetCanary
+    GetCanary (GetCanary'),
+    newGetCanary,
+    GetCanaryResponse (GetCanaryResponse'),
+    newGetCanaryResponse,
+
+    -- ** GetCanaryRuns
+    GetCanaryRuns (GetCanaryRuns'),
+    newGetCanaryRuns,
+    GetCanaryRunsResponse (GetCanaryRunsResponse'),
+    newGetCanaryRunsResponse,
+
+    -- ** GetGroup
+    GetGroup (GetGroup'),
+    newGetGroup,
+    GetGroupResponse (GetGroupResponse'),
+    newGetGroupResponse,
+
+    -- ** ListAssociatedGroups
+    ListAssociatedGroups (ListAssociatedGroups'),
+    newListAssociatedGroups,
+    ListAssociatedGroupsResponse (ListAssociatedGroupsResponse'),
+    newListAssociatedGroupsResponse,
+
+    -- ** ListGroupResources
+    ListGroupResources (ListGroupResources'),
+    newListGroupResources,
+    ListGroupResourcesResponse (ListGroupResourcesResponse'),
+    newListGroupResourcesResponse,
+
+    -- ** ListGroups
+    ListGroups (ListGroups'),
+    newListGroups,
+    ListGroupsResponse (ListGroupsResponse'),
+    newListGroupsResponse,
+
+    -- ** ListTagsForResource
+    ListTagsForResource (ListTagsForResource'),
+    newListTagsForResource,
+    ListTagsForResourceResponse (ListTagsForResourceResponse'),
+    newListTagsForResourceResponse,
+
+    -- ** StartCanary
+    StartCanary (StartCanary'),
+    newStartCanary,
+    StartCanaryResponse (StartCanaryResponse'),
+    newStartCanaryResponse,
+
+    -- ** StopCanary
+    StopCanary (StopCanary'),
+    newStopCanary,
+    StopCanaryResponse (StopCanaryResponse'),
+    newStopCanaryResponse,
+
+    -- ** TagResource
+    TagResource (TagResource'),
+    newTagResource,
+    TagResourceResponse (TagResourceResponse'),
+    newTagResourceResponse,
+
+    -- ** UntagResource
+    UntagResource (UntagResource'),
+    newUntagResource,
+    UntagResourceResponse (UntagResourceResponse'),
+    newUntagResourceResponse,
+
+    -- ** UpdateCanary
+    UpdateCanary (UpdateCanary'),
+    newUpdateCanary,
+    UpdateCanaryResponse (UpdateCanaryResponse'),
+    newUpdateCanaryResponse,
+
+    -- * Types
+
+    -- ** CanaryRunState
+    CanaryRunState (..),
+
+    -- ** CanaryRunStateReasonCode
+    CanaryRunStateReasonCode (..),
+
+    -- ** CanaryState
+    CanaryState (..),
+
+    -- ** CanaryStateReasonCode
+    CanaryStateReasonCode (..),
+
+    -- ** EncryptionMode
+    EncryptionMode (..),
+
+    -- ** ArtifactConfigInput
+    ArtifactConfigInput (ArtifactConfigInput'),
+    newArtifactConfigInput,
+
+    -- ** ArtifactConfigOutput
+    ArtifactConfigOutput (ArtifactConfigOutput'),
+    newArtifactConfigOutput,
+
+    -- ** BaseScreenshot
+    BaseScreenshot (BaseScreenshot'),
+    newBaseScreenshot,
+
+    -- ** Canary
+    Canary (Canary'),
+    newCanary,
+
+    -- ** CanaryCodeInput
+    CanaryCodeInput (CanaryCodeInput'),
+    newCanaryCodeInput,
+
+    -- ** CanaryCodeOutput
+    CanaryCodeOutput (CanaryCodeOutput'),
+    newCanaryCodeOutput,
+
+    -- ** CanaryLastRun
+    CanaryLastRun (CanaryLastRun'),
+    newCanaryLastRun,
+
+    -- ** CanaryRun
+    CanaryRun (CanaryRun'),
+    newCanaryRun,
+
+    -- ** CanaryRunConfigInput
+    CanaryRunConfigInput (CanaryRunConfigInput'),
+    newCanaryRunConfigInput,
+
+    -- ** CanaryRunConfigOutput
+    CanaryRunConfigOutput (CanaryRunConfigOutput'),
+    newCanaryRunConfigOutput,
+
+    -- ** CanaryRunStatus
+    CanaryRunStatus (CanaryRunStatus'),
+    newCanaryRunStatus,
+
+    -- ** CanaryRunTimeline
+    CanaryRunTimeline (CanaryRunTimeline'),
+    newCanaryRunTimeline,
+
+    -- ** CanaryScheduleInput
+    CanaryScheduleInput (CanaryScheduleInput'),
+    newCanaryScheduleInput,
+
+    -- ** CanaryScheduleOutput
+    CanaryScheduleOutput (CanaryScheduleOutput'),
+    newCanaryScheduleOutput,
+
+    -- ** CanaryStatus
+    CanaryStatus (CanaryStatus'),
+    newCanaryStatus,
+
+    -- ** CanaryTimeline
+    CanaryTimeline (CanaryTimeline'),
+    newCanaryTimeline,
+
+    -- ** Group
+    Group (Group'),
+    newGroup,
+
+    -- ** GroupSummary
+    GroupSummary (GroupSummary'),
+    newGroupSummary,
+
+    -- ** RuntimeVersion
+    RuntimeVersion (RuntimeVersion'),
+    newRuntimeVersion,
+
+    -- ** S3EncryptionConfig
+    S3EncryptionConfig (S3EncryptionConfig'),
+    newS3EncryptionConfig,
+
+    -- ** VisualReferenceInput
+    VisualReferenceInput (VisualReferenceInput'),
+    newVisualReferenceInput,
+
+    -- ** VisualReferenceOutput
+    VisualReferenceOutput (VisualReferenceOutput'),
+    newVisualReferenceOutput,
+
+    -- ** VpcConfigInput
+    VpcConfigInput (VpcConfigInput'),
+    newVpcConfigInput,
+
+    -- ** VpcConfigOutput
+    VpcConfigOutput (VpcConfigOutput'),
+    newVpcConfigOutput,
+  )
+where
+
+import Amazonka.Synthetics.AssociateResource
+import Amazonka.Synthetics.CreateCanary
+import Amazonka.Synthetics.CreateGroup
+import Amazonka.Synthetics.DeleteCanary
+import Amazonka.Synthetics.DeleteGroup
+import Amazonka.Synthetics.DescribeCanaries
+import Amazonka.Synthetics.DescribeCanariesLastRun
+import Amazonka.Synthetics.DescribeRuntimeVersions
+import Amazonka.Synthetics.DisassociateResource
+import Amazonka.Synthetics.GetCanary
+import Amazonka.Synthetics.GetCanaryRuns
+import Amazonka.Synthetics.GetGroup
+import Amazonka.Synthetics.Lens
+import Amazonka.Synthetics.ListAssociatedGroups
+import Amazonka.Synthetics.ListGroupResources
+import Amazonka.Synthetics.ListGroups
+import Amazonka.Synthetics.ListTagsForResource
+import Amazonka.Synthetics.StartCanary
+import Amazonka.Synthetics.StopCanary
+import Amazonka.Synthetics.TagResource
+import Amazonka.Synthetics.Types
+import Amazonka.Synthetics.UntagResource
+import Amazonka.Synthetics.UpdateCanary
+import Amazonka.Synthetics.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 'Synthetics'.
+
+-- $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/Synthetics/AssociateResource.hs b/gen/Amazonka/Synthetics/AssociateResource.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/AssociateResource.hs
@@ -0,0 +1,183 @@
+{-# 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.Synthetics.AssociateResource
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Associates a canary with a group. Using groups can help you with
+-- managing and automating your canaries, and you can also view aggregated
+-- run results and statistics for all canaries in a group.
+--
+-- You must run this operation in the Region where the canary exists.
+module Amazonka.Synthetics.AssociateResource
+  ( -- * Creating a Request
+    AssociateResource (..),
+    newAssociateResource,
+
+    -- * Request Lenses
+    associateResource_groupIdentifier,
+    associateResource_resourceArn,
+
+    -- * Destructuring the Response
+    AssociateResourceResponse (..),
+    newAssociateResourceResponse,
+
+    -- * Response Lenses
+    associateResourceResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newAssociateResource' smart constructor.
+data AssociateResource = AssociateResource'
+  { -- | Specifies the group. You can specify the group name, the ARN, or the
+    -- group ID as the @GroupIdentifier@.
+    groupIdentifier :: Prelude.Text,
+    -- | The ARN of the canary that you want to associate with the specified
+    -- group.
+    resourceArn :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'AssociateResource' 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:
+--
+-- 'groupIdentifier', 'associateResource_groupIdentifier' - Specifies the group. You can specify the group name, the ARN, or the
+-- group ID as the @GroupIdentifier@.
+--
+-- 'resourceArn', 'associateResource_resourceArn' - The ARN of the canary that you want to associate with the specified
+-- group.
+newAssociateResource ::
+  -- | 'groupIdentifier'
+  Prelude.Text ->
+  -- | 'resourceArn'
+  Prelude.Text ->
+  AssociateResource
+newAssociateResource pGroupIdentifier_ pResourceArn_ =
+  AssociateResource'
+    { groupIdentifier =
+        pGroupIdentifier_,
+      resourceArn = pResourceArn_
+    }
+
+-- | Specifies the group. You can specify the group name, the ARN, or the
+-- group ID as the @GroupIdentifier@.
+associateResource_groupIdentifier :: Lens.Lens' AssociateResource Prelude.Text
+associateResource_groupIdentifier = Lens.lens (\AssociateResource' {groupIdentifier} -> groupIdentifier) (\s@AssociateResource' {} a -> s {groupIdentifier = a} :: AssociateResource)
+
+-- | The ARN of the canary that you want to associate with the specified
+-- group.
+associateResource_resourceArn :: Lens.Lens' AssociateResource Prelude.Text
+associateResource_resourceArn = Lens.lens (\AssociateResource' {resourceArn} -> resourceArn) (\s@AssociateResource' {} a -> s {resourceArn = a} :: AssociateResource)
+
+instance Core.AWSRequest AssociateResource where
+  type
+    AWSResponse AssociateResource =
+      AssociateResourceResponse
+  request overrides =
+    Request.patchJSON (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          AssociateResourceResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable AssociateResource where
+  hashWithSalt _salt AssociateResource' {..} =
+    _salt
+      `Prelude.hashWithSalt` groupIdentifier
+      `Prelude.hashWithSalt` resourceArn
+
+instance Prelude.NFData AssociateResource where
+  rnf AssociateResource' {..} =
+    Prelude.rnf groupIdentifier
+      `Prelude.seq` Prelude.rnf resourceArn
+
+instance Data.ToHeaders AssociateResource where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON AssociateResource where
+  toJSON AssociateResource' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [Prelude.Just ("ResourceArn" Data..= resourceArn)]
+      )
+
+instance Data.ToPath AssociateResource where
+  toPath AssociateResource' {..} =
+    Prelude.mconcat
+      ["/group/", Data.toBS groupIdentifier, "/associate"]
+
+instance Data.ToQuery AssociateResource where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newAssociateResourceResponse' smart constructor.
+data AssociateResourceResponse = AssociateResourceResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'AssociateResourceResponse' 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:
+--
+-- 'httpStatus', 'associateResourceResponse_httpStatus' - The response's http status code.
+newAssociateResourceResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  AssociateResourceResponse
+newAssociateResourceResponse pHttpStatus_ =
+  AssociateResourceResponse'
+    { httpStatus =
+        pHttpStatus_
+    }
+
+-- | The response's http status code.
+associateResourceResponse_httpStatus :: Lens.Lens' AssociateResourceResponse Prelude.Int
+associateResourceResponse_httpStatus = Lens.lens (\AssociateResourceResponse' {httpStatus} -> httpStatus) (\s@AssociateResourceResponse' {} a -> s {httpStatus = a} :: AssociateResourceResponse)
+
+instance Prelude.NFData AssociateResourceResponse where
+  rnf AssociateResourceResponse' {..} =
+    Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/CreateCanary.hs b/gen/Amazonka/Synthetics/CreateCanary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/CreateCanary.hs
@@ -0,0 +1,492 @@
+{-# 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.Synthetics.CreateCanary
+-- 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 canary. Canaries are scripts that monitor your endpoints and
+-- APIs from the outside-in. Canaries help you check the availability and
+-- latency of your web services and troubleshoot anomalies by investigating
+-- load time data, screenshots of the UI, logs, and metrics. You can set up
+-- a canary to run continuously or just once.
+--
+-- Do not use @CreateCanary@ to modify an existing canary. Use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_UpdateCanary.html UpdateCanary>
+-- instead.
+--
+-- To create canaries, you must have the @CloudWatchSyntheticsFullAccess@
+-- policy. If you are creating a new IAM role for the canary, you also need
+-- the @iam:CreateRole@, @iam:CreatePolicy@ and @iam:AttachRolePolicy@
+-- permissions. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Roles Necessary Roles and Permissions>.
+--
+-- Do not include secrets or proprietary information in your canary names.
+-- The canary name makes up part of the Amazon Resource Name (ARN) for the
+-- canary, and the ARN is included in outbound calls over the internet. For
+-- more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html Security Considerations for Synthetics Canaries>.
+module Amazonka.Synthetics.CreateCanary
+  ( -- * Creating a Request
+    CreateCanary (..),
+    newCreateCanary,
+
+    -- * Request Lenses
+    createCanary_artifactConfig,
+    createCanary_failureRetentionPeriodInDays,
+    createCanary_runConfig,
+    createCanary_successRetentionPeriodInDays,
+    createCanary_tags,
+    createCanary_vpcConfig,
+    createCanary_name,
+    createCanary_code,
+    createCanary_artifactS3Location,
+    createCanary_executionRoleArn,
+    createCanary_schedule,
+    createCanary_runtimeVersion,
+
+    -- * Destructuring the Response
+    CreateCanaryResponse (..),
+    newCreateCanaryResponse,
+
+    -- * Response Lenses
+    createCanaryResponse_canary,
+    createCanaryResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newCreateCanary' smart constructor.
+data CreateCanary = CreateCanary'
+  { -- | A structure that contains the configuration for canary artifacts,
+    -- including the encryption-at-rest settings for artifacts that the canary
+    -- uploads to Amazon S3.
+    artifactConfig :: Prelude.Maybe ArtifactConfigInput,
+    -- | The number of days to retain data about failed runs of this canary. If
+    -- you omit this field, the default of 31 days is used. The valid range is
+    -- 1 to 455 days.
+    failureRetentionPeriodInDays :: Prelude.Maybe Prelude.Natural,
+    -- | A structure that contains the configuration for individual canary runs,
+    -- such as timeout value and environment variables.
+    --
+    -- The environment variables keys and values are not encrypted. Do not
+    -- store sensitive information in this field.
+    runConfig :: Prelude.Maybe CanaryRunConfigInput,
+    -- | The number of days to retain data about successful runs of this canary.
+    -- If you omit this field, the default of 31 days is used. The valid range
+    -- is 1 to 455 days.
+    successRetentionPeriodInDays :: Prelude.Maybe Prelude.Natural,
+    -- | A list of key-value pairs to associate with the canary. You can
+    -- associate as many as 50 tags with a canary.
+    --
+    -- Tags can help you organize and categorize your resources. You can also
+    -- use them to scope user permissions, by granting a user permission to
+    -- access or change only the resources that have certain tag values.
+    tags :: Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text),
+    -- | If this canary is to test an endpoint in a VPC, this structure contains
+    -- information about the subnet and security groups of the VPC endpoint.
+    -- For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+    vpcConfig :: Prelude.Maybe VpcConfigInput,
+    -- | The name for this canary. Be sure to give it a descriptive name that
+    -- distinguishes it from other canaries in your account.
+    --
+    -- Do not include secrets or proprietary information in your canary names.
+    -- The canary name makes up part of the canary ARN, and the ARN is included
+    -- in outbound calls over the internet. For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html Security Considerations for Synthetics Canaries>.
+    name :: Prelude.Text,
+    -- | A structure that includes the entry point from which the canary should
+    -- start running your script. If the script is stored in an S3 bucket, the
+    -- bucket name, key, and version are also included.
+    code :: CanaryCodeInput,
+    -- | The location in Amazon S3 where Synthetics stores artifacts from the
+    -- test runs of this canary. Artifacts include the log file, screenshots,
+    -- and HAR files. The name of the S3 bucket can\'t include a period (.).
+    artifactS3Location :: Prelude.Text,
+    -- | The ARN of the IAM role to be used to run the canary. This role must
+    -- already exist, and must include @lambda.amazonaws.com@ as a principal in
+    -- the trust policy. The role must also have the following permissions:
+    --
+    -- -   @s3:PutObject@
+    --
+    -- -   @s3:GetBucketLocation@
+    --
+    -- -   @s3:ListAllMyBuckets@
+    --
+    -- -   @cloudwatch:PutMetricData@
+    --
+    -- -   @logs:CreateLogGroup@
+    --
+    -- -   @logs:CreateLogStream@
+    --
+    -- -   @logs:PutLogEvents@
+    executionRoleArn :: Prelude.Text,
+    -- | A structure that contains information about how often the canary is to
+    -- run and when these test runs are to stop.
+    schedule :: CanaryScheduleInput,
+    -- | Specifies the runtime version to use for the canary. For a list of valid
+    -- runtime versions and more information about runtime versions, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+    runtimeVersion :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CreateCanary' 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:
+--
+-- 'artifactConfig', 'createCanary_artifactConfig' - A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+--
+-- 'failureRetentionPeriodInDays', 'createCanary_failureRetentionPeriodInDays' - The number of days to retain data about failed runs of this canary. If
+-- you omit this field, the default of 31 days is used. The valid range is
+-- 1 to 455 days.
+--
+-- 'runConfig', 'createCanary_runConfig' - A structure that contains the configuration for individual canary runs,
+-- such as timeout value and environment variables.
+--
+-- The environment variables keys and values are not encrypted. Do not
+-- store sensitive information in this field.
+--
+-- 'successRetentionPeriodInDays', 'createCanary_successRetentionPeriodInDays' - The number of days to retain data about successful runs of this canary.
+-- If you omit this field, the default of 31 days is used. The valid range
+-- is 1 to 455 days.
+--
+-- 'tags', 'createCanary_tags' - A list of key-value pairs to associate with the canary. You can
+-- associate as many as 50 tags with a canary.
+--
+-- Tags can help you organize and categorize your resources. You can also
+-- use them to scope user permissions, by granting a user permission to
+-- access or change only the resources that have certain tag values.
+--
+-- 'vpcConfig', 'createCanary_vpcConfig' - If this canary is to test an endpoint in a VPC, this structure contains
+-- information about the subnet and security groups of the VPC endpoint.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+--
+-- 'name', 'createCanary_name' - The name for this canary. Be sure to give it a descriptive name that
+-- distinguishes it from other canaries in your account.
+--
+-- Do not include secrets or proprietary information in your canary names.
+-- The canary name makes up part of the canary ARN, and the ARN is included
+-- in outbound calls over the internet. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html Security Considerations for Synthetics Canaries>.
+--
+-- 'code', 'createCanary_code' - A structure that includes the entry point from which the canary should
+-- start running your script. If the script is stored in an S3 bucket, the
+-- bucket name, key, and version are also included.
+--
+-- 'artifactS3Location', 'createCanary_artifactS3Location' - The location in Amazon S3 where Synthetics stores artifacts from the
+-- test runs of this canary. Artifacts include the log file, screenshots,
+-- and HAR files. The name of the S3 bucket can\'t include a period (.).
+--
+-- 'executionRoleArn', 'createCanary_executionRoleArn' - The ARN of the IAM role to be used to run the canary. This role must
+-- already exist, and must include @lambda.amazonaws.com@ as a principal in
+-- the trust policy. The role must also have the following permissions:
+--
+-- -   @s3:PutObject@
+--
+-- -   @s3:GetBucketLocation@
+--
+-- -   @s3:ListAllMyBuckets@
+--
+-- -   @cloudwatch:PutMetricData@
+--
+-- -   @logs:CreateLogGroup@
+--
+-- -   @logs:CreateLogStream@
+--
+-- -   @logs:PutLogEvents@
+--
+-- 'schedule', 'createCanary_schedule' - A structure that contains information about how often the canary is to
+-- run and when these test runs are to stop.
+--
+-- 'runtimeVersion', 'createCanary_runtimeVersion' - Specifies the runtime version to use for the canary. For a list of valid
+-- runtime versions and more information about runtime versions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+newCreateCanary ::
+  -- | 'name'
+  Prelude.Text ->
+  -- | 'code'
+  CanaryCodeInput ->
+  -- | 'artifactS3Location'
+  Prelude.Text ->
+  -- | 'executionRoleArn'
+  Prelude.Text ->
+  -- | 'schedule'
+  CanaryScheduleInput ->
+  -- | 'runtimeVersion'
+  Prelude.Text ->
+  CreateCanary
+newCreateCanary
+  pName_
+  pCode_
+  pArtifactS3Location_
+  pExecutionRoleArn_
+  pSchedule_
+  pRuntimeVersion_ =
+    CreateCanary'
+      { artifactConfig = Prelude.Nothing,
+        failureRetentionPeriodInDays = Prelude.Nothing,
+        runConfig = Prelude.Nothing,
+        successRetentionPeriodInDays = Prelude.Nothing,
+        tags = Prelude.Nothing,
+        vpcConfig = Prelude.Nothing,
+        name = pName_,
+        code = pCode_,
+        artifactS3Location = pArtifactS3Location_,
+        executionRoleArn = pExecutionRoleArn_,
+        schedule = pSchedule_,
+        runtimeVersion = pRuntimeVersion_
+      }
+
+-- | A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+createCanary_artifactConfig :: Lens.Lens' CreateCanary (Prelude.Maybe ArtifactConfigInput)
+createCanary_artifactConfig = Lens.lens (\CreateCanary' {artifactConfig} -> artifactConfig) (\s@CreateCanary' {} a -> s {artifactConfig = a} :: CreateCanary)
+
+-- | The number of days to retain data about failed runs of this canary. If
+-- you omit this field, the default of 31 days is used. The valid range is
+-- 1 to 455 days.
+createCanary_failureRetentionPeriodInDays :: Lens.Lens' CreateCanary (Prelude.Maybe Prelude.Natural)
+createCanary_failureRetentionPeriodInDays = Lens.lens (\CreateCanary' {failureRetentionPeriodInDays} -> failureRetentionPeriodInDays) (\s@CreateCanary' {} a -> s {failureRetentionPeriodInDays = a} :: CreateCanary)
+
+-- | A structure that contains the configuration for individual canary runs,
+-- such as timeout value and environment variables.
+--
+-- The environment variables keys and values are not encrypted. Do not
+-- store sensitive information in this field.
+createCanary_runConfig :: Lens.Lens' CreateCanary (Prelude.Maybe CanaryRunConfigInput)
+createCanary_runConfig = Lens.lens (\CreateCanary' {runConfig} -> runConfig) (\s@CreateCanary' {} a -> s {runConfig = a} :: CreateCanary)
+
+-- | The number of days to retain data about successful runs of this canary.
+-- If you omit this field, the default of 31 days is used. The valid range
+-- is 1 to 455 days.
+createCanary_successRetentionPeriodInDays :: Lens.Lens' CreateCanary (Prelude.Maybe Prelude.Natural)
+createCanary_successRetentionPeriodInDays = Lens.lens (\CreateCanary' {successRetentionPeriodInDays} -> successRetentionPeriodInDays) (\s@CreateCanary' {} a -> s {successRetentionPeriodInDays = a} :: CreateCanary)
+
+-- | A list of key-value pairs to associate with the canary. You can
+-- associate as many as 50 tags with a canary.
+--
+-- Tags can help you organize and categorize your resources. You can also
+-- use them to scope user permissions, by granting a user permission to
+-- access or change only the resources that have certain tag values.
+createCanary_tags :: Lens.Lens' CreateCanary (Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text))
+createCanary_tags = Lens.lens (\CreateCanary' {tags} -> tags) (\s@CreateCanary' {} a -> s {tags = a} :: CreateCanary) Prelude.. Lens.mapping Lens.coerced
+
+-- | If this canary is to test an endpoint in a VPC, this structure contains
+-- information about the subnet and security groups of the VPC endpoint.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+createCanary_vpcConfig :: Lens.Lens' CreateCanary (Prelude.Maybe VpcConfigInput)
+createCanary_vpcConfig = Lens.lens (\CreateCanary' {vpcConfig} -> vpcConfig) (\s@CreateCanary' {} a -> s {vpcConfig = a} :: CreateCanary)
+
+-- | The name for this canary. Be sure to give it a descriptive name that
+-- distinguishes it from other canaries in your account.
+--
+-- Do not include secrets or proprietary information in your canary names.
+-- The canary name makes up part of the canary ARN, and the ARN is included
+-- in outbound calls over the internet. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html Security Considerations for Synthetics Canaries>.
+createCanary_name :: Lens.Lens' CreateCanary Prelude.Text
+createCanary_name = Lens.lens (\CreateCanary' {name} -> name) (\s@CreateCanary' {} a -> s {name = a} :: CreateCanary)
+
+-- | A structure that includes the entry point from which the canary should
+-- start running your script. If the script is stored in an S3 bucket, the
+-- bucket name, key, and version are also included.
+createCanary_code :: Lens.Lens' CreateCanary CanaryCodeInput
+createCanary_code = Lens.lens (\CreateCanary' {code} -> code) (\s@CreateCanary' {} a -> s {code = a} :: CreateCanary)
+
+-- | The location in Amazon S3 where Synthetics stores artifacts from the
+-- test runs of this canary. Artifacts include the log file, screenshots,
+-- and HAR files. The name of the S3 bucket can\'t include a period (.).
+createCanary_artifactS3Location :: Lens.Lens' CreateCanary Prelude.Text
+createCanary_artifactS3Location = Lens.lens (\CreateCanary' {artifactS3Location} -> artifactS3Location) (\s@CreateCanary' {} a -> s {artifactS3Location = a} :: CreateCanary)
+
+-- | The ARN of the IAM role to be used to run the canary. This role must
+-- already exist, and must include @lambda.amazonaws.com@ as a principal in
+-- the trust policy. The role must also have the following permissions:
+--
+-- -   @s3:PutObject@
+--
+-- -   @s3:GetBucketLocation@
+--
+-- -   @s3:ListAllMyBuckets@
+--
+-- -   @cloudwatch:PutMetricData@
+--
+-- -   @logs:CreateLogGroup@
+--
+-- -   @logs:CreateLogStream@
+--
+-- -   @logs:PutLogEvents@
+createCanary_executionRoleArn :: Lens.Lens' CreateCanary Prelude.Text
+createCanary_executionRoleArn = Lens.lens (\CreateCanary' {executionRoleArn} -> executionRoleArn) (\s@CreateCanary' {} a -> s {executionRoleArn = a} :: CreateCanary)
+
+-- | A structure that contains information about how often the canary is to
+-- run and when these test runs are to stop.
+createCanary_schedule :: Lens.Lens' CreateCanary CanaryScheduleInput
+createCanary_schedule = Lens.lens (\CreateCanary' {schedule} -> schedule) (\s@CreateCanary' {} a -> s {schedule = a} :: CreateCanary)
+
+-- | Specifies the runtime version to use for the canary. For a list of valid
+-- runtime versions and more information about runtime versions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+createCanary_runtimeVersion :: Lens.Lens' CreateCanary Prelude.Text
+createCanary_runtimeVersion = Lens.lens (\CreateCanary' {runtimeVersion} -> runtimeVersion) (\s@CreateCanary' {} a -> s {runtimeVersion = a} :: CreateCanary)
+
+instance Core.AWSRequest CreateCanary where
+  type AWSResponse CreateCanary = CreateCanaryResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          CreateCanaryResponse'
+            Prelude.<$> (x Data..?> "Canary")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable CreateCanary where
+  hashWithSalt _salt CreateCanary' {..} =
+    _salt
+      `Prelude.hashWithSalt` artifactConfig
+      `Prelude.hashWithSalt` failureRetentionPeriodInDays
+      `Prelude.hashWithSalt` runConfig
+      `Prelude.hashWithSalt` successRetentionPeriodInDays
+      `Prelude.hashWithSalt` tags
+      `Prelude.hashWithSalt` vpcConfig
+      `Prelude.hashWithSalt` name
+      `Prelude.hashWithSalt` code
+      `Prelude.hashWithSalt` artifactS3Location
+      `Prelude.hashWithSalt` executionRoleArn
+      `Prelude.hashWithSalt` schedule
+      `Prelude.hashWithSalt` runtimeVersion
+
+instance Prelude.NFData CreateCanary where
+  rnf CreateCanary' {..} =
+    Prelude.rnf artifactConfig
+      `Prelude.seq` Prelude.rnf failureRetentionPeriodInDays
+      `Prelude.seq` Prelude.rnf runConfig
+      `Prelude.seq` Prelude.rnf successRetentionPeriodInDays
+      `Prelude.seq` Prelude.rnf tags
+      `Prelude.seq` Prelude.rnf vpcConfig
+      `Prelude.seq` Prelude.rnf name
+      `Prelude.seq` Prelude.rnf code
+      `Prelude.seq` Prelude.rnf artifactS3Location
+      `Prelude.seq` Prelude.rnf executionRoleArn
+      `Prelude.seq` Prelude.rnf schedule
+      `Prelude.seq` Prelude.rnf runtimeVersion
+
+instance Data.ToHeaders CreateCanary where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON CreateCanary where
+  toJSON CreateCanary' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("ArtifactConfig" Data..=)
+              Prelude.<$> artifactConfig,
+            ("FailureRetentionPeriodInDays" Data..=)
+              Prelude.<$> failureRetentionPeriodInDays,
+            ("RunConfig" Data..=) Prelude.<$> runConfig,
+            ("SuccessRetentionPeriodInDays" Data..=)
+              Prelude.<$> successRetentionPeriodInDays,
+            ("Tags" Data..=) Prelude.<$> tags,
+            ("VpcConfig" Data..=) Prelude.<$> vpcConfig,
+            Prelude.Just ("Name" Data..= name),
+            Prelude.Just ("Code" Data..= code),
+            Prelude.Just
+              ("ArtifactS3Location" Data..= artifactS3Location),
+            Prelude.Just
+              ("ExecutionRoleArn" Data..= executionRoleArn),
+            Prelude.Just ("Schedule" Data..= schedule),
+            Prelude.Just
+              ("RuntimeVersion" Data..= runtimeVersion)
+          ]
+      )
+
+instance Data.ToPath CreateCanary where
+  toPath = Prelude.const "/canary"
+
+instance Data.ToQuery CreateCanary where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newCreateCanaryResponse' smart constructor.
+data CreateCanaryResponse = CreateCanaryResponse'
+  { -- | The full details about the canary you have created.
+    canary :: Prelude.Maybe Canary,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CreateCanaryResponse' 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:
+--
+-- 'canary', 'createCanaryResponse_canary' - The full details about the canary you have created.
+--
+-- 'httpStatus', 'createCanaryResponse_httpStatus' - The response's http status code.
+newCreateCanaryResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  CreateCanaryResponse
+newCreateCanaryResponse pHttpStatus_ =
+  CreateCanaryResponse'
+    { canary = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | The full details about the canary you have created.
+createCanaryResponse_canary :: Lens.Lens' CreateCanaryResponse (Prelude.Maybe Canary)
+createCanaryResponse_canary = Lens.lens (\CreateCanaryResponse' {canary} -> canary) (\s@CreateCanaryResponse' {} a -> s {canary = a} :: CreateCanaryResponse)
+
+-- | The response's http status code.
+createCanaryResponse_httpStatus :: Lens.Lens' CreateCanaryResponse Prelude.Int
+createCanaryResponse_httpStatus = Lens.lens (\CreateCanaryResponse' {httpStatus} -> httpStatus) (\s@CreateCanaryResponse' {} a -> s {httpStatus = a} :: CreateCanaryResponse)
+
+instance Prelude.NFData CreateCanaryResponse where
+  rnf CreateCanaryResponse' {..} =
+    Prelude.rnf canary
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/CreateGroup.hs b/gen/Amazonka/Synthetics/CreateGroup.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/CreateGroup.hs
@@ -0,0 +1,221 @@
+{-# 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.Synthetics.CreateGroup
+-- 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 group which you can use to associate canaries with each other,
+-- including cross-Region canaries. Using groups can help you with managing
+-- and automating your canaries, and you can also view aggregated run
+-- results and statistics for all canaries in a group.
+--
+-- Groups are global resources. When you create a group, it is replicated
+-- across Amazon Web Services Regions, and you can view it and add canaries
+-- to it from any Region. Although the group ARN format reflects the Region
+-- name where it was created, a group is not constrained to any Region.
+-- This means that you can put canaries from multiple Regions into the same
+-- group, and then use that group to view and manage all of those canaries
+-- in a single view.
+--
+-- Groups are supported in all Regions except the Regions that are disabled
+-- by default. For more information about these Regions, see
+-- <https://docs.aws.amazon.com/general/latest/gr/rande-manage.html#rande-manage-enable Enabling a Region>.
+--
+-- Each group can contain as many as 10 canaries. You can have as many as
+-- 20 groups in your account. Any single canary can be a member of up to 10
+-- groups.
+module Amazonka.Synthetics.CreateGroup
+  ( -- * Creating a Request
+    CreateGroup (..),
+    newCreateGroup,
+
+    -- * Request Lenses
+    createGroup_tags,
+    createGroup_name,
+
+    -- * Destructuring the Response
+    CreateGroupResponse (..),
+    newCreateGroupResponse,
+
+    -- * Response Lenses
+    createGroupResponse_group,
+    createGroupResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newCreateGroup' smart constructor.
+data CreateGroup = CreateGroup'
+  { -- | A list of key-value pairs to associate with the group. You can associate
+    -- as many as 50 tags with a group.
+    --
+    -- Tags can help you organize and categorize your resources. You can also
+    -- use them to scope user permissions, by granting a user permission to
+    -- access or change only the resources that have certain tag values.
+    tags :: Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text),
+    -- | The name for the group. It can include any Unicode characters.
+    --
+    -- The names for all groups in your account, across all Regions, must be
+    -- unique.
+    name :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CreateGroup' 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:
+--
+-- 'tags', 'createGroup_tags' - A list of key-value pairs to associate with the group. You can associate
+-- as many as 50 tags with a group.
+--
+-- Tags can help you organize and categorize your resources. You can also
+-- use them to scope user permissions, by granting a user permission to
+-- access or change only the resources that have certain tag values.
+--
+-- 'name', 'createGroup_name' - The name for the group. It can include any Unicode characters.
+--
+-- The names for all groups in your account, across all Regions, must be
+-- unique.
+newCreateGroup ::
+  -- | 'name'
+  Prelude.Text ->
+  CreateGroup
+newCreateGroup pName_ =
+  CreateGroup' {tags = Prelude.Nothing, name = pName_}
+
+-- | A list of key-value pairs to associate with the group. You can associate
+-- as many as 50 tags with a group.
+--
+-- Tags can help you organize and categorize your resources. You can also
+-- use them to scope user permissions, by granting a user permission to
+-- access or change only the resources that have certain tag values.
+createGroup_tags :: Lens.Lens' CreateGroup (Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text))
+createGroup_tags = Lens.lens (\CreateGroup' {tags} -> tags) (\s@CreateGroup' {} a -> s {tags = a} :: CreateGroup) Prelude.. Lens.mapping Lens.coerced
+
+-- | The name for the group. It can include any Unicode characters.
+--
+-- The names for all groups in your account, across all Regions, must be
+-- unique.
+createGroup_name :: Lens.Lens' CreateGroup Prelude.Text
+createGroup_name = Lens.lens (\CreateGroup' {name} -> name) (\s@CreateGroup' {} a -> s {name = a} :: CreateGroup)
+
+instance Core.AWSRequest CreateGroup where
+  type AWSResponse CreateGroup = CreateGroupResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          CreateGroupResponse'
+            Prelude.<$> (x Data..?> "Group")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable CreateGroup where
+  hashWithSalt _salt CreateGroup' {..} =
+    _salt
+      `Prelude.hashWithSalt` tags
+      `Prelude.hashWithSalt` name
+
+instance Prelude.NFData CreateGroup where
+  rnf CreateGroup' {..} =
+    Prelude.rnf tags `Prelude.seq` Prelude.rnf name
+
+instance Data.ToHeaders CreateGroup where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON CreateGroup where
+  toJSON CreateGroup' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("Tags" Data..=) Prelude.<$> tags,
+            Prelude.Just ("Name" Data..= name)
+          ]
+      )
+
+instance Data.ToPath CreateGroup where
+  toPath = Prelude.const "/group"
+
+instance Data.ToQuery CreateGroup where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newCreateGroupResponse' smart constructor.
+data CreateGroupResponse = CreateGroupResponse'
+  { -- | A structure that contains information about the group that was just
+    -- created.
+    group' :: Prelude.Maybe Group,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CreateGroupResponse' 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:
+--
+-- 'group'', 'createGroupResponse_group' - A structure that contains information about the group that was just
+-- created.
+--
+-- 'httpStatus', 'createGroupResponse_httpStatus' - The response's http status code.
+newCreateGroupResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  CreateGroupResponse
+newCreateGroupResponse pHttpStatus_ =
+  CreateGroupResponse'
+    { group' = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | A structure that contains information about the group that was just
+-- created.
+createGroupResponse_group :: Lens.Lens' CreateGroupResponse (Prelude.Maybe Group)
+createGroupResponse_group = Lens.lens (\CreateGroupResponse' {group'} -> group') (\s@CreateGroupResponse' {} a -> s {group' = a} :: CreateGroupResponse)
+
+-- | The response's http status code.
+createGroupResponse_httpStatus :: Lens.Lens' CreateGroupResponse Prelude.Int
+createGroupResponse_httpStatus = Lens.lens (\CreateGroupResponse' {httpStatus} -> httpStatus) (\s@CreateGroupResponse' {} a -> s {httpStatus = a} :: CreateGroupResponse)
+
+instance Prelude.NFData CreateGroupResponse where
+  rnf CreateGroupResponse' {..} =
+    Prelude.rnf group'
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/DeleteCanary.hs b/gen/Amazonka/Synthetics/DeleteCanary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/DeleteCanary.hs
@@ -0,0 +1,199 @@
+{-# 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.Synthetics.DeleteCanary
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Permanently deletes the specified canary.
+--
+-- If you specify @DeleteLambda@ to @true@, CloudWatch Synthetics also
+-- deletes the Lambda functions and layers that are used by the canary.
+--
+-- Other resources used and created by the canary are not automatically
+-- deleted. After you delete a canary that you do not intend to use again,
+-- you should also delete the following:
+--
+-- -   The CloudWatch alarms created for this canary. These alarms have a
+--     name of @Synthetics-SharpDrop-Alarm-@/@MyCanaryName@/@ @.
+--
+-- -   Amazon S3 objects and buckets, such as the canary\'s artifact
+--     location.
+--
+-- -   IAM roles created for the canary. If they were created in the
+--     console, these roles have the name
+--     @ role\/service-role\/CloudWatchSyntheticsRole-@/@MyCanaryName@/@ @.
+--
+-- -   CloudWatch Logs log groups created for the canary. These logs groups
+--     have the name @\/aws\/lambda\/cwsyn-@/@MyCanaryName@/@ @.
+--
+-- Before you delete a canary, you might want to use @GetCanary@ to display
+-- the information about this canary. Make note of the information returned
+-- by this operation so that you can delete these resources after you
+-- delete the canary.
+module Amazonka.Synthetics.DeleteCanary
+  ( -- * Creating a Request
+    DeleteCanary (..),
+    newDeleteCanary,
+
+    -- * Request Lenses
+    deleteCanary_deleteLambda,
+    deleteCanary_name,
+
+    -- * Destructuring the Response
+    DeleteCanaryResponse (..),
+    newDeleteCanaryResponse,
+
+    -- * Response Lenses
+    deleteCanaryResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newDeleteCanary' smart constructor.
+data DeleteCanary = DeleteCanary'
+  { -- | Specifies whether to also delete the Lambda functions and layers used by
+    -- this canary. The default is false.
+    --
+    -- Type: Boolean
+    deleteLambda :: Prelude.Maybe Prelude.Bool,
+    -- | The name of the canary that you want to delete. To find the names of
+    -- your canaries, use
+    -- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+    name :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DeleteCanary' 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:
+--
+-- 'deleteLambda', 'deleteCanary_deleteLambda' - Specifies whether to also delete the Lambda functions and layers used by
+-- this canary. The default is false.
+--
+-- Type: Boolean
+--
+-- 'name', 'deleteCanary_name' - The name of the canary that you want to delete. To find the names of
+-- your canaries, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+newDeleteCanary ::
+  -- | 'name'
+  Prelude.Text ->
+  DeleteCanary
+newDeleteCanary pName_ =
+  DeleteCanary'
+    { deleteLambda = Prelude.Nothing,
+      name = pName_
+    }
+
+-- | Specifies whether to also delete the Lambda functions and layers used by
+-- this canary. The default is false.
+--
+-- Type: Boolean
+deleteCanary_deleteLambda :: Lens.Lens' DeleteCanary (Prelude.Maybe Prelude.Bool)
+deleteCanary_deleteLambda = Lens.lens (\DeleteCanary' {deleteLambda} -> deleteLambda) (\s@DeleteCanary' {} a -> s {deleteLambda = a} :: DeleteCanary)
+
+-- | The name of the canary that you want to delete. To find the names of
+-- your canaries, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+deleteCanary_name :: Lens.Lens' DeleteCanary Prelude.Text
+deleteCanary_name = Lens.lens (\DeleteCanary' {name} -> name) (\s@DeleteCanary' {} a -> s {name = a} :: DeleteCanary)
+
+instance Core.AWSRequest DeleteCanary where
+  type AWSResponse DeleteCanary = DeleteCanaryResponse
+  request overrides =
+    Request.delete (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          DeleteCanaryResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable DeleteCanary where
+  hashWithSalt _salt DeleteCanary' {..} =
+    _salt
+      `Prelude.hashWithSalt` deleteLambda
+      `Prelude.hashWithSalt` name
+
+instance Prelude.NFData DeleteCanary where
+  rnf DeleteCanary' {..} =
+    Prelude.rnf deleteLambda
+      `Prelude.seq` Prelude.rnf name
+
+instance Data.ToHeaders DeleteCanary where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath DeleteCanary where
+  toPath DeleteCanary' {..} =
+    Prelude.mconcat ["/canary/", Data.toBS name]
+
+instance Data.ToQuery DeleteCanary where
+  toQuery DeleteCanary' {..} =
+    Prelude.mconcat
+      ["deleteLambda" Data.=: deleteLambda]
+
+-- | /See:/ 'newDeleteCanaryResponse' smart constructor.
+data DeleteCanaryResponse = DeleteCanaryResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DeleteCanaryResponse' 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:
+--
+-- 'httpStatus', 'deleteCanaryResponse_httpStatus' - The response's http status code.
+newDeleteCanaryResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  DeleteCanaryResponse
+newDeleteCanaryResponse pHttpStatus_ =
+  DeleteCanaryResponse' {httpStatus = pHttpStatus_}
+
+-- | The response's http status code.
+deleteCanaryResponse_httpStatus :: Lens.Lens' DeleteCanaryResponse Prelude.Int
+deleteCanaryResponse_httpStatus = Lens.lens (\DeleteCanaryResponse' {httpStatus} -> httpStatus) (\s@DeleteCanaryResponse' {} a -> s {httpStatus = a} :: DeleteCanaryResponse)
+
+instance Prelude.NFData DeleteCanaryResponse where
+  rnf DeleteCanaryResponse' {..} =
+    Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/DeleteGroup.hs b/gen/Amazonka/Synthetics/DeleteGroup.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/DeleteGroup.hs
@@ -0,0 +1,150 @@
+{-# 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.Synthetics.DeleteGroup
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Deletes a group. The group doesn\'t need to be empty to be deleted. If
+-- there are canaries in the group, they are not deleted when you delete
+-- the group.
+--
+-- Groups are a global resource that appear in all Regions, but the request
+-- to delete a group must be made from its home Region. You can find the
+-- home Region of a group within its ARN.
+module Amazonka.Synthetics.DeleteGroup
+  ( -- * Creating a Request
+    DeleteGroup (..),
+    newDeleteGroup,
+
+    -- * Request Lenses
+    deleteGroup_groupIdentifier,
+
+    -- * Destructuring the Response
+    DeleteGroupResponse (..),
+    newDeleteGroupResponse,
+
+    -- * Response Lenses
+    deleteGroupResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newDeleteGroup' smart constructor.
+data DeleteGroup = DeleteGroup'
+  { -- | Specifies which group to delete. You can specify the group name, the
+    -- ARN, or the group ID as the @GroupIdentifier@.
+    groupIdentifier :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DeleteGroup' 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:
+--
+-- 'groupIdentifier', 'deleteGroup_groupIdentifier' - Specifies which group to delete. You can specify the group name, the
+-- ARN, or the group ID as the @GroupIdentifier@.
+newDeleteGroup ::
+  -- | 'groupIdentifier'
+  Prelude.Text ->
+  DeleteGroup
+newDeleteGroup pGroupIdentifier_ =
+  DeleteGroup' {groupIdentifier = pGroupIdentifier_}
+
+-- | Specifies which group to delete. You can specify the group name, the
+-- ARN, or the group ID as the @GroupIdentifier@.
+deleteGroup_groupIdentifier :: Lens.Lens' DeleteGroup Prelude.Text
+deleteGroup_groupIdentifier = Lens.lens (\DeleteGroup' {groupIdentifier} -> groupIdentifier) (\s@DeleteGroup' {} a -> s {groupIdentifier = a} :: DeleteGroup)
+
+instance Core.AWSRequest DeleteGroup where
+  type AWSResponse DeleteGroup = DeleteGroupResponse
+  request overrides =
+    Request.delete (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          DeleteGroupResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable DeleteGroup where
+  hashWithSalt _salt DeleteGroup' {..} =
+    _salt `Prelude.hashWithSalt` groupIdentifier
+
+instance Prelude.NFData DeleteGroup where
+  rnf DeleteGroup' {..} = Prelude.rnf groupIdentifier
+
+instance Data.ToHeaders DeleteGroup where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath DeleteGroup where
+  toPath DeleteGroup' {..} =
+    Prelude.mconcat
+      ["/group/", Data.toBS groupIdentifier]
+
+instance Data.ToQuery DeleteGroup where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newDeleteGroupResponse' smart constructor.
+data DeleteGroupResponse = DeleteGroupResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DeleteGroupResponse' 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:
+--
+-- 'httpStatus', 'deleteGroupResponse_httpStatus' - The response's http status code.
+newDeleteGroupResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  DeleteGroupResponse
+newDeleteGroupResponse pHttpStatus_ =
+  DeleteGroupResponse' {httpStatus = pHttpStatus_}
+
+-- | The response's http status code.
+deleteGroupResponse_httpStatus :: Lens.Lens' DeleteGroupResponse Prelude.Int
+deleteGroupResponse_httpStatus = Lens.lens (\DeleteGroupResponse' {httpStatus} -> httpStatus) (\s@DeleteGroupResponse' {} a -> s {httpStatus = a} :: DeleteGroupResponse)
+
+instance Prelude.NFData DeleteGroupResponse where
+  rnf DeleteGroupResponse' {..} = Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/DescribeCanaries.hs b/gen/Amazonka/Synthetics/DescribeCanaries.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/DescribeCanaries.hs
@@ -0,0 +1,271 @@
+{-# 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.Synthetics.DescribeCanaries
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- This operation returns a list of the canaries in your account, along
+-- with full details about each canary.
+--
+-- This operation supports resource-level authorization using an IAM policy
+-- and the @Names@ parameter. If you specify the @Names@ parameter, the
+-- operation is successful only if you have authorization to view all the
+-- canaries that you specify in your request. If you do not have permission
+-- to view any of the canaries, the request fails with a 403 response.
+--
+-- You are required to use the @Names@ parameter if you are logged on to a
+-- user or role that has an IAM policy that restricts which canaries that
+-- you are allowed to view. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+module Amazonka.Synthetics.DescribeCanaries
+  ( -- * Creating a Request
+    DescribeCanaries (..),
+    newDescribeCanaries,
+
+    -- * Request Lenses
+    describeCanaries_maxResults,
+    describeCanaries_names,
+    describeCanaries_nextToken,
+
+    -- * Destructuring the Response
+    DescribeCanariesResponse (..),
+    newDescribeCanariesResponse,
+
+    -- * Response Lenses
+    describeCanariesResponse_canaries,
+    describeCanariesResponse_nextToken,
+    describeCanariesResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newDescribeCanaries' smart constructor.
+data DescribeCanaries = DescribeCanaries'
+  { -- | Specify this parameter to limit how many canaries are returned each time
+    -- you use the @DescribeCanaries@ operation. If you omit this parameter,
+    -- the default of 100 is used.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | Use this parameter to return only canaries that match the names that you
+    -- specify here. You can specify as many as five canary names.
+    --
+    -- If you specify this parameter, the operation is successful only if you
+    -- have authorization to view all the canaries that you specify in your
+    -- request. If you do not have permission to view any of the canaries, the
+    -- request fails with a 403 response.
+    --
+    -- You are required to use this parameter if you are logged on to a user or
+    -- role that has an IAM policy that restricts which canaries that you are
+    -- allowed to view. For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+    names :: Prelude.Maybe (Prelude.NonEmpty Prelude.Text),
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent operation to retrieve the next set of
+    -- results.
+    nextToken :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DescribeCanaries' 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', 'describeCanaries_maxResults' - Specify this parameter to limit how many canaries are returned each time
+-- you use the @DescribeCanaries@ operation. If you omit this parameter,
+-- the default of 100 is used.
+--
+-- 'names', 'describeCanaries_names' - Use this parameter to return only canaries that match the names that you
+-- specify here. You can specify as many as five canary names.
+--
+-- If you specify this parameter, the operation is successful only if you
+-- have authorization to view all the canaries that you specify in your
+-- request. If you do not have permission to view any of the canaries, the
+-- request fails with a 403 response.
+--
+-- You are required to use this parameter if you are logged on to a user or
+-- role that has an IAM policy that restricts which canaries that you are
+-- allowed to view. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+--
+-- 'nextToken', 'describeCanaries_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+newDescribeCanaries ::
+  DescribeCanaries
+newDescribeCanaries =
+  DescribeCanaries'
+    { maxResults = Prelude.Nothing,
+      names = Prelude.Nothing,
+      nextToken = Prelude.Nothing
+    }
+
+-- | Specify this parameter to limit how many canaries are returned each time
+-- you use the @DescribeCanaries@ operation. If you omit this parameter,
+-- the default of 100 is used.
+describeCanaries_maxResults :: Lens.Lens' DescribeCanaries (Prelude.Maybe Prelude.Natural)
+describeCanaries_maxResults = Lens.lens (\DescribeCanaries' {maxResults} -> maxResults) (\s@DescribeCanaries' {} a -> s {maxResults = a} :: DescribeCanaries)
+
+-- | Use this parameter to return only canaries that match the names that you
+-- specify here. You can specify as many as five canary names.
+--
+-- If you specify this parameter, the operation is successful only if you
+-- have authorization to view all the canaries that you specify in your
+-- request. If you do not have permission to view any of the canaries, the
+-- request fails with a 403 response.
+--
+-- You are required to use this parameter if you are logged on to a user or
+-- role that has an IAM policy that restricts which canaries that you are
+-- allowed to view. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+describeCanaries_names :: Lens.Lens' DescribeCanaries (Prelude.Maybe (Prelude.NonEmpty Prelude.Text))
+describeCanaries_names = Lens.lens (\DescribeCanaries' {names} -> names) (\s@DescribeCanaries' {} a -> s {names = a} :: DescribeCanaries) Prelude.. Lens.mapping Lens.coerced
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+describeCanaries_nextToken :: Lens.Lens' DescribeCanaries (Prelude.Maybe Prelude.Text)
+describeCanaries_nextToken = Lens.lens (\DescribeCanaries' {nextToken} -> nextToken) (\s@DescribeCanaries' {} a -> s {nextToken = a} :: DescribeCanaries)
+
+instance Core.AWSRequest DescribeCanaries where
+  type
+    AWSResponse DescribeCanaries =
+      DescribeCanariesResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          DescribeCanariesResponse'
+            Prelude.<$> (x Data..?> "Canaries" Core..!@ Prelude.mempty)
+            Prelude.<*> (x Data..?> "NextToken")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable DescribeCanaries where
+  hashWithSalt _salt DescribeCanaries' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` names
+      `Prelude.hashWithSalt` nextToken
+
+instance Prelude.NFData DescribeCanaries where
+  rnf DescribeCanaries' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf names
+      `Prelude.seq` Prelude.rnf nextToken
+
+instance Data.ToHeaders DescribeCanaries where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON DescribeCanaries where
+  toJSON DescribeCanaries' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("MaxResults" Data..=) Prelude.<$> maxResults,
+            ("Names" Data..=) Prelude.<$> names,
+            ("NextToken" Data..=) Prelude.<$> nextToken
+          ]
+      )
+
+instance Data.ToPath DescribeCanaries where
+  toPath = Prelude.const "/canaries"
+
+instance Data.ToQuery DescribeCanaries where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newDescribeCanariesResponse' smart constructor.
+data DescribeCanariesResponse = DescribeCanariesResponse'
+  { -- | Returns an array. Each item in the array contains the full information
+    -- about one canary.
+    canaries :: Prelude.Maybe [Canary],
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @DescribeCanaries@ operation to retrieve the
+    -- next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DescribeCanariesResponse' 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:
+--
+-- 'canaries', 'describeCanariesResponse_canaries' - Returns an array. Each item in the array contains the full information
+-- about one canary.
+--
+-- 'nextToken', 'describeCanariesResponse_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeCanaries@ operation to retrieve the
+-- next set of results.
+--
+-- 'httpStatus', 'describeCanariesResponse_httpStatus' - The response's http status code.
+newDescribeCanariesResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  DescribeCanariesResponse
+newDescribeCanariesResponse pHttpStatus_ =
+  DescribeCanariesResponse'
+    { canaries =
+        Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | Returns an array. Each item in the array contains the full information
+-- about one canary.
+describeCanariesResponse_canaries :: Lens.Lens' DescribeCanariesResponse (Prelude.Maybe [Canary])
+describeCanariesResponse_canaries = Lens.lens (\DescribeCanariesResponse' {canaries} -> canaries) (\s@DescribeCanariesResponse' {} a -> s {canaries = a} :: DescribeCanariesResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeCanaries@ operation to retrieve the
+-- next set of results.
+describeCanariesResponse_nextToken :: Lens.Lens' DescribeCanariesResponse (Prelude.Maybe Prelude.Text)
+describeCanariesResponse_nextToken = Lens.lens (\DescribeCanariesResponse' {nextToken} -> nextToken) (\s@DescribeCanariesResponse' {} a -> s {nextToken = a} :: DescribeCanariesResponse)
+
+-- | The response's http status code.
+describeCanariesResponse_httpStatus :: Lens.Lens' DescribeCanariesResponse Prelude.Int
+describeCanariesResponse_httpStatus = Lens.lens (\DescribeCanariesResponse' {httpStatus} -> httpStatus) (\s@DescribeCanariesResponse' {} a -> s {httpStatus = a} :: DescribeCanariesResponse)
+
+instance Prelude.NFData DescribeCanariesResponse where
+  rnf DescribeCanariesResponse' {..} =
+    Prelude.rnf canaries
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/DescribeCanariesLastRun.hs b/gen/Amazonka/Synthetics/DescribeCanariesLastRun.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/DescribeCanariesLastRun.hs
@@ -0,0 +1,278 @@
+{-# 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.Synthetics.DescribeCanariesLastRun
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Use this operation to see information from the most recent run of each
+-- canary that you have created.
+--
+-- This operation supports resource-level authorization using an IAM policy
+-- and the @Names@ parameter. If you specify the @Names@ parameter, the
+-- operation is successful only if you have authorization to view all the
+-- canaries that you specify in your request. If you do not have permission
+-- to view any of the canaries, the request fails with a 403 response.
+--
+-- You are required to use the @Names@ parameter if you are logged on to a
+-- user or role that has an IAM policy that restricts which canaries that
+-- you are allowed to view. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+module Amazonka.Synthetics.DescribeCanariesLastRun
+  ( -- * Creating a Request
+    DescribeCanariesLastRun (..),
+    newDescribeCanariesLastRun,
+
+    -- * Request Lenses
+    describeCanariesLastRun_maxResults,
+    describeCanariesLastRun_names,
+    describeCanariesLastRun_nextToken,
+
+    -- * Destructuring the Response
+    DescribeCanariesLastRunResponse (..),
+    newDescribeCanariesLastRunResponse,
+
+    -- * Response Lenses
+    describeCanariesLastRunResponse_canariesLastRun,
+    describeCanariesLastRunResponse_nextToken,
+    describeCanariesLastRunResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newDescribeCanariesLastRun' smart constructor.
+data DescribeCanariesLastRun = DescribeCanariesLastRun'
+  { -- | Specify this parameter to limit how many runs are returned each time you
+    -- use the @DescribeLastRun@ operation. If you omit this parameter, the
+    -- default of 100 is used.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | Use this parameter to return only canaries that match the names that you
+    -- specify here. You can specify as many as five canary names.
+    --
+    -- If you specify this parameter, the operation is successful only if you
+    -- have authorization to view all the canaries that you specify in your
+    -- request. If you do not have permission to view any of the canaries, the
+    -- request fails with a 403 response.
+    --
+    -- You are required to use the @Names@ parameter if you are logged on to a
+    -- user or role that has an IAM policy that restricts which canaries that
+    -- you are allowed to view. For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+    names :: Prelude.Maybe (Prelude.NonEmpty Prelude.Text),
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @DescribeCanariesLastRun@ operation to
+    -- retrieve the next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DescribeCanariesLastRun' 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', 'describeCanariesLastRun_maxResults' - Specify this parameter to limit how many runs are returned each time you
+-- use the @DescribeLastRun@ operation. If you omit this parameter, the
+-- default of 100 is used.
+--
+-- 'names', 'describeCanariesLastRun_names' - Use this parameter to return only canaries that match the names that you
+-- specify here. You can specify as many as five canary names.
+--
+-- If you specify this parameter, the operation is successful only if you
+-- have authorization to view all the canaries that you specify in your
+-- request. If you do not have permission to view any of the canaries, the
+-- request fails with a 403 response.
+--
+-- You are required to use the @Names@ parameter if you are logged on to a
+-- user or role that has an IAM policy that restricts which canaries that
+-- you are allowed to view. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+--
+-- 'nextToken', 'describeCanariesLastRun_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeCanariesLastRun@ operation to
+-- retrieve the next set of results.
+newDescribeCanariesLastRun ::
+  DescribeCanariesLastRun
+newDescribeCanariesLastRun =
+  DescribeCanariesLastRun'
+    { maxResults =
+        Prelude.Nothing,
+      names = Prelude.Nothing,
+      nextToken = Prelude.Nothing
+    }
+
+-- | Specify this parameter to limit how many runs are returned each time you
+-- use the @DescribeLastRun@ operation. If you omit this parameter, the
+-- default of 100 is used.
+describeCanariesLastRun_maxResults :: Lens.Lens' DescribeCanariesLastRun (Prelude.Maybe Prelude.Natural)
+describeCanariesLastRun_maxResults = Lens.lens (\DescribeCanariesLastRun' {maxResults} -> maxResults) (\s@DescribeCanariesLastRun' {} a -> s {maxResults = a} :: DescribeCanariesLastRun)
+
+-- | Use this parameter to return only canaries that match the names that you
+-- specify here. You can specify as many as five canary names.
+--
+-- If you specify this parameter, the operation is successful only if you
+-- have authorization to view all the canaries that you specify in your
+-- request. If you do not have permission to view any of the canaries, the
+-- request fails with a 403 response.
+--
+-- You are required to use the @Names@ parameter if you are logged on to a
+-- user or role that has an IAM policy that restricts which canaries that
+-- you are allowed to view. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Restricted.html Limiting a user to viewing specific canaries>.
+describeCanariesLastRun_names :: Lens.Lens' DescribeCanariesLastRun (Prelude.Maybe (Prelude.NonEmpty Prelude.Text))
+describeCanariesLastRun_names = Lens.lens (\DescribeCanariesLastRun' {names} -> names) (\s@DescribeCanariesLastRun' {} a -> s {names = a} :: DescribeCanariesLastRun) Prelude.. Lens.mapping Lens.coerced
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeCanariesLastRun@ operation to
+-- retrieve the next set of results.
+describeCanariesLastRun_nextToken :: Lens.Lens' DescribeCanariesLastRun (Prelude.Maybe Prelude.Text)
+describeCanariesLastRun_nextToken = Lens.lens (\DescribeCanariesLastRun' {nextToken} -> nextToken) (\s@DescribeCanariesLastRun' {} a -> s {nextToken = a} :: DescribeCanariesLastRun)
+
+instance Core.AWSRequest DescribeCanariesLastRun where
+  type
+    AWSResponse DescribeCanariesLastRun =
+      DescribeCanariesLastRunResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          DescribeCanariesLastRunResponse'
+            Prelude.<$> ( x
+                            Data..?> "CanariesLastRun"
+                            Core..!@ Prelude.mempty
+                        )
+            Prelude.<*> (x Data..?> "NextToken")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable DescribeCanariesLastRun where
+  hashWithSalt _salt DescribeCanariesLastRun' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` names
+      `Prelude.hashWithSalt` nextToken
+
+instance Prelude.NFData DescribeCanariesLastRun where
+  rnf DescribeCanariesLastRun' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf names
+      `Prelude.seq` Prelude.rnf nextToken
+
+instance Data.ToHeaders DescribeCanariesLastRun where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON DescribeCanariesLastRun where
+  toJSON DescribeCanariesLastRun' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("MaxResults" Data..=) Prelude.<$> maxResults,
+            ("Names" Data..=) Prelude.<$> names,
+            ("NextToken" Data..=) Prelude.<$> nextToken
+          ]
+      )
+
+instance Data.ToPath DescribeCanariesLastRun where
+  toPath = Prelude.const "/canaries/last-run"
+
+instance Data.ToQuery DescribeCanariesLastRun where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newDescribeCanariesLastRunResponse' smart constructor.
+data DescribeCanariesLastRunResponse = DescribeCanariesLastRunResponse'
+  { -- | An array that contains the information from the most recent run of each
+    -- canary.
+    canariesLastRun :: Prelude.Maybe [CanaryLastRun],
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @DescribeCanariesLastRun@ operation to
+    -- retrieve the next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DescribeCanariesLastRunResponse' 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:
+--
+-- 'canariesLastRun', 'describeCanariesLastRunResponse_canariesLastRun' - An array that contains the information from the most recent run of each
+-- canary.
+--
+-- 'nextToken', 'describeCanariesLastRunResponse_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeCanariesLastRun@ operation to
+-- retrieve the next set of results.
+--
+-- 'httpStatus', 'describeCanariesLastRunResponse_httpStatus' - The response's http status code.
+newDescribeCanariesLastRunResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  DescribeCanariesLastRunResponse
+newDescribeCanariesLastRunResponse pHttpStatus_ =
+  DescribeCanariesLastRunResponse'
+    { canariesLastRun =
+        Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | An array that contains the information from the most recent run of each
+-- canary.
+describeCanariesLastRunResponse_canariesLastRun :: Lens.Lens' DescribeCanariesLastRunResponse (Prelude.Maybe [CanaryLastRun])
+describeCanariesLastRunResponse_canariesLastRun = Lens.lens (\DescribeCanariesLastRunResponse' {canariesLastRun} -> canariesLastRun) (\s@DescribeCanariesLastRunResponse' {} a -> s {canariesLastRun = a} :: DescribeCanariesLastRunResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeCanariesLastRun@ operation to
+-- retrieve the next set of results.
+describeCanariesLastRunResponse_nextToken :: Lens.Lens' DescribeCanariesLastRunResponse (Prelude.Maybe Prelude.Text)
+describeCanariesLastRunResponse_nextToken = Lens.lens (\DescribeCanariesLastRunResponse' {nextToken} -> nextToken) (\s@DescribeCanariesLastRunResponse' {} a -> s {nextToken = a} :: DescribeCanariesLastRunResponse)
+
+-- | The response's http status code.
+describeCanariesLastRunResponse_httpStatus :: Lens.Lens' DescribeCanariesLastRunResponse Prelude.Int
+describeCanariesLastRunResponse_httpStatus = Lens.lens (\DescribeCanariesLastRunResponse' {httpStatus} -> httpStatus) (\s@DescribeCanariesLastRunResponse' {} a -> s {httpStatus = a} :: DescribeCanariesLastRunResponse)
+
+instance
+  Prelude.NFData
+    DescribeCanariesLastRunResponse
+  where
+  rnf DescribeCanariesLastRunResponse' {..} =
+    Prelude.rnf canariesLastRun
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/DescribeRuntimeVersions.hs b/gen/Amazonka/Synthetics/DescribeRuntimeVersions.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/DescribeRuntimeVersions.hs
@@ -0,0 +1,222 @@
+{-# 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.Synthetics.DescribeRuntimeVersions
+-- 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 a list of Synthetics canary runtime versions. For more
+-- information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+module Amazonka.Synthetics.DescribeRuntimeVersions
+  ( -- * Creating a Request
+    DescribeRuntimeVersions (..),
+    newDescribeRuntimeVersions,
+
+    -- * Request Lenses
+    describeRuntimeVersions_maxResults,
+    describeRuntimeVersions_nextToken,
+
+    -- * Destructuring the Response
+    DescribeRuntimeVersionsResponse (..),
+    newDescribeRuntimeVersionsResponse,
+
+    -- * Response Lenses
+    describeRuntimeVersionsResponse_nextToken,
+    describeRuntimeVersionsResponse_runtimeVersions,
+    describeRuntimeVersionsResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newDescribeRuntimeVersions' smart constructor.
+data DescribeRuntimeVersions = DescribeRuntimeVersions'
+  { -- | Specify this parameter to limit how many runs are returned each time you
+    -- use the @DescribeRuntimeVersions@ operation. If you omit this parameter,
+    -- the default of 100 is used.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @DescribeRuntimeVersions@ operation to
+    -- retrieve the next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DescribeRuntimeVersions' 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', 'describeRuntimeVersions_maxResults' - Specify this parameter to limit how many runs are returned each time you
+-- use the @DescribeRuntimeVersions@ operation. If you omit this parameter,
+-- the default of 100 is used.
+--
+-- 'nextToken', 'describeRuntimeVersions_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeRuntimeVersions@ operation to
+-- retrieve the next set of results.
+newDescribeRuntimeVersions ::
+  DescribeRuntimeVersions
+newDescribeRuntimeVersions =
+  DescribeRuntimeVersions'
+    { maxResults =
+        Prelude.Nothing,
+      nextToken = Prelude.Nothing
+    }
+
+-- | Specify this parameter to limit how many runs are returned each time you
+-- use the @DescribeRuntimeVersions@ operation. If you omit this parameter,
+-- the default of 100 is used.
+describeRuntimeVersions_maxResults :: Lens.Lens' DescribeRuntimeVersions (Prelude.Maybe Prelude.Natural)
+describeRuntimeVersions_maxResults = Lens.lens (\DescribeRuntimeVersions' {maxResults} -> maxResults) (\s@DescribeRuntimeVersions' {} a -> s {maxResults = a} :: DescribeRuntimeVersions)
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeRuntimeVersions@ operation to
+-- retrieve the next set of results.
+describeRuntimeVersions_nextToken :: Lens.Lens' DescribeRuntimeVersions (Prelude.Maybe Prelude.Text)
+describeRuntimeVersions_nextToken = Lens.lens (\DescribeRuntimeVersions' {nextToken} -> nextToken) (\s@DescribeRuntimeVersions' {} a -> s {nextToken = a} :: DescribeRuntimeVersions)
+
+instance Core.AWSRequest DescribeRuntimeVersions where
+  type
+    AWSResponse DescribeRuntimeVersions =
+      DescribeRuntimeVersionsResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          DescribeRuntimeVersionsResponse'
+            Prelude.<$> (x Data..?> "NextToken")
+            Prelude.<*> ( x
+                            Data..?> "RuntimeVersions"
+                            Core..!@ Prelude.mempty
+                        )
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable DescribeRuntimeVersions where
+  hashWithSalt _salt DescribeRuntimeVersions' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` nextToken
+
+instance Prelude.NFData DescribeRuntimeVersions where
+  rnf DescribeRuntimeVersions' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf nextToken
+
+instance Data.ToHeaders DescribeRuntimeVersions where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON DescribeRuntimeVersions where
+  toJSON DescribeRuntimeVersions' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("MaxResults" Data..=) Prelude.<$> maxResults,
+            ("NextToken" Data..=) Prelude.<$> nextToken
+          ]
+      )
+
+instance Data.ToPath DescribeRuntimeVersions where
+  toPath = Prelude.const "/runtime-versions"
+
+instance Data.ToQuery DescribeRuntimeVersions where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newDescribeRuntimeVersionsResponse' smart constructor.
+data DescribeRuntimeVersionsResponse = DescribeRuntimeVersionsResponse'
+  { -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @DescribeRuntimeVersions@ operation to
+    -- retrieve the next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | An array of objects that display the details about each Synthetics
+    -- canary runtime version.
+    runtimeVersions :: Prelude.Maybe [RuntimeVersion],
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DescribeRuntimeVersionsResponse' 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:
+--
+-- 'nextToken', 'describeRuntimeVersionsResponse_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeRuntimeVersions@ operation to
+-- retrieve the next set of results.
+--
+-- 'runtimeVersions', 'describeRuntimeVersionsResponse_runtimeVersions' - An array of objects that display the details about each Synthetics
+-- canary runtime version.
+--
+-- 'httpStatus', 'describeRuntimeVersionsResponse_httpStatus' - The response's http status code.
+newDescribeRuntimeVersionsResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  DescribeRuntimeVersionsResponse
+newDescribeRuntimeVersionsResponse pHttpStatus_ =
+  DescribeRuntimeVersionsResponse'
+    { nextToken =
+        Prelude.Nothing,
+      runtimeVersions = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @DescribeRuntimeVersions@ operation to
+-- retrieve the next set of results.
+describeRuntimeVersionsResponse_nextToken :: Lens.Lens' DescribeRuntimeVersionsResponse (Prelude.Maybe Prelude.Text)
+describeRuntimeVersionsResponse_nextToken = Lens.lens (\DescribeRuntimeVersionsResponse' {nextToken} -> nextToken) (\s@DescribeRuntimeVersionsResponse' {} a -> s {nextToken = a} :: DescribeRuntimeVersionsResponse)
+
+-- | An array of objects that display the details about each Synthetics
+-- canary runtime version.
+describeRuntimeVersionsResponse_runtimeVersions :: Lens.Lens' DescribeRuntimeVersionsResponse (Prelude.Maybe [RuntimeVersion])
+describeRuntimeVersionsResponse_runtimeVersions = Lens.lens (\DescribeRuntimeVersionsResponse' {runtimeVersions} -> runtimeVersions) (\s@DescribeRuntimeVersionsResponse' {} a -> s {runtimeVersions = a} :: DescribeRuntimeVersionsResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | The response's http status code.
+describeRuntimeVersionsResponse_httpStatus :: Lens.Lens' DescribeRuntimeVersionsResponse Prelude.Int
+describeRuntimeVersionsResponse_httpStatus = Lens.lens (\DescribeRuntimeVersionsResponse' {httpStatus} -> httpStatus) (\s@DescribeRuntimeVersionsResponse' {} a -> s {httpStatus = a} :: DescribeRuntimeVersionsResponse)
+
+instance
+  Prelude.NFData
+    DescribeRuntimeVersionsResponse
+  where
+  rnf DescribeRuntimeVersionsResponse' {..} =
+    Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf runtimeVersions
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/DisassociateResource.hs b/gen/Amazonka/Synthetics/DisassociateResource.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/DisassociateResource.hs
@@ -0,0 +1,182 @@
+{-# 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.Synthetics.DisassociateResource
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Removes a canary from a group. You must run this operation in the Region
+-- where the canary exists.
+module Amazonka.Synthetics.DisassociateResource
+  ( -- * Creating a Request
+    DisassociateResource (..),
+    newDisassociateResource,
+
+    -- * Request Lenses
+    disassociateResource_groupIdentifier,
+    disassociateResource_resourceArn,
+
+    -- * Destructuring the Response
+    DisassociateResourceResponse (..),
+    newDisassociateResourceResponse,
+
+    -- * Response Lenses
+    disassociateResourceResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newDisassociateResource' smart constructor.
+data DisassociateResource = DisassociateResource'
+  { -- | Specifies the group. You can specify the group name, the ARN, or the
+    -- group ID as the @GroupIdentifier@.
+    groupIdentifier :: Prelude.Text,
+    -- | The ARN of the canary that you want to remove from the specified group.
+    resourceArn :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DisassociateResource' 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:
+--
+-- 'groupIdentifier', 'disassociateResource_groupIdentifier' - Specifies the group. You can specify the group name, the ARN, or the
+-- group ID as the @GroupIdentifier@.
+--
+-- 'resourceArn', 'disassociateResource_resourceArn' - The ARN of the canary that you want to remove from the specified group.
+newDisassociateResource ::
+  -- | 'groupIdentifier'
+  Prelude.Text ->
+  -- | 'resourceArn'
+  Prelude.Text ->
+  DisassociateResource
+newDisassociateResource
+  pGroupIdentifier_
+  pResourceArn_ =
+    DisassociateResource'
+      { groupIdentifier =
+          pGroupIdentifier_,
+        resourceArn = pResourceArn_
+      }
+
+-- | Specifies the group. You can specify the group name, the ARN, or the
+-- group ID as the @GroupIdentifier@.
+disassociateResource_groupIdentifier :: Lens.Lens' DisassociateResource Prelude.Text
+disassociateResource_groupIdentifier = Lens.lens (\DisassociateResource' {groupIdentifier} -> groupIdentifier) (\s@DisassociateResource' {} a -> s {groupIdentifier = a} :: DisassociateResource)
+
+-- | The ARN of the canary that you want to remove from the specified group.
+disassociateResource_resourceArn :: Lens.Lens' DisassociateResource Prelude.Text
+disassociateResource_resourceArn = Lens.lens (\DisassociateResource' {resourceArn} -> resourceArn) (\s@DisassociateResource' {} a -> s {resourceArn = a} :: DisassociateResource)
+
+instance Core.AWSRequest DisassociateResource where
+  type
+    AWSResponse DisassociateResource =
+      DisassociateResourceResponse
+  request overrides =
+    Request.patchJSON (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          DisassociateResourceResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable DisassociateResource where
+  hashWithSalt _salt DisassociateResource' {..} =
+    _salt
+      `Prelude.hashWithSalt` groupIdentifier
+      `Prelude.hashWithSalt` resourceArn
+
+instance Prelude.NFData DisassociateResource where
+  rnf DisassociateResource' {..} =
+    Prelude.rnf groupIdentifier
+      `Prelude.seq` Prelude.rnf resourceArn
+
+instance Data.ToHeaders DisassociateResource where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON DisassociateResource where
+  toJSON DisassociateResource' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [Prelude.Just ("ResourceArn" Data..= resourceArn)]
+      )
+
+instance Data.ToPath DisassociateResource where
+  toPath DisassociateResource' {..} =
+    Prelude.mconcat
+      [ "/group/",
+        Data.toBS groupIdentifier,
+        "/disassociate"
+      ]
+
+instance Data.ToQuery DisassociateResource where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newDisassociateResourceResponse' smart constructor.
+data DisassociateResourceResponse = DisassociateResourceResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'DisassociateResourceResponse' 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:
+--
+-- 'httpStatus', 'disassociateResourceResponse_httpStatus' - The response's http status code.
+newDisassociateResourceResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  DisassociateResourceResponse
+newDisassociateResourceResponse pHttpStatus_ =
+  DisassociateResourceResponse'
+    { httpStatus =
+        pHttpStatus_
+    }
+
+-- | The response's http status code.
+disassociateResourceResponse_httpStatus :: Lens.Lens' DisassociateResourceResponse Prelude.Int
+disassociateResourceResponse_httpStatus = Lens.lens (\DisassociateResourceResponse' {httpStatus} -> httpStatus) (\s@DisassociateResourceResponse' {} a -> s {httpStatus = a} :: DisassociateResourceResponse)
+
+instance Prelude.NFData DisassociateResourceResponse where
+  rnf DisassociateResourceResponse' {..} =
+    Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/GetCanary.hs b/gen/Amazonka/Synthetics/GetCanary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/GetCanary.hs
@@ -0,0 +1,157 @@
+{-# 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.Synthetics.GetCanary
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Retrieves complete information about one canary. You must specify the
+-- name of the canary that you want. To get a list of canaries and their
+-- names, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+module Amazonka.Synthetics.GetCanary
+  ( -- * Creating a Request
+    GetCanary (..),
+    newGetCanary,
+
+    -- * Request Lenses
+    getCanary_name,
+
+    -- * Destructuring the Response
+    GetCanaryResponse (..),
+    newGetCanaryResponse,
+
+    -- * Response Lenses
+    getCanaryResponse_canary,
+    getCanaryResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newGetCanary' smart constructor.
+data GetCanary = GetCanary'
+  { -- | The name of the canary that you want details for.
+    name :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetCanary' 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:
+--
+-- 'name', 'getCanary_name' - The name of the canary that you want details for.
+newGetCanary ::
+  -- | 'name'
+  Prelude.Text ->
+  GetCanary
+newGetCanary pName_ = GetCanary' {name = pName_}
+
+-- | The name of the canary that you want details for.
+getCanary_name :: Lens.Lens' GetCanary Prelude.Text
+getCanary_name = Lens.lens (\GetCanary' {name} -> name) (\s@GetCanary' {} a -> s {name = a} :: GetCanary)
+
+instance Core.AWSRequest GetCanary where
+  type AWSResponse GetCanary = GetCanaryResponse
+  request overrides =
+    Request.get (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          GetCanaryResponse'
+            Prelude.<$> (x Data..?> "Canary")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable GetCanary where
+  hashWithSalt _salt GetCanary' {..} =
+    _salt `Prelude.hashWithSalt` name
+
+instance Prelude.NFData GetCanary where
+  rnf GetCanary' {..} = Prelude.rnf name
+
+instance Data.ToHeaders GetCanary where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath GetCanary where
+  toPath GetCanary' {..} =
+    Prelude.mconcat ["/canary/", Data.toBS name]
+
+instance Data.ToQuery GetCanary where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newGetCanaryResponse' smart constructor.
+data GetCanaryResponse = GetCanaryResponse'
+  { -- | A structure that contains the full information about the canary.
+    canary :: Prelude.Maybe Canary,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetCanaryResponse' 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:
+--
+-- 'canary', 'getCanaryResponse_canary' - A structure that contains the full information about the canary.
+--
+-- 'httpStatus', 'getCanaryResponse_httpStatus' - The response's http status code.
+newGetCanaryResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  GetCanaryResponse
+newGetCanaryResponse pHttpStatus_ =
+  GetCanaryResponse'
+    { canary = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | A structure that contains the full information about the canary.
+getCanaryResponse_canary :: Lens.Lens' GetCanaryResponse (Prelude.Maybe Canary)
+getCanaryResponse_canary = Lens.lens (\GetCanaryResponse' {canary} -> canary) (\s@GetCanaryResponse' {} a -> s {canary = a} :: GetCanaryResponse)
+
+-- | The response's http status code.
+getCanaryResponse_httpStatus :: Lens.Lens' GetCanaryResponse Prelude.Int
+getCanaryResponse_httpStatus = Lens.lens (\GetCanaryResponse' {httpStatus} -> httpStatus) (\s@GetCanaryResponse' {} a -> s {httpStatus = a} :: GetCanaryResponse)
+
+instance Prelude.NFData GetCanaryResponse where
+  rnf GetCanaryResponse' {..} =
+    Prelude.rnf canary
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/GetCanaryRuns.hs b/gen/Amazonka/Synthetics/GetCanaryRuns.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/GetCanaryRuns.hs
@@ -0,0 +1,229 @@
+{-# 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.Synthetics.GetCanaryRuns
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Retrieves a list of runs for a specified canary.
+module Amazonka.Synthetics.GetCanaryRuns
+  ( -- * Creating a Request
+    GetCanaryRuns (..),
+    newGetCanaryRuns,
+
+    -- * Request Lenses
+    getCanaryRuns_maxResults,
+    getCanaryRuns_nextToken,
+    getCanaryRuns_name,
+
+    -- * Destructuring the Response
+    GetCanaryRunsResponse (..),
+    newGetCanaryRunsResponse,
+
+    -- * Response Lenses
+    getCanaryRunsResponse_canaryRuns,
+    getCanaryRunsResponse_nextToken,
+    getCanaryRunsResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newGetCanaryRuns' smart constructor.
+data GetCanaryRuns = GetCanaryRuns'
+  { -- | Specify this parameter to limit how many runs are returned each time you
+    -- use the @GetCanaryRuns@ operation. If you omit this parameter, the
+    -- default of 100 is used.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @GetCanaryRuns@ operation to retrieve the
+    -- next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The name of the canary that you want to see runs for.
+    name :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetCanaryRuns' 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', 'getCanaryRuns_maxResults' - Specify this parameter to limit how many runs are returned each time you
+-- use the @GetCanaryRuns@ operation. If you omit this parameter, the
+-- default of 100 is used.
+--
+-- 'nextToken', 'getCanaryRuns_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @GetCanaryRuns@ operation to retrieve the
+-- next set of results.
+--
+-- 'name', 'getCanaryRuns_name' - The name of the canary that you want to see runs for.
+newGetCanaryRuns ::
+  -- | 'name'
+  Prelude.Text ->
+  GetCanaryRuns
+newGetCanaryRuns pName_ =
+  GetCanaryRuns'
+    { maxResults = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      name = pName_
+    }
+
+-- | Specify this parameter to limit how many runs are returned each time you
+-- use the @GetCanaryRuns@ operation. If you omit this parameter, the
+-- default of 100 is used.
+getCanaryRuns_maxResults :: Lens.Lens' GetCanaryRuns (Prelude.Maybe Prelude.Natural)
+getCanaryRuns_maxResults = Lens.lens (\GetCanaryRuns' {maxResults} -> maxResults) (\s@GetCanaryRuns' {} a -> s {maxResults = a} :: GetCanaryRuns)
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @GetCanaryRuns@ operation to retrieve the
+-- next set of results.
+getCanaryRuns_nextToken :: Lens.Lens' GetCanaryRuns (Prelude.Maybe Prelude.Text)
+getCanaryRuns_nextToken = Lens.lens (\GetCanaryRuns' {nextToken} -> nextToken) (\s@GetCanaryRuns' {} a -> s {nextToken = a} :: GetCanaryRuns)
+
+-- | The name of the canary that you want to see runs for.
+getCanaryRuns_name :: Lens.Lens' GetCanaryRuns Prelude.Text
+getCanaryRuns_name = Lens.lens (\GetCanaryRuns' {name} -> name) (\s@GetCanaryRuns' {} a -> s {name = a} :: GetCanaryRuns)
+
+instance Core.AWSRequest GetCanaryRuns where
+  type
+    AWSResponse GetCanaryRuns =
+      GetCanaryRunsResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          GetCanaryRunsResponse'
+            Prelude.<$> (x Data..?> "CanaryRuns" Core..!@ Prelude.mempty)
+            Prelude.<*> (x Data..?> "NextToken")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable GetCanaryRuns where
+  hashWithSalt _salt GetCanaryRuns' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` nextToken
+      `Prelude.hashWithSalt` name
+
+instance Prelude.NFData GetCanaryRuns where
+  rnf GetCanaryRuns' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf name
+
+instance Data.ToHeaders GetCanaryRuns where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON GetCanaryRuns where
+  toJSON GetCanaryRuns' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("MaxResults" Data..=) Prelude.<$> maxResults,
+            ("NextToken" Data..=) Prelude.<$> nextToken
+          ]
+      )
+
+instance Data.ToPath GetCanaryRuns where
+  toPath GetCanaryRuns' {..} =
+    Prelude.mconcat
+      ["/canary/", Data.toBS name, "/runs"]
+
+instance Data.ToQuery GetCanaryRuns where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newGetCanaryRunsResponse' smart constructor.
+data GetCanaryRunsResponse = GetCanaryRunsResponse'
+  { -- | An array of structures. Each structure contains the details of one of
+    -- the retrieved canary runs.
+    canaryRuns :: Prelude.Maybe [CanaryRun],
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @GetCanaryRuns@ operation to retrieve the
+    -- next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetCanaryRunsResponse' 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:
+--
+-- 'canaryRuns', 'getCanaryRunsResponse_canaryRuns' - An array of structures. Each structure contains the details of one of
+-- the retrieved canary runs.
+--
+-- 'nextToken', 'getCanaryRunsResponse_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @GetCanaryRuns@ operation to retrieve the
+-- next set of results.
+--
+-- 'httpStatus', 'getCanaryRunsResponse_httpStatus' - The response's http status code.
+newGetCanaryRunsResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  GetCanaryRunsResponse
+newGetCanaryRunsResponse pHttpStatus_ =
+  GetCanaryRunsResponse'
+    { canaryRuns =
+        Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | An array of structures. Each structure contains the details of one of
+-- the retrieved canary runs.
+getCanaryRunsResponse_canaryRuns :: Lens.Lens' GetCanaryRunsResponse (Prelude.Maybe [CanaryRun])
+getCanaryRunsResponse_canaryRuns = Lens.lens (\GetCanaryRunsResponse' {canaryRuns} -> canaryRuns) (\s@GetCanaryRunsResponse' {} a -> s {canaryRuns = a} :: GetCanaryRunsResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @GetCanaryRuns@ operation to retrieve the
+-- next set of results.
+getCanaryRunsResponse_nextToken :: Lens.Lens' GetCanaryRunsResponse (Prelude.Maybe Prelude.Text)
+getCanaryRunsResponse_nextToken = Lens.lens (\GetCanaryRunsResponse' {nextToken} -> nextToken) (\s@GetCanaryRunsResponse' {} a -> s {nextToken = a} :: GetCanaryRunsResponse)
+
+-- | The response's http status code.
+getCanaryRunsResponse_httpStatus :: Lens.Lens' GetCanaryRunsResponse Prelude.Int
+getCanaryRunsResponse_httpStatus = Lens.lens (\GetCanaryRunsResponse' {httpStatus} -> httpStatus) (\s@GetCanaryRunsResponse' {} a -> s {httpStatus = a} :: GetCanaryRunsResponse)
+
+instance Prelude.NFData GetCanaryRunsResponse where
+  rnf GetCanaryRunsResponse' {..} =
+    Prelude.rnf canaryRuns
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/GetGroup.hs b/gen/Amazonka/Synthetics/GetGroup.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/GetGroup.hs
@@ -0,0 +1,160 @@
+{-# 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.Synthetics.GetGroup
+-- 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 one group. Groups are a global resource, so
+-- you can use this operation from any Region.
+module Amazonka.Synthetics.GetGroup
+  ( -- * Creating a Request
+    GetGroup (..),
+    newGetGroup,
+
+    -- * Request Lenses
+    getGroup_groupIdentifier,
+
+    -- * Destructuring the Response
+    GetGroupResponse (..),
+    newGetGroupResponse,
+
+    -- * Response Lenses
+    getGroupResponse_group,
+    getGroupResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newGetGroup' smart constructor.
+data GetGroup = GetGroup'
+  { -- | Specifies the group to return information for. You can specify the group
+    -- name, the ARN, or the group ID as the @GroupIdentifier@.
+    groupIdentifier :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetGroup' 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:
+--
+-- 'groupIdentifier', 'getGroup_groupIdentifier' - Specifies the group to return information for. You can specify the group
+-- name, the ARN, or the group ID as the @GroupIdentifier@.
+newGetGroup ::
+  -- | 'groupIdentifier'
+  Prelude.Text ->
+  GetGroup
+newGetGroup pGroupIdentifier_ =
+  GetGroup' {groupIdentifier = pGroupIdentifier_}
+
+-- | Specifies the group to return information for. You can specify the group
+-- name, the ARN, or the group ID as the @GroupIdentifier@.
+getGroup_groupIdentifier :: Lens.Lens' GetGroup Prelude.Text
+getGroup_groupIdentifier = Lens.lens (\GetGroup' {groupIdentifier} -> groupIdentifier) (\s@GetGroup' {} a -> s {groupIdentifier = a} :: GetGroup)
+
+instance Core.AWSRequest GetGroup where
+  type AWSResponse GetGroup = GetGroupResponse
+  request overrides =
+    Request.get (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          GetGroupResponse'
+            Prelude.<$> (x Data..?> "Group")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable GetGroup where
+  hashWithSalt _salt GetGroup' {..} =
+    _salt `Prelude.hashWithSalt` groupIdentifier
+
+instance Prelude.NFData GetGroup where
+  rnf GetGroup' {..} = Prelude.rnf groupIdentifier
+
+instance Data.ToHeaders GetGroup where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath GetGroup where
+  toPath GetGroup' {..} =
+    Prelude.mconcat
+      ["/group/", Data.toBS groupIdentifier]
+
+instance Data.ToQuery GetGroup where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newGetGroupResponse' smart constructor.
+data GetGroupResponse = GetGroupResponse'
+  { -- | A structure that contains information about the group.
+    group' :: Prelude.Maybe Group,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GetGroupResponse' 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:
+--
+-- 'group'', 'getGroupResponse_group' - A structure that contains information about the group.
+--
+-- 'httpStatus', 'getGroupResponse_httpStatus' - The response's http status code.
+newGetGroupResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  GetGroupResponse
+newGetGroupResponse pHttpStatus_ =
+  GetGroupResponse'
+    { group' = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | A structure that contains information about the group.
+getGroupResponse_group :: Lens.Lens' GetGroupResponse (Prelude.Maybe Group)
+getGroupResponse_group = Lens.lens (\GetGroupResponse' {group'} -> group') (\s@GetGroupResponse' {} a -> s {group' = a} :: GetGroupResponse)
+
+-- | The response's http status code.
+getGroupResponse_httpStatus :: Lens.Lens' GetGroupResponse Prelude.Int
+getGroupResponse_httpStatus = Lens.lens (\GetGroupResponse' {httpStatus} -> httpStatus) (\s@GetGroupResponse' {} a -> s {httpStatus = a} :: GetGroupResponse)
+
+instance Prelude.NFData GetGroupResponse where
+  rnf GetGroupResponse' {..} =
+    Prelude.rnf group'
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/Lens.hs b/gen/Amazonka/Synthetics/Lens.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Lens.hs
@@ -0,0 +1,338 @@
+{-# 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.Synthetics.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.Synthetics.Lens
+  ( -- * Operations
+
+    -- ** AssociateResource
+    associateResource_groupIdentifier,
+    associateResource_resourceArn,
+    associateResourceResponse_httpStatus,
+
+    -- ** CreateCanary
+    createCanary_artifactConfig,
+    createCanary_failureRetentionPeriodInDays,
+    createCanary_runConfig,
+    createCanary_successRetentionPeriodInDays,
+    createCanary_tags,
+    createCanary_vpcConfig,
+    createCanary_name,
+    createCanary_code,
+    createCanary_artifactS3Location,
+    createCanary_executionRoleArn,
+    createCanary_schedule,
+    createCanary_runtimeVersion,
+    createCanaryResponse_canary,
+    createCanaryResponse_httpStatus,
+
+    -- ** CreateGroup
+    createGroup_tags,
+    createGroup_name,
+    createGroupResponse_group,
+    createGroupResponse_httpStatus,
+
+    -- ** DeleteCanary
+    deleteCanary_deleteLambda,
+    deleteCanary_name,
+    deleteCanaryResponse_httpStatus,
+
+    -- ** DeleteGroup
+    deleteGroup_groupIdentifier,
+    deleteGroupResponse_httpStatus,
+
+    -- ** DescribeCanaries
+    describeCanaries_maxResults,
+    describeCanaries_names,
+    describeCanaries_nextToken,
+    describeCanariesResponse_canaries,
+    describeCanariesResponse_nextToken,
+    describeCanariesResponse_httpStatus,
+
+    -- ** DescribeCanariesLastRun
+    describeCanariesLastRun_maxResults,
+    describeCanariesLastRun_names,
+    describeCanariesLastRun_nextToken,
+    describeCanariesLastRunResponse_canariesLastRun,
+    describeCanariesLastRunResponse_nextToken,
+    describeCanariesLastRunResponse_httpStatus,
+
+    -- ** DescribeRuntimeVersions
+    describeRuntimeVersions_maxResults,
+    describeRuntimeVersions_nextToken,
+    describeRuntimeVersionsResponse_nextToken,
+    describeRuntimeVersionsResponse_runtimeVersions,
+    describeRuntimeVersionsResponse_httpStatus,
+
+    -- ** DisassociateResource
+    disassociateResource_groupIdentifier,
+    disassociateResource_resourceArn,
+    disassociateResourceResponse_httpStatus,
+
+    -- ** GetCanary
+    getCanary_name,
+    getCanaryResponse_canary,
+    getCanaryResponse_httpStatus,
+
+    -- ** GetCanaryRuns
+    getCanaryRuns_maxResults,
+    getCanaryRuns_nextToken,
+    getCanaryRuns_name,
+    getCanaryRunsResponse_canaryRuns,
+    getCanaryRunsResponse_nextToken,
+    getCanaryRunsResponse_httpStatus,
+
+    -- ** GetGroup
+    getGroup_groupIdentifier,
+    getGroupResponse_group,
+    getGroupResponse_httpStatus,
+
+    -- ** ListAssociatedGroups
+    listAssociatedGroups_maxResults,
+    listAssociatedGroups_nextToken,
+    listAssociatedGroups_resourceArn,
+    listAssociatedGroupsResponse_groups,
+    listAssociatedGroupsResponse_nextToken,
+    listAssociatedGroupsResponse_httpStatus,
+
+    -- ** ListGroupResources
+    listGroupResources_maxResults,
+    listGroupResources_nextToken,
+    listGroupResources_groupIdentifier,
+    listGroupResourcesResponse_nextToken,
+    listGroupResourcesResponse_resources,
+    listGroupResourcesResponse_httpStatus,
+
+    -- ** ListGroups
+    listGroups_maxResults,
+    listGroups_nextToken,
+    listGroupsResponse_groups,
+    listGroupsResponse_nextToken,
+    listGroupsResponse_httpStatus,
+
+    -- ** ListTagsForResource
+    listTagsForResource_resourceArn,
+    listTagsForResourceResponse_tags,
+    listTagsForResourceResponse_httpStatus,
+
+    -- ** StartCanary
+    startCanary_name,
+    startCanaryResponse_httpStatus,
+
+    -- ** StopCanary
+    stopCanary_name,
+    stopCanaryResponse_httpStatus,
+
+    -- ** TagResource
+    tagResource_resourceArn,
+    tagResource_tags,
+    tagResourceResponse_httpStatus,
+
+    -- ** UntagResource
+    untagResource_resourceArn,
+    untagResource_tagKeys,
+    untagResourceResponse_httpStatus,
+
+    -- ** UpdateCanary
+    updateCanary_artifactConfig,
+    updateCanary_artifactS3Location,
+    updateCanary_code,
+    updateCanary_executionRoleArn,
+    updateCanary_failureRetentionPeriodInDays,
+    updateCanary_runConfig,
+    updateCanary_runtimeVersion,
+    updateCanary_schedule,
+    updateCanary_successRetentionPeriodInDays,
+    updateCanary_visualReference,
+    updateCanary_vpcConfig,
+    updateCanary_name,
+    updateCanaryResponse_httpStatus,
+
+    -- * Types
+
+    -- ** ArtifactConfigInput
+    artifactConfigInput_s3Encryption,
+
+    -- ** ArtifactConfigOutput
+    artifactConfigOutput_s3Encryption,
+
+    -- ** BaseScreenshot
+    baseScreenshot_ignoreCoordinates,
+    baseScreenshot_screenshotName,
+
+    -- ** Canary
+    canary_artifactConfig,
+    canary_artifactS3Location,
+    canary_code,
+    canary_engineArn,
+    canary_executionRoleArn,
+    canary_failureRetentionPeriodInDays,
+    canary_id,
+    canary_name,
+    canary_runConfig,
+    canary_runtimeVersion,
+    canary_schedule,
+    canary_status,
+    canary_successRetentionPeriodInDays,
+    canary_tags,
+    canary_timeline,
+    canary_visualReference,
+    canary_vpcConfig,
+
+    -- ** CanaryCodeInput
+    canaryCodeInput_s3Bucket,
+    canaryCodeInput_s3Key,
+    canaryCodeInput_s3Version,
+    canaryCodeInput_zipFile,
+    canaryCodeInput_handler,
+
+    -- ** CanaryCodeOutput
+    canaryCodeOutput_handler,
+    canaryCodeOutput_sourceLocationArn,
+
+    -- ** CanaryLastRun
+    canaryLastRun_canaryName,
+    canaryLastRun_lastRun,
+
+    -- ** CanaryRun
+    canaryRun_artifactS3Location,
+    canaryRun_id,
+    canaryRun_name,
+    canaryRun_status,
+    canaryRun_timeline,
+
+    -- ** CanaryRunConfigInput
+    canaryRunConfigInput_activeTracing,
+    canaryRunConfigInput_environmentVariables,
+    canaryRunConfigInput_memoryInMB,
+    canaryRunConfigInput_timeoutInSeconds,
+
+    -- ** CanaryRunConfigOutput
+    canaryRunConfigOutput_activeTracing,
+    canaryRunConfigOutput_memoryInMB,
+    canaryRunConfigOutput_timeoutInSeconds,
+
+    -- ** CanaryRunStatus
+    canaryRunStatus_state,
+    canaryRunStatus_stateReason,
+    canaryRunStatus_stateReasonCode,
+
+    -- ** CanaryRunTimeline
+    canaryRunTimeline_completed,
+    canaryRunTimeline_started,
+
+    -- ** CanaryScheduleInput
+    canaryScheduleInput_durationInSeconds,
+    canaryScheduleInput_expression,
+
+    -- ** CanaryScheduleOutput
+    canaryScheduleOutput_durationInSeconds,
+    canaryScheduleOutput_expression,
+
+    -- ** CanaryStatus
+    canaryStatus_state,
+    canaryStatus_stateReason,
+    canaryStatus_stateReasonCode,
+
+    -- ** CanaryTimeline
+    canaryTimeline_created,
+    canaryTimeline_lastModified,
+    canaryTimeline_lastStarted,
+    canaryTimeline_lastStopped,
+
+    -- ** Group
+    group_arn,
+    group_createdTime,
+    group_id,
+    group_lastModifiedTime,
+    group_name,
+    group_tags,
+
+    -- ** GroupSummary
+    groupSummary_arn,
+    groupSummary_id,
+    groupSummary_name,
+
+    -- ** RuntimeVersion
+    runtimeVersion_deprecationDate,
+    runtimeVersion_description,
+    runtimeVersion_releaseDate,
+    runtimeVersion_versionName,
+
+    -- ** S3EncryptionConfig
+    s3EncryptionConfig_encryptionMode,
+    s3EncryptionConfig_kmsKeyArn,
+
+    -- ** VisualReferenceInput
+    visualReferenceInput_baseScreenshots,
+    visualReferenceInput_baseCanaryRunId,
+
+    -- ** VisualReferenceOutput
+    visualReferenceOutput_baseCanaryRunId,
+    visualReferenceOutput_baseScreenshots,
+
+    -- ** VpcConfigInput
+    vpcConfigInput_securityGroupIds,
+    vpcConfigInput_subnetIds,
+
+    -- ** VpcConfigOutput
+    vpcConfigOutput_securityGroupIds,
+    vpcConfigOutput_subnetIds,
+    vpcConfigOutput_vpcId,
+  )
+where
+
+import Amazonka.Synthetics.AssociateResource
+import Amazonka.Synthetics.CreateCanary
+import Amazonka.Synthetics.CreateGroup
+import Amazonka.Synthetics.DeleteCanary
+import Amazonka.Synthetics.DeleteGroup
+import Amazonka.Synthetics.DescribeCanaries
+import Amazonka.Synthetics.DescribeCanariesLastRun
+import Amazonka.Synthetics.DescribeRuntimeVersions
+import Amazonka.Synthetics.DisassociateResource
+import Amazonka.Synthetics.GetCanary
+import Amazonka.Synthetics.GetCanaryRuns
+import Amazonka.Synthetics.GetGroup
+import Amazonka.Synthetics.ListAssociatedGroups
+import Amazonka.Synthetics.ListGroupResources
+import Amazonka.Synthetics.ListGroups
+import Amazonka.Synthetics.ListTagsForResource
+import Amazonka.Synthetics.StartCanary
+import Amazonka.Synthetics.StopCanary
+import Amazonka.Synthetics.TagResource
+import Amazonka.Synthetics.Types.ArtifactConfigInput
+import Amazonka.Synthetics.Types.ArtifactConfigOutput
+import Amazonka.Synthetics.Types.BaseScreenshot
+import Amazonka.Synthetics.Types.Canary
+import Amazonka.Synthetics.Types.CanaryCodeInput
+import Amazonka.Synthetics.Types.CanaryCodeOutput
+import Amazonka.Synthetics.Types.CanaryLastRun
+import Amazonka.Synthetics.Types.CanaryRun
+import Amazonka.Synthetics.Types.CanaryRunConfigInput
+import Amazonka.Synthetics.Types.CanaryRunConfigOutput
+import Amazonka.Synthetics.Types.CanaryRunStatus
+import Amazonka.Synthetics.Types.CanaryRunTimeline
+import Amazonka.Synthetics.Types.CanaryScheduleInput
+import Amazonka.Synthetics.Types.CanaryScheduleOutput
+import Amazonka.Synthetics.Types.CanaryStatus
+import Amazonka.Synthetics.Types.CanaryTimeline
+import Amazonka.Synthetics.Types.Group
+import Amazonka.Synthetics.Types.GroupSummary
+import Amazonka.Synthetics.Types.RuntimeVersion
+import Amazonka.Synthetics.Types.S3EncryptionConfig
+import Amazonka.Synthetics.Types.VisualReferenceInput
+import Amazonka.Synthetics.Types.VisualReferenceOutput
+import Amazonka.Synthetics.Types.VpcConfigInput
+import Amazonka.Synthetics.Types.VpcConfigOutput
+import Amazonka.Synthetics.UntagResource
+import Amazonka.Synthetics.UpdateCanary
diff --git a/gen/Amazonka/Synthetics/ListAssociatedGroups.hs b/gen/Amazonka/Synthetics/ListAssociatedGroups.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/ListAssociatedGroups.hs
@@ -0,0 +1,230 @@
+{-# 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.Synthetics.ListAssociatedGroups
+-- 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 a list of the groups that the specified canary is associated
+-- with. The canary that you specify must be in the current Region.
+module Amazonka.Synthetics.ListAssociatedGroups
+  ( -- * Creating a Request
+    ListAssociatedGroups (..),
+    newListAssociatedGroups,
+
+    -- * Request Lenses
+    listAssociatedGroups_maxResults,
+    listAssociatedGroups_nextToken,
+    listAssociatedGroups_resourceArn,
+
+    -- * Destructuring the Response
+    ListAssociatedGroupsResponse (..),
+    newListAssociatedGroupsResponse,
+
+    -- * Response Lenses
+    listAssociatedGroupsResponse_groups,
+    listAssociatedGroupsResponse_nextToken,
+    listAssociatedGroupsResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newListAssociatedGroups' smart constructor.
+data ListAssociatedGroups = ListAssociatedGroups'
+  { -- | Specify this parameter to limit how many groups are returned each time
+    -- you use the @ListAssociatedGroups@ operation. If you omit this
+    -- parameter, the default of 20 is used.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent operation to retrieve the next set of
+    -- results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The ARN of the canary that you want to view groups for.
+    resourceArn :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListAssociatedGroups' 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', 'listAssociatedGroups_maxResults' - Specify this parameter to limit how many groups are returned each time
+-- you use the @ListAssociatedGroups@ operation. If you omit this
+-- parameter, the default of 20 is used.
+--
+-- 'nextToken', 'listAssociatedGroups_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+--
+-- 'resourceArn', 'listAssociatedGroups_resourceArn' - The ARN of the canary that you want to view groups for.
+newListAssociatedGroups ::
+  -- | 'resourceArn'
+  Prelude.Text ->
+  ListAssociatedGroups
+newListAssociatedGroups pResourceArn_ =
+  ListAssociatedGroups'
+    { maxResults = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      resourceArn = pResourceArn_
+    }
+
+-- | Specify this parameter to limit how many groups are returned each time
+-- you use the @ListAssociatedGroups@ operation. If you omit this
+-- parameter, the default of 20 is used.
+listAssociatedGroups_maxResults :: Lens.Lens' ListAssociatedGroups (Prelude.Maybe Prelude.Natural)
+listAssociatedGroups_maxResults = Lens.lens (\ListAssociatedGroups' {maxResults} -> maxResults) (\s@ListAssociatedGroups' {} a -> s {maxResults = a} :: ListAssociatedGroups)
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+listAssociatedGroups_nextToken :: Lens.Lens' ListAssociatedGroups (Prelude.Maybe Prelude.Text)
+listAssociatedGroups_nextToken = Lens.lens (\ListAssociatedGroups' {nextToken} -> nextToken) (\s@ListAssociatedGroups' {} a -> s {nextToken = a} :: ListAssociatedGroups)
+
+-- | The ARN of the canary that you want to view groups for.
+listAssociatedGroups_resourceArn :: Lens.Lens' ListAssociatedGroups Prelude.Text
+listAssociatedGroups_resourceArn = Lens.lens (\ListAssociatedGroups' {resourceArn} -> resourceArn) (\s@ListAssociatedGroups' {} a -> s {resourceArn = a} :: ListAssociatedGroups)
+
+instance Core.AWSRequest ListAssociatedGroups where
+  type
+    AWSResponse ListAssociatedGroups =
+      ListAssociatedGroupsResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          ListAssociatedGroupsResponse'
+            Prelude.<$> (x Data..?> "Groups" Core..!@ Prelude.mempty)
+            Prelude.<*> (x Data..?> "NextToken")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable ListAssociatedGroups where
+  hashWithSalt _salt ListAssociatedGroups' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` nextToken
+      `Prelude.hashWithSalt` resourceArn
+
+instance Prelude.NFData ListAssociatedGroups where
+  rnf ListAssociatedGroups' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf resourceArn
+
+instance Data.ToHeaders ListAssociatedGroups where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON ListAssociatedGroups where
+  toJSON ListAssociatedGroups' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("MaxResults" Data..=) Prelude.<$> maxResults,
+            ("NextToken" Data..=) Prelude.<$> nextToken
+          ]
+      )
+
+instance Data.ToPath ListAssociatedGroups where
+  toPath ListAssociatedGroups' {..} =
+    Prelude.mconcat
+      ["/resource/", Data.toBS resourceArn, "/groups"]
+
+instance Data.ToQuery ListAssociatedGroups where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newListAssociatedGroupsResponse' smart constructor.
+data ListAssociatedGroupsResponse = ListAssociatedGroupsResponse'
+  { -- | An array of structures that contain information about the groups that
+    -- this canary is associated with.
+    groups :: Prelude.Maybe [GroupSummary],
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @ListAssociatedGroups@ operation to retrieve
+    -- the next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListAssociatedGroupsResponse' 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:
+--
+-- 'groups', 'listAssociatedGroupsResponse_groups' - An array of structures that contain information about the groups that
+-- this canary is associated with.
+--
+-- 'nextToken', 'listAssociatedGroupsResponse_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @ListAssociatedGroups@ operation to retrieve
+-- the next set of results.
+--
+-- 'httpStatus', 'listAssociatedGroupsResponse_httpStatus' - The response's http status code.
+newListAssociatedGroupsResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  ListAssociatedGroupsResponse
+newListAssociatedGroupsResponse pHttpStatus_ =
+  ListAssociatedGroupsResponse'
+    { groups =
+        Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | An array of structures that contain information about the groups that
+-- this canary is associated with.
+listAssociatedGroupsResponse_groups :: Lens.Lens' ListAssociatedGroupsResponse (Prelude.Maybe [GroupSummary])
+listAssociatedGroupsResponse_groups = Lens.lens (\ListAssociatedGroupsResponse' {groups} -> groups) (\s@ListAssociatedGroupsResponse' {} a -> s {groups = a} :: ListAssociatedGroupsResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @ListAssociatedGroups@ operation to retrieve
+-- the next set of results.
+listAssociatedGroupsResponse_nextToken :: Lens.Lens' ListAssociatedGroupsResponse (Prelude.Maybe Prelude.Text)
+listAssociatedGroupsResponse_nextToken = Lens.lens (\ListAssociatedGroupsResponse' {nextToken} -> nextToken) (\s@ListAssociatedGroupsResponse' {} a -> s {nextToken = a} :: ListAssociatedGroupsResponse)
+
+-- | The response's http status code.
+listAssociatedGroupsResponse_httpStatus :: Lens.Lens' ListAssociatedGroupsResponse Prelude.Int
+listAssociatedGroupsResponse_httpStatus = Lens.lens (\ListAssociatedGroupsResponse' {httpStatus} -> httpStatus) (\s@ListAssociatedGroupsResponse' {} a -> s {httpStatus = a} :: ListAssociatedGroupsResponse)
+
+instance Prelude.NFData ListAssociatedGroupsResponse where
+  rnf ListAssociatedGroupsResponse' {..} =
+    Prelude.rnf groups
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/ListGroupResources.hs b/gen/Amazonka/Synthetics/ListGroupResources.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/ListGroupResources.hs
@@ -0,0 +1,233 @@
+{-# 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.Synthetics.ListGroupResources
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- This operation returns a list of the ARNs of the canaries that are
+-- associated with the specified group.
+module Amazonka.Synthetics.ListGroupResources
+  ( -- * Creating a Request
+    ListGroupResources (..),
+    newListGroupResources,
+
+    -- * Request Lenses
+    listGroupResources_maxResults,
+    listGroupResources_nextToken,
+    listGroupResources_groupIdentifier,
+
+    -- * Destructuring the Response
+    ListGroupResourcesResponse (..),
+    newListGroupResourcesResponse,
+
+    -- * Response Lenses
+    listGroupResourcesResponse_nextToken,
+    listGroupResourcesResponse_resources,
+    listGroupResourcesResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newListGroupResources' smart constructor.
+data ListGroupResources = ListGroupResources'
+  { -- | Specify this parameter to limit how many canary ARNs are returned each
+    -- time you use the @ListGroupResources@ operation. If you omit this
+    -- parameter, the default of 20 is used.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent operation to retrieve the next set of
+    -- results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | Specifies the group to return information for. You can specify the group
+    -- name, the ARN, or the group ID as the @GroupIdentifier@.
+    groupIdentifier :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListGroupResources' 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', 'listGroupResources_maxResults' - Specify this parameter to limit how many canary ARNs are returned each
+-- time you use the @ListGroupResources@ operation. If you omit this
+-- parameter, the default of 20 is used.
+--
+-- 'nextToken', 'listGroupResources_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+--
+-- 'groupIdentifier', 'listGroupResources_groupIdentifier' - Specifies the group to return information for. You can specify the group
+-- name, the ARN, or the group ID as the @GroupIdentifier@.
+newListGroupResources ::
+  -- | 'groupIdentifier'
+  Prelude.Text ->
+  ListGroupResources
+newListGroupResources pGroupIdentifier_ =
+  ListGroupResources'
+    { maxResults = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      groupIdentifier = pGroupIdentifier_
+    }
+
+-- | Specify this parameter to limit how many canary ARNs are returned each
+-- time you use the @ListGroupResources@ operation. If you omit this
+-- parameter, the default of 20 is used.
+listGroupResources_maxResults :: Lens.Lens' ListGroupResources (Prelude.Maybe Prelude.Natural)
+listGroupResources_maxResults = Lens.lens (\ListGroupResources' {maxResults} -> maxResults) (\s@ListGroupResources' {} a -> s {maxResults = a} :: ListGroupResources)
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+listGroupResources_nextToken :: Lens.Lens' ListGroupResources (Prelude.Maybe Prelude.Text)
+listGroupResources_nextToken = Lens.lens (\ListGroupResources' {nextToken} -> nextToken) (\s@ListGroupResources' {} a -> s {nextToken = a} :: ListGroupResources)
+
+-- | Specifies the group to return information for. You can specify the group
+-- name, the ARN, or the group ID as the @GroupIdentifier@.
+listGroupResources_groupIdentifier :: Lens.Lens' ListGroupResources Prelude.Text
+listGroupResources_groupIdentifier = Lens.lens (\ListGroupResources' {groupIdentifier} -> groupIdentifier) (\s@ListGroupResources' {} a -> s {groupIdentifier = a} :: ListGroupResources)
+
+instance Core.AWSRequest ListGroupResources where
+  type
+    AWSResponse ListGroupResources =
+      ListGroupResourcesResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          ListGroupResourcesResponse'
+            Prelude.<$> (x Data..?> "NextToken")
+            Prelude.<*> (x Data..?> "Resources" Core..!@ Prelude.mempty)
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable ListGroupResources where
+  hashWithSalt _salt ListGroupResources' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` nextToken
+      `Prelude.hashWithSalt` groupIdentifier
+
+instance Prelude.NFData ListGroupResources where
+  rnf ListGroupResources' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf groupIdentifier
+
+instance Data.ToHeaders ListGroupResources where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON ListGroupResources where
+  toJSON ListGroupResources' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("MaxResults" Data..=) Prelude.<$> maxResults,
+            ("NextToken" Data..=) Prelude.<$> nextToken
+          ]
+      )
+
+instance Data.ToPath ListGroupResources where
+  toPath ListGroupResources' {..} =
+    Prelude.mconcat
+      ["/group/", Data.toBS groupIdentifier, "/resources"]
+
+instance Data.ToQuery ListGroupResources where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newListGroupResourcesResponse' smart constructor.
+data ListGroupResourcesResponse = ListGroupResourcesResponse'
+  { -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @ListGroupResources@ operation to retrieve
+    -- the next set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | An array of ARNs. These ARNs are for the canaries that are associated
+    -- with the group.
+    resources :: Prelude.Maybe [Prelude.Text],
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListGroupResourcesResponse' 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:
+--
+-- 'nextToken', 'listGroupResourcesResponse_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @ListGroupResources@ operation to retrieve
+-- the next set of results.
+--
+-- 'resources', 'listGroupResourcesResponse_resources' - An array of ARNs. These ARNs are for the canaries that are associated
+-- with the group.
+--
+-- 'httpStatus', 'listGroupResourcesResponse_httpStatus' - The response's http status code.
+newListGroupResourcesResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  ListGroupResourcesResponse
+newListGroupResourcesResponse pHttpStatus_ =
+  ListGroupResourcesResponse'
+    { nextToken =
+        Prelude.Nothing,
+      resources = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @ListGroupResources@ operation to retrieve
+-- the next set of results.
+listGroupResourcesResponse_nextToken :: Lens.Lens' ListGroupResourcesResponse (Prelude.Maybe Prelude.Text)
+listGroupResourcesResponse_nextToken = Lens.lens (\ListGroupResourcesResponse' {nextToken} -> nextToken) (\s@ListGroupResourcesResponse' {} a -> s {nextToken = a} :: ListGroupResourcesResponse)
+
+-- | An array of ARNs. These ARNs are for the canaries that are associated
+-- with the group.
+listGroupResourcesResponse_resources :: Lens.Lens' ListGroupResourcesResponse (Prelude.Maybe [Prelude.Text])
+listGroupResourcesResponse_resources = Lens.lens (\ListGroupResourcesResponse' {resources} -> resources) (\s@ListGroupResourcesResponse' {} a -> s {resources = a} :: ListGroupResourcesResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | The response's http status code.
+listGroupResourcesResponse_httpStatus :: Lens.Lens' ListGroupResourcesResponse Prelude.Int
+listGroupResourcesResponse_httpStatus = Lens.lens (\ListGroupResourcesResponse' {httpStatus} -> httpStatus) (\s@ListGroupResourcesResponse' {} a -> s {httpStatus = a} :: ListGroupResourcesResponse)
+
+instance Prelude.NFData ListGroupResourcesResponse where
+  rnf ListGroupResourcesResponse' {..} =
+    Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf resources
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/ListGroups.hs b/gen/Amazonka/Synthetics/ListGroups.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/ListGroups.hs
@@ -0,0 +1,208 @@
+{-# 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.Synthetics.ListGroups
+-- 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 a list of all groups in the account, displaying their names,
+-- unique IDs, and ARNs. The groups from all Regions are returned.
+module Amazonka.Synthetics.ListGroups
+  ( -- * Creating a Request
+    ListGroups (..),
+    newListGroups,
+
+    -- * Request Lenses
+    listGroups_maxResults,
+    listGroups_nextToken,
+
+    -- * Destructuring the Response
+    ListGroupsResponse (..),
+    newListGroupsResponse,
+
+    -- * Response Lenses
+    listGroupsResponse_groups,
+    listGroupsResponse_nextToken,
+    listGroupsResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newListGroups' smart constructor.
+data ListGroups = ListGroups'
+  { -- | Specify this parameter to limit how many groups are returned each time
+    -- you use the @ListGroups@ operation. If you omit this parameter, the
+    -- default of 20 is used.
+    maxResults :: Prelude.Maybe Prelude.Natural,
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent operation to retrieve the next set of
+    -- results.
+    nextToken :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListGroups' 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', 'listGroups_maxResults' - Specify this parameter to limit how many groups are returned each time
+-- you use the @ListGroups@ operation. If you omit this parameter, the
+-- default of 20 is used.
+--
+-- 'nextToken', 'listGroups_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+newListGroups ::
+  ListGroups
+newListGroups =
+  ListGroups'
+    { maxResults = Prelude.Nothing,
+      nextToken = Prelude.Nothing
+    }
+
+-- | Specify this parameter to limit how many groups are returned each time
+-- you use the @ListGroups@ operation. If you omit this parameter, the
+-- default of 20 is used.
+listGroups_maxResults :: Lens.Lens' ListGroups (Prelude.Maybe Prelude.Natural)
+listGroups_maxResults = Lens.lens (\ListGroups' {maxResults} -> maxResults) (\s@ListGroups' {} a -> s {maxResults = a} :: ListGroups)
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent operation to retrieve the next set of
+-- results.
+listGroups_nextToken :: Lens.Lens' ListGroups (Prelude.Maybe Prelude.Text)
+listGroups_nextToken = Lens.lens (\ListGroups' {nextToken} -> nextToken) (\s@ListGroups' {} a -> s {nextToken = a} :: ListGroups)
+
+instance Core.AWSRequest ListGroups where
+  type AWSResponse ListGroups = ListGroupsResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          ListGroupsResponse'
+            Prelude.<$> (x Data..?> "Groups" Core..!@ Prelude.mempty)
+            Prelude.<*> (x Data..?> "NextToken")
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable ListGroups where
+  hashWithSalt _salt ListGroups' {..} =
+    _salt
+      `Prelude.hashWithSalt` maxResults
+      `Prelude.hashWithSalt` nextToken
+
+instance Prelude.NFData ListGroups where
+  rnf ListGroups' {..} =
+    Prelude.rnf maxResults
+      `Prelude.seq` Prelude.rnf nextToken
+
+instance Data.ToHeaders ListGroups where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON ListGroups where
+  toJSON ListGroups' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("MaxResults" Data..=) Prelude.<$> maxResults,
+            ("NextToken" Data..=) Prelude.<$> nextToken
+          ]
+      )
+
+instance Data.ToPath ListGroups where
+  toPath = Prelude.const "/groups"
+
+instance Data.ToQuery ListGroups where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newListGroupsResponse' smart constructor.
+data ListGroupsResponse = ListGroupsResponse'
+  { -- | An array of structures that each contain information about one group.
+    groups :: Prelude.Maybe [GroupSummary],
+    -- | A token that indicates that there is more data available. You can use
+    -- this token in a subsequent @ListGroups@ operation to retrieve the next
+    -- set of results.
+    nextToken :: Prelude.Maybe Prelude.Text,
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListGroupsResponse' 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:
+--
+-- 'groups', 'listGroupsResponse_groups' - An array of structures that each contain information about one group.
+--
+-- 'nextToken', 'listGroupsResponse_nextToken' - A token that indicates that there is more data available. You can use
+-- this token in a subsequent @ListGroups@ operation to retrieve the next
+-- set of results.
+--
+-- 'httpStatus', 'listGroupsResponse_httpStatus' - The response's http status code.
+newListGroupsResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  ListGroupsResponse
+newListGroupsResponse pHttpStatus_ =
+  ListGroupsResponse'
+    { groups = Prelude.Nothing,
+      nextToken = Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | An array of structures that each contain information about one group.
+listGroupsResponse_groups :: Lens.Lens' ListGroupsResponse (Prelude.Maybe [GroupSummary])
+listGroupsResponse_groups = Lens.lens (\ListGroupsResponse' {groups} -> groups) (\s@ListGroupsResponse' {} a -> s {groups = a} :: ListGroupsResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | A token that indicates that there is more data available. You can use
+-- this token in a subsequent @ListGroups@ operation to retrieve the next
+-- set of results.
+listGroupsResponse_nextToken :: Lens.Lens' ListGroupsResponse (Prelude.Maybe Prelude.Text)
+listGroupsResponse_nextToken = Lens.lens (\ListGroupsResponse' {nextToken} -> nextToken) (\s@ListGroupsResponse' {} a -> s {nextToken = a} :: ListGroupsResponse)
+
+-- | The response's http status code.
+listGroupsResponse_httpStatus :: Lens.Lens' ListGroupsResponse Prelude.Int
+listGroupsResponse_httpStatus = Lens.lens (\ListGroupsResponse' {httpStatus} -> httpStatus) (\s@ListGroupsResponse' {} a -> s {httpStatus = a} :: ListGroupsResponse)
+
+instance Prelude.NFData ListGroupsResponse where
+  rnf ListGroupsResponse' {..} =
+    Prelude.rnf groups
+      `Prelude.seq` Prelude.rnf nextToken
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/ListTagsForResource.hs b/gen/Amazonka/Synthetics/ListTagsForResource.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/ListTagsForResource.hs
@@ -0,0 +1,180 @@
+{-# 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.Synthetics.ListTagsForResource
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Displays the tags associated with a canary or group.
+module Amazonka.Synthetics.ListTagsForResource
+  ( -- * Creating a Request
+    ListTagsForResource (..),
+    newListTagsForResource,
+
+    -- * Request Lenses
+    listTagsForResource_resourceArn,
+
+    -- * Destructuring the Response
+    ListTagsForResourceResponse (..),
+    newListTagsForResourceResponse,
+
+    -- * Response Lenses
+    listTagsForResourceResponse_tags,
+    listTagsForResourceResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newListTagsForResource' smart constructor.
+data ListTagsForResource = ListTagsForResource'
+  { -- | The ARN of the canary or group that you want to view tags for.
+    --
+    -- The ARN format of a canary is
+    -- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+    --
+    -- The ARN format of a group is
+    -- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+    resourceArn :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListTagsForResource' 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:
+--
+-- 'resourceArn', 'listTagsForResource_resourceArn' - The ARN of the canary or group that you want to view tags for.
+--
+-- The ARN format of a canary is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+--
+-- The ARN format of a group is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+newListTagsForResource ::
+  -- | 'resourceArn'
+  Prelude.Text ->
+  ListTagsForResource
+newListTagsForResource pResourceArn_ =
+  ListTagsForResource' {resourceArn = pResourceArn_}
+
+-- | The ARN of the canary or group that you want to view tags for.
+--
+-- The ARN format of a canary is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+--
+-- The ARN format of a group is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+listTagsForResource_resourceArn :: Lens.Lens' ListTagsForResource Prelude.Text
+listTagsForResource_resourceArn = Lens.lens (\ListTagsForResource' {resourceArn} -> resourceArn) (\s@ListTagsForResource' {} a -> s {resourceArn = a} :: ListTagsForResource)
+
+instance Core.AWSRequest ListTagsForResource where
+  type
+    AWSResponse ListTagsForResource =
+      ListTagsForResourceResponse
+  request overrides =
+    Request.get (overrides defaultService)
+  response =
+    Response.receiveJSON
+      ( \s h x ->
+          ListTagsForResourceResponse'
+            Prelude.<$> (x Data..?> "Tags" Core..!@ Prelude.mempty)
+            Prelude.<*> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable ListTagsForResource where
+  hashWithSalt _salt ListTagsForResource' {..} =
+    _salt `Prelude.hashWithSalt` resourceArn
+
+instance Prelude.NFData ListTagsForResource where
+  rnf ListTagsForResource' {..} =
+    Prelude.rnf resourceArn
+
+instance Data.ToHeaders ListTagsForResource where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath ListTagsForResource where
+  toPath ListTagsForResource' {..} =
+    Prelude.mconcat ["/tags/", Data.toBS resourceArn]
+
+instance Data.ToQuery ListTagsForResource where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newListTagsForResourceResponse' smart constructor.
+data ListTagsForResourceResponse = ListTagsForResourceResponse'
+  { -- | The list of tag keys and values associated with the resource that you
+    -- specified.
+    tags :: Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text),
+    -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ListTagsForResourceResponse' 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:
+--
+-- 'tags', 'listTagsForResourceResponse_tags' - The list of tag keys and values associated with the resource that you
+-- specified.
+--
+-- 'httpStatus', 'listTagsForResourceResponse_httpStatus' - The response's http status code.
+newListTagsForResourceResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  ListTagsForResourceResponse
+newListTagsForResourceResponse pHttpStatus_ =
+  ListTagsForResourceResponse'
+    { tags =
+        Prelude.Nothing,
+      httpStatus = pHttpStatus_
+    }
+
+-- | The list of tag keys and values associated with the resource that you
+-- specified.
+listTagsForResourceResponse_tags :: Lens.Lens' ListTagsForResourceResponse (Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text))
+listTagsForResourceResponse_tags = Lens.lens (\ListTagsForResourceResponse' {tags} -> tags) (\s@ListTagsForResourceResponse' {} a -> s {tags = a} :: ListTagsForResourceResponse) Prelude.. Lens.mapping Lens.coerced
+
+-- | The response's http status code.
+listTagsForResourceResponse_httpStatus :: Lens.Lens' ListTagsForResourceResponse Prelude.Int
+listTagsForResourceResponse_httpStatus = Lens.lens (\ListTagsForResourceResponse' {httpStatus} -> httpStatus) (\s@ListTagsForResourceResponse' {} a -> s {httpStatus = a} :: ListTagsForResourceResponse)
+
+instance Prelude.NFData ListTagsForResourceResponse where
+  rnf ListTagsForResourceResponse' {..} =
+    Prelude.rnf tags
+      `Prelude.seq` Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/StartCanary.hs b/gen/Amazonka/Synthetics/StartCanary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/StartCanary.hs
@@ -0,0 +1,149 @@
+{-# 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.Synthetics.StartCanary
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Use this operation to run a canary that has already been created. The
+-- frequency of the canary runs is determined by the value of the canary\'s
+-- @Schedule@. To see a canary\'s schedule, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_GetCanary.html GetCanary>.
+module Amazonka.Synthetics.StartCanary
+  ( -- * Creating a Request
+    StartCanary (..),
+    newStartCanary,
+
+    -- * Request Lenses
+    startCanary_name,
+
+    -- * Destructuring the Response
+    StartCanaryResponse (..),
+    newStartCanaryResponse,
+
+    -- * Response Lenses
+    startCanaryResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newStartCanary' smart constructor.
+data StartCanary = StartCanary'
+  { -- | The name of the canary that you want to run. To find canary names, use
+    -- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+    name :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'StartCanary' 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:
+--
+-- 'name', 'startCanary_name' - The name of the canary that you want to run. To find canary names, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+newStartCanary ::
+  -- | 'name'
+  Prelude.Text ->
+  StartCanary
+newStartCanary pName_ = StartCanary' {name = pName_}
+
+-- | The name of the canary that you want to run. To find canary names, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+startCanary_name :: Lens.Lens' StartCanary Prelude.Text
+startCanary_name = Lens.lens (\StartCanary' {name} -> name) (\s@StartCanary' {} a -> s {name = a} :: StartCanary)
+
+instance Core.AWSRequest StartCanary where
+  type AWSResponse StartCanary = StartCanaryResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          StartCanaryResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable StartCanary where
+  hashWithSalt _salt StartCanary' {..} =
+    _salt `Prelude.hashWithSalt` name
+
+instance Prelude.NFData StartCanary where
+  rnf StartCanary' {..} = Prelude.rnf name
+
+instance Data.ToHeaders StartCanary where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON StartCanary where
+  toJSON = Prelude.const (Data.Object Prelude.mempty)
+
+instance Data.ToPath StartCanary where
+  toPath StartCanary' {..} =
+    Prelude.mconcat
+      ["/canary/", Data.toBS name, "/start"]
+
+instance Data.ToQuery StartCanary where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newStartCanaryResponse' smart constructor.
+data StartCanaryResponse = StartCanaryResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'StartCanaryResponse' 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:
+--
+-- 'httpStatus', 'startCanaryResponse_httpStatus' - The response's http status code.
+newStartCanaryResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  StartCanaryResponse
+newStartCanaryResponse pHttpStatus_ =
+  StartCanaryResponse' {httpStatus = pHttpStatus_}
+
+-- | The response's http status code.
+startCanaryResponse_httpStatus :: Lens.Lens' StartCanaryResponse Prelude.Int
+startCanaryResponse_httpStatus = Lens.lens (\StartCanaryResponse' {httpStatus} -> httpStatus) (\s@StartCanaryResponse' {} a -> s {httpStatus = a} :: StartCanaryResponse)
+
+instance Prelude.NFData StartCanaryResponse where
+  rnf StartCanaryResponse' {..} = Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/StopCanary.hs b/gen/Amazonka/Synthetics/StopCanary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/StopCanary.hs
@@ -0,0 +1,155 @@
+{-# 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.Synthetics.StopCanary
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Stops the canary to prevent all future runs. If the canary is currently
+-- running,the run that is in progress completes on its own, publishes
+-- metrics, and uploads artifacts, but it is not recorded in Synthetics as
+-- a completed run.
+--
+-- You can use @StartCanary@ to start it running again with the canary’s
+-- current schedule at any point in the future.
+module Amazonka.Synthetics.StopCanary
+  ( -- * Creating a Request
+    StopCanary (..),
+    newStopCanary,
+
+    -- * Request Lenses
+    stopCanary_name,
+
+    -- * Destructuring the Response
+    StopCanaryResponse (..),
+    newStopCanaryResponse,
+
+    -- * Response Lenses
+    stopCanaryResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newStopCanary' smart constructor.
+data StopCanary = StopCanary'
+  { -- | The name of the canary that you want to stop. To find the names of your
+    -- canaries, use
+    -- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html ListCanaries>.
+    name :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'StopCanary' 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:
+--
+-- 'name', 'stopCanary_name' - The name of the canary that you want to stop. To find the names of your
+-- canaries, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html ListCanaries>.
+newStopCanary ::
+  -- | 'name'
+  Prelude.Text ->
+  StopCanary
+newStopCanary pName_ = StopCanary' {name = pName_}
+
+-- | The name of the canary that you want to stop. To find the names of your
+-- canaries, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html ListCanaries>.
+stopCanary_name :: Lens.Lens' StopCanary Prelude.Text
+stopCanary_name = Lens.lens (\StopCanary' {name} -> name) (\s@StopCanary' {} a -> s {name = a} :: StopCanary)
+
+instance Core.AWSRequest StopCanary where
+  type AWSResponse StopCanary = StopCanaryResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          StopCanaryResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable StopCanary where
+  hashWithSalt _salt StopCanary' {..} =
+    _salt `Prelude.hashWithSalt` name
+
+instance Prelude.NFData StopCanary where
+  rnf StopCanary' {..} = Prelude.rnf name
+
+instance Data.ToHeaders StopCanary where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON StopCanary where
+  toJSON = Prelude.const (Data.Object Prelude.mempty)
+
+instance Data.ToPath StopCanary where
+  toPath StopCanary' {..} =
+    Prelude.mconcat
+      ["/canary/", Data.toBS name, "/stop"]
+
+instance Data.ToQuery StopCanary where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newStopCanaryResponse' smart constructor.
+data StopCanaryResponse = StopCanaryResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'StopCanaryResponse' 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:
+--
+-- 'httpStatus', 'stopCanaryResponse_httpStatus' - The response's http status code.
+newStopCanaryResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  StopCanaryResponse
+newStopCanaryResponse pHttpStatus_ =
+  StopCanaryResponse' {httpStatus = pHttpStatus_}
+
+-- | The response's http status code.
+stopCanaryResponse_httpStatus :: Lens.Lens' StopCanaryResponse Prelude.Int
+stopCanaryResponse_httpStatus = Lens.lens (\StopCanaryResponse' {httpStatus} -> httpStatus) (\s@StopCanaryResponse' {} a -> s {httpStatus = a} :: StopCanaryResponse)
+
+instance Prelude.NFData StopCanaryResponse where
+  rnf StopCanaryResponse' {..} = Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/TagResource.hs b/gen/Amazonka/Synthetics/TagResource.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/TagResource.hs
@@ -0,0 +1,197 @@
+{-# 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.Synthetics.TagResource
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Assigns one or more tags (key-value pairs) to the specified canary or
+-- group.
+--
+-- Tags can help you organize and categorize your resources. You can also
+-- use them to scope user permissions, by granting a user permission to
+-- access or change only resources with certain tag values.
+--
+-- Tags don\'t have any semantic meaning to Amazon Web Services and are
+-- interpreted strictly as strings of characters.
+--
+-- You can use the @TagResource@ action with a resource that already has
+-- tags. If you specify a new tag key for the resource, this tag is
+-- appended to the list of tags associated with the resource. If you
+-- specify a tag key that is already associated with the resource, the new
+-- tag value that you specify replaces the previous value for that tag.
+--
+-- You can associate as many as 50 tags with a canary or group.
+module Amazonka.Synthetics.TagResource
+  ( -- * Creating a Request
+    TagResource (..),
+    newTagResource,
+
+    -- * Request Lenses
+    tagResource_resourceArn,
+    tagResource_tags,
+
+    -- * Destructuring the Response
+    TagResourceResponse (..),
+    newTagResourceResponse,
+
+    -- * Response Lenses
+    tagResourceResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newTagResource' smart constructor.
+data TagResource = TagResource'
+  { -- | The ARN of the canary or group that you\'re adding tags to.
+    --
+    -- The ARN format of a canary is
+    -- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+    --
+    -- The ARN format of a group is
+    -- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+    resourceArn :: Prelude.Text,
+    -- | The list of key-value pairs to associate with the resource.
+    tags :: Prelude.HashMap Prelude.Text Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'TagResource' 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:
+--
+-- 'resourceArn', 'tagResource_resourceArn' - The ARN of the canary or group that you\'re adding tags to.
+--
+-- The ARN format of a canary is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+--
+-- The ARN format of a group is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+--
+-- 'tags', 'tagResource_tags' - The list of key-value pairs to associate with the resource.
+newTagResource ::
+  -- | 'resourceArn'
+  Prelude.Text ->
+  TagResource
+newTagResource pResourceArn_ =
+  TagResource'
+    { resourceArn = pResourceArn_,
+      tags = Prelude.mempty
+    }
+
+-- | The ARN of the canary or group that you\'re adding tags to.
+--
+-- The ARN format of a canary is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+--
+-- The ARN format of a group is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+tagResource_resourceArn :: Lens.Lens' TagResource Prelude.Text
+tagResource_resourceArn = Lens.lens (\TagResource' {resourceArn} -> resourceArn) (\s@TagResource' {} a -> s {resourceArn = a} :: TagResource)
+
+-- | The list of key-value pairs to associate with the resource.
+tagResource_tags :: Lens.Lens' TagResource (Prelude.HashMap Prelude.Text Prelude.Text)
+tagResource_tags = Lens.lens (\TagResource' {tags} -> tags) (\s@TagResource' {} a -> s {tags = a} :: TagResource) Prelude.. Lens.coerced
+
+instance Core.AWSRequest TagResource where
+  type AWSResponse TagResource = TagResourceResponse
+  request overrides =
+    Request.postJSON (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          TagResourceResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable TagResource where
+  hashWithSalt _salt TagResource' {..} =
+    _salt
+      `Prelude.hashWithSalt` resourceArn
+      `Prelude.hashWithSalt` tags
+
+instance Prelude.NFData TagResource where
+  rnf TagResource' {..} =
+    Prelude.rnf resourceArn
+      `Prelude.seq` Prelude.rnf tags
+
+instance Data.ToHeaders TagResource where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON TagResource where
+  toJSON TagResource' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [Prelude.Just ("Tags" Data..= tags)]
+      )
+
+instance Data.ToPath TagResource where
+  toPath TagResource' {..} =
+    Prelude.mconcat ["/tags/", Data.toBS resourceArn]
+
+instance Data.ToQuery TagResource where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newTagResourceResponse' smart constructor.
+data TagResourceResponse = TagResourceResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'TagResourceResponse' 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:
+--
+-- 'httpStatus', 'tagResourceResponse_httpStatus' - The response's http status code.
+newTagResourceResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  TagResourceResponse
+newTagResourceResponse pHttpStatus_ =
+  TagResourceResponse' {httpStatus = pHttpStatus_}
+
+-- | The response's http status code.
+tagResourceResponse_httpStatus :: Lens.Lens' TagResourceResponse Prelude.Int
+tagResourceResponse_httpStatus = Lens.lens (\TagResourceResponse' {httpStatus} -> httpStatus) (\s@TagResourceResponse' {} a -> s {httpStatus = a} :: TagResourceResponse)
+
+instance Prelude.NFData TagResourceResponse where
+  rnf TagResourceResponse' {..} = Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/Types.hs b/gen/Amazonka/Synthetics/Types.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types.hs
@@ -0,0 +1,409 @@
+{-# 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.Synthetics.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.Synthetics.Types
+  ( -- * Service Configuration
+    defaultService,
+
+    -- * Errors
+    _BadRequestException,
+    _ConflictException,
+    _InternalFailureException,
+    _InternalServerException,
+    _NotFoundException,
+    _RequestEntityTooLargeException,
+    _ResourceNotFoundException,
+    _ServiceQuotaExceededException,
+    _TooManyRequestsException,
+    _ValidationException,
+
+    -- * CanaryRunState
+    CanaryRunState (..),
+
+    -- * CanaryRunStateReasonCode
+    CanaryRunStateReasonCode (..),
+
+    -- * CanaryState
+    CanaryState (..),
+
+    -- * CanaryStateReasonCode
+    CanaryStateReasonCode (..),
+
+    -- * EncryptionMode
+    EncryptionMode (..),
+
+    -- * ArtifactConfigInput
+    ArtifactConfigInput (..),
+    newArtifactConfigInput,
+    artifactConfigInput_s3Encryption,
+
+    -- * ArtifactConfigOutput
+    ArtifactConfigOutput (..),
+    newArtifactConfigOutput,
+    artifactConfigOutput_s3Encryption,
+
+    -- * BaseScreenshot
+    BaseScreenshot (..),
+    newBaseScreenshot,
+    baseScreenshot_ignoreCoordinates,
+    baseScreenshot_screenshotName,
+
+    -- * Canary
+    Canary (..),
+    newCanary,
+    canary_artifactConfig,
+    canary_artifactS3Location,
+    canary_code,
+    canary_engineArn,
+    canary_executionRoleArn,
+    canary_failureRetentionPeriodInDays,
+    canary_id,
+    canary_name,
+    canary_runConfig,
+    canary_runtimeVersion,
+    canary_schedule,
+    canary_status,
+    canary_successRetentionPeriodInDays,
+    canary_tags,
+    canary_timeline,
+    canary_visualReference,
+    canary_vpcConfig,
+
+    -- * CanaryCodeInput
+    CanaryCodeInput (..),
+    newCanaryCodeInput,
+    canaryCodeInput_s3Bucket,
+    canaryCodeInput_s3Key,
+    canaryCodeInput_s3Version,
+    canaryCodeInput_zipFile,
+    canaryCodeInput_handler,
+
+    -- * CanaryCodeOutput
+    CanaryCodeOutput (..),
+    newCanaryCodeOutput,
+    canaryCodeOutput_handler,
+    canaryCodeOutput_sourceLocationArn,
+
+    -- * CanaryLastRun
+    CanaryLastRun (..),
+    newCanaryLastRun,
+    canaryLastRun_canaryName,
+    canaryLastRun_lastRun,
+
+    -- * CanaryRun
+    CanaryRun (..),
+    newCanaryRun,
+    canaryRun_artifactS3Location,
+    canaryRun_id,
+    canaryRun_name,
+    canaryRun_status,
+    canaryRun_timeline,
+
+    -- * CanaryRunConfigInput
+    CanaryRunConfigInput (..),
+    newCanaryRunConfigInput,
+    canaryRunConfigInput_activeTracing,
+    canaryRunConfigInput_environmentVariables,
+    canaryRunConfigInput_memoryInMB,
+    canaryRunConfigInput_timeoutInSeconds,
+
+    -- * CanaryRunConfigOutput
+    CanaryRunConfigOutput (..),
+    newCanaryRunConfigOutput,
+    canaryRunConfigOutput_activeTracing,
+    canaryRunConfigOutput_memoryInMB,
+    canaryRunConfigOutput_timeoutInSeconds,
+
+    -- * CanaryRunStatus
+    CanaryRunStatus (..),
+    newCanaryRunStatus,
+    canaryRunStatus_state,
+    canaryRunStatus_stateReason,
+    canaryRunStatus_stateReasonCode,
+
+    -- * CanaryRunTimeline
+    CanaryRunTimeline (..),
+    newCanaryRunTimeline,
+    canaryRunTimeline_completed,
+    canaryRunTimeline_started,
+
+    -- * CanaryScheduleInput
+    CanaryScheduleInput (..),
+    newCanaryScheduleInput,
+    canaryScheduleInput_durationInSeconds,
+    canaryScheduleInput_expression,
+
+    -- * CanaryScheduleOutput
+    CanaryScheduleOutput (..),
+    newCanaryScheduleOutput,
+    canaryScheduleOutput_durationInSeconds,
+    canaryScheduleOutput_expression,
+
+    -- * CanaryStatus
+    CanaryStatus (..),
+    newCanaryStatus,
+    canaryStatus_state,
+    canaryStatus_stateReason,
+    canaryStatus_stateReasonCode,
+
+    -- * CanaryTimeline
+    CanaryTimeline (..),
+    newCanaryTimeline,
+    canaryTimeline_created,
+    canaryTimeline_lastModified,
+    canaryTimeline_lastStarted,
+    canaryTimeline_lastStopped,
+
+    -- * Group
+    Group (..),
+    newGroup,
+    group_arn,
+    group_createdTime,
+    group_id,
+    group_lastModifiedTime,
+    group_name,
+    group_tags,
+
+    -- * GroupSummary
+    GroupSummary (..),
+    newGroupSummary,
+    groupSummary_arn,
+    groupSummary_id,
+    groupSummary_name,
+
+    -- * RuntimeVersion
+    RuntimeVersion (..),
+    newRuntimeVersion,
+    runtimeVersion_deprecationDate,
+    runtimeVersion_description,
+    runtimeVersion_releaseDate,
+    runtimeVersion_versionName,
+
+    -- * S3EncryptionConfig
+    S3EncryptionConfig (..),
+    newS3EncryptionConfig,
+    s3EncryptionConfig_encryptionMode,
+    s3EncryptionConfig_kmsKeyArn,
+
+    -- * VisualReferenceInput
+    VisualReferenceInput (..),
+    newVisualReferenceInput,
+    visualReferenceInput_baseScreenshots,
+    visualReferenceInput_baseCanaryRunId,
+
+    -- * VisualReferenceOutput
+    VisualReferenceOutput (..),
+    newVisualReferenceOutput,
+    visualReferenceOutput_baseCanaryRunId,
+    visualReferenceOutput_baseScreenshots,
+
+    -- * VpcConfigInput
+    VpcConfigInput (..),
+    newVpcConfigInput,
+    vpcConfigInput_securityGroupIds,
+    vpcConfigInput_subnetIds,
+
+    -- * VpcConfigOutput
+    VpcConfigOutput (..),
+    newVpcConfigOutput,
+    vpcConfigOutput_securityGroupIds,
+    vpcConfigOutput_subnetIds,
+    vpcConfigOutput_vpcId,
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Core.Lens.Internal as Lens
+import qualified Amazonka.Prelude as Prelude
+import qualified Amazonka.Sign.V4 as Sign
+import Amazonka.Synthetics.Types.ArtifactConfigInput
+import Amazonka.Synthetics.Types.ArtifactConfigOutput
+import Amazonka.Synthetics.Types.BaseScreenshot
+import Amazonka.Synthetics.Types.Canary
+import Amazonka.Synthetics.Types.CanaryCodeInput
+import Amazonka.Synthetics.Types.CanaryCodeOutput
+import Amazonka.Synthetics.Types.CanaryLastRun
+import Amazonka.Synthetics.Types.CanaryRun
+import Amazonka.Synthetics.Types.CanaryRunConfigInput
+import Amazonka.Synthetics.Types.CanaryRunConfigOutput
+import Amazonka.Synthetics.Types.CanaryRunState
+import Amazonka.Synthetics.Types.CanaryRunStateReasonCode
+import Amazonka.Synthetics.Types.CanaryRunStatus
+import Amazonka.Synthetics.Types.CanaryRunTimeline
+import Amazonka.Synthetics.Types.CanaryScheduleInput
+import Amazonka.Synthetics.Types.CanaryScheduleOutput
+import Amazonka.Synthetics.Types.CanaryState
+import Amazonka.Synthetics.Types.CanaryStateReasonCode
+import Amazonka.Synthetics.Types.CanaryStatus
+import Amazonka.Synthetics.Types.CanaryTimeline
+import Amazonka.Synthetics.Types.EncryptionMode
+import Amazonka.Synthetics.Types.Group
+import Amazonka.Synthetics.Types.GroupSummary
+import Amazonka.Synthetics.Types.RuntimeVersion
+import Amazonka.Synthetics.Types.S3EncryptionConfig
+import Amazonka.Synthetics.Types.VisualReferenceInput
+import Amazonka.Synthetics.Types.VisualReferenceOutput
+import Amazonka.Synthetics.Types.VpcConfigInput
+import Amazonka.Synthetics.Types.VpcConfigOutput
+
+-- | API version @2017-10-11@ of the Amazon Synthetics SDK configuration.
+defaultService :: Core.Service
+defaultService =
+  Core.Service
+    { Core.abbrev = "Synthetics",
+      Core.signer = Sign.v4,
+      Core.endpointPrefix = "synthetics",
+      Core.signingName = "synthetics",
+      Core.version = "2017-10-11",
+      Core.s3AddressingStyle = Core.S3AddressingStyleAuto,
+      Core.endpoint = Core.defaultEndpoint defaultService,
+      Core.timeout = Prelude.Just 70,
+      Core.check = Core.statusSuccess,
+      Core.error = Core.parseJSONError "Synthetics",
+      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
+
+-- | The request was not valid.
+_BadRequestException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_BadRequestException =
+  Core._MatchServiceError
+    defaultService
+    "BadRequestException"
+    Prelude.. Core.hasStatus 400
+
+-- | A conflicting operation is already in progress.
+_ConflictException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ConflictException =
+  Core._MatchServiceError
+    defaultService
+    "ConflictException"
+    Prelude.. Core.hasStatus 409
+
+-- | An internal failure occurred. Try the operation again.
+_InternalFailureException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_InternalFailureException =
+  Core._MatchServiceError
+    defaultService
+    "InternalFailureException"
+    Prelude.. Core.hasStatus 500
+
+-- | An unknown internal error occurred.
+_InternalServerException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_InternalServerException =
+  Core._MatchServiceError
+    defaultService
+    "InternalServerException"
+    Prelude.. Core.hasStatus 500
+
+-- | The specified resource was not found.
+_NotFoundException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_NotFoundException =
+  Core._MatchServiceError
+    defaultService
+    "NotFoundException"
+    Prelude.. Core.hasStatus 404
+
+-- | One of the input resources is larger than is allowed.
+_RequestEntityTooLargeException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_RequestEntityTooLargeException =
+  Core._MatchServiceError
+    defaultService
+    "RequestEntityTooLargeException"
+    Prelude.. Core.hasStatus 413
+
+-- | One of the specified resources was not found.
+_ResourceNotFoundException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ResourceNotFoundException =
+  Core._MatchServiceError
+    defaultService
+    "ResourceNotFoundException"
+    Prelude.. Core.hasStatus 404
+
+-- | The request exceeded a service quota value.
+_ServiceQuotaExceededException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ServiceQuotaExceededException =
+  Core._MatchServiceError
+    defaultService
+    "ServiceQuotaExceededException"
+    Prelude.. Core.hasStatus 402
+
+-- | There were too many simultaneous requests. Try the operation again.
+_TooManyRequestsException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_TooManyRequestsException =
+  Core._MatchServiceError
+    defaultService
+    "TooManyRequestsException"
+    Prelude.. Core.hasStatus 429
+
+-- | A parameter could not be validated.
+_ValidationException :: (Core.AsError a) => Lens.Fold a Core.ServiceError
+_ValidationException =
+  Core._MatchServiceError
+    defaultService
+    "ValidationException"
+    Prelude.. Core.hasStatus 400
diff --git a/gen/Amazonka/Synthetics/Types/ArtifactConfigInput.hs b/gen/Amazonka/Synthetics/Types/ArtifactConfigInput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/ArtifactConfigInput.hs
@@ -0,0 +1,88 @@
+{-# 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.Synthetics.Types.ArtifactConfigInput
+-- 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.Synthetics.Types.ArtifactConfigInput 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
+import Amazonka.Synthetics.Types.S3EncryptionConfig
+
+-- | A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+--
+-- /See:/ 'newArtifactConfigInput' smart constructor.
+data ArtifactConfigInput = ArtifactConfigInput'
+  { -- | A structure that contains the configuration of the encryption-at-rest
+    -- settings for artifacts that the canary uploads to Amazon S3. Artifact
+    -- encryption functionality is available only for canaries that use
+    -- Synthetics runtime version syn-nodejs-puppeteer-3.3 or later. For more
+    -- information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_artifact_encryption.html Encrypting canary artifacts>
+    s3Encryption :: Prelude.Maybe S3EncryptionConfig
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ArtifactConfigInput' 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:
+--
+-- 's3Encryption', 'artifactConfigInput_s3Encryption' - A structure that contains the configuration of the encryption-at-rest
+-- settings for artifacts that the canary uploads to Amazon S3. Artifact
+-- encryption functionality is available only for canaries that use
+-- Synthetics runtime version syn-nodejs-puppeteer-3.3 or later. For more
+-- information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_artifact_encryption.html Encrypting canary artifacts>
+newArtifactConfigInput ::
+  ArtifactConfigInput
+newArtifactConfigInput =
+  ArtifactConfigInput'
+    { s3Encryption =
+        Prelude.Nothing
+    }
+
+-- | A structure that contains the configuration of the encryption-at-rest
+-- settings for artifacts that the canary uploads to Amazon S3. Artifact
+-- encryption functionality is available only for canaries that use
+-- Synthetics runtime version syn-nodejs-puppeteer-3.3 or later. For more
+-- information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_artifact_encryption.html Encrypting canary artifacts>
+artifactConfigInput_s3Encryption :: Lens.Lens' ArtifactConfigInput (Prelude.Maybe S3EncryptionConfig)
+artifactConfigInput_s3Encryption = Lens.lens (\ArtifactConfigInput' {s3Encryption} -> s3Encryption) (\s@ArtifactConfigInput' {} a -> s {s3Encryption = a} :: ArtifactConfigInput)
+
+instance Prelude.Hashable ArtifactConfigInput where
+  hashWithSalt _salt ArtifactConfigInput' {..} =
+    _salt `Prelude.hashWithSalt` s3Encryption
+
+instance Prelude.NFData ArtifactConfigInput where
+  rnf ArtifactConfigInput' {..} =
+    Prelude.rnf s3Encryption
+
+instance Data.ToJSON ArtifactConfigInput where
+  toJSON ArtifactConfigInput' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [("S3Encryption" Data..=) Prelude.<$> s3Encryption]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/ArtifactConfigOutput.hs b/gen/Amazonka/Synthetics/Types/ArtifactConfigOutput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/ArtifactConfigOutput.hs
@@ -0,0 +1,78 @@
+{-# 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.Synthetics.Types.ArtifactConfigOutput
+-- 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.Synthetics.Types.ArtifactConfigOutput 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
+import Amazonka.Synthetics.Types.S3EncryptionConfig
+
+-- | A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+--
+-- /See:/ 'newArtifactConfigOutput' smart constructor.
+data ArtifactConfigOutput = ArtifactConfigOutput'
+  { -- | A structure that contains the configuration of encryption settings for
+    -- canary artifacts that are stored in Amazon S3.
+    s3Encryption :: Prelude.Maybe S3EncryptionConfig
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'ArtifactConfigOutput' 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:
+--
+-- 's3Encryption', 'artifactConfigOutput_s3Encryption' - A structure that contains the configuration of encryption settings for
+-- canary artifacts that are stored in Amazon S3.
+newArtifactConfigOutput ::
+  ArtifactConfigOutput
+newArtifactConfigOutput =
+  ArtifactConfigOutput'
+    { s3Encryption =
+        Prelude.Nothing
+    }
+
+-- | A structure that contains the configuration of encryption settings for
+-- canary artifacts that are stored in Amazon S3.
+artifactConfigOutput_s3Encryption :: Lens.Lens' ArtifactConfigOutput (Prelude.Maybe S3EncryptionConfig)
+artifactConfigOutput_s3Encryption = Lens.lens (\ArtifactConfigOutput' {s3Encryption} -> s3Encryption) (\s@ArtifactConfigOutput' {} a -> s {s3Encryption = a} :: ArtifactConfigOutput)
+
+instance Data.FromJSON ArtifactConfigOutput where
+  parseJSON =
+    Data.withObject
+      "ArtifactConfigOutput"
+      ( \x ->
+          ArtifactConfigOutput'
+            Prelude.<$> (x Data..:? "S3Encryption")
+      )
+
+instance Prelude.Hashable ArtifactConfigOutput where
+  hashWithSalt _salt ArtifactConfigOutput' {..} =
+    _salt `Prelude.hashWithSalt` s3Encryption
+
+instance Prelude.NFData ArtifactConfigOutput where
+  rnf ArtifactConfigOutput' {..} =
+    Prelude.rnf s3Encryption
diff --git a/gen/Amazonka/Synthetics/Types/BaseScreenshot.hs b/gen/Amazonka/Synthetics/Types/BaseScreenshot.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/BaseScreenshot.hs
@@ -0,0 +1,117 @@
+{-# 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.Synthetics.Types.BaseScreenshot
+-- 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.Synthetics.Types.BaseScreenshot 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 structure representing a screenshot that is used as a baseline during
+-- visual monitoring comparisons made by the canary.
+--
+-- /See:/ 'newBaseScreenshot' smart constructor.
+data BaseScreenshot = BaseScreenshot'
+  { -- | Coordinates that define the part of a screen to ignore during screenshot
+    -- comparisons. To obtain the coordinates to use here, use the CloudWatch
+    -- console to draw the boundaries on the screen. For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/synthetics_canaries_deletion.html Editing or deleting a canary>
+    ignoreCoordinates :: Prelude.Maybe [Prelude.Text],
+    -- | The name of the screenshot. This is generated the first time the canary
+    -- is run after the @UpdateCanary@ operation that specified for this canary
+    -- to perform visual monitoring.
+    screenshotName :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'BaseScreenshot' 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:
+--
+-- 'ignoreCoordinates', 'baseScreenshot_ignoreCoordinates' - Coordinates that define the part of a screen to ignore during screenshot
+-- comparisons. To obtain the coordinates to use here, use the CloudWatch
+-- console to draw the boundaries on the screen. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/synthetics_canaries_deletion.html Editing or deleting a canary>
+--
+-- 'screenshotName', 'baseScreenshot_screenshotName' - The name of the screenshot. This is generated the first time the canary
+-- is run after the @UpdateCanary@ operation that specified for this canary
+-- to perform visual monitoring.
+newBaseScreenshot ::
+  -- | 'screenshotName'
+  Prelude.Text ->
+  BaseScreenshot
+newBaseScreenshot pScreenshotName_ =
+  BaseScreenshot'
+    { ignoreCoordinates =
+        Prelude.Nothing,
+      screenshotName = pScreenshotName_
+    }
+
+-- | Coordinates that define the part of a screen to ignore during screenshot
+-- comparisons. To obtain the coordinates to use here, use the CloudWatch
+-- console to draw the boundaries on the screen. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/synthetics_canaries_deletion.html Editing or deleting a canary>
+baseScreenshot_ignoreCoordinates :: Lens.Lens' BaseScreenshot (Prelude.Maybe [Prelude.Text])
+baseScreenshot_ignoreCoordinates = Lens.lens (\BaseScreenshot' {ignoreCoordinates} -> ignoreCoordinates) (\s@BaseScreenshot' {} a -> s {ignoreCoordinates = a} :: BaseScreenshot) Prelude.. Lens.mapping Lens.coerced
+
+-- | The name of the screenshot. This is generated the first time the canary
+-- is run after the @UpdateCanary@ operation that specified for this canary
+-- to perform visual monitoring.
+baseScreenshot_screenshotName :: Lens.Lens' BaseScreenshot Prelude.Text
+baseScreenshot_screenshotName = Lens.lens (\BaseScreenshot' {screenshotName} -> screenshotName) (\s@BaseScreenshot' {} a -> s {screenshotName = a} :: BaseScreenshot)
+
+instance Data.FromJSON BaseScreenshot where
+  parseJSON =
+    Data.withObject
+      "BaseScreenshot"
+      ( \x ->
+          BaseScreenshot'
+            Prelude.<$> ( x
+                            Data..:? "IgnoreCoordinates"
+                            Data..!= Prelude.mempty
+                        )
+            Prelude.<*> (x Data..: "ScreenshotName")
+      )
+
+instance Prelude.Hashable BaseScreenshot where
+  hashWithSalt _salt BaseScreenshot' {..} =
+    _salt
+      `Prelude.hashWithSalt` ignoreCoordinates
+      `Prelude.hashWithSalt` screenshotName
+
+instance Prelude.NFData BaseScreenshot where
+  rnf BaseScreenshot' {..} =
+    Prelude.rnf ignoreCoordinates
+      `Prelude.seq` Prelude.rnf screenshotName
+
+instance Data.ToJSON BaseScreenshot where
+  toJSON BaseScreenshot' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("IgnoreCoordinates" Data..=)
+              Prelude.<$> ignoreCoordinates,
+            Prelude.Just
+              ("ScreenshotName" Data..= screenshotName)
+          ]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/Canary.hs b/gen/Amazonka/Synthetics/Types/Canary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/Canary.hs
@@ -0,0 +1,312 @@
+{-# 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.Synthetics.Types.Canary
+-- 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.Synthetics.Types.Canary 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
+import Amazonka.Synthetics.Types.ArtifactConfigOutput
+import Amazonka.Synthetics.Types.CanaryCodeOutput
+import Amazonka.Synthetics.Types.CanaryRunConfigOutput
+import Amazonka.Synthetics.Types.CanaryScheduleOutput
+import Amazonka.Synthetics.Types.CanaryStatus
+import Amazonka.Synthetics.Types.CanaryTimeline
+import Amazonka.Synthetics.Types.VisualReferenceOutput
+import Amazonka.Synthetics.Types.VpcConfigOutput
+
+-- | This structure contains all information about one canary in your
+-- account.
+--
+-- /See:/ 'newCanary' smart constructor.
+data Canary = Canary'
+  { -- | A structure that contains the configuration for canary artifacts,
+    -- including the encryption-at-rest settings for artifacts that the canary
+    -- uploads to Amazon S3.
+    artifactConfig :: Prelude.Maybe ArtifactConfigOutput,
+    -- | The location in Amazon S3 where Synthetics stores artifacts from the
+    -- runs of this canary. Artifacts include the log file, screenshots, and
+    -- HAR files.
+    artifactS3Location :: Prelude.Maybe Prelude.Text,
+    code :: Prelude.Maybe CanaryCodeOutput,
+    -- | The ARN of the Lambda function that is used as your canary\'s engine.
+    -- For more information about Lambda ARN format, see
+    -- <https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html Resources and Conditions for Lambda Actions>.
+    engineArn :: Prelude.Maybe Prelude.Text,
+    -- | The ARN of the IAM role used to run the canary. This role must include
+    -- @lambda.amazonaws.com@ as a principal in the trust policy.
+    executionRoleArn :: Prelude.Maybe Prelude.Text,
+    -- | The number of days to retain data about failed runs of this canary.
+    failureRetentionPeriodInDays :: Prelude.Maybe Prelude.Natural,
+    -- | The unique ID of this canary.
+    id :: Prelude.Maybe Prelude.Text,
+    -- | The name of the canary.
+    name :: Prelude.Maybe Prelude.Text,
+    runConfig :: Prelude.Maybe CanaryRunConfigOutput,
+    -- | Specifies the runtime version to use for the canary. For more
+    -- information about runtime versions, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+    runtimeVersion :: Prelude.Maybe Prelude.Text,
+    -- | A structure that contains information about how often the canary is to
+    -- run, and when these runs are to stop.
+    schedule :: Prelude.Maybe CanaryScheduleOutput,
+    -- | A structure that contains information about the canary\'s status.
+    status :: Prelude.Maybe CanaryStatus,
+    -- | The number of days to retain data about successful runs of this canary.
+    successRetentionPeriodInDays :: Prelude.Maybe Prelude.Natural,
+    -- | The list of key-value pairs that are associated with the canary.
+    tags :: Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text),
+    -- | A structure that contains information about when the canary was created,
+    -- modified, and most recently run.
+    timeline :: Prelude.Maybe CanaryTimeline,
+    -- | If this canary performs visual monitoring by comparing screenshots, this
+    -- structure contains the ID of the canary run to use as the baseline for
+    -- screenshots, and the coordinates of any parts of the screen to ignore
+    -- during the visual monitoring comparison.
+    visualReference :: Prelude.Maybe VisualReferenceOutput,
+    vpcConfig :: Prelude.Maybe VpcConfigOutput
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'Canary' 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:
+--
+-- 'artifactConfig', 'canary_artifactConfig' - A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+--
+-- 'artifactS3Location', 'canary_artifactS3Location' - The location in Amazon S3 where Synthetics stores artifacts from the
+-- runs of this canary. Artifacts include the log file, screenshots, and
+-- HAR files.
+--
+-- 'code', 'canary_code' - Undocumented member.
+--
+-- 'engineArn', 'canary_engineArn' - The ARN of the Lambda function that is used as your canary\'s engine.
+-- For more information about Lambda ARN format, see
+-- <https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html Resources and Conditions for Lambda Actions>.
+--
+-- 'executionRoleArn', 'canary_executionRoleArn' - The ARN of the IAM role used to run the canary. This role must include
+-- @lambda.amazonaws.com@ as a principal in the trust policy.
+--
+-- 'failureRetentionPeriodInDays', 'canary_failureRetentionPeriodInDays' - The number of days to retain data about failed runs of this canary.
+--
+-- 'id', 'canary_id' - The unique ID of this canary.
+--
+-- 'name', 'canary_name' - The name of the canary.
+--
+-- 'runConfig', 'canary_runConfig' - Undocumented member.
+--
+-- 'runtimeVersion', 'canary_runtimeVersion' - Specifies the runtime version to use for the canary. For more
+-- information about runtime versions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+--
+-- 'schedule', 'canary_schedule' - A structure that contains information about how often the canary is to
+-- run, and when these runs are to stop.
+--
+-- 'status', 'canary_status' - A structure that contains information about the canary\'s status.
+--
+-- 'successRetentionPeriodInDays', 'canary_successRetentionPeriodInDays' - The number of days to retain data about successful runs of this canary.
+--
+-- 'tags', 'canary_tags' - The list of key-value pairs that are associated with the canary.
+--
+-- 'timeline', 'canary_timeline' - A structure that contains information about when the canary was created,
+-- modified, and most recently run.
+--
+-- 'visualReference', 'canary_visualReference' - If this canary performs visual monitoring by comparing screenshots, this
+-- structure contains the ID of the canary run to use as the baseline for
+-- screenshots, and the coordinates of any parts of the screen to ignore
+-- during the visual monitoring comparison.
+--
+-- 'vpcConfig', 'canary_vpcConfig' - Undocumented member.
+newCanary ::
+  Canary
+newCanary =
+  Canary'
+    { artifactConfig = Prelude.Nothing,
+      artifactS3Location = Prelude.Nothing,
+      code = Prelude.Nothing,
+      engineArn = Prelude.Nothing,
+      executionRoleArn = Prelude.Nothing,
+      failureRetentionPeriodInDays = Prelude.Nothing,
+      id = Prelude.Nothing,
+      name = Prelude.Nothing,
+      runConfig = Prelude.Nothing,
+      runtimeVersion = Prelude.Nothing,
+      schedule = Prelude.Nothing,
+      status = Prelude.Nothing,
+      successRetentionPeriodInDays = Prelude.Nothing,
+      tags = Prelude.Nothing,
+      timeline = Prelude.Nothing,
+      visualReference = Prelude.Nothing,
+      vpcConfig = Prelude.Nothing
+    }
+
+-- | A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+canary_artifactConfig :: Lens.Lens' Canary (Prelude.Maybe ArtifactConfigOutput)
+canary_artifactConfig = Lens.lens (\Canary' {artifactConfig} -> artifactConfig) (\s@Canary' {} a -> s {artifactConfig = a} :: Canary)
+
+-- | The location in Amazon S3 where Synthetics stores artifacts from the
+-- runs of this canary. Artifacts include the log file, screenshots, and
+-- HAR files.
+canary_artifactS3Location :: Lens.Lens' Canary (Prelude.Maybe Prelude.Text)
+canary_artifactS3Location = Lens.lens (\Canary' {artifactS3Location} -> artifactS3Location) (\s@Canary' {} a -> s {artifactS3Location = a} :: Canary)
+
+-- | Undocumented member.
+canary_code :: Lens.Lens' Canary (Prelude.Maybe CanaryCodeOutput)
+canary_code = Lens.lens (\Canary' {code} -> code) (\s@Canary' {} a -> s {code = a} :: Canary)
+
+-- | The ARN of the Lambda function that is used as your canary\'s engine.
+-- For more information about Lambda ARN format, see
+-- <https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html Resources and Conditions for Lambda Actions>.
+canary_engineArn :: Lens.Lens' Canary (Prelude.Maybe Prelude.Text)
+canary_engineArn = Lens.lens (\Canary' {engineArn} -> engineArn) (\s@Canary' {} a -> s {engineArn = a} :: Canary)
+
+-- | The ARN of the IAM role used to run the canary. This role must include
+-- @lambda.amazonaws.com@ as a principal in the trust policy.
+canary_executionRoleArn :: Lens.Lens' Canary (Prelude.Maybe Prelude.Text)
+canary_executionRoleArn = Lens.lens (\Canary' {executionRoleArn} -> executionRoleArn) (\s@Canary' {} a -> s {executionRoleArn = a} :: Canary)
+
+-- | The number of days to retain data about failed runs of this canary.
+canary_failureRetentionPeriodInDays :: Lens.Lens' Canary (Prelude.Maybe Prelude.Natural)
+canary_failureRetentionPeriodInDays = Lens.lens (\Canary' {failureRetentionPeriodInDays} -> failureRetentionPeriodInDays) (\s@Canary' {} a -> s {failureRetentionPeriodInDays = a} :: Canary)
+
+-- | The unique ID of this canary.
+canary_id :: Lens.Lens' Canary (Prelude.Maybe Prelude.Text)
+canary_id = Lens.lens (\Canary' {id} -> id) (\s@Canary' {} a -> s {id = a} :: Canary)
+
+-- | The name of the canary.
+canary_name :: Lens.Lens' Canary (Prelude.Maybe Prelude.Text)
+canary_name = Lens.lens (\Canary' {name} -> name) (\s@Canary' {} a -> s {name = a} :: Canary)
+
+-- | Undocumented member.
+canary_runConfig :: Lens.Lens' Canary (Prelude.Maybe CanaryRunConfigOutput)
+canary_runConfig = Lens.lens (\Canary' {runConfig} -> runConfig) (\s@Canary' {} a -> s {runConfig = a} :: Canary)
+
+-- | Specifies the runtime version to use for the canary. For more
+-- information about runtime versions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+canary_runtimeVersion :: Lens.Lens' Canary (Prelude.Maybe Prelude.Text)
+canary_runtimeVersion = Lens.lens (\Canary' {runtimeVersion} -> runtimeVersion) (\s@Canary' {} a -> s {runtimeVersion = a} :: Canary)
+
+-- | A structure that contains information about how often the canary is to
+-- run, and when these runs are to stop.
+canary_schedule :: Lens.Lens' Canary (Prelude.Maybe CanaryScheduleOutput)
+canary_schedule = Lens.lens (\Canary' {schedule} -> schedule) (\s@Canary' {} a -> s {schedule = a} :: Canary)
+
+-- | A structure that contains information about the canary\'s status.
+canary_status :: Lens.Lens' Canary (Prelude.Maybe CanaryStatus)
+canary_status = Lens.lens (\Canary' {status} -> status) (\s@Canary' {} a -> s {status = a} :: Canary)
+
+-- | The number of days to retain data about successful runs of this canary.
+canary_successRetentionPeriodInDays :: Lens.Lens' Canary (Prelude.Maybe Prelude.Natural)
+canary_successRetentionPeriodInDays = Lens.lens (\Canary' {successRetentionPeriodInDays} -> successRetentionPeriodInDays) (\s@Canary' {} a -> s {successRetentionPeriodInDays = a} :: Canary)
+
+-- | The list of key-value pairs that are associated with the canary.
+canary_tags :: Lens.Lens' Canary (Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text))
+canary_tags = Lens.lens (\Canary' {tags} -> tags) (\s@Canary' {} a -> s {tags = a} :: Canary) Prelude.. Lens.mapping Lens.coerced
+
+-- | A structure that contains information about when the canary was created,
+-- modified, and most recently run.
+canary_timeline :: Lens.Lens' Canary (Prelude.Maybe CanaryTimeline)
+canary_timeline = Lens.lens (\Canary' {timeline} -> timeline) (\s@Canary' {} a -> s {timeline = a} :: Canary)
+
+-- | If this canary performs visual monitoring by comparing screenshots, this
+-- structure contains the ID of the canary run to use as the baseline for
+-- screenshots, and the coordinates of any parts of the screen to ignore
+-- during the visual monitoring comparison.
+canary_visualReference :: Lens.Lens' Canary (Prelude.Maybe VisualReferenceOutput)
+canary_visualReference = Lens.lens (\Canary' {visualReference} -> visualReference) (\s@Canary' {} a -> s {visualReference = a} :: Canary)
+
+-- | Undocumented member.
+canary_vpcConfig :: Lens.Lens' Canary (Prelude.Maybe VpcConfigOutput)
+canary_vpcConfig = Lens.lens (\Canary' {vpcConfig} -> vpcConfig) (\s@Canary' {} a -> s {vpcConfig = a} :: Canary)
+
+instance Data.FromJSON Canary where
+  parseJSON =
+    Data.withObject
+      "Canary"
+      ( \x ->
+          Canary'
+            Prelude.<$> (x Data..:? "ArtifactConfig")
+            Prelude.<*> (x Data..:? "ArtifactS3Location")
+            Prelude.<*> (x Data..:? "Code")
+            Prelude.<*> (x Data..:? "EngineArn")
+            Prelude.<*> (x Data..:? "ExecutionRoleArn")
+            Prelude.<*> (x Data..:? "FailureRetentionPeriodInDays")
+            Prelude.<*> (x Data..:? "Id")
+            Prelude.<*> (x Data..:? "Name")
+            Prelude.<*> (x Data..:? "RunConfig")
+            Prelude.<*> (x Data..:? "RuntimeVersion")
+            Prelude.<*> (x Data..:? "Schedule")
+            Prelude.<*> (x Data..:? "Status")
+            Prelude.<*> (x Data..:? "SuccessRetentionPeriodInDays")
+            Prelude.<*> (x Data..:? "Tags" Data..!= Prelude.mempty)
+            Prelude.<*> (x Data..:? "Timeline")
+            Prelude.<*> (x Data..:? "VisualReference")
+            Prelude.<*> (x Data..:? "VpcConfig")
+      )
+
+instance Prelude.Hashable Canary where
+  hashWithSalt _salt Canary' {..} =
+    _salt
+      `Prelude.hashWithSalt` artifactConfig
+      `Prelude.hashWithSalt` artifactS3Location
+      `Prelude.hashWithSalt` code
+      `Prelude.hashWithSalt` engineArn
+      `Prelude.hashWithSalt` executionRoleArn
+      `Prelude.hashWithSalt` failureRetentionPeriodInDays
+      `Prelude.hashWithSalt` id
+      `Prelude.hashWithSalt` name
+      `Prelude.hashWithSalt` runConfig
+      `Prelude.hashWithSalt` runtimeVersion
+      `Prelude.hashWithSalt` schedule
+      `Prelude.hashWithSalt` status
+      `Prelude.hashWithSalt` successRetentionPeriodInDays
+      `Prelude.hashWithSalt` tags
+      `Prelude.hashWithSalt` timeline
+      `Prelude.hashWithSalt` visualReference
+      `Prelude.hashWithSalt` vpcConfig
+
+instance Prelude.NFData Canary where
+  rnf Canary' {..} =
+    Prelude.rnf artifactConfig
+      `Prelude.seq` Prelude.rnf artifactS3Location
+      `Prelude.seq` Prelude.rnf code
+      `Prelude.seq` Prelude.rnf engineArn
+      `Prelude.seq` Prelude.rnf executionRoleArn
+      `Prelude.seq` Prelude.rnf failureRetentionPeriodInDays
+      `Prelude.seq` Prelude.rnf id
+      `Prelude.seq` Prelude.rnf name
+      `Prelude.seq` Prelude.rnf runConfig
+      `Prelude.seq` Prelude.rnf runtimeVersion
+      `Prelude.seq` Prelude.rnf schedule
+      `Prelude.seq` Prelude.rnf status
+      `Prelude.seq` Prelude.rnf successRetentionPeriodInDays
+      `Prelude.seq` Prelude.rnf tags
+      `Prelude.seq` Prelude.rnf timeline
+      `Prelude.seq` Prelude.rnf visualReference
+      `Prelude.seq` Prelude.rnf vpcConfig
diff --git a/gen/Amazonka/Synthetics/Types/CanaryCodeInput.hs b/gen/Amazonka/Synthetics/Types/CanaryCodeInput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryCodeInput.hs
@@ -0,0 +1,182 @@
+{-# 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.Synthetics.Types.CanaryCodeInput
+-- 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.Synthetics.Types.CanaryCodeInput 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
+
+-- | Use this structure to input your script code for the canary. This
+-- structure contains the Lambda handler with the location where the canary
+-- should start running the script. If the script is stored in an S3
+-- bucket, the bucket name, key, and version are also included. If the
+-- script was passed into the canary directly, the script code is contained
+-- in the value of @Zipfile@.
+--
+-- /See:/ 'newCanaryCodeInput' smart constructor.
+data CanaryCodeInput = CanaryCodeInput'
+  { -- | If your canary script is located in S3, specify the bucket name here. Do
+    -- not include @s3:\/\/@ as the start of the bucket name.
+    s3Bucket :: Prelude.Maybe Prelude.Text,
+    -- | The S3 key of your script. For more information, see
+    -- <https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingObjects.html Working with Amazon S3 Objects>.
+    s3Key :: Prelude.Maybe Prelude.Text,
+    -- | The S3 version ID of your script.
+    s3Version :: Prelude.Maybe Prelude.Text,
+    -- | If you input your canary script directly into the canary instead of
+    -- referring to an S3 location, the value of this parameter is the
+    -- base64-encoded contents of the .zip file that contains the script. It
+    -- must be smaller than 225 Kb.
+    --
+    -- For large canary scripts, we recommend that you use an S3 location
+    -- instead of inputting it directly with this parameter.
+    zipFile :: Prelude.Maybe Data.Base64,
+    -- | The entry point to use for the source code when running the canary. For
+    -- canaries that use the @syn-python-selenium-1.0@ runtime or a
+    -- @syn-nodejs.puppeteer@ runtime earlier than @syn-nodejs.puppeteer-3.4@,
+    -- the handler must be specified as @ @/@fileName@/@.handler@. For
+    -- @syn-python-selenium-1.1@, @syn-nodejs.puppeteer-3.4@, and later
+    -- runtimes, the handler can be specified as
+    -- @ @/@fileName@/@.@/@functionName@/@ @, or you can specify a folder where
+    -- canary scripts reside as
+    -- @ @/@folder@/@\/@/@fileName@/@.@/@functionName@/@ @.
+    handler :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryCodeInput' 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:
+--
+-- 's3Bucket', 'canaryCodeInput_s3Bucket' - If your canary script is located in S3, specify the bucket name here. Do
+-- not include @s3:\/\/@ as the start of the bucket name.
+--
+-- 's3Key', 'canaryCodeInput_s3Key' - The S3 key of your script. For more information, see
+-- <https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingObjects.html Working with Amazon S3 Objects>.
+--
+-- 's3Version', 'canaryCodeInput_s3Version' - The S3 version ID of your script.
+--
+-- 'zipFile', 'canaryCodeInput_zipFile' - If you input your canary script directly into the canary instead of
+-- referring to an S3 location, the value of this parameter is the
+-- base64-encoded contents of the .zip file that contains the script. It
+-- must be smaller than 225 Kb.
+--
+-- For large canary scripts, we recommend that you use an S3 location
+-- instead of inputting it directly with this parameter.--
+-- -- /Note:/ This 'Lens' automatically encodes and decodes Base64 data.
+-- -- The underlying isomorphism will encode to Base64 representation during
+-- -- serialisation, and decode from Base64 representation during deserialisation.
+-- -- This 'Lens' accepts and returns only raw unencoded data.
+--
+-- 'handler', 'canaryCodeInput_handler' - The entry point to use for the source code when running the canary. For
+-- canaries that use the @syn-python-selenium-1.0@ runtime or a
+-- @syn-nodejs.puppeteer@ runtime earlier than @syn-nodejs.puppeteer-3.4@,
+-- the handler must be specified as @ @/@fileName@/@.handler@. For
+-- @syn-python-selenium-1.1@, @syn-nodejs.puppeteer-3.4@, and later
+-- runtimes, the handler can be specified as
+-- @ @/@fileName@/@.@/@functionName@/@ @, or you can specify a folder where
+-- canary scripts reside as
+-- @ @/@folder@/@\/@/@fileName@/@.@/@functionName@/@ @.
+newCanaryCodeInput ::
+  -- | 'handler'
+  Prelude.Text ->
+  CanaryCodeInput
+newCanaryCodeInput pHandler_ =
+  CanaryCodeInput'
+    { s3Bucket = Prelude.Nothing,
+      s3Key = Prelude.Nothing,
+      s3Version = Prelude.Nothing,
+      zipFile = Prelude.Nothing,
+      handler = pHandler_
+    }
+
+-- | If your canary script is located in S3, specify the bucket name here. Do
+-- not include @s3:\/\/@ as the start of the bucket name.
+canaryCodeInput_s3Bucket :: Lens.Lens' CanaryCodeInput (Prelude.Maybe Prelude.Text)
+canaryCodeInput_s3Bucket = Lens.lens (\CanaryCodeInput' {s3Bucket} -> s3Bucket) (\s@CanaryCodeInput' {} a -> s {s3Bucket = a} :: CanaryCodeInput)
+
+-- | The S3 key of your script. For more information, see
+-- <https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingObjects.html Working with Amazon S3 Objects>.
+canaryCodeInput_s3Key :: Lens.Lens' CanaryCodeInput (Prelude.Maybe Prelude.Text)
+canaryCodeInput_s3Key = Lens.lens (\CanaryCodeInput' {s3Key} -> s3Key) (\s@CanaryCodeInput' {} a -> s {s3Key = a} :: CanaryCodeInput)
+
+-- | The S3 version ID of your script.
+canaryCodeInput_s3Version :: Lens.Lens' CanaryCodeInput (Prelude.Maybe Prelude.Text)
+canaryCodeInput_s3Version = Lens.lens (\CanaryCodeInput' {s3Version} -> s3Version) (\s@CanaryCodeInput' {} a -> s {s3Version = a} :: CanaryCodeInput)
+
+-- | If you input your canary script directly into the canary instead of
+-- referring to an S3 location, the value of this parameter is the
+-- base64-encoded contents of the .zip file that contains the script. It
+-- must be smaller than 225 Kb.
+--
+-- For large canary scripts, we recommend that you use an S3 location
+-- instead of inputting it directly with this parameter.--
+-- -- /Note:/ This 'Lens' automatically encodes and decodes Base64 data.
+-- -- The underlying isomorphism will encode to Base64 representation during
+-- -- serialisation, and decode from Base64 representation during deserialisation.
+-- -- This 'Lens' accepts and returns only raw unencoded data.
+canaryCodeInput_zipFile :: Lens.Lens' CanaryCodeInput (Prelude.Maybe Prelude.ByteString)
+canaryCodeInput_zipFile = Lens.lens (\CanaryCodeInput' {zipFile} -> zipFile) (\s@CanaryCodeInput' {} a -> s {zipFile = a} :: CanaryCodeInput) Prelude.. Lens.mapping Data._Base64
+
+-- | The entry point to use for the source code when running the canary. For
+-- canaries that use the @syn-python-selenium-1.0@ runtime or a
+-- @syn-nodejs.puppeteer@ runtime earlier than @syn-nodejs.puppeteer-3.4@,
+-- the handler must be specified as @ @/@fileName@/@.handler@. For
+-- @syn-python-selenium-1.1@, @syn-nodejs.puppeteer-3.4@, and later
+-- runtimes, the handler can be specified as
+-- @ @/@fileName@/@.@/@functionName@/@ @, or you can specify a folder where
+-- canary scripts reside as
+-- @ @/@folder@/@\/@/@fileName@/@.@/@functionName@/@ @.
+canaryCodeInput_handler :: Lens.Lens' CanaryCodeInput Prelude.Text
+canaryCodeInput_handler = Lens.lens (\CanaryCodeInput' {handler} -> handler) (\s@CanaryCodeInput' {} a -> s {handler = a} :: CanaryCodeInput)
+
+instance Prelude.Hashable CanaryCodeInput where
+  hashWithSalt _salt CanaryCodeInput' {..} =
+    _salt
+      `Prelude.hashWithSalt` s3Bucket
+      `Prelude.hashWithSalt` s3Key
+      `Prelude.hashWithSalt` s3Version
+      `Prelude.hashWithSalt` zipFile
+      `Prelude.hashWithSalt` handler
+
+instance Prelude.NFData CanaryCodeInput where
+  rnf CanaryCodeInput' {..} =
+    Prelude.rnf s3Bucket
+      `Prelude.seq` Prelude.rnf s3Key
+      `Prelude.seq` Prelude.rnf s3Version
+      `Prelude.seq` Prelude.rnf zipFile
+      `Prelude.seq` Prelude.rnf handler
+
+instance Data.ToJSON CanaryCodeInput where
+  toJSON CanaryCodeInput' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("S3Bucket" Data..=) Prelude.<$> s3Bucket,
+            ("S3Key" Data..=) Prelude.<$> s3Key,
+            ("S3Version" Data..=) Prelude.<$> s3Version,
+            ("ZipFile" Data..=) Prelude.<$> zipFile,
+            Prelude.Just ("Handler" Data..= handler)
+          ]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/CanaryCodeOutput.hs b/gen/Amazonka/Synthetics/Types/CanaryCodeOutput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryCodeOutput.hs
@@ -0,0 +1,88 @@
+{-# 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.Synthetics.Types.CanaryCodeOutput
+-- 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.Synthetics.Types.CanaryCodeOutput 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
+
+-- | This structure contains information about the canary\'s Lambda handler
+-- and where its code is stored by CloudWatch Synthetics.
+--
+-- /See:/ 'newCanaryCodeOutput' smart constructor.
+data CanaryCodeOutput = CanaryCodeOutput'
+  { -- | The entry point to use for the source code when running the canary.
+    handler :: Prelude.Maybe Prelude.Text,
+    -- | The ARN of the Lambda layer where Synthetics stores the canary script
+    -- code.
+    sourceLocationArn :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryCodeOutput' 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:
+--
+-- 'handler', 'canaryCodeOutput_handler' - The entry point to use for the source code when running the canary.
+--
+-- 'sourceLocationArn', 'canaryCodeOutput_sourceLocationArn' - The ARN of the Lambda layer where Synthetics stores the canary script
+-- code.
+newCanaryCodeOutput ::
+  CanaryCodeOutput
+newCanaryCodeOutput =
+  CanaryCodeOutput'
+    { handler = Prelude.Nothing,
+      sourceLocationArn = Prelude.Nothing
+    }
+
+-- | The entry point to use for the source code when running the canary.
+canaryCodeOutput_handler :: Lens.Lens' CanaryCodeOutput (Prelude.Maybe Prelude.Text)
+canaryCodeOutput_handler = Lens.lens (\CanaryCodeOutput' {handler} -> handler) (\s@CanaryCodeOutput' {} a -> s {handler = a} :: CanaryCodeOutput)
+
+-- | The ARN of the Lambda layer where Synthetics stores the canary script
+-- code.
+canaryCodeOutput_sourceLocationArn :: Lens.Lens' CanaryCodeOutput (Prelude.Maybe Prelude.Text)
+canaryCodeOutput_sourceLocationArn = Lens.lens (\CanaryCodeOutput' {sourceLocationArn} -> sourceLocationArn) (\s@CanaryCodeOutput' {} a -> s {sourceLocationArn = a} :: CanaryCodeOutput)
+
+instance Data.FromJSON CanaryCodeOutput where
+  parseJSON =
+    Data.withObject
+      "CanaryCodeOutput"
+      ( \x ->
+          CanaryCodeOutput'
+            Prelude.<$> (x Data..:? "Handler")
+            Prelude.<*> (x Data..:? "SourceLocationArn")
+      )
+
+instance Prelude.Hashable CanaryCodeOutput where
+  hashWithSalt _salt CanaryCodeOutput' {..} =
+    _salt
+      `Prelude.hashWithSalt` handler
+      `Prelude.hashWithSalt` sourceLocationArn
+
+instance Prelude.NFData CanaryCodeOutput where
+  rnf CanaryCodeOutput' {..} =
+    Prelude.rnf handler
+      `Prelude.seq` Prelude.rnf sourceLocationArn
diff --git a/gen/Amazonka/Synthetics/Types/CanaryLastRun.hs b/gen/Amazonka/Synthetics/Types/CanaryLastRun.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryLastRun.hs
@@ -0,0 +1,86 @@
+{-# 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.Synthetics.Types.CanaryLastRun
+-- 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.Synthetics.Types.CanaryLastRun 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
+import Amazonka.Synthetics.Types.CanaryRun
+
+-- | This structure contains information about the most recent run of a
+-- single canary.
+--
+-- /See:/ 'newCanaryLastRun' smart constructor.
+data CanaryLastRun = CanaryLastRun'
+  { -- | The name of the canary.
+    canaryName :: Prelude.Maybe Prelude.Text,
+    -- | The results from this canary\'s most recent run.
+    lastRun :: Prelude.Maybe CanaryRun
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryLastRun' 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:
+--
+-- 'canaryName', 'canaryLastRun_canaryName' - The name of the canary.
+--
+-- 'lastRun', 'canaryLastRun_lastRun' - The results from this canary\'s most recent run.
+newCanaryLastRun ::
+  CanaryLastRun
+newCanaryLastRun =
+  CanaryLastRun'
+    { canaryName = Prelude.Nothing,
+      lastRun = Prelude.Nothing
+    }
+
+-- | The name of the canary.
+canaryLastRun_canaryName :: Lens.Lens' CanaryLastRun (Prelude.Maybe Prelude.Text)
+canaryLastRun_canaryName = Lens.lens (\CanaryLastRun' {canaryName} -> canaryName) (\s@CanaryLastRun' {} a -> s {canaryName = a} :: CanaryLastRun)
+
+-- | The results from this canary\'s most recent run.
+canaryLastRun_lastRun :: Lens.Lens' CanaryLastRun (Prelude.Maybe CanaryRun)
+canaryLastRun_lastRun = Lens.lens (\CanaryLastRun' {lastRun} -> lastRun) (\s@CanaryLastRun' {} a -> s {lastRun = a} :: CanaryLastRun)
+
+instance Data.FromJSON CanaryLastRun where
+  parseJSON =
+    Data.withObject
+      "CanaryLastRun"
+      ( \x ->
+          CanaryLastRun'
+            Prelude.<$> (x Data..:? "CanaryName")
+            Prelude.<*> (x Data..:? "LastRun")
+      )
+
+instance Prelude.Hashable CanaryLastRun where
+  hashWithSalt _salt CanaryLastRun' {..} =
+    _salt
+      `Prelude.hashWithSalt` canaryName
+      `Prelude.hashWithSalt` lastRun
+
+instance Prelude.NFData CanaryLastRun where
+  rnf CanaryLastRun' {..} =
+    Prelude.rnf canaryName
+      `Prelude.seq` Prelude.rnf lastRun
diff --git a/gen/Amazonka/Synthetics/Types/CanaryRun.hs b/gen/Amazonka/Synthetics/Types/CanaryRun.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryRun.hs
@@ -0,0 +1,125 @@
+{-# 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.Synthetics.Types.CanaryRun
+-- 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.Synthetics.Types.CanaryRun 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
+import Amazonka.Synthetics.Types.CanaryRunStatus
+import Amazonka.Synthetics.Types.CanaryRunTimeline
+
+-- | This structure contains the details about one run of one canary.
+--
+-- /See:/ 'newCanaryRun' smart constructor.
+data CanaryRun = CanaryRun'
+  { -- | The location where the canary stored artifacts from the run. Artifacts
+    -- include the log file, screenshots, and HAR files.
+    artifactS3Location :: Prelude.Maybe Prelude.Text,
+    -- | A unique ID that identifies this canary run.
+    id :: Prelude.Maybe Prelude.Text,
+    -- | The name of the canary.
+    name :: Prelude.Maybe Prelude.Text,
+    -- | The status of this run.
+    status :: Prelude.Maybe CanaryRunStatus,
+    -- | A structure that contains the start and end times of this run.
+    timeline :: Prelude.Maybe CanaryRunTimeline
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryRun' 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:
+--
+-- 'artifactS3Location', 'canaryRun_artifactS3Location' - The location where the canary stored artifacts from the run. Artifacts
+-- include the log file, screenshots, and HAR files.
+--
+-- 'id', 'canaryRun_id' - A unique ID that identifies this canary run.
+--
+-- 'name', 'canaryRun_name' - The name of the canary.
+--
+-- 'status', 'canaryRun_status' - The status of this run.
+--
+-- 'timeline', 'canaryRun_timeline' - A structure that contains the start and end times of this run.
+newCanaryRun ::
+  CanaryRun
+newCanaryRun =
+  CanaryRun'
+    { artifactS3Location = Prelude.Nothing,
+      id = Prelude.Nothing,
+      name = Prelude.Nothing,
+      status = Prelude.Nothing,
+      timeline = Prelude.Nothing
+    }
+
+-- | The location where the canary stored artifacts from the run. Artifacts
+-- include the log file, screenshots, and HAR files.
+canaryRun_artifactS3Location :: Lens.Lens' CanaryRun (Prelude.Maybe Prelude.Text)
+canaryRun_artifactS3Location = Lens.lens (\CanaryRun' {artifactS3Location} -> artifactS3Location) (\s@CanaryRun' {} a -> s {artifactS3Location = a} :: CanaryRun)
+
+-- | A unique ID that identifies this canary run.
+canaryRun_id :: Lens.Lens' CanaryRun (Prelude.Maybe Prelude.Text)
+canaryRun_id = Lens.lens (\CanaryRun' {id} -> id) (\s@CanaryRun' {} a -> s {id = a} :: CanaryRun)
+
+-- | The name of the canary.
+canaryRun_name :: Lens.Lens' CanaryRun (Prelude.Maybe Prelude.Text)
+canaryRun_name = Lens.lens (\CanaryRun' {name} -> name) (\s@CanaryRun' {} a -> s {name = a} :: CanaryRun)
+
+-- | The status of this run.
+canaryRun_status :: Lens.Lens' CanaryRun (Prelude.Maybe CanaryRunStatus)
+canaryRun_status = Lens.lens (\CanaryRun' {status} -> status) (\s@CanaryRun' {} a -> s {status = a} :: CanaryRun)
+
+-- | A structure that contains the start and end times of this run.
+canaryRun_timeline :: Lens.Lens' CanaryRun (Prelude.Maybe CanaryRunTimeline)
+canaryRun_timeline = Lens.lens (\CanaryRun' {timeline} -> timeline) (\s@CanaryRun' {} a -> s {timeline = a} :: CanaryRun)
+
+instance Data.FromJSON CanaryRun where
+  parseJSON =
+    Data.withObject
+      "CanaryRun"
+      ( \x ->
+          CanaryRun'
+            Prelude.<$> (x Data..:? "ArtifactS3Location")
+            Prelude.<*> (x Data..:? "Id")
+            Prelude.<*> (x Data..:? "Name")
+            Prelude.<*> (x Data..:? "Status")
+            Prelude.<*> (x Data..:? "Timeline")
+      )
+
+instance Prelude.Hashable CanaryRun where
+  hashWithSalt _salt CanaryRun' {..} =
+    _salt
+      `Prelude.hashWithSalt` artifactS3Location
+      `Prelude.hashWithSalt` id
+      `Prelude.hashWithSalt` name
+      `Prelude.hashWithSalt` status
+      `Prelude.hashWithSalt` timeline
+
+instance Prelude.NFData CanaryRun where
+  rnf CanaryRun' {..} =
+    Prelude.rnf artifactS3Location
+      `Prelude.seq` Prelude.rnf id
+      `Prelude.seq` Prelude.rnf name
+      `Prelude.seq` Prelude.rnf status
+      `Prelude.seq` Prelude.rnf timeline
diff --git a/gen/Amazonka/Synthetics/Types/CanaryRunConfigInput.hs b/gen/Amazonka/Synthetics/Types/CanaryRunConfigInput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryRunConfigInput.hs
@@ -0,0 +1,188 @@
+{-# 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.Synthetics.Types.CanaryRunConfigInput
+-- 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.Synthetics.Types.CanaryRunConfigInput 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 structure that contains input information for a canary run.
+--
+-- /See:/ 'newCanaryRunConfigInput' smart constructor.
+data CanaryRunConfigInput = CanaryRunConfigInput'
+  { -- | Specifies whether this canary is to use active X-Ray tracing when it
+    -- runs. Active tracing enables this canary run to be displayed in the
+    -- ServiceLens and X-Ray service maps even if the canary does not hit an
+    -- endpoint that has X-Ray tracing enabled. Using X-Ray tracing incurs
+    -- charges. For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_tracing.html Canaries and X-Ray tracing>.
+    --
+    -- You can enable active tracing only for canaries that use version
+    -- @syn-nodejs-2.0@ or later for their canary runtime.
+    activeTracing :: Prelude.Maybe Prelude.Bool,
+    -- | Specifies the keys and values to use for any environment variables used
+    -- in the canary script. Use the following format:
+    --
+    -- { \"key1\" : \"value1\", \"key2\" : \"value2\", ...}
+    --
+    -- Keys must start with a letter and be at least two characters. The total
+    -- size of your environment variables cannot exceed 4 KB. You can\'t
+    -- specify any Lambda reserved environment variables as the keys for your
+    -- environment variables. For more information about reserved keys, see
+    -- <https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime Runtime environment variables>.
+    --
+    -- The environment variables keys and values are not encrypted. Do not
+    -- store sensitive information in this field.
+    environmentVariables :: Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text),
+    -- | The maximum amount of memory available to the canary while it is
+    -- running, in MB. This value must be a multiple of 64.
+    memoryInMB :: Prelude.Maybe Prelude.Natural,
+    -- | How long the canary is allowed to run before it must stop. You can\'t
+    -- set this time to be longer than the frequency of the runs of this
+    -- canary.
+    --
+    -- If you omit this field, the frequency of the canary is used as this
+    -- value, up to a maximum of 14 minutes.
+    timeoutInSeconds :: Prelude.Maybe Prelude.Natural
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryRunConfigInput' 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:
+--
+-- 'activeTracing', 'canaryRunConfigInput_activeTracing' - Specifies whether this canary is to use active X-Ray tracing when it
+-- runs. Active tracing enables this canary run to be displayed in the
+-- ServiceLens and X-Ray service maps even if the canary does not hit an
+-- endpoint that has X-Ray tracing enabled. Using X-Ray tracing incurs
+-- charges. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_tracing.html Canaries and X-Ray tracing>.
+--
+-- You can enable active tracing only for canaries that use version
+-- @syn-nodejs-2.0@ or later for their canary runtime.
+--
+-- 'environmentVariables', 'canaryRunConfigInput_environmentVariables' - Specifies the keys and values to use for any environment variables used
+-- in the canary script. Use the following format:
+--
+-- { \"key1\" : \"value1\", \"key2\" : \"value2\", ...}
+--
+-- Keys must start with a letter and be at least two characters. The total
+-- size of your environment variables cannot exceed 4 KB. You can\'t
+-- specify any Lambda reserved environment variables as the keys for your
+-- environment variables. For more information about reserved keys, see
+-- <https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime Runtime environment variables>.
+--
+-- The environment variables keys and values are not encrypted. Do not
+-- store sensitive information in this field.
+--
+-- 'memoryInMB', 'canaryRunConfigInput_memoryInMB' - The maximum amount of memory available to the canary while it is
+-- running, in MB. This value must be a multiple of 64.
+--
+-- 'timeoutInSeconds', 'canaryRunConfigInput_timeoutInSeconds' - How long the canary is allowed to run before it must stop. You can\'t
+-- set this time to be longer than the frequency of the runs of this
+-- canary.
+--
+-- If you omit this field, the frequency of the canary is used as this
+-- value, up to a maximum of 14 minutes.
+newCanaryRunConfigInput ::
+  CanaryRunConfigInput
+newCanaryRunConfigInput =
+  CanaryRunConfigInput'
+    { activeTracing =
+        Prelude.Nothing,
+      environmentVariables = Prelude.Nothing,
+      memoryInMB = Prelude.Nothing,
+      timeoutInSeconds = Prelude.Nothing
+    }
+
+-- | Specifies whether this canary is to use active X-Ray tracing when it
+-- runs. Active tracing enables this canary run to be displayed in the
+-- ServiceLens and X-Ray service maps even if the canary does not hit an
+-- endpoint that has X-Ray tracing enabled. Using X-Ray tracing incurs
+-- charges. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_tracing.html Canaries and X-Ray tracing>.
+--
+-- You can enable active tracing only for canaries that use version
+-- @syn-nodejs-2.0@ or later for their canary runtime.
+canaryRunConfigInput_activeTracing :: Lens.Lens' CanaryRunConfigInput (Prelude.Maybe Prelude.Bool)
+canaryRunConfigInput_activeTracing = Lens.lens (\CanaryRunConfigInput' {activeTracing} -> activeTracing) (\s@CanaryRunConfigInput' {} a -> s {activeTracing = a} :: CanaryRunConfigInput)
+
+-- | Specifies the keys and values to use for any environment variables used
+-- in the canary script. Use the following format:
+--
+-- { \"key1\" : \"value1\", \"key2\" : \"value2\", ...}
+--
+-- Keys must start with a letter and be at least two characters. The total
+-- size of your environment variables cannot exceed 4 KB. You can\'t
+-- specify any Lambda reserved environment variables as the keys for your
+-- environment variables. For more information about reserved keys, see
+-- <https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime Runtime environment variables>.
+--
+-- The environment variables keys and values are not encrypted. Do not
+-- store sensitive information in this field.
+canaryRunConfigInput_environmentVariables :: Lens.Lens' CanaryRunConfigInput (Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text))
+canaryRunConfigInput_environmentVariables = Lens.lens (\CanaryRunConfigInput' {environmentVariables} -> environmentVariables) (\s@CanaryRunConfigInput' {} a -> s {environmentVariables = a} :: CanaryRunConfigInput) Prelude.. Lens.mapping Lens.coerced
+
+-- | The maximum amount of memory available to the canary while it is
+-- running, in MB. This value must be a multiple of 64.
+canaryRunConfigInput_memoryInMB :: Lens.Lens' CanaryRunConfigInput (Prelude.Maybe Prelude.Natural)
+canaryRunConfigInput_memoryInMB = Lens.lens (\CanaryRunConfigInput' {memoryInMB} -> memoryInMB) (\s@CanaryRunConfigInput' {} a -> s {memoryInMB = a} :: CanaryRunConfigInput)
+
+-- | How long the canary is allowed to run before it must stop. You can\'t
+-- set this time to be longer than the frequency of the runs of this
+-- canary.
+--
+-- If you omit this field, the frequency of the canary is used as this
+-- value, up to a maximum of 14 minutes.
+canaryRunConfigInput_timeoutInSeconds :: Lens.Lens' CanaryRunConfigInput (Prelude.Maybe Prelude.Natural)
+canaryRunConfigInput_timeoutInSeconds = Lens.lens (\CanaryRunConfigInput' {timeoutInSeconds} -> timeoutInSeconds) (\s@CanaryRunConfigInput' {} a -> s {timeoutInSeconds = a} :: CanaryRunConfigInput)
+
+instance Prelude.Hashable CanaryRunConfigInput where
+  hashWithSalt _salt CanaryRunConfigInput' {..} =
+    _salt
+      `Prelude.hashWithSalt` activeTracing
+      `Prelude.hashWithSalt` environmentVariables
+      `Prelude.hashWithSalt` memoryInMB
+      `Prelude.hashWithSalt` timeoutInSeconds
+
+instance Prelude.NFData CanaryRunConfigInput where
+  rnf CanaryRunConfigInput' {..} =
+    Prelude.rnf activeTracing
+      `Prelude.seq` Prelude.rnf environmentVariables
+      `Prelude.seq` Prelude.rnf memoryInMB
+      `Prelude.seq` Prelude.rnf timeoutInSeconds
+
+instance Data.ToJSON CanaryRunConfigInput where
+  toJSON CanaryRunConfigInput' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("ActiveTracing" Data..=) Prelude.<$> activeTracing,
+            ("EnvironmentVariables" Data..=)
+              Prelude.<$> environmentVariables,
+            ("MemoryInMB" Data..=) Prelude.<$> memoryInMB,
+            ("TimeoutInSeconds" Data..=)
+              Prelude.<$> timeoutInSeconds
+          ]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/CanaryRunConfigOutput.hs b/gen/Amazonka/Synthetics/Types/CanaryRunConfigOutput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryRunConfigOutput.hs
@@ -0,0 +1,100 @@
+{-# 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.Synthetics.Types.CanaryRunConfigOutput
+-- 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.Synthetics.Types.CanaryRunConfigOutput 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 structure that contains information about a canary run.
+--
+-- /See:/ 'newCanaryRunConfigOutput' smart constructor.
+data CanaryRunConfigOutput = CanaryRunConfigOutput'
+  { -- | Displays whether this canary run used active X-Ray tracing.
+    activeTracing :: Prelude.Maybe Prelude.Bool,
+    -- | The maximum amount of memory available to the canary while it is
+    -- running, in MB. This value must be a multiple of 64.
+    memoryInMB :: Prelude.Maybe Prelude.Natural,
+    -- | How long the canary is allowed to run before it must stop.
+    timeoutInSeconds :: Prelude.Maybe Prelude.Natural
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryRunConfigOutput' 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:
+--
+-- 'activeTracing', 'canaryRunConfigOutput_activeTracing' - Displays whether this canary run used active X-Ray tracing.
+--
+-- 'memoryInMB', 'canaryRunConfigOutput_memoryInMB' - The maximum amount of memory available to the canary while it is
+-- running, in MB. This value must be a multiple of 64.
+--
+-- 'timeoutInSeconds', 'canaryRunConfigOutput_timeoutInSeconds' - How long the canary is allowed to run before it must stop.
+newCanaryRunConfigOutput ::
+  CanaryRunConfigOutput
+newCanaryRunConfigOutput =
+  CanaryRunConfigOutput'
+    { activeTracing =
+        Prelude.Nothing,
+      memoryInMB = Prelude.Nothing,
+      timeoutInSeconds = Prelude.Nothing
+    }
+
+-- | Displays whether this canary run used active X-Ray tracing.
+canaryRunConfigOutput_activeTracing :: Lens.Lens' CanaryRunConfigOutput (Prelude.Maybe Prelude.Bool)
+canaryRunConfigOutput_activeTracing = Lens.lens (\CanaryRunConfigOutput' {activeTracing} -> activeTracing) (\s@CanaryRunConfigOutput' {} a -> s {activeTracing = a} :: CanaryRunConfigOutput)
+
+-- | The maximum amount of memory available to the canary while it is
+-- running, in MB. This value must be a multiple of 64.
+canaryRunConfigOutput_memoryInMB :: Lens.Lens' CanaryRunConfigOutput (Prelude.Maybe Prelude.Natural)
+canaryRunConfigOutput_memoryInMB = Lens.lens (\CanaryRunConfigOutput' {memoryInMB} -> memoryInMB) (\s@CanaryRunConfigOutput' {} a -> s {memoryInMB = a} :: CanaryRunConfigOutput)
+
+-- | How long the canary is allowed to run before it must stop.
+canaryRunConfigOutput_timeoutInSeconds :: Lens.Lens' CanaryRunConfigOutput (Prelude.Maybe Prelude.Natural)
+canaryRunConfigOutput_timeoutInSeconds = Lens.lens (\CanaryRunConfigOutput' {timeoutInSeconds} -> timeoutInSeconds) (\s@CanaryRunConfigOutput' {} a -> s {timeoutInSeconds = a} :: CanaryRunConfigOutput)
+
+instance Data.FromJSON CanaryRunConfigOutput where
+  parseJSON =
+    Data.withObject
+      "CanaryRunConfigOutput"
+      ( \x ->
+          CanaryRunConfigOutput'
+            Prelude.<$> (x Data..:? "ActiveTracing")
+            Prelude.<*> (x Data..:? "MemoryInMB")
+            Prelude.<*> (x Data..:? "TimeoutInSeconds")
+      )
+
+instance Prelude.Hashable CanaryRunConfigOutput where
+  hashWithSalt _salt CanaryRunConfigOutput' {..} =
+    _salt
+      `Prelude.hashWithSalt` activeTracing
+      `Prelude.hashWithSalt` memoryInMB
+      `Prelude.hashWithSalt` timeoutInSeconds
+
+instance Prelude.NFData CanaryRunConfigOutput where
+  rnf CanaryRunConfigOutput' {..} =
+    Prelude.rnf activeTracing
+      `Prelude.seq` Prelude.rnf memoryInMB
+      `Prelude.seq` Prelude.rnf timeoutInSeconds
diff --git a/gen/Amazonka/Synthetics/Types/CanaryRunState.hs b/gen/Amazonka/Synthetics/Types/CanaryRunState.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryRunState.hs
@@ -0,0 +1,76 @@
+{-# 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.Synthetics.Types.CanaryRunState
+-- 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.Synthetics.Types.CanaryRunState
+  ( CanaryRunState
+      ( ..,
+        CanaryRunState_FAILED,
+        CanaryRunState_PASSED,
+        CanaryRunState_RUNNING
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype CanaryRunState = CanaryRunState'
+  { fromCanaryRunState ::
+      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 CanaryRunState_FAILED :: CanaryRunState
+pattern CanaryRunState_FAILED = CanaryRunState' "FAILED"
+
+pattern CanaryRunState_PASSED :: CanaryRunState
+pattern CanaryRunState_PASSED = CanaryRunState' "PASSED"
+
+pattern CanaryRunState_RUNNING :: CanaryRunState
+pattern CanaryRunState_RUNNING = CanaryRunState' "RUNNING"
+
+{-# COMPLETE
+  CanaryRunState_FAILED,
+  CanaryRunState_PASSED,
+  CanaryRunState_RUNNING,
+  CanaryRunState'
+  #-}
diff --git a/gen/Amazonka/Synthetics/Types/CanaryRunStateReasonCode.hs b/gen/Amazonka/Synthetics/Types/CanaryRunStateReasonCode.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryRunStateReasonCode.hs
@@ -0,0 +1,71 @@
+{-# 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.Synthetics.Types.CanaryRunStateReasonCode
+-- 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.Synthetics.Types.CanaryRunStateReasonCode
+  ( CanaryRunStateReasonCode
+      ( ..,
+        CanaryRunStateReasonCode_CANARY_FAILURE,
+        CanaryRunStateReasonCode_EXECUTION_FAILURE
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype CanaryRunStateReasonCode = CanaryRunStateReasonCode'
+  { fromCanaryRunStateReasonCode ::
+      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 CanaryRunStateReasonCode_CANARY_FAILURE :: CanaryRunStateReasonCode
+pattern CanaryRunStateReasonCode_CANARY_FAILURE = CanaryRunStateReasonCode' "CANARY_FAILURE"
+
+pattern CanaryRunStateReasonCode_EXECUTION_FAILURE :: CanaryRunStateReasonCode
+pattern CanaryRunStateReasonCode_EXECUTION_FAILURE = CanaryRunStateReasonCode' "EXECUTION_FAILURE"
+
+{-# COMPLETE
+  CanaryRunStateReasonCode_CANARY_FAILURE,
+  CanaryRunStateReasonCode_EXECUTION_FAILURE,
+  CanaryRunStateReasonCode'
+  #-}
diff --git a/gen/Amazonka/Synthetics/Types/CanaryRunStatus.hs b/gen/Amazonka/Synthetics/Types/CanaryRunStatus.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryRunStatus.hs
@@ -0,0 +1,107 @@
+{-# 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.Synthetics.Types.CanaryRunStatus
+-- 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.Synthetics.Types.CanaryRunStatus 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
+import Amazonka.Synthetics.Types.CanaryRunState
+import Amazonka.Synthetics.Types.CanaryRunStateReasonCode
+
+-- | This structure contains the status information about a canary run.
+--
+-- /See:/ 'newCanaryRunStatus' smart constructor.
+data CanaryRunStatus = CanaryRunStatus'
+  { -- | The current state of the run.
+    state :: Prelude.Maybe CanaryRunState,
+    -- | If run of the canary failed, this field contains the reason for the
+    -- error.
+    stateReason :: Prelude.Maybe Prelude.Text,
+    -- | If this value is @CANARY_FAILURE@, an exception occurred in the canary
+    -- code. If this value is @EXECUTION_FAILURE@, an exception occurred in
+    -- CloudWatch Synthetics.
+    stateReasonCode :: Prelude.Maybe CanaryRunStateReasonCode
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryRunStatus' 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:
+--
+-- 'state', 'canaryRunStatus_state' - The current state of the run.
+--
+-- 'stateReason', 'canaryRunStatus_stateReason' - If run of the canary failed, this field contains the reason for the
+-- error.
+--
+-- 'stateReasonCode', 'canaryRunStatus_stateReasonCode' - If this value is @CANARY_FAILURE@, an exception occurred in the canary
+-- code. If this value is @EXECUTION_FAILURE@, an exception occurred in
+-- CloudWatch Synthetics.
+newCanaryRunStatus ::
+  CanaryRunStatus
+newCanaryRunStatus =
+  CanaryRunStatus'
+    { state = Prelude.Nothing,
+      stateReason = Prelude.Nothing,
+      stateReasonCode = Prelude.Nothing
+    }
+
+-- | The current state of the run.
+canaryRunStatus_state :: Lens.Lens' CanaryRunStatus (Prelude.Maybe CanaryRunState)
+canaryRunStatus_state = Lens.lens (\CanaryRunStatus' {state} -> state) (\s@CanaryRunStatus' {} a -> s {state = a} :: CanaryRunStatus)
+
+-- | If run of the canary failed, this field contains the reason for the
+-- error.
+canaryRunStatus_stateReason :: Lens.Lens' CanaryRunStatus (Prelude.Maybe Prelude.Text)
+canaryRunStatus_stateReason = Lens.lens (\CanaryRunStatus' {stateReason} -> stateReason) (\s@CanaryRunStatus' {} a -> s {stateReason = a} :: CanaryRunStatus)
+
+-- | If this value is @CANARY_FAILURE@, an exception occurred in the canary
+-- code. If this value is @EXECUTION_FAILURE@, an exception occurred in
+-- CloudWatch Synthetics.
+canaryRunStatus_stateReasonCode :: Lens.Lens' CanaryRunStatus (Prelude.Maybe CanaryRunStateReasonCode)
+canaryRunStatus_stateReasonCode = Lens.lens (\CanaryRunStatus' {stateReasonCode} -> stateReasonCode) (\s@CanaryRunStatus' {} a -> s {stateReasonCode = a} :: CanaryRunStatus)
+
+instance Data.FromJSON CanaryRunStatus where
+  parseJSON =
+    Data.withObject
+      "CanaryRunStatus"
+      ( \x ->
+          CanaryRunStatus'
+            Prelude.<$> (x Data..:? "State")
+            Prelude.<*> (x Data..:? "StateReason")
+            Prelude.<*> (x Data..:? "StateReasonCode")
+      )
+
+instance Prelude.Hashable CanaryRunStatus where
+  hashWithSalt _salt CanaryRunStatus' {..} =
+    _salt
+      `Prelude.hashWithSalt` state
+      `Prelude.hashWithSalt` stateReason
+      `Prelude.hashWithSalt` stateReasonCode
+
+instance Prelude.NFData CanaryRunStatus where
+  rnf CanaryRunStatus' {..} =
+    Prelude.rnf state
+      `Prelude.seq` Prelude.rnf stateReason
+      `Prelude.seq` Prelude.rnf stateReasonCode
diff --git a/gen/Amazonka/Synthetics/Types/CanaryRunTimeline.hs b/gen/Amazonka/Synthetics/Types/CanaryRunTimeline.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryRunTimeline.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.Synthetics.Types.CanaryRunTimeline
+-- 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.Synthetics.Types.CanaryRunTimeline 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
+
+-- | This structure contains the start and end times of a single canary run.
+--
+-- /See:/ 'newCanaryRunTimeline' smart constructor.
+data CanaryRunTimeline = CanaryRunTimeline'
+  { -- | The end time of the run.
+    completed :: Prelude.Maybe Data.POSIX,
+    -- | The start time of the run.
+    started :: Prelude.Maybe Data.POSIX
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryRunTimeline' 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:
+--
+-- 'completed', 'canaryRunTimeline_completed' - The end time of the run.
+--
+-- 'started', 'canaryRunTimeline_started' - The start time of the run.
+newCanaryRunTimeline ::
+  CanaryRunTimeline
+newCanaryRunTimeline =
+  CanaryRunTimeline'
+    { completed = Prelude.Nothing,
+      started = Prelude.Nothing
+    }
+
+-- | The end time of the run.
+canaryRunTimeline_completed :: Lens.Lens' CanaryRunTimeline (Prelude.Maybe Prelude.UTCTime)
+canaryRunTimeline_completed = Lens.lens (\CanaryRunTimeline' {completed} -> completed) (\s@CanaryRunTimeline' {} a -> s {completed = a} :: CanaryRunTimeline) Prelude.. Lens.mapping Data._Time
+
+-- | The start time of the run.
+canaryRunTimeline_started :: Lens.Lens' CanaryRunTimeline (Prelude.Maybe Prelude.UTCTime)
+canaryRunTimeline_started = Lens.lens (\CanaryRunTimeline' {started} -> started) (\s@CanaryRunTimeline' {} a -> s {started = a} :: CanaryRunTimeline) Prelude.. Lens.mapping Data._Time
+
+instance Data.FromJSON CanaryRunTimeline where
+  parseJSON =
+    Data.withObject
+      "CanaryRunTimeline"
+      ( \x ->
+          CanaryRunTimeline'
+            Prelude.<$> (x Data..:? "Completed")
+            Prelude.<*> (x Data..:? "Started")
+      )
+
+instance Prelude.Hashable CanaryRunTimeline where
+  hashWithSalt _salt CanaryRunTimeline' {..} =
+    _salt
+      `Prelude.hashWithSalt` completed
+      `Prelude.hashWithSalt` started
+
+instance Prelude.NFData CanaryRunTimeline where
+  rnf CanaryRunTimeline' {..} =
+    Prelude.rnf completed
+      `Prelude.seq` Prelude.rnf started
diff --git a/gen/Amazonka/Synthetics/Types/CanaryScheduleInput.hs b/gen/Amazonka/Synthetics/Types/CanaryScheduleInput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryScheduleInput.hs
@@ -0,0 +1,148 @@
+{-# 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.Synthetics.Types.CanaryScheduleInput
+-- 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.Synthetics.Types.CanaryScheduleInput 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
+
+-- | This structure specifies how often a canary is to make runs and the date
+-- and time when it should stop making runs.
+--
+-- /See:/ 'newCanaryScheduleInput' smart constructor.
+data CanaryScheduleInput = CanaryScheduleInput'
+  { -- | How long, in seconds, for the canary to continue making regular runs
+    -- according to the schedule in the @Expression@ value. If you specify 0,
+    -- the canary continues making runs until you stop it. If you omit this
+    -- field, the default of 0 is used.
+    durationInSeconds :: Prelude.Maybe Prelude.Natural,
+    -- | A @rate@ expression or a @cron@ expression that defines how often the
+    -- canary is to run.
+    --
+    -- For a rate expression, The syntax is @rate(@/@number unit@/@)@. /unit/
+    -- can be @minute@, @minutes@, or @hour@.
+    --
+    -- For example, @rate(1 minute)@ runs the canary once a minute,
+    -- @rate(10 minutes)@ runs it once every 10 minutes, and @rate(1 hour)@
+    -- runs it once every hour. You can specify a frequency between
+    -- @rate(1 minute)@ and @rate(1 hour)@.
+    --
+    -- Specifying @rate(0 minute)@ or @rate(0 hour)@ is a special value that
+    -- causes the canary to run only once when it is started.
+    --
+    -- Use @cron(@/@expression@/@)@ to specify a cron expression. You can\'t
+    -- schedule a canary to wait for more than a year before running. For
+    -- information about the syntax for cron expressions, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html Scheduling canary runs using cron>.
+    expression :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryScheduleInput' 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:
+--
+-- 'durationInSeconds', 'canaryScheduleInput_durationInSeconds' - How long, in seconds, for the canary to continue making regular runs
+-- according to the schedule in the @Expression@ value. If you specify 0,
+-- the canary continues making runs until you stop it. If you omit this
+-- field, the default of 0 is used.
+--
+-- 'expression', 'canaryScheduleInput_expression' - A @rate@ expression or a @cron@ expression that defines how often the
+-- canary is to run.
+--
+-- For a rate expression, The syntax is @rate(@/@number unit@/@)@. /unit/
+-- can be @minute@, @minutes@, or @hour@.
+--
+-- For example, @rate(1 minute)@ runs the canary once a minute,
+-- @rate(10 minutes)@ runs it once every 10 minutes, and @rate(1 hour)@
+-- runs it once every hour. You can specify a frequency between
+-- @rate(1 minute)@ and @rate(1 hour)@.
+--
+-- Specifying @rate(0 minute)@ or @rate(0 hour)@ is a special value that
+-- causes the canary to run only once when it is started.
+--
+-- Use @cron(@/@expression@/@)@ to specify a cron expression. You can\'t
+-- schedule a canary to wait for more than a year before running. For
+-- information about the syntax for cron expressions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html Scheduling canary runs using cron>.
+newCanaryScheduleInput ::
+  -- | 'expression'
+  Prelude.Text ->
+  CanaryScheduleInput
+newCanaryScheduleInput pExpression_ =
+  CanaryScheduleInput'
+    { durationInSeconds =
+        Prelude.Nothing,
+      expression = pExpression_
+    }
+
+-- | How long, in seconds, for the canary to continue making regular runs
+-- according to the schedule in the @Expression@ value. If you specify 0,
+-- the canary continues making runs until you stop it. If you omit this
+-- field, the default of 0 is used.
+canaryScheduleInput_durationInSeconds :: Lens.Lens' CanaryScheduleInput (Prelude.Maybe Prelude.Natural)
+canaryScheduleInput_durationInSeconds = Lens.lens (\CanaryScheduleInput' {durationInSeconds} -> durationInSeconds) (\s@CanaryScheduleInput' {} a -> s {durationInSeconds = a} :: CanaryScheduleInput)
+
+-- | A @rate@ expression or a @cron@ expression that defines how often the
+-- canary is to run.
+--
+-- For a rate expression, The syntax is @rate(@/@number unit@/@)@. /unit/
+-- can be @minute@, @minutes@, or @hour@.
+--
+-- For example, @rate(1 minute)@ runs the canary once a minute,
+-- @rate(10 minutes)@ runs it once every 10 minutes, and @rate(1 hour)@
+-- runs it once every hour. You can specify a frequency between
+-- @rate(1 minute)@ and @rate(1 hour)@.
+--
+-- Specifying @rate(0 minute)@ or @rate(0 hour)@ is a special value that
+-- causes the canary to run only once when it is started.
+--
+-- Use @cron(@/@expression@/@)@ to specify a cron expression. You can\'t
+-- schedule a canary to wait for more than a year before running. For
+-- information about the syntax for cron expressions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html Scheduling canary runs using cron>.
+canaryScheduleInput_expression :: Lens.Lens' CanaryScheduleInput Prelude.Text
+canaryScheduleInput_expression = Lens.lens (\CanaryScheduleInput' {expression} -> expression) (\s@CanaryScheduleInput' {} a -> s {expression = a} :: CanaryScheduleInput)
+
+instance Prelude.Hashable CanaryScheduleInput where
+  hashWithSalt _salt CanaryScheduleInput' {..} =
+    _salt
+      `Prelude.hashWithSalt` durationInSeconds
+      `Prelude.hashWithSalt` expression
+
+instance Prelude.NFData CanaryScheduleInput where
+  rnf CanaryScheduleInput' {..} =
+    Prelude.rnf durationInSeconds
+      `Prelude.seq` Prelude.rnf expression
+
+instance Data.ToJSON CanaryScheduleInput where
+  toJSON CanaryScheduleInput' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("DurationInSeconds" Data..=)
+              Prelude.<$> durationInSeconds,
+            Prelude.Just ("Expression" Data..= expression)
+          ]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/CanaryScheduleOutput.hs b/gen/Amazonka/Synthetics/Types/CanaryScheduleOutput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryScheduleOutput.hs
@@ -0,0 +1,140 @@
+{-# 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.Synthetics.Types.CanaryScheduleOutput
+-- 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.Synthetics.Types.CanaryScheduleOutput 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
+
+-- | How long, in seconds, for the canary to continue making regular runs
+-- according to the schedule in the @Expression@ value.
+--
+-- /See:/ 'newCanaryScheduleOutput' smart constructor.
+data CanaryScheduleOutput = CanaryScheduleOutput'
+  { -- | How long, in seconds, for the canary to continue making regular runs
+    -- after it was created. The runs are performed according to the schedule
+    -- in the @Expression@ value.
+    durationInSeconds :: Prelude.Maybe Prelude.Natural,
+    -- | A @rate@ expression or a @cron@ expression that defines how often the
+    -- canary is to run.
+    --
+    -- For a rate expression, The syntax is @rate(@/@number unit@/@)@. /unit/
+    -- can be @minute@, @minutes@, or @hour@.
+    --
+    -- For example, @rate(1 minute)@ runs the canary once a minute,
+    -- @rate(10 minutes)@ runs it once every 10 minutes, and @rate(1 hour)@
+    -- runs it once every hour. You can specify a frequency between
+    -- @rate(1 minute)@ and @rate(1 hour)@.
+    --
+    -- Specifying @rate(0 minute)@ or @rate(0 hour)@ is a special value that
+    -- causes the canary to run only once when it is started.
+    --
+    -- Use @cron(@/@expression@/@)@ to specify a cron expression. For
+    -- information about the syntax for cron expressions, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html Scheduling canary runs using cron>.
+    expression :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryScheduleOutput' 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:
+--
+-- 'durationInSeconds', 'canaryScheduleOutput_durationInSeconds' - How long, in seconds, for the canary to continue making regular runs
+-- after it was created. The runs are performed according to the schedule
+-- in the @Expression@ value.
+--
+-- 'expression', 'canaryScheduleOutput_expression' - A @rate@ expression or a @cron@ expression that defines how often the
+-- canary is to run.
+--
+-- For a rate expression, The syntax is @rate(@/@number unit@/@)@. /unit/
+-- can be @minute@, @minutes@, or @hour@.
+--
+-- For example, @rate(1 minute)@ runs the canary once a minute,
+-- @rate(10 minutes)@ runs it once every 10 minutes, and @rate(1 hour)@
+-- runs it once every hour. You can specify a frequency between
+-- @rate(1 minute)@ and @rate(1 hour)@.
+--
+-- Specifying @rate(0 minute)@ or @rate(0 hour)@ is a special value that
+-- causes the canary to run only once when it is started.
+--
+-- Use @cron(@/@expression@/@)@ to specify a cron expression. For
+-- information about the syntax for cron expressions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html Scheduling canary runs using cron>.
+newCanaryScheduleOutput ::
+  CanaryScheduleOutput
+newCanaryScheduleOutput =
+  CanaryScheduleOutput'
+    { durationInSeconds =
+        Prelude.Nothing,
+      expression = Prelude.Nothing
+    }
+
+-- | How long, in seconds, for the canary to continue making regular runs
+-- after it was created. The runs are performed according to the schedule
+-- in the @Expression@ value.
+canaryScheduleOutput_durationInSeconds :: Lens.Lens' CanaryScheduleOutput (Prelude.Maybe Prelude.Natural)
+canaryScheduleOutput_durationInSeconds = Lens.lens (\CanaryScheduleOutput' {durationInSeconds} -> durationInSeconds) (\s@CanaryScheduleOutput' {} a -> s {durationInSeconds = a} :: CanaryScheduleOutput)
+
+-- | A @rate@ expression or a @cron@ expression that defines how often the
+-- canary is to run.
+--
+-- For a rate expression, The syntax is @rate(@/@number unit@/@)@. /unit/
+-- can be @minute@, @minutes@, or @hour@.
+--
+-- For example, @rate(1 minute)@ runs the canary once a minute,
+-- @rate(10 minutes)@ runs it once every 10 minutes, and @rate(1 hour)@
+-- runs it once every hour. You can specify a frequency between
+-- @rate(1 minute)@ and @rate(1 hour)@.
+--
+-- Specifying @rate(0 minute)@ or @rate(0 hour)@ is a special value that
+-- causes the canary to run only once when it is started.
+--
+-- Use @cron(@/@expression@/@)@ to specify a cron expression. For
+-- information about the syntax for cron expressions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html Scheduling canary runs using cron>.
+canaryScheduleOutput_expression :: Lens.Lens' CanaryScheduleOutput (Prelude.Maybe Prelude.Text)
+canaryScheduleOutput_expression = Lens.lens (\CanaryScheduleOutput' {expression} -> expression) (\s@CanaryScheduleOutput' {} a -> s {expression = a} :: CanaryScheduleOutput)
+
+instance Data.FromJSON CanaryScheduleOutput where
+  parseJSON =
+    Data.withObject
+      "CanaryScheduleOutput"
+      ( \x ->
+          CanaryScheduleOutput'
+            Prelude.<$> (x Data..:? "DurationInSeconds")
+            Prelude.<*> (x Data..:? "Expression")
+      )
+
+instance Prelude.Hashable CanaryScheduleOutput where
+  hashWithSalt _salt CanaryScheduleOutput' {..} =
+    _salt
+      `Prelude.hashWithSalt` durationInSeconds
+      `Prelude.hashWithSalt` expression
+
+instance Prelude.NFData CanaryScheduleOutput where
+  rnf CanaryScheduleOutput' {..} =
+    Prelude.rnf durationInSeconds
+      `Prelude.seq` Prelude.rnf expression
diff --git a/gen/Amazonka/Synthetics/Types/CanaryState.hs b/gen/Amazonka/Synthetics/Types/CanaryState.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryState.hs
@@ -0,0 +1,106 @@
+{-# 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.Synthetics.Types.CanaryState
+-- 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.Synthetics.Types.CanaryState
+  ( CanaryState
+      ( ..,
+        CanaryState_CREATING,
+        CanaryState_DELETING,
+        CanaryState_ERROR,
+        CanaryState_READY,
+        CanaryState_RUNNING,
+        CanaryState_STARTING,
+        CanaryState_STOPPED,
+        CanaryState_STOPPING,
+        CanaryState_UPDATING
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype CanaryState = CanaryState'
+  { fromCanaryState ::
+      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 CanaryState_CREATING :: CanaryState
+pattern CanaryState_CREATING = CanaryState' "CREATING"
+
+pattern CanaryState_DELETING :: CanaryState
+pattern CanaryState_DELETING = CanaryState' "DELETING"
+
+pattern CanaryState_ERROR :: CanaryState
+pattern CanaryState_ERROR = CanaryState' "ERROR"
+
+pattern CanaryState_READY :: CanaryState
+pattern CanaryState_READY = CanaryState' "READY"
+
+pattern CanaryState_RUNNING :: CanaryState
+pattern CanaryState_RUNNING = CanaryState' "RUNNING"
+
+pattern CanaryState_STARTING :: CanaryState
+pattern CanaryState_STARTING = CanaryState' "STARTING"
+
+pattern CanaryState_STOPPED :: CanaryState
+pattern CanaryState_STOPPED = CanaryState' "STOPPED"
+
+pattern CanaryState_STOPPING :: CanaryState
+pattern CanaryState_STOPPING = CanaryState' "STOPPING"
+
+pattern CanaryState_UPDATING :: CanaryState
+pattern CanaryState_UPDATING = CanaryState' "UPDATING"
+
+{-# COMPLETE
+  CanaryState_CREATING,
+  CanaryState_DELETING,
+  CanaryState_ERROR,
+  CanaryState_READY,
+  CanaryState_RUNNING,
+  CanaryState_STARTING,
+  CanaryState_STOPPED,
+  CanaryState_STOPPING,
+  CanaryState_UPDATING,
+  CanaryState'
+  #-}
diff --git a/gen/Amazonka/Synthetics/Types/CanaryStateReasonCode.hs b/gen/Amazonka/Synthetics/Types/CanaryStateReasonCode.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryStateReasonCode.hs
@@ -0,0 +1,121 @@
+{-# 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.Synthetics.Types.CanaryStateReasonCode
+-- 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.Synthetics.Types.CanaryStateReasonCode
+  ( CanaryStateReasonCode
+      ( ..,
+        CanaryStateReasonCode_CREATE_FAILED,
+        CanaryStateReasonCode_CREATE_IN_PROGRESS,
+        CanaryStateReasonCode_CREATE_PENDING,
+        CanaryStateReasonCode_DELETE_FAILED,
+        CanaryStateReasonCode_DELETE_IN_PROGRESS,
+        CanaryStateReasonCode_INVALID_PERMISSIONS,
+        CanaryStateReasonCode_ROLLBACK_COMPLETE,
+        CanaryStateReasonCode_ROLLBACK_FAILED,
+        CanaryStateReasonCode_SYNC_DELETE_IN_PROGRESS,
+        CanaryStateReasonCode_UPDATE_COMPLETE,
+        CanaryStateReasonCode_UPDATE_IN_PROGRESS,
+        CanaryStateReasonCode_UPDATE_PENDING
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype CanaryStateReasonCode = CanaryStateReasonCode'
+  { fromCanaryStateReasonCode ::
+      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 CanaryStateReasonCode_CREATE_FAILED :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_CREATE_FAILED = CanaryStateReasonCode' "CREATE_FAILED"
+
+pattern CanaryStateReasonCode_CREATE_IN_PROGRESS :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_CREATE_IN_PROGRESS = CanaryStateReasonCode' "CREATE_IN_PROGRESS"
+
+pattern CanaryStateReasonCode_CREATE_PENDING :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_CREATE_PENDING = CanaryStateReasonCode' "CREATE_PENDING"
+
+pattern CanaryStateReasonCode_DELETE_FAILED :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_DELETE_FAILED = CanaryStateReasonCode' "DELETE_FAILED"
+
+pattern CanaryStateReasonCode_DELETE_IN_PROGRESS :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_DELETE_IN_PROGRESS = CanaryStateReasonCode' "DELETE_IN_PROGRESS"
+
+pattern CanaryStateReasonCode_INVALID_PERMISSIONS :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_INVALID_PERMISSIONS = CanaryStateReasonCode' "INVALID_PERMISSIONS"
+
+pattern CanaryStateReasonCode_ROLLBACK_COMPLETE :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_ROLLBACK_COMPLETE = CanaryStateReasonCode' "ROLLBACK_COMPLETE"
+
+pattern CanaryStateReasonCode_ROLLBACK_FAILED :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_ROLLBACK_FAILED = CanaryStateReasonCode' "ROLLBACK_FAILED"
+
+pattern CanaryStateReasonCode_SYNC_DELETE_IN_PROGRESS :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_SYNC_DELETE_IN_PROGRESS = CanaryStateReasonCode' "SYNC_DELETE_IN_PROGRESS"
+
+pattern CanaryStateReasonCode_UPDATE_COMPLETE :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_UPDATE_COMPLETE = CanaryStateReasonCode' "UPDATE_COMPLETE"
+
+pattern CanaryStateReasonCode_UPDATE_IN_PROGRESS :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_UPDATE_IN_PROGRESS = CanaryStateReasonCode' "UPDATE_IN_PROGRESS"
+
+pattern CanaryStateReasonCode_UPDATE_PENDING :: CanaryStateReasonCode
+pattern CanaryStateReasonCode_UPDATE_PENDING = CanaryStateReasonCode' "UPDATE_PENDING"
+
+{-# COMPLETE
+  CanaryStateReasonCode_CREATE_FAILED,
+  CanaryStateReasonCode_CREATE_IN_PROGRESS,
+  CanaryStateReasonCode_CREATE_PENDING,
+  CanaryStateReasonCode_DELETE_FAILED,
+  CanaryStateReasonCode_DELETE_IN_PROGRESS,
+  CanaryStateReasonCode_INVALID_PERMISSIONS,
+  CanaryStateReasonCode_ROLLBACK_COMPLETE,
+  CanaryStateReasonCode_ROLLBACK_FAILED,
+  CanaryStateReasonCode_SYNC_DELETE_IN_PROGRESS,
+  CanaryStateReasonCode_UPDATE_COMPLETE,
+  CanaryStateReasonCode_UPDATE_IN_PROGRESS,
+  CanaryStateReasonCode_UPDATE_PENDING,
+  CanaryStateReasonCode'
+  #-}
diff --git a/gen/Amazonka/Synthetics/Types/CanaryStatus.hs b/gen/Amazonka/Synthetics/Types/CanaryStatus.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryStatus.hs
@@ -0,0 +1,101 @@
+{-# 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.Synthetics.Types.CanaryStatus
+-- 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.Synthetics.Types.CanaryStatus 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
+import Amazonka.Synthetics.Types.CanaryState
+import Amazonka.Synthetics.Types.CanaryStateReasonCode
+
+-- | A structure that contains the current state of the canary.
+--
+-- /See:/ 'newCanaryStatus' smart constructor.
+data CanaryStatus = CanaryStatus'
+  { -- | The current state of the canary.
+    state :: Prelude.Maybe CanaryState,
+    -- | If the canary has insufficient permissions to run, this field provides
+    -- more details.
+    stateReason :: Prelude.Maybe Prelude.Text,
+    -- | If the canary cannot run or has failed, this field displays the reason.
+    stateReasonCode :: Prelude.Maybe CanaryStateReasonCode
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryStatus' 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:
+--
+-- 'state', 'canaryStatus_state' - The current state of the canary.
+--
+-- 'stateReason', 'canaryStatus_stateReason' - If the canary has insufficient permissions to run, this field provides
+-- more details.
+--
+-- 'stateReasonCode', 'canaryStatus_stateReasonCode' - If the canary cannot run or has failed, this field displays the reason.
+newCanaryStatus ::
+  CanaryStatus
+newCanaryStatus =
+  CanaryStatus'
+    { state = Prelude.Nothing,
+      stateReason = Prelude.Nothing,
+      stateReasonCode = Prelude.Nothing
+    }
+
+-- | The current state of the canary.
+canaryStatus_state :: Lens.Lens' CanaryStatus (Prelude.Maybe CanaryState)
+canaryStatus_state = Lens.lens (\CanaryStatus' {state} -> state) (\s@CanaryStatus' {} a -> s {state = a} :: CanaryStatus)
+
+-- | If the canary has insufficient permissions to run, this field provides
+-- more details.
+canaryStatus_stateReason :: Lens.Lens' CanaryStatus (Prelude.Maybe Prelude.Text)
+canaryStatus_stateReason = Lens.lens (\CanaryStatus' {stateReason} -> stateReason) (\s@CanaryStatus' {} a -> s {stateReason = a} :: CanaryStatus)
+
+-- | If the canary cannot run or has failed, this field displays the reason.
+canaryStatus_stateReasonCode :: Lens.Lens' CanaryStatus (Prelude.Maybe CanaryStateReasonCode)
+canaryStatus_stateReasonCode = Lens.lens (\CanaryStatus' {stateReasonCode} -> stateReasonCode) (\s@CanaryStatus' {} a -> s {stateReasonCode = a} :: CanaryStatus)
+
+instance Data.FromJSON CanaryStatus where
+  parseJSON =
+    Data.withObject
+      "CanaryStatus"
+      ( \x ->
+          CanaryStatus'
+            Prelude.<$> (x Data..:? "State")
+            Prelude.<*> (x Data..:? "StateReason")
+            Prelude.<*> (x Data..:? "StateReasonCode")
+      )
+
+instance Prelude.Hashable CanaryStatus where
+  hashWithSalt _salt CanaryStatus' {..} =
+    _salt
+      `Prelude.hashWithSalt` state
+      `Prelude.hashWithSalt` stateReason
+      `Prelude.hashWithSalt` stateReasonCode
+
+instance Prelude.NFData CanaryStatus where
+  rnf CanaryStatus' {..} =
+    Prelude.rnf state
+      `Prelude.seq` Prelude.rnf stateReason
+      `Prelude.seq` Prelude.rnf stateReasonCode
diff --git a/gen/Amazonka/Synthetics/Types/CanaryTimeline.hs b/gen/Amazonka/Synthetics/Types/CanaryTimeline.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/CanaryTimeline.hs
@@ -0,0 +1,109 @@
+{-# 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.Synthetics.Types.CanaryTimeline
+-- 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.Synthetics.Types.CanaryTimeline 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
+
+-- | This structure contains information about when the canary was created
+-- and modified.
+--
+-- /See:/ 'newCanaryTimeline' smart constructor.
+data CanaryTimeline = CanaryTimeline'
+  { -- | The date and time the canary was created.
+    created :: Prelude.Maybe Data.POSIX,
+    -- | The date and time the canary was most recently modified.
+    lastModified :: Prelude.Maybe Data.POSIX,
+    -- | The date and time that the canary\'s most recent run started.
+    lastStarted :: Prelude.Maybe Data.POSIX,
+    -- | The date and time that the canary\'s most recent run ended.
+    lastStopped :: Prelude.Maybe Data.POSIX
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'CanaryTimeline' 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:
+--
+-- 'created', 'canaryTimeline_created' - The date and time the canary was created.
+--
+-- 'lastModified', 'canaryTimeline_lastModified' - The date and time the canary was most recently modified.
+--
+-- 'lastStarted', 'canaryTimeline_lastStarted' - The date and time that the canary\'s most recent run started.
+--
+-- 'lastStopped', 'canaryTimeline_lastStopped' - The date and time that the canary\'s most recent run ended.
+newCanaryTimeline ::
+  CanaryTimeline
+newCanaryTimeline =
+  CanaryTimeline'
+    { created = Prelude.Nothing,
+      lastModified = Prelude.Nothing,
+      lastStarted = Prelude.Nothing,
+      lastStopped = Prelude.Nothing
+    }
+
+-- | The date and time the canary was created.
+canaryTimeline_created :: Lens.Lens' CanaryTimeline (Prelude.Maybe Prelude.UTCTime)
+canaryTimeline_created = Lens.lens (\CanaryTimeline' {created} -> created) (\s@CanaryTimeline' {} a -> s {created = a} :: CanaryTimeline) Prelude.. Lens.mapping Data._Time
+
+-- | The date and time the canary was most recently modified.
+canaryTimeline_lastModified :: Lens.Lens' CanaryTimeline (Prelude.Maybe Prelude.UTCTime)
+canaryTimeline_lastModified = Lens.lens (\CanaryTimeline' {lastModified} -> lastModified) (\s@CanaryTimeline' {} a -> s {lastModified = a} :: CanaryTimeline) Prelude.. Lens.mapping Data._Time
+
+-- | The date and time that the canary\'s most recent run started.
+canaryTimeline_lastStarted :: Lens.Lens' CanaryTimeline (Prelude.Maybe Prelude.UTCTime)
+canaryTimeline_lastStarted = Lens.lens (\CanaryTimeline' {lastStarted} -> lastStarted) (\s@CanaryTimeline' {} a -> s {lastStarted = a} :: CanaryTimeline) Prelude.. Lens.mapping Data._Time
+
+-- | The date and time that the canary\'s most recent run ended.
+canaryTimeline_lastStopped :: Lens.Lens' CanaryTimeline (Prelude.Maybe Prelude.UTCTime)
+canaryTimeline_lastStopped = Lens.lens (\CanaryTimeline' {lastStopped} -> lastStopped) (\s@CanaryTimeline' {} a -> s {lastStopped = a} :: CanaryTimeline) Prelude.. Lens.mapping Data._Time
+
+instance Data.FromJSON CanaryTimeline where
+  parseJSON =
+    Data.withObject
+      "CanaryTimeline"
+      ( \x ->
+          CanaryTimeline'
+            Prelude.<$> (x Data..:? "Created")
+            Prelude.<*> (x Data..:? "LastModified")
+            Prelude.<*> (x Data..:? "LastStarted")
+            Prelude.<*> (x Data..:? "LastStopped")
+      )
+
+instance Prelude.Hashable CanaryTimeline where
+  hashWithSalt _salt CanaryTimeline' {..} =
+    _salt
+      `Prelude.hashWithSalt` created
+      `Prelude.hashWithSalt` lastModified
+      `Prelude.hashWithSalt` lastStarted
+      `Prelude.hashWithSalt` lastStopped
+
+instance Prelude.NFData CanaryTimeline where
+  rnf CanaryTimeline' {..} =
+    Prelude.rnf created
+      `Prelude.seq` Prelude.rnf lastModified
+      `Prelude.seq` Prelude.rnf lastStarted
+      `Prelude.seq` Prelude.rnf lastStopped
diff --git a/gen/Amazonka/Synthetics/Types/EncryptionMode.hs b/gen/Amazonka/Synthetics/Types/EncryptionMode.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/EncryptionMode.hs
@@ -0,0 +1,71 @@
+{-# 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.Synthetics.Types.EncryptionMode
+-- 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.Synthetics.Types.EncryptionMode
+  ( EncryptionMode
+      ( ..,
+        EncryptionMode_SSE_KMS,
+        EncryptionMode_SSE_S3
+      ),
+  )
+where
+
+import qualified Amazonka.Core as Core
+import qualified Amazonka.Data as Data
+import qualified Amazonka.Prelude as Prelude
+
+newtype EncryptionMode = EncryptionMode'
+  { fromEncryptionMode ::
+      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 EncryptionMode_SSE_KMS :: EncryptionMode
+pattern EncryptionMode_SSE_KMS = EncryptionMode' "SSE_KMS"
+
+pattern EncryptionMode_SSE_S3 :: EncryptionMode
+pattern EncryptionMode_SSE_S3 = EncryptionMode' "SSE_S3"
+
+{-# COMPLETE
+  EncryptionMode_SSE_KMS,
+  EncryptionMode_SSE_S3,
+  EncryptionMode'
+  #-}
diff --git a/gen/Amazonka/Synthetics/Types/Group.hs b/gen/Amazonka/Synthetics/Types/Group.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/Group.hs
@@ -0,0 +1,132 @@
+{-# 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.Synthetics.Types.Group
+-- 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.Synthetics.Types.Group 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
+
+-- | This structure contains information about one group.
+--
+-- /See:/ 'newGroup' smart constructor.
+data Group = Group'
+  { -- | The ARN of the group.
+    arn :: Prelude.Maybe Prelude.Text,
+    -- | The date and time that the group was created.
+    createdTime :: Prelude.Maybe Data.POSIX,
+    -- | The unique ID of the group.
+    id :: Prelude.Maybe Prelude.Text,
+    -- | The date and time that the group was most recently updated.
+    lastModifiedTime :: Prelude.Maybe Data.POSIX,
+    -- | The name of the group.
+    name :: Prelude.Maybe Prelude.Text,
+    -- | The list of key-value pairs that are associated with the canary.
+    tags :: Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text)
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'Group' 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:
+--
+-- 'arn', 'group_arn' - The ARN of the group.
+--
+-- 'createdTime', 'group_createdTime' - The date and time that the group was created.
+--
+-- 'id', 'group_id' - The unique ID of the group.
+--
+-- 'lastModifiedTime', 'group_lastModifiedTime' - The date and time that the group was most recently updated.
+--
+-- 'name', 'group_name' - The name of the group.
+--
+-- 'tags', 'group_tags' - The list of key-value pairs that are associated with the canary.
+newGroup ::
+  Group
+newGroup =
+  Group'
+    { arn = Prelude.Nothing,
+      createdTime = Prelude.Nothing,
+      id = Prelude.Nothing,
+      lastModifiedTime = Prelude.Nothing,
+      name = Prelude.Nothing,
+      tags = Prelude.Nothing
+    }
+
+-- | The ARN of the group.
+group_arn :: Lens.Lens' Group (Prelude.Maybe Prelude.Text)
+group_arn = Lens.lens (\Group' {arn} -> arn) (\s@Group' {} a -> s {arn = a} :: Group)
+
+-- | The date and time that the group was created.
+group_createdTime :: Lens.Lens' Group (Prelude.Maybe Prelude.UTCTime)
+group_createdTime = Lens.lens (\Group' {createdTime} -> createdTime) (\s@Group' {} a -> s {createdTime = a} :: Group) Prelude.. Lens.mapping Data._Time
+
+-- | The unique ID of the group.
+group_id :: Lens.Lens' Group (Prelude.Maybe Prelude.Text)
+group_id = Lens.lens (\Group' {id} -> id) (\s@Group' {} a -> s {id = a} :: Group)
+
+-- | The date and time that the group was most recently updated.
+group_lastModifiedTime :: Lens.Lens' Group (Prelude.Maybe Prelude.UTCTime)
+group_lastModifiedTime = Lens.lens (\Group' {lastModifiedTime} -> lastModifiedTime) (\s@Group' {} a -> s {lastModifiedTime = a} :: Group) Prelude.. Lens.mapping Data._Time
+
+-- | The name of the group.
+group_name :: Lens.Lens' Group (Prelude.Maybe Prelude.Text)
+group_name = Lens.lens (\Group' {name} -> name) (\s@Group' {} a -> s {name = a} :: Group)
+
+-- | The list of key-value pairs that are associated with the canary.
+group_tags :: Lens.Lens' Group (Prelude.Maybe (Prelude.HashMap Prelude.Text Prelude.Text))
+group_tags = Lens.lens (\Group' {tags} -> tags) (\s@Group' {} a -> s {tags = a} :: Group) Prelude.. Lens.mapping Lens.coerced
+
+instance Data.FromJSON Group where
+  parseJSON =
+    Data.withObject
+      "Group"
+      ( \x ->
+          Group'
+            Prelude.<$> (x Data..:? "Arn")
+            Prelude.<*> (x Data..:? "CreatedTime")
+            Prelude.<*> (x Data..:? "Id")
+            Prelude.<*> (x Data..:? "LastModifiedTime")
+            Prelude.<*> (x Data..:? "Name")
+            Prelude.<*> (x Data..:? "Tags" Data..!= Prelude.mempty)
+      )
+
+instance Prelude.Hashable Group where
+  hashWithSalt _salt Group' {..} =
+    _salt
+      `Prelude.hashWithSalt` arn
+      `Prelude.hashWithSalt` createdTime
+      `Prelude.hashWithSalt` id
+      `Prelude.hashWithSalt` lastModifiedTime
+      `Prelude.hashWithSalt` name
+      `Prelude.hashWithSalt` tags
+
+instance Prelude.NFData Group where
+  rnf Group' {..} =
+    Prelude.rnf arn
+      `Prelude.seq` Prelude.rnf createdTime
+      `Prelude.seq` Prelude.rnf id
+      `Prelude.seq` Prelude.rnf lastModifiedTime
+      `Prelude.seq` Prelude.rnf name
+      `Prelude.seq` Prelude.rnf tags
diff --git a/gen/Amazonka/Synthetics/Types/GroupSummary.hs b/gen/Amazonka/Synthetics/Types/GroupSummary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/GroupSummary.hs
@@ -0,0 +1,96 @@
+{-# 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.Synthetics.Types.GroupSummary
+-- 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.Synthetics.Types.GroupSummary 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 structure containing some information about a group.
+--
+-- /See:/ 'newGroupSummary' smart constructor.
+data GroupSummary = GroupSummary'
+  { -- | The ARN of the group.
+    arn :: Prelude.Maybe Prelude.Text,
+    -- | The unique ID of the group.
+    id :: Prelude.Maybe Prelude.Text,
+    -- | The name of the group.
+    name :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'GroupSummary' 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:
+--
+-- 'arn', 'groupSummary_arn' - The ARN of the group.
+--
+-- 'id', 'groupSummary_id' - The unique ID of the group.
+--
+-- 'name', 'groupSummary_name' - The name of the group.
+newGroupSummary ::
+  GroupSummary
+newGroupSummary =
+  GroupSummary'
+    { arn = Prelude.Nothing,
+      id = Prelude.Nothing,
+      name = Prelude.Nothing
+    }
+
+-- | The ARN of the group.
+groupSummary_arn :: Lens.Lens' GroupSummary (Prelude.Maybe Prelude.Text)
+groupSummary_arn = Lens.lens (\GroupSummary' {arn} -> arn) (\s@GroupSummary' {} a -> s {arn = a} :: GroupSummary)
+
+-- | The unique ID of the group.
+groupSummary_id :: Lens.Lens' GroupSummary (Prelude.Maybe Prelude.Text)
+groupSummary_id = Lens.lens (\GroupSummary' {id} -> id) (\s@GroupSummary' {} a -> s {id = a} :: GroupSummary)
+
+-- | The name of the group.
+groupSummary_name :: Lens.Lens' GroupSummary (Prelude.Maybe Prelude.Text)
+groupSummary_name = Lens.lens (\GroupSummary' {name} -> name) (\s@GroupSummary' {} a -> s {name = a} :: GroupSummary)
+
+instance Data.FromJSON GroupSummary where
+  parseJSON =
+    Data.withObject
+      "GroupSummary"
+      ( \x ->
+          GroupSummary'
+            Prelude.<$> (x Data..:? "Arn")
+            Prelude.<*> (x Data..:? "Id")
+            Prelude.<*> (x Data..:? "Name")
+      )
+
+instance Prelude.Hashable GroupSummary where
+  hashWithSalt _salt GroupSummary' {..} =
+    _salt
+      `Prelude.hashWithSalt` arn
+      `Prelude.hashWithSalt` id
+      `Prelude.hashWithSalt` name
+
+instance Prelude.NFData GroupSummary where
+  rnf GroupSummary' {..} =
+    Prelude.rnf arn
+      `Prelude.seq` Prelude.rnf id
+      `Prelude.seq` Prelude.rnf name
diff --git a/gen/Amazonka/Synthetics/Types/RuntimeVersion.hs b/gen/Amazonka/Synthetics/Types/RuntimeVersion.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/RuntimeVersion.hs
@@ -0,0 +1,119 @@
+{-# 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.Synthetics.Types.RuntimeVersion
+-- 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.Synthetics.Types.RuntimeVersion 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
+
+-- | This structure contains information about one canary runtime version.
+-- For more information about runtime versions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+--
+-- /See:/ 'newRuntimeVersion' smart constructor.
+data RuntimeVersion = RuntimeVersion'
+  { -- | If this runtime version is deprecated, this value is the date of
+    -- deprecation.
+    deprecationDate :: Prelude.Maybe Data.POSIX,
+    -- | A description of the runtime version, created by Amazon.
+    description :: Prelude.Maybe Prelude.Text,
+    -- | The date that the runtime version was released.
+    releaseDate :: Prelude.Maybe Data.POSIX,
+    -- | The name of the runtime version. For a list of valid runtime versions,
+    -- see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+    versionName :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'RuntimeVersion' 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:
+--
+-- 'deprecationDate', 'runtimeVersion_deprecationDate' - If this runtime version is deprecated, this value is the date of
+-- deprecation.
+--
+-- 'description', 'runtimeVersion_description' - A description of the runtime version, created by Amazon.
+--
+-- 'releaseDate', 'runtimeVersion_releaseDate' - The date that the runtime version was released.
+--
+-- 'versionName', 'runtimeVersion_versionName' - The name of the runtime version. For a list of valid runtime versions,
+-- see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+newRuntimeVersion ::
+  RuntimeVersion
+newRuntimeVersion =
+  RuntimeVersion'
+    { deprecationDate = Prelude.Nothing,
+      description = Prelude.Nothing,
+      releaseDate = Prelude.Nothing,
+      versionName = Prelude.Nothing
+    }
+
+-- | If this runtime version is deprecated, this value is the date of
+-- deprecation.
+runtimeVersion_deprecationDate :: Lens.Lens' RuntimeVersion (Prelude.Maybe Prelude.UTCTime)
+runtimeVersion_deprecationDate = Lens.lens (\RuntimeVersion' {deprecationDate} -> deprecationDate) (\s@RuntimeVersion' {} a -> s {deprecationDate = a} :: RuntimeVersion) Prelude.. Lens.mapping Data._Time
+
+-- | A description of the runtime version, created by Amazon.
+runtimeVersion_description :: Lens.Lens' RuntimeVersion (Prelude.Maybe Prelude.Text)
+runtimeVersion_description = Lens.lens (\RuntimeVersion' {description} -> description) (\s@RuntimeVersion' {} a -> s {description = a} :: RuntimeVersion)
+
+-- | The date that the runtime version was released.
+runtimeVersion_releaseDate :: Lens.Lens' RuntimeVersion (Prelude.Maybe Prelude.UTCTime)
+runtimeVersion_releaseDate = Lens.lens (\RuntimeVersion' {releaseDate} -> releaseDate) (\s@RuntimeVersion' {} a -> s {releaseDate = a} :: RuntimeVersion) Prelude.. Lens.mapping Data._Time
+
+-- | The name of the runtime version. For a list of valid runtime versions,
+-- see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+runtimeVersion_versionName :: Lens.Lens' RuntimeVersion (Prelude.Maybe Prelude.Text)
+runtimeVersion_versionName = Lens.lens (\RuntimeVersion' {versionName} -> versionName) (\s@RuntimeVersion' {} a -> s {versionName = a} :: RuntimeVersion)
+
+instance Data.FromJSON RuntimeVersion where
+  parseJSON =
+    Data.withObject
+      "RuntimeVersion"
+      ( \x ->
+          RuntimeVersion'
+            Prelude.<$> (x Data..:? "DeprecationDate")
+            Prelude.<*> (x Data..:? "Description")
+            Prelude.<*> (x Data..:? "ReleaseDate")
+            Prelude.<*> (x Data..:? "VersionName")
+      )
+
+instance Prelude.Hashable RuntimeVersion where
+  hashWithSalt _salt RuntimeVersion' {..} =
+    _salt
+      `Prelude.hashWithSalt` deprecationDate
+      `Prelude.hashWithSalt` description
+      `Prelude.hashWithSalt` releaseDate
+      `Prelude.hashWithSalt` versionName
+
+instance Prelude.NFData RuntimeVersion where
+  rnf RuntimeVersion' {..} =
+    Prelude.rnf deprecationDate
+      `Prelude.seq` Prelude.rnf description
+      `Prelude.seq` Prelude.rnf releaseDate
+      `Prelude.seq` Prelude.rnf versionName
diff --git a/gen/Amazonka/Synthetics/Types/S3EncryptionConfig.hs b/gen/Amazonka/Synthetics/Types/S3EncryptionConfig.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/S3EncryptionConfig.hs
@@ -0,0 +1,121 @@
+{-# 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.Synthetics.Types.S3EncryptionConfig
+-- 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.Synthetics.Types.S3EncryptionConfig 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
+import Amazonka.Synthetics.Types.EncryptionMode
+
+-- | A structure that contains the configuration of encryption-at-rest
+-- settings for canary artifacts that the canary uploads to Amazon S3.
+--
+-- For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_artifact_encryption.html Encrypting canary artifacts>
+--
+-- /See:/ 'newS3EncryptionConfig' smart constructor.
+data S3EncryptionConfig = S3EncryptionConfig'
+  { -- | The encryption method to use for artifacts created by this canary.
+    -- Specify @SSE_S3@ to use server-side encryption (SSE) with an Amazon
+    -- S3-managed key. Specify @SSE-KMS@ to use server-side encryption with a
+    -- customer-managed KMS key.
+    --
+    -- If you omit this parameter, an Amazon Web Services-managed KMS key is
+    -- used.
+    encryptionMode :: Prelude.Maybe EncryptionMode,
+    -- | The ARN of the customer-managed KMS key to use, if you specify @SSE-KMS@
+    -- for @EncryptionMode@
+    kmsKeyArn :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'S3EncryptionConfig' 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:
+--
+-- 'encryptionMode', 's3EncryptionConfig_encryptionMode' - The encryption method to use for artifacts created by this canary.
+-- Specify @SSE_S3@ to use server-side encryption (SSE) with an Amazon
+-- S3-managed key. Specify @SSE-KMS@ to use server-side encryption with a
+-- customer-managed KMS key.
+--
+-- If you omit this parameter, an Amazon Web Services-managed KMS key is
+-- used.
+--
+-- 'kmsKeyArn', 's3EncryptionConfig_kmsKeyArn' - The ARN of the customer-managed KMS key to use, if you specify @SSE-KMS@
+-- for @EncryptionMode@
+newS3EncryptionConfig ::
+  S3EncryptionConfig
+newS3EncryptionConfig =
+  S3EncryptionConfig'
+    { encryptionMode =
+        Prelude.Nothing,
+      kmsKeyArn = Prelude.Nothing
+    }
+
+-- | The encryption method to use for artifacts created by this canary.
+-- Specify @SSE_S3@ to use server-side encryption (SSE) with an Amazon
+-- S3-managed key. Specify @SSE-KMS@ to use server-side encryption with a
+-- customer-managed KMS key.
+--
+-- If you omit this parameter, an Amazon Web Services-managed KMS key is
+-- used.
+s3EncryptionConfig_encryptionMode :: Lens.Lens' S3EncryptionConfig (Prelude.Maybe EncryptionMode)
+s3EncryptionConfig_encryptionMode = Lens.lens (\S3EncryptionConfig' {encryptionMode} -> encryptionMode) (\s@S3EncryptionConfig' {} a -> s {encryptionMode = a} :: S3EncryptionConfig)
+
+-- | The ARN of the customer-managed KMS key to use, if you specify @SSE-KMS@
+-- for @EncryptionMode@
+s3EncryptionConfig_kmsKeyArn :: Lens.Lens' S3EncryptionConfig (Prelude.Maybe Prelude.Text)
+s3EncryptionConfig_kmsKeyArn = Lens.lens (\S3EncryptionConfig' {kmsKeyArn} -> kmsKeyArn) (\s@S3EncryptionConfig' {} a -> s {kmsKeyArn = a} :: S3EncryptionConfig)
+
+instance Data.FromJSON S3EncryptionConfig where
+  parseJSON =
+    Data.withObject
+      "S3EncryptionConfig"
+      ( \x ->
+          S3EncryptionConfig'
+            Prelude.<$> (x Data..:? "EncryptionMode")
+            Prelude.<*> (x Data..:? "KmsKeyArn")
+      )
+
+instance Prelude.Hashable S3EncryptionConfig where
+  hashWithSalt _salt S3EncryptionConfig' {..} =
+    _salt
+      `Prelude.hashWithSalt` encryptionMode
+      `Prelude.hashWithSalt` kmsKeyArn
+
+instance Prelude.NFData S3EncryptionConfig where
+  rnf S3EncryptionConfig' {..} =
+    Prelude.rnf encryptionMode
+      `Prelude.seq` Prelude.rnf kmsKeyArn
+
+instance Data.ToJSON S3EncryptionConfig where
+  toJSON S3EncryptionConfig' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("EncryptionMode" Data..=)
+              Prelude.<$> encryptionMode,
+            ("KmsKeyArn" Data..=) Prelude.<$> kmsKeyArn
+          ]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/VisualReferenceInput.hs b/gen/Amazonka/Synthetics/Types/VisualReferenceInput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/VisualReferenceInput.hs
@@ -0,0 +1,124 @@
+{-# 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.Synthetics.Types.VisualReferenceInput
+-- 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.Synthetics.Types.VisualReferenceInput 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
+import Amazonka.Synthetics.Types.BaseScreenshot
+
+-- | An object that specifies what screenshots to use as a baseline for
+-- visual monitoring by this canary. It can optionally also specify parts
+-- of the screenshots to ignore during the visual monitoring comparison.
+--
+-- Visual monitoring is supported only on canaries running the
+-- __syn-puppeteer-node-3.2__ runtime or later. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_SyntheticsLogger_VisualTesting.html Visual monitoring>
+-- and
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Blueprints_VisualTesting.html Visual monitoring blueprint>
+--
+-- /See:/ 'newVisualReferenceInput' smart constructor.
+data VisualReferenceInput = VisualReferenceInput'
+  { -- | An array of screenshots that will be used as the baseline for visual
+    -- monitoring in future runs of this canary. If there is a screenshot that
+    -- you don\'t want to be used for visual monitoring, remove it from this
+    -- array.
+    baseScreenshots :: Prelude.Maybe [BaseScreenshot],
+    -- | Specifies which canary run to use the screenshots from as the baseline
+    -- for future visual monitoring with this canary. Valid values are
+    -- @nextrun@ to use the screenshots from the next run after this update is
+    -- made, @lastrun@ to use the screenshots from the most recent run before
+    -- this update was made, or the value of @Id@ in the
+    -- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_CanaryRun.html CanaryRun>
+    -- from any past run of this canary.
+    baseCanaryRunId :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'VisualReferenceInput' 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:
+--
+-- 'baseScreenshots', 'visualReferenceInput_baseScreenshots' - An array of screenshots that will be used as the baseline for visual
+-- monitoring in future runs of this canary. If there is a screenshot that
+-- you don\'t want to be used for visual monitoring, remove it from this
+-- array.
+--
+-- 'baseCanaryRunId', 'visualReferenceInput_baseCanaryRunId' - Specifies which canary run to use the screenshots from as the baseline
+-- for future visual monitoring with this canary. Valid values are
+-- @nextrun@ to use the screenshots from the next run after this update is
+-- made, @lastrun@ to use the screenshots from the most recent run before
+-- this update was made, or the value of @Id@ in the
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_CanaryRun.html CanaryRun>
+-- from any past run of this canary.
+newVisualReferenceInput ::
+  -- | 'baseCanaryRunId'
+  Prelude.Text ->
+  VisualReferenceInput
+newVisualReferenceInput pBaseCanaryRunId_ =
+  VisualReferenceInput'
+    { baseScreenshots =
+        Prelude.Nothing,
+      baseCanaryRunId = pBaseCanaryRunId_
+    }
+
+-- | An array of screenshots that will be used as the baseline for visual
+-- monitoring in future runs of this canary. If there is a screenshot that
+-- you don\'t want to be used for visual monitoring, remove it from this
+-- array.
+visualReferenceInput_baseScreenshots :: Lens.Lens' VisualReferenceInput (Prelude.Maybe [BaseScreenshot])
+visualReferenceInput_baseScreenshots = Lens.lens (\VisualReferenceInput' {baseScreenshots} -> baseScreenshots) (\s@VisualReferenceInput' {} a -> s {baseScreenshots = a} :: VisualReferenceInput) Prelude.. Lens.mapping Lens.coerced
+
+-- | Specifies which canary run to use the screenshots from as the baseline
+-- for future visual monitoring with this canary. Valid values are
+-- @nextrun@ to use the screenshots from the next run after this update is
+-- made, @lastrun@ to use the screenshots from the most recent run before
+-- this update was made, or the value of @Id@ in the
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_CanaryRun.html CanaryRun>
+-- from any past run of this canary.
+visualReferenceInput_baseCanaryRunId :: Lens.Lens' VisualReferenceInput Prelude.Text
+visualReferenceInput_baseCanaryRunId = Lens.lens (\VisualReferenceInput' {baseCanaryRunId} -> baseCanaryRunId) (\s@VisualReferenceInput' {} a -> s {baseCanaryRunId = a} :: VisualReferenceInput)
+
+instance Prelude.Hashable VisualReferenceInput where
+  hashWithSalt _salt VisualReferenceInput' {..} =
+    _salt
+      `Prelude.hashWithSalt` baseScreenshots
+      `Prelude.hashWithSalt` baseCanaryRunId
+
+instance Prelude.NFData VisualReferenceInput where
+  rnf VisualReferenceInput' {..} =
+    Prelude.rnf baseScreenshots
+      `Prelude.seq` Prelude.rnf baseCanaryRunId
+
+instance Data.ToJSON VisualReferenceInput where
+  toJSON VisualReferenceInput' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("BaseScreenshots" Data..=)
+              Prelude.<$> baseScreenshots,
+            Prelude.Just
+              ("BaseCanaryRunId" Data..= baseCanaryRunId)
+          ]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/VisualReferenceOutput.hs b/gen/Amazonka/Synthetics/Types/VisualReferenceOutput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/VisualReferenceOutput.hs
@@ -0,0 +1,101 @@
+{-# 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.Synthetics.Types.VisualReferenceOutput
+-- 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.Synthetics.Types.VisualReferenceOutput 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
+import Amazonka.Synthetics.Types.BaseScreenshot
+
+-- | If this canary performs visual monitoring by comparing screenshots, this
+-- structure contains the ID of the canary run that is used as the baseline
+-- for screenshots, and the coordinates of any parts of those screenshots
+-- that are ignored during visual monitoring comparison.
+--
+-- Visual monitoring is supported only on canaries running the
+-- __syn-puppeteer-node-3.2__ runtime or later.
+--
+-- /See:/ 'newVisualReferenceOutput' smart constructor.
+data VisualReferenceOutput = VisualReferenceOutput'
+  { -- | The ID of the canary run that produced the baseline screenshots that are
+    -- used for visual monitoring comparisons by this canary.
+    baseCanaryRunId :: Prelude.Maybe Prelude.Text,
+    -- | An array of screenshots that are used as the baseline for comparisons
+    -- during visual monitoring.
+    baseScreenshots :: Prelude.Maybe [BaseScreenshot]
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'VisualReferenceOutput' 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:
+--
+-- 'baseCanaryRunId', 'visualReferenceOutput_baseCanaryRunId' - The ID of the canary run that produced the baseline screenshots that are
+-- used for visual monitoring comparisons by this canary.
+--
+-- 'baseScreenshots', 'visualReferenceOutput_baseScreenshots' - An array of screenshots that are used as the baseline for comparisons
+-- during visual monitoring.
+newVisualReferenceOutput ::
+  VisualReferenceOutput
+newVisualReferenceOutput =
+  VisualReferenceOutput'
+    { baseCanaryRunId =
+        Prelude.Nothing,
+      baseScreenshots = Prelude.Nothing
+    }
+
+-- | The ID of the canary run that produced the baseline screenshots that are
+-- used for visual monitoring comparisons by this canary.
+visualReferenceOutput_baseCanaryRunId :: Lens.Lens' VisualReferenceOutput (Prelude.Maybe Prelude.Text)
+visualReferenceOutput_baseCanaryRunId = Lens.lens (\VisualReferenceOutput' {baseCanaryRunId} -> baseCanaryRunId) (\s@VisualReferenceOutput' {} a -> s {baseCanaryRunId = a} :: VisualReferenceOutput)
+
+-- | An array of screenshots that are used as the baseline for comparisons
+-- during visual monitoring.
+visualReferenceOutput_baseScreenshots :: Lens.Lens' VisualReferenceOutput (Prelude.Maybe [BaseScreenshot])
+visualReferenceOutput_baseScreenshots = Lens.lens (\VisualReferenceOutput' {baseScreenshots} -> baseScreenshots) (\s@VisualReferenceOutput' {} a -> s {baseScreenshots = a} :: VisualReferenceOutput) Prelude.. Lens.mapping Lens.coerced
+
+instance Data.FromJSON VisualReferenceOutput where
+  parseJSON =
+    Data.withObject
+      "VisualReferenceOutput"
+      ( \x ->
+          VisualReferenceOutput'
+            Prelude.<$> (x Data..:? "BaseCanaryRunId")
+            Prelude.<*> ( x
+                            Data..:? "BaseScreenshots"
+                            Data..!= Prelude.mempty
+                        )
+      )
+
+instance Prelude.Hashable VisualReferenceOutput where
+  hashWithSalt _salt VisualReferenceOutput' {..} =
+    _salt
+      `Prelude.hashWithSalt` baseCanaryRunId
+      `Prelude.hashWithSalt` baseScreenshots
+
+instance Prelude.NFData VisualReferenceOutput where
+  rnf VisualReferenceOutput' {..} =
+    Prelude.rnf baseCanaryRunId
+      `Prelude.seq` Prelude.rnf baseScreenshots
diff --git a/gen/Amazonka/Synthetics/Types/VpcConfigInput.hs b/gen/Amazonka/Synthetics/Types/VpcConfigInput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/VpcConfigInput.hs
@@ -0,0 +1,87 @@
+{-# 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.Synthetics.Types.VpcConfigInput
+-- 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.Synthetics.Types.VpcConfigInput 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
+
+-- | If this canary is to test an endpoint in a VPC, this structure contains
+-- information about the subnets and security groups of the VPC endpoint.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+--
+-- /See:/ 'newVpcConfigInput' smart constructor.
+data VpcConfigInput = VpcConfigInput'
+  { -- | The IDs of the security groups for this canary.
+    securityGroupIds :: Prelude.Maybe [Prelude.Text],
+    -- | The IDs of the subnets where this canary is to run.
+    subnetIds :: Prelude.Maybe [Prelude.Text]
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'VpcConfigInput' 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:
+--
+-- 'securityGroupIds', 'vpcConfigInput_securityGroupIds' - The IDs of the security groups for this canary.
+--
+-- 'subnetIds', 'vpcConfigInput_subnetIds' - The IDs of the subnets where this canary is to run.
+newVpcConfigInput ::
+  VpcConfigInput
+newVpcConfigInput =
+  VpcConfigInput'
+    { securityGroupIds = Prelude.Nothing,
+      subnetIds = Prelude.Nothing
+    }
+
+-- | The IDs of the security groups for this canary.
+vpcConfigInput_securityGroupIds :: Lens.Lens' VpcConfigInput (Prelude.Maybe [Prelude.Text])
+vpcConfigInput_securityGroupIds = Lens.lens (\VpcConfigInput' {securityGroupIds} -> securityGroupIds) (\s@VpcConfigInput' {} a -> s {securityGroupIds = a} :: VpcConfigInput) Prelude.. Lens.mapping Lens.coerced
+
+-- | The IDs of the subnets where this canary is to run.
+vpcConfigInput_subnetIds :: Lens.Lens' VpcConfigInput (Prelude.Maybe [Prelude.Text])
+vpcConfigInput_subnetIds = Lens.lens (\VpcConfigInput' {subnetIds} -> subnetIds) (\s@VpcConfigInput' {} a -> s {subnetIds = a} :: VpcConfigInput) Prelude.. Lens.mapping Lens.coerced
+
+instance Prelude.Hashable VpcConfigInput where
+  hashWithSalt _salt VpcConfigInput' {..} =
+    _salt
+      `Prelude.hashWithSalt` securityGroupIds
+      `Prelude.hashWithSalt` subnetIds
+
+instance Prelude.NFData VpcConfigInput where
+  rnf VpcConfigInput' {..} =
+    Prelude.rnf securityGroupIds
+      `Prelude.seq` Prelude.rnf subnetIds
+
+instance Data.ToJSON VpcConfigInput where
+  toJSON VpcConfigInput' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("SecurityGroupIds" Data..=)
+              Prelude.<$> securityGroupIds,
+            ("SubnetIds" Data..=) Prelude.<$> subnetIds
+          ]
+      )
diff --git a/gen/Amazonka/Synthetics/Types/VpcConfigOutput.hs b/gen/Amazonka/Synthetics/Types/VpcConfigOutput.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/Types/VpcConfigOutput.hs
@@ -0,0 +1,103 @@
+{-# 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.Synthetics.Types.VpcConfigOutput
+-- 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.Synthetics.Types.VpcConfigOutput 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
+
+-- | If this canary is to test an endpoint in a VPC, this structure contains
+-- information about the subnets and security groups of the VPC endpoint.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+--
+-- /See:/ 'newVpcConfigOutput' smart constructor.
+data VpcConfigOutput = VpcConfigOutput'
+  { -- | The IDs of the security groups for this canary.
+    securityGroupIds :: Prelude.Maybe [Prelude.Text],
+    -- | The IDs of the subnets where this canary is to run.
+    subnetIds :: Prelude.Maybe [Prelude.Text],
+    -- | The IDs of the VPC where this canary is to run.
+    vpcId :: Prelude.Maybe Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'VpcConfigOutput' 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:
+--
+-- 'securityGroupIds', 'vpcConfigOutput_securityGroupIds' - The IDs of the security groups for this canary.
+--
+-- 'subnetIds', 'vpcConfigOutput_subnetIds' - The IDs of the subnets where this canary is to run.
+--
+-- 'vpcId', 'vpcConfigOutput_vpcId' - The IDs of the VPC where this canary is to run.
+newVpcConfigOutput ::
+  VpcConfigOutput
+newVpcConfigOutput =
+  VpcConfigOutput'
+    { securityGroupIds =
+        Prelude.Nothing,
+      subnetIds = Prelude.Nothing,
+      vpcId = Prelude.Nothing
+    }
+
+-- | The IDs of the security groups for this canary.
+vpcConfigOutput_securityGroupIds :: Lens.Lens' VpcConfigOutput (Prelude.Maybe [Prelude.Text])
+vpcConfigOutput_securityGroupIds = Lens.lens (\VpcConfigOutput' {securityGroupIds} -> securityGroupIds) (\s@VpcConfigOutput' {} a -> s {securityGroupIds = a} :: VpcConfigOutput) Prelude.. Lens.mapping Lens.coerced
+
+-- | The IDs of the subnets where this canary is to run.
+vpcConfigOutput_subnetIds :: Lens.Lens' VpcConfigOutput (Prelude.Maybe [Prelude.Text])
+vpcConfigOutput_subnetIds = Lens.lens (\VpcConfigOutput' {subnetIds} -> subnetIds) (\s@VpcConfigOutput' {} a -> s {subnetIds = a} :: VpcConfigOutput) Prelude.. Lens.mapping Lens.coerced
+
+-- | The IDs of the VPC where this canary is to run.
+vpcConfigOutput_vpcId :: Lens.Lens' VpcConfigOutput (Prelude.Maybe Prelude.Text)
+vpcConfigOutput_vpcId = Lens.lens (\VpcConfigOutput' {vpcId} -> vpcId) (\s@VpcConfigOutput' {} a -> s {vpcId = a} :: VpcConfigOutput)
+
+instance Data.FromJSON VpcConfigOutput where
+  parseJSON =
+    Data.withObject
+      "VpcConfigOutput"
+      ( \x ->
+          VpcConfigOutput'
+            Prelude.<$> ( x
+                            Data..:? "SecurityGroupIds"
+                            Data..!= Prelude.mempty
+                        )
+            Prelude.<*> (x Data..:? "SubnetIds" Data..!= Prelude.mempty)
+            Prelude.<*> (x Data..:? "VpcId")
+      )
+
+instance Prelude.Hashable VpcConfigOutput where
+  hashWithSalt _salt VpcConfigOutput' {..} =
+    _salt
+      `Prelude.hashWithSalt` securityGroupIds
+      `Prelude.hashWithSalt` subnetIds
+      `Prelude.hashWithSalt` vpcId
+
+instance Prelude.NFData VpcConfigOutput where
+  rnf VpcConfigOutput' {..} =
+    Prelude.rnf securityGroupIds
+      `Prelude.seq` Prelude.rnf subnetIds
+      `Prelude.seq` Prelude.rnf vpcId
diff --git a/gen/Amazonka/Synthetics/UntagResource.hs b/gen/Amazonka/Synthetics/UntagResource.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/UntagResource.hs
@@ -0,0 +1,181 @@
+{-# 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.Synthetics.UntagResource
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Removes one or more tags from the specified resource.
+module Amazonka.Synthetics.UntagResource
+  ( -- * Creating a Request
+    UntagResource (..),
+    newUntagResource,
+
+    -- * Request Lenses
+    untagResource_resourceArn,
+    untagResource_tagKeys,
+
+    -- * Destructuring the Response
+    UntagResourceResponse (..),
+    newUntagResourceResponse,
+
+    -- * Response Lenses
+    untagResourceResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newUntagResource' smart constructor.
+data UntagResource = UntagResource'
+  { -- | The ARN of the canary or group that you\'re removing tags from.
+    --
+    -- The ARN format of a canary is
+    -- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+    --
+    -- The ARN format of a group is
+    -- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+    resourceArn :: Prelude.Text,
+    -- | The list of tag keys to remove from the resource.
+    tagKeys :: Prelude.NonEmpty Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'UntagResource' 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:
+--
+-- 'resourceArn', 'untagResource_resourceArn' - The ARN of the canary or group that you\'re removing tags from.
+--
+-- The ARN format of a canary is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+--
+-- The ARN format of a group is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+--
+-- 'tagKeys', 'untagResource_tagKeys' - The list of tag keys to remove from the resource.
+newUntagResource ::
+  -- | 'resourceArn'
+  Prelude.Text ->
+  -- | 'tagKeys'
+  Prelude.NonEmpty Prelude.Text ->
+  UntagResource
+newUntagResource pResourceArn_ pTagKeys_ =
+  UntagResource'
+    { resourceArn = pResourceArn_,
+      tagKeys = Lens.coerced Lens.# pTagKeys_
+    }
+
+-- | The ARN of the canary or group that you\'re removing tags from.
+--
+-- The ARN format of a canary is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:canary:@/@canary-name@/@ @.
+--
+-- The ARN format of a group is
+-- @arn:aws:synthetics:@/@Region@/@:@/@account-id@/@:group:@/@group-name@/@ @
+untagResource_resourceArn :: Lens.Lens' UntagResource Prelude.Text
+untagResource_resourceArn = Lens.lens (\UntagResource' {resourceArn} -> resourceArn) (\s@UntagResource' {} a -> s {resourceArn = a} :: UntagResource)
+
+-- | The list of tag keys to remove from the resource.
+untagResource_tagKeys :: Lens.Lens' UntagResource (Prelude.NonEmpty Prelude.Text)
+untagResource_tagKeys = Lens.lens (\UntagResource' {tagKeys} -> tagKeys) (\s@UntagResource' {} a -> s {tagKeys = a} :: UntagResource) Prelude.. Lens.coerced
+
+instance Core.AWSRequest UntagResource where
+  type
+    AWSResponse UntagResource =
+      UntagResourceResponse
+  request overrides =
+    Request.delete (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          UntagResourceResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable UntagResource where
+  hashWithSalt _salt UntagResource' {..} =
+    _salt
+      `Prelude.hashWithSalt` resourceArn
+      `Prelude.hashWithSalt` tagKeys
+
+instance Prelude.NFData UntagResource where
+  rnf UntagResource' {..} =
+    Prelude.rnf resourceArn
+      `Prelude.seq` Prelude.rnf tagKeys
+
+instance Data.ToHeaders UntagResource where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToPath UntagResource where
+  toPath UntagResource' {..} =
+    Prelude.mconcat ["/tags/", Data.toBS resourceArn]
+
+instance Data.ToQuery UntagResource where
+  toQuery UntagResource' {..} =
+    Prelude.mconcat
+      ["tagKeys" Data.=: Data.toQueryList "member" tagKeys]
+
+-- | /See:/ 'newUntagResourceResponse' smart constructor.
+data UntagResourceResponse = UntagResourceResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'UntagResourceResponse' 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:
+--
+-- 'httpStatus', 'untagResourceResponse_httpStatus' - The response's http status code.
+newUntagResourceResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  UntagResourceResponse
+newUntagResourceResponse pHttpStatus_ =
+  UntagResourceResponse' {httpStatus = pHttpStatus_}
+
+-- | The response's http status code.
+untagResourceResponse_httpStatus :: Lens.Lens' UntagResourceResponse Prelude.Int
+untagResourceResponse_httpStatus = Lens.lens (\UntagResourceResponse' {httpStatus} -> httpStatus) (\s@UntagResourceResponse' {} a -> s {httpStatus = a} :: UntagResourceResponse)
+
+instance Prelude.NFData UntagResourceResponse where
+  rnf UntagResourceResponse' {..} =
+    Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/UpdateCanary.hs b/gen/Amazonka/Synthetics/UpdateCanary.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/UpdateCanary.hs
@@ -0,0 +1,441 @@
+{-# 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.Synthetics.UpdateCanary
+-- Copyright   : (c) 2013-2023 Brendan Hay
+-- License     : Mozilla Public License, v. 2.0.
+-- Maintainer  : Brendan Hay
+-- Stability   : auto-generated
+-- Portability : non-portable (GHC extensions)
+--
+-- Updates the configuration of a canary that has already been created.
+--
+-- You can\'t use this operation to update the tags of an existing canary.
+-- To change the tags of an existing canary, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_TagResource.html TagResource>.
+module Amazonka.Synthetics.UpdateCanary
+  ( -- * Creating a Request
+    UpdateCanary (..),
+    newUpdateCanary,
+
+    -- * Request Lenses
+    updateCanary_artifactConfig,
+    updateCanary_artifactS3Location,
+    updateCanary_code,
+    updateCanary_executionRoleArn,
+    updateCanary_failureRetentionPeriodInDays,
+    updateCanary_runConfig,
+    updateCanary_runtimeVersion,
+    updateCanary_schedule,
+    updateCanary_successRetentionPeriodInDays,
+    updateCanary_visualReference,
+    updateCanary_vpcConfig,
+    updateCanary_name,
+
+    -- * Destructuring the Response
+    UpdateCanaryResponse (..),
+    newUpdateCanaryResponse,
+
+    -- * Response Lenses
+    updateCanaryResponse_httpStatus,
+  )
+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
+import qualified Amazonka.Request as Request
+import qualified Amazonka.Response as Response
+import Amazonka.Synthetics.Types
+
+-- | /See:/ 'newUpdateCanary' smart constructor.
+data UpdateCanary = UpdateCanary'
+  { -- | A structure that contains the configuration for canary artifacts,
+    -- including the encryption-at-rest settings for artifacts that the canary
+    -- uploads to Amazon S3.
+    artifactConfig :: Prelude.Maybe ArtifactConfigInput,
+    -- | The location in Amazon S3 where Synthetics stores artifacts from the
+    -- test runs of this canary. Artifacts include the log file, screenshots,
+    -- and HAR files. The name of the S3 bucket can\'t include a period (.).
+    artifactS3Location :: Prelude.Maybe Prelude.Text,
+    -- | A structure that includes the entry point from which the canary should
+    -- start running your script. If the script is stored in an S3 bucket, the
+    -- bucket name, key, and version are also included.
+    code :: Prelude.Maybe CanaryCodeInput,
+    -- | The ARN of the IAM role to be used to run the canary. This role must
+    -- already exist, and must include @lambda.amazonaws.com@ as a principal in
+    -- the trust policy. The role must also have the following permissions:
+    --
+    -- -   @s3:PutObject@
+    --
+    -- -   @s3:GetBucketLocation@
+    --
+    -- -   @s3:ListAllMyBuckets@
+    --
+    -- -   @cloudwatch:PutMetricData@
+    --
+    -- -   @logs:CreateLogGroup@
+    --
+    -- -   @logs:CreateLogStream@
+    --
+    -- -   @logs:CreateLogStream@
+    executionRoleArn :: Prelude.Maybe Prelude.Text,
+    -- | The number of days to retain data about failed runs of this canary.
+    failureRetentionPeriodInDays :: Prelude.Maybe Prelude.Natural,
+    -- | A structure that contains the timeout value that is used for each
+    -- individual run of the canary.
+    --
+    -- The environment variables keys and values are not encrypted. Do not
+    -- store sensitive information in this field.
+    runConfig :: Prelude.Maybe CanaryRunConfigInput,
+    -- | Specifies the runtime version to use for the canary. For a list of valid
+    -- runtime versions and for more information about runtime versions, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+    runtimeVersion :: Prelude.Maybe Prelude.Text,
+    -- | A structure that contains information about how often the canary is to
+    -- run, and when these runs are to stop.
+    schedule :: Prelude.Maybe CanaryScheduleInput,
+    -- | The number of days to retain data about successful runs of this canary.
+    successRetentionPeriodInDays :: Prelude.Maybe Prelude.Natural,
+    -- | Defines the screenshots to use as the baseline for comparisons during
+    -- visual monitoring comparisons during future runs of this canary. If you
+    -- omit this parameter, no changes are made to any baseline screenshots
+    -- that the canary might be using already.
+    --
+    -- Visual monitoring is supported only on canaries running the
+    -- __syn-puppeteer-node-3.2__ runtime or later. For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_SyntheticsLogger_VisualTesting.html Visual monitoring>
+    -- and
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Blueprints_VisualTesting.html Visual monitoring blueprint>
+    visualReference :: Prelude.Maybe VisualReferenceInput,
+    -- | If this canary is to test an endpoint in a VPC, this structure contains
+    -- information about the subnet and security groups of the VPC endpoint.
+    -- For more information, see
+    -- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+    vpcConfig :: Prelude.Maybe VpcConfigInput,
+    -- | The name of the canary that you want to update. To find the names of
+    -- your canaries, use
+    -- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+    --
+    -- You cannot change the name of a canary that has already been created.
+    name :: Prelude.Text
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'UpdateCanary' 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:
+--
+-- 'artifactConfig', 'updateCanary_artifactConfig' - A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+--
+-- 'artifactS3Location', 'updateCanary_artifactS3Location' - The location in Amazon S3 where Synthetics stores artifacts from the
+-- test runs of this canary. Artifacts include the log file, screenshots,
+-- and HAR files. The name of the S3 bucket can\'t include a period (.).
+--
+-- 'code', 'updateCanary_code' - A structure that includes the entry point from which the canary should
+-- start running your script. If the script is stored in an S3 bucket, the
+-- bucket name, key, and version are also included.
+--
+-- 'executionRoleArn', 'updateCanary_executionRoleArn' - The ARN of the IAM role to be used to run the canary. This role must
+-- already exist, and must include @lambda.amazonaws.com@ as a principal in
+-- the trust policy. The role must also have the following permissions:
+--
+-- -   @s3:PutObject@
+--
+-- -   @s3:GetBucketLocation@
+--
+-- -   @s3:ListAllMyBuckets@
+--
+-- -   @cloudwatch:PutMetricData@
+--
+-- -   @logs:CreateLogGroup@
+--
+-- -   @logs:CreateLogStream@
+--
+-- -   @logs:CreateLogStream@
+--
+-- 'failureRetentionPeriodInDays', 'updateCanary_failureRetentionPeriodInDays' - The number of days to retain data about failed runs of this canary.
+--
+-- 'runConfig', 'updateCanary_runConfig' - A structure that contains the timeout value that is used for each
+-- individual run of the canary.
+--
+-- The environment variables keys and values are not encrypted. Do not
+-- store sensitive information in this field.
+--
+-- 'runtimeVersion', 'updateCanary_runtimeVersion' - Specifies the runtime version to use for the canary. For a list of valid
+-- runtime versions and for more information about runtime versions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+--
+-- 'schedule', 'updateCanary_schedule' - A structure that contains information about how often the canary is to
+-- run, and when these runs are to stop.
+--
+-- 'successRetentionPeriodInDays', 'updateCanary_successRetentionPeriodInDays' - The number of days to retain data about successful runs of this canary.
+--
+-- 'visualReference', 'updateCanary_visualReference' - Defines the screenshots to use as the baseline for comparisons during
+-- visual monitoring comparisons during future runs of this canary. If you
+-- omit this parameter, no changes are made to any baseline screenshots
+-- that the canary might be using already.
+--
+-- Visual monitoring is supported only on canaries running the
+-- __syn-puppeteer-node-3.2__ runtime or later. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_SyntheticsLogger_VisualTesting.html Visual monitoring>
+-- and
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Blueprints_VisualTesting.html Visual monitoring blueprint>
+--
+-- 'vpcConfig', 'updateCanary_vpcConfig' - If this canary is to test an endpoint in a VPC, this structure contains
+-- information about the subnet and security groups of the VPC endpoint.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+--
+-- 'name', 'updateCanary_name' - The name of the canary that you want to update. To find the names of
+-- your canaries, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+--
+-- You cannot change the name of a canary that has already been created.
+newUpdateCanary ::
+  -- | 'name'
+  Prelude.Text ->
+  UpdateCanary
+newUpdateCanary pName_ =
+  UpdateCanary'
+    { artifactConfig = Prelude.Nothing,
+      artifactS3Location = Prelude.Nothing,
+      code = Prelude.Nothing,
+      executionRoleArn = Prelude.Nothing,
+      failureRetentionPeriodInDays = Prelude.Nothing,
+      runConfig = Prelude.Nothing,
+      runtimeVersion = Prelude.Nothing,
+      schedule = Prelude.Nothing,
+      successRetentionPeriodInDays = Prelude.Nothing,
+      visualReference = Prelude.Nothing,
+      vpcConfig = Prelude.Nothing,
+      name = pName_
+    }
+
+-- | A structure that contains the configuration for canary artifacts,
+-- including the encryption-at-rest settings for artifacts that the canary
+-- uploads to Amazon S3.
+updateCanary_artifactConfig :: Lens.Lens' UpdateCanary (Prelude.Maybe ArtifactConfigInput)
+updateCanary_artifactConfig = Lens.lens (\UpdateCanary' {artifactConfig} -> artifactConfig) (\s@UpdateCanary' {} a -> s {artifactConfig = a} :: UpdateCanary)
+
+-- | The location in Amazon S3 where Synthetics stores artifacts from the
+-- test runs of this canary. Artifacts include the log file, screenshots,
+-- and HAR files. The name of the S3 bucket can\'t include a period (.).
+updateCanary_artifactS3Location :: Lens.Lens' UpdateCanary (Prelude.Maybe Prelude.Text)
+updateCanary_artifactS3Location = Lens.lens (\UpdateCanary' {artifactS3Location} -> artifactS3Location) (\s@UpdateCanary' {} a -> s {artifactS3Location = a} :: UpdateCanary)
+
+-- | A structure that includes the entry point from which the canary should
+-- start running your script. If the script is stored in an S3 bucket, the
+-- bucket name, key, and version are also included.
+updateCanary_code :: Lens.Lens' UpdateCanary (Prelude.Maybe CanaryCodeInput)
+updateCanary_code = Lens.lens (\UpdateCanary' {code} -> code) (\s@UpdateCanary' {} a -> s {code = a} :: UpdateCanary)
+
+-- | The ARN of the IAM role to be used to run the canary. This role must
+-- already exist, and must include @lambda.amazonaws.com@ as a principal in
+-- the trust policy. The role must also have the following permissions:
+--
+-- -   @s3:PutObject@
+--
+-- -   @s3:GetBucketLocation@
+--
+-- -   @s3:ListAllMyBuckets@
+--
+-- -   @cloudwatch:PutMetricData@
+--
+-- -   @logs:CreateLogGroup@
+--
+-- -   @logs:CreateLogStream@
+--
+-- -   @logs:CreateLogStream@
+updateCanary_executionRoleArn :: Lens.Lens' UpdateCanary (Prelude.Maybe Prelude.Text)
+updateCanary_executionRoleArn = Lens.lens (\UpdateCanary' {executionRoleArn} -> executionRoleArn) (\s@UpdateCanary' {} a -> s {executionRoleArn = a} :: UpdateCanary)
+
+-- | The number of days to retain data about failed runs of this canary.
+updateCanary_failureRetentionPeriodInDays :: Lens.Lens' UpdateCanary (Prelude.Maybe Prelude.Natural)
+updateCanary_failureRetentionPeriodInDays = Lens.lens (\UpdateCanary' {failureRetentionPeriodInDays} -> failureRetentionPeriodInDays) (\s@UpdateCanary' {} a -> s {failureRetentionPeriodInDays = a} :: UpdateCanary)
+
+-- | A structure that contains the timeout value that is used for each
+-- individual run of the canary.
+--
+-- The environment variables keys and values are not encrypted. Do not
+-- store sensitive information in this field.
+updateCanary_runConfig :: Lens.Lens' UpdateCanary (Prelude.Maybe CanaryRunConfigInput)
+updateCanary_runConfig = Lens.lens (\UpdateCanary' {runConfig} -> runConfig) (\s@UpdateCanary' {} a -> s {runConfig = a} :: UpdateCanary)
+
+-- | Specifies the runtime version to use for the canary. For a list of valid
+-- runtime versions and for more information about runtime versions, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html Canary Runtime Versions>.
+updateCanary_runtimeVersion :: Lens.Lens' UpdateCanary (Prelude.Maybe Prelude.Text)
+updateCanary_runtimeVersion = Lens.lens (\UpdateCanary' {runtimeVersion} -> runtimeVersion) (\s@UpdateCanary' {} a -> s {runtimeVersion = a} :: UpdateCanary)
+
+-- | A structure that contains information about how often the canary is to
+-- run, and when these runs are to stop.
+updateCanary_schedule :: Lens.Lens' UpdateCanary (Prelude.Maybe CanaryScheduleInput)
+updateCanary_schedule = Lens.lens (\UpdateCanary' {schedule} -> schedule) (\s@UpdateCanary' {} a -> s {schedule = a} :: UpdateCanary)
+
+-- | The number of days to retain data about successful runs of this canary.
+updateCanary_successRetentionPeriodInDays :: Lens.Lens' UpdateCanary (Prelude.Maybe Prelude.Natural)
+updateCanary_successRetentionPeriodInDays = Lens.lens (\UpdateCanary' {successRetentionPeriodInDays} -> successRetentionPeriodInDays) (\s@UpdateCanary' {} a -> s {successRetentionPeriodInDays = a} :: UpdateCanary)
+
+-- | Defines the screenshots to use as the baseline for comparisons during
+-- visual monitoring comparisons during future runs of this canary. If you
+-- omit this parameter, no changes are made to any baseline screenshots
+-- that the canary might be using already.
+--
+-- Visual monitoring is supported only on canaries running the
+-- __syn-puppeteer-node-3.2__ runtime or later. For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_SyntheticsLogger_VisualTesting.html Visual monitoring>
+-- and
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Blueprints_VisualTesting.html Visual monitoring blueprint>
+updateCanary_visualReference :: Lens.Lens' UpdateCanary (Prelude.Maybe VisualReferenceInput)
+updateCanary_visualReference = Lens.lens (\UpdateCanary' {visualReference} -> visualReference) (\s@UpdateCanary' {} a -> s {visualReference = a} :: UpdateCanary)
+
+-- | If this canary is to test an endpoint in a VPC, this structure contains
+-- information about the subnet and security groups of the VPC endpoint.
+-- For more information, see
+-- <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html Running a Canary in a VPC>.
+updateCanary_vpcConfig :: Lens.Lens' UpdateCanary (Prelude.Maybe VpcConfigInput)
+updateCanary_vpcConfig = Lens.lens (\UpdateCanary' {vpcConfig} -> vpcConfig) (\s@UpdateCanary' {} a -> s {vpcConfig = a} :: UpdateCanary)
+
+-- | The name of the canary that you want to update. To find the names of
+-- your canaries, use
+-- <https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html DescribeCanaries>.
+--
+-- You cannot change the name of a canary that has already been created.
+updateCanary_name :: Lens.Lens' UpdateCanary Prelude.Text
+updateCanary_name = Lens.lens (\UpdateCanary' {name} -> name) (\s@UpdateCanary' {} a -> s {name = a} :: UpdateCanary)
+
+instance Core.AWSRequest UpdateCanary where
+  type AWSResponse UpdateCanary = UpdateCanaryResponse
+  request overrides =
+    Request.patchJSON (overrides defaultService)
+  response =
+    Response.receiveEmpty
+      ( \s h x ->
+          UpdateCanaryResponse'
+            Prelude.<$> (Prelude.pure (Prelude.fromEnum s))
+      )
+
+instance Prelude.Hashable UpdateCanary where
+  hashWithSalt _salt UpdateCanary' {..} =
+    _salt
+      `Prelude.hashWithSalt` artifactConfig
+      `Prelude.hashWithSalt` artifactS3Location
+      `Prelude.hashWithSalt` code
+      `Prelude.hashWithSalt` executionRoleArn
+      `Prelude.hashWithSalt` failureRetentionPeriodInDays
+      `Prelude.hashWithSalt` runConfig
+      `Prelude.hashWithSalt` runtimeVersion
+      `Prelude.hashWithSalt` schedule
+      `Prelude.hashWithSalt` successRetentionPeriodInDays
+      `Prelude.hashWithSalt` visualReference
+      `Prelude.hashWithSalt` vpcConfig
+      `Prelude.hashWithSalt` name
+
+instance Prelude.NFData UpdateCanary where
+  rnf UpdateCanary' {..} =
+    Prelude.rnf artifactConfig
+      `Prelude.seq` Prelude.rnf artifactS3Location
+      `Prelude.seq` Prelude.rnf code
+      `Prelude.seq` Prelude.rnf executionRoleArn
+      `Prelude.seq` Prelude.rnf failureRetentionPeriodInDays
+      `Prelude.seq` Prelude.rnf runConfig
+      `Prelude.seq` Prelude.rnf runtimeVersion
+      `Prelude.seq` Prelude.rnf schedule
+      `Prelude.seq` Prelude.rnf successRetentionPeriodInDays
+      `Prelude.seq` Prelude.rnf visualReference
+      `Prelude.seq` Prelude.rnf vpcConfig
+      `Prelude.seq` Prelude.rnf name
+
+instance Data.ToHeaders UpdateCanary where
+  toHeaders =
+    Prelude.const
+      ( Prelude.mconcat
+          [ "Content-Type"
+              Data.=# ( "application/x-amz-json-1.1" ::
+                          Prelude.ByteString
+                      )
+          ]
+      )
+
+instance Data.ToJSON UpdateCanary where
+  toJSON UpdateCanary' {..} =
+    Data.object
+      ( Prelude.catMaybes
+          [ ("ArtifactConfig" Data..=)
+              Prelude.<$> artifactConfig,
+            ("ArtifactS3Location" Data..=)
+              Prelude.<$> artifactS3Location,
+            ("Code" Data..=) Prelude.<$> code,
+            ("ExecutionRoleArn" Data..=)
+              Prelude.<$> executionRoleArn,
+            ("FailureRetentionPeriodInDays" Data..=)
+              Prelude.<$> failureRetentionPeriodInDays,
+            ("RunConfig" Data..=) Prelude.<$> runConfig,
+            ("RuntimeVersion" Data..=)
+              Prelude.<$> runtimeVersion,
+            ("Schedule" Data..=) Prelude.<$> schedule,
+            ("SuccessRetentionPeriodInDays" Data..=)
+              Prelude.<$> successRetentionPeriodInDays,
+            ("VisualReference" Data..=)
+              Prelude.<$> visualReference,
+            ("VpcConfig" Data..=) Prelude.<$> vpcConfig
+          ]
+      )
+
+instance Data.ToPath UpdateCanary where
+  toPath UpdateCanary' {..} =
+    Prelude.mconcat ["/canary/", Data.toBS name]
+
+instance Data.ToQuery UpdateCanary where
+  toQuery = Prelude.const Prelude.mempty
+
+-- | /See:/ 'newUpdateCanaryResponse' smart constructor.
+data UpdateCanaryResponse = UpdateCanaryResponse'
+  { -- | The response's http status code.
+    httpStatus :: Prelude.Int
+  }
+  deriving (Prelude.Eq, Prelude.Read, Prelude.Show, Prelude.Generic)
+
+-- |
+-- Create a value of 'UpdateCanaryResponse' 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:
+--
+-- 'httpStatus', 'updateCanaryResponse_httpStatus' - The response's http status code.
+newUpdateCanaryResponse ::
+  -- | 'httpStatus'
+  Prelude.Int ->
+  UpdateCanaryResponse
+newUpdateCanaryResponse pHttpStatus_ =
+  UpdateCanaryResponse' {httpStatus = pHttpStatus_}
+
+-- | The response's http status code.
+updateCanaryResponse_httpStatus :: Lens.Lens' UpdateCanaryResponse Prelude.Int
+updateCanaryResponse_httpStatus = Lens.lens (\UpdateCanaryResponse' {httpStatus} -> httpStatus) (\s@UpdateCanaryResponse' {} a -> s {httpStatus = a} :: UpdateCanaryResponse)
+
+instance Prelude.NFData UpdateCanaryResponse where
+  rnf UpdateCanaryResponse' {..} =
+    Prelude.rnf httpStatus
diff --git a/gen/Amazonka/Synthetics/Waiters.hs b/gen/Amazonka/Synthetics/Waiters.hs
new file mode 100644
--- /dev/null
+++ b/gen/Amazonka/Synthetics/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.Synthetics.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.Synthetics.Waiters 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
+import Amazonka.Synthetics.Lens
+import Amazonka.Synthetics.Types
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.Synthetics
+import Test.Amazonka.Synthetics.Internal
+import Test.Tasty
+
+main :: IO ()
+main =
+  defaultMain $
+    testGroup
+      "Synthetics"
+      [ testGroup "tests" tests,
+        testGroup "fixtures" fixtures
+      ]
diff --git a/test/Test/Amazonka/Gen/Synthetics.hs b/test/Test/Amazonka/Gen/Synthetics.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Amazonka/Gen/Synthetics.hs
@@ -0,0 +1,458 @@
+{-# 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.Synthetics
+-- 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.Synthetics where
+
+import Amazonka.Synthetics
+import qualified Data.Proxy as Proxy
+import Test.Amazonka.Fixture
+import Test.Amazonka.Prelude
+import Test.Amazonka.Synthetics.Internal
+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"
+--         [ requestAssociateResource $
+--             newAssociateResource
+--
+--         , requestCreateCanary $
+--             newCreateCanary
+--
+--         , requestCreateGroup $
+--             newCreateGroup
+--
+--         , requestDeleteCanary $
+--             newDeleteCanary
+--
+--         , requestDeleteGroup $
+--             newDeleteGroup
+--
+--         , requestDescribeCanaries $
+--             newDescribeCanaries
+--
+--         , requestDescribeCanariesLastRun $
+--             newDescribeCanariesLastRun
+--
+--         , requestDescribeRuntimeVersions $
+--             newDescribeRuntimeVersions
+--
+--         , requestDisassociateResource $
+--             newDisassociateResource
+--
+--         , requestGetCanary $
+--             newGetCanary
+--
+--         , requestGetCanaryRuns $
+--             newGetCanaryRuns
+--
+--         , requestGetGroup $
+--             newGetGroup
+--
+--         , requestListAssociatedGroups $
+--             newListAssociatedGroups
+--
+--         , requestListGroupResources $
+--             newListGroupResources
+--
+--         , requestListGroups $
+--             newListGroups
+--
+--         , requestListTagsForResource $
+--             newListTagsForResource
+--
+--         , requestStartCanary $
+--             newStartCanary
+--
+--         , requestStopCanary $
+--             newStopCanary
+--
+--         , requestTagResource $
+--             newTagResource
+--
+--         , requestUntagResource $
+--             newUntagResource
+--
+--         , requestUpdateCanary $
+--             newUpdateCanary
+--
+--           ]
+
+--     , testGroup "response"
+--         [ responseAssociateResource $
+--             newAssociateResourceResponse
+--
+--         , responseCreateCanary $
+--             newCreateCanaryResponse
+--
+--         , responseCreateGroup $
+--             newCreateGroupResponse
+--
+--         , responseDeleteCanary $
+--             newDeleteCanaryResponse
+--
+--         , responseDeleteGroup $
+--             newDeleteGroupResponse
+--
+--         , responseDescribeCanaries $
+--             newDescribeCanariesResponse
+--
+--         , responseDescribeCanariesLastRun $
+--             newDescribeCanariesLastRunResponse
+--
+--         , responseDescribeRuntimeVersions $
+--             newDescribeRuntimeVersionsResponse
+--
+--         , responseDisassociateResource $
+--             newDisassociateResourceResponse
+--
+--         , responseGetCanary $
+--             newGetCanaryResponse
+--
+--         , responseGetCanaryRuns $
+--             newGetCanaryRunsResponse
+--
+--         , responseGetGroup $
+--             newGetGroupResponse
+--
+--         , responseListAssociatedGroups $
+--             newListAssociatedGroupsResponse
+--
+--         , responseListGroupResources $
+--             newListGroupResourcesResponse
+--
+--         , responseListGroups $
+--             newListGroupsResponse
+--
+--         , responseListTagsForResource $
+--             newListTagsForResourceResponse
+--
+--         , responseStartCanary $
+--             newStartCanaryResponse
+--
+--         , responseStopCanary $
+--             newStopCanaryResponse
+--
+--         , responseTagResource $
+--             newTagResourceResponse
+--
+--         , responseUntagResource $
+--             newUntagResourceResponse
+--
+--         , responseUpdateCanary $
+--             newUpdateCanaryResponse
+--
+--           ]
+--     ]
+
+-- Requests
+
+requestAssociateResource :: AssociateResource -> TestTree
+requestAssociateResource =
+  req
+    "AssociateResource"
+    "fixture/AssociateResource.yaml"
+
+requestCreateCanary :: CreateCanary -> TestTree
+requestCreateCanary =
+  req
+    "CreateCanary"
+    "fixture/CreateCanary.yaml"
+
+requestCreateGroup :: CreateGroup -> TestTree
+requestCreateGroup =
+  req
+    "CreateGroup"
+    "fixture/CreateGroup.yaml"
+
+requestDeleteCanary :: DeleteCanary -> TestTree
+requestDeleteCanary =
+  req
+    "DeleteCanary"
+    "fixture/DeleteCanary.yaml"
+
+requestDeleteGroup :: DeleteGroup -> TestTree
+requestDeleteGroup =
+  req
+    "DeleteGroup"
+    "fixture/DeleteGroup.yaml"
+
+requestDescribeCanaries :: DescribeCanaries -> TestTree
+requestDescribeCanaries =
+  req
+    "DescribeCanaries"
+    "fixture/DescribeCanaries.yaml"
+
+requestDescribeCanariesLastRun :: DescribeCanariesLastRun -> TestTree
+requestDescribeCanariesLastRun =
+  req
+    "DescribeCanariesLastRun"
+    "fixture/DescribeCanariesLastRun.yaml"
+
+requestDescribeRuntimeVersions :: DescribeRuntimeVersions -> TestTree
+requestDescribeRuntimeVersions =
+  req
+    "DescribeRuntimeVersions"
+    "fixture/DescribeRuntimeVersions.yaml"
+
+requestDisassociateResource :: DisassociateResource -> TestTree
+requestDisassociateResource =
+  req
+    "DisassociateResource"
+    "fixture/DisassociateResource.yaml"
+
+requestGetCanary :: GetCanary -> TestTree
+requestGetCanary =
+  req
+    "GetCanary"
+    "fixture/GetCanary.yaml"
+
+requestGetCanaryRuns :: GetCanaryRuns -> TestTree
+requestGetCanaryRuns =
+  req
+    "GetCanaryRuns"
+    "fixture/GetCanaryRuns.yaml"
+
+requestGetGroup :: GetGroup -> TestTree
+requestGetGroup =
+  req
+    "GetGroup"
+    "fixture/GetGroup.yaml"
+
+requestListAssociatedGroups :: ListAssociatedGroups -> TestTree
+requestListAssociatedGroups =
+  req
+    "ListAssociatedGroups"
+    "fixture/ListAssociatedGroups.yaml"
+
+requestListGroupResources :: ListGroupResources -> TestTree
+requestListGroupResources =
+  req
+    "ListGroupResources"
+    "fixture/ListGroupResources.yaml"
+
+requestListGroups :: ListGroups -> TestTree
+requestListGroups =
+  req
+    "ListGroups"
+    "fixture/ListGroups.yaml"
+
+requestListTagsForResource :: ListTagsForResource -> TestTree
+requestListTagsForResource =
+  req
+    "ListTagsForResource"
+    "fixture/ListTagsForResource.yaml"
+
+requestStartCanary :: StartCanary -> TestTree
+requestStartCanary =
+  req
+    "StartCanary"
+    "fixture/StartCanary.yaml"
+
+requestStopCanary :: StopCanary -> TestTree
+requestStopCanary =
+  req
+    "StopCanary"
+    "fixture/StopCanary.yaml"
+
+requestTagResource :: TagResource -> TestTree
+requestTagResource =
+  req
+    "TagResource"
+    "fixture/TagResource.yaml"
+
+requestUntagResource :: UntagResource -> TestTree
+requestUntagResource =
+  req
+    "UntagResource"
+    "fixture/UntagResource.yaml"
+
+requestUpdateCanary :: UpdateCanary -> TestTree
+requestUpdateCanary =
+  req
+    "UpdateCanary"
+    "fixture/UpdateCanary.yaml"
+
+-- Responses
+
+responseAssociateResource :: AssociateResourceResponse -> TestTree
+responseAssociateResource =
+  res
+    "AssociateResourceResponse"
+    "fixture/AssociateResourceResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy AssociateResource)
+
+responseCreateCanary :: CreateCanaryResponse -> TestTree
+responseCreateCanary =
+  res
+    "CreateCanaryResponse"
+    "fixture/CreateCanaryResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy CreateCanary)
+
+responseCreateGroup :: CreateGroupResponse -> TestTree
+responseCreateGroup =
+  res
+    "CreateGroupResponse"
+    "fixture/CreateGroupResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy CreateGroup)
+
+responseDeleteCanary :: DeleteCanaryResponse -> TestTree
+responseDeleteCanary =
+  res
+    "DeleteCanaryResponse"
+    "fixture/DeleteCanaryResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy DeleteCanary)
+
+responseDeleteGroup :: DeleteGroupResponse -> TestTree
+responseDeleteGroup =
+  res
+    "DeleteGroupResponse"
+    "fixture/DeleteGroupResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy DeleteGroup)
+
+responseDescribeCanaries :: DescribeCanariesResponse -> TestTree
+responseDescribeCanaries =
+  res
+    "DescribeCanariesResponse"
+    "fixture/DescribeCanariesResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy DescribeCanaries)
+
+responseDescribeCanariesLastRun :: DescribeCanariesLastRunResponse -> TestTree
+responseDescribeCanariesLastRun =
+  res
+    "DescribeCanariesLastRunResponse"
+    "fixture/DescribeCanariesLastRunResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy DescribeCanariesLastRun)
+
+responseDescribeRuntimeVersions :: DescribeRuntimeVersionsResponse -> TestTree
+responseDescribeRuntimeVersions =
+  res
+    "DescribeRuntimeVersionsResponse"
+    "fixture/DescribeRuntimeVersionsResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy DescribeRuntimeVersions)
+
+responseDisassociateResource :: DisassociateResourceResponse -> TestTree
+responseDisassociateResource =
+  res
+    "DisassociateResourceResponse"
+    "fixture/DisassociateResourceResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy DisassociateResource)
+
+responseGetCanary :: GetCanaryResponse -> TestTree
+responseGetCanary =
+  res
+    "GetCanaryResponse"
+    "fixture/GetCanaryResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy GetCanary)
+
+responseGetCanaryRuns :: GetCanaryRunsResponse -> TestTree
+responseGetCanaryRuns =
+  res
+    "GetCanaryRunsResponse"
+    "fixture/GetCanaryRunsResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy GetCanaryRuns)
+
+responseGetGroup :: GetGroupResponse -> TestTree
+responseGetGroup =
+  res
+    "GetGroupResponse"
+    "fixture/GetGroupResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy GetGroup)
+
+responseListAssociatedGroups :: ListAssociatedGroupsResponse -> TestTree
+responseListAssociatedGroups =
+  res
+    "ListAssociatedGroupsResponse"
+    "fixture/ListAssociatedGroupsResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy ListAssociatedGroups)
+
+responseListGroupResources :: ListGroupResourcesResponse -> TestTree
+responseListGroupResources =
+  res
+    "ListGroupResourcesResponse"
+    "fixture/ListGroupResourcesResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy ListGroupResources)
+
+responseListGroups :: ListGroupsResponse -> TestTree
+responseListGroups =
+  res
+    "ListGroupsResponse"
+    "fixture/ListGroupsResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy ListGroups)
+
+responseListTagsForResource :: ListTagsForResourceResponse -> TestTree
+responseListTagsForResource =
+  res
+    "ListTagsForResourceResponse"
+    "fixture/ListTagsForResourceResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy ListTagsForResource)
+
+responseStartCanary :: StartCanaryResponse -> TestTree
+responseStartCanary =
+  res
+    "StartCanaryResponse"
+    "fixture/StartCanaryResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy StartCanary)
+
+responseStopCanary :: StopCanaryResponse -> TestTree
+responseStopCanary =
+  res
+    "StopCanaryResponse"
+    "fixture/StopCanaryResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy StopCanary)
+
+responseTagResource :: TagResourceResponse -> TestTree
+responseTagResource =
+  res
+    "TagResourceResponse"
+    "fixture/TagResourceResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy TagResource)
+
+responseUntagResource :: UntagResourceResponse -> TestTree
+responseUntagResource =
+  res
+    "UntagResourceResponse"
+    "fixture/UntagResourceResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy UntagResource)
+
+responseUpdateCanary :: UpdateCanaryResponse -> TestTree
+responseUpdateCanary =
+  res
+    "UpdateCanaryResponse"
+    "fixture/UpdateCanaryResponse.proto"
+    defaultService
+    (Proxy.Proxy :: Proxy.Proxy UpdateCanary)
diff --git a/test/Test/Amazonka/Synthetics.hs b/test/Test/Amazonka/Synthetics.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Amazonka/Synthetics.hs
@@ -0,0 +1,20 @@
+-- |
+-- Module      : Test.Amazonka.Synthetics
+-- 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.Synthetics
+  ( tests,
+    fixtures,
+  )
+where
+
+import Test.Tasty (TestTree)
+
+tests :: [TestTree]
+tests = []
+
+fixtures :: [TestTree]
+fixtures = []
diff --git a/test/Test/Amazonka/Synthetics/Internal.hs b/test/Test/Amazonka/Synthetics/Internal.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Amazonka/Synthetics/Internal.hs
@@ -0,0 +1,8 @@
+-- |
+-- Module      : Test.Amazonka.Synthetics.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.Synthetics.Internal where
