Repository: getmoto/moto
Pull request #6440 (2023-06-24 17:28:25)

Prep Release 4.1.12


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c655a558..b79eae254 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,76 @@ Moto Changelog
 ==============
 
 
+4.1.12
+------
+Docker Digest for 4.1.12: <autopopulateddigest>
+
+    General:
+        * Support for ISO regions
+        * The official Docker image now comes with curl pre-installed
+
+    New Services:
+        * AppConfig:
+            * create_application()
+            * create_configuration_profile()
+            * create_hosted_configuration_version()
+            * delete_application()
+            * delete_configuration_profile()
+            * delete_hosted_configuration_version()
+            * get_application()
+            * get_configuration_profile()
+            * get_hosted_configuration_version()
+            * list_configuration_profiles()
+            * list_tags_for_resource()
+            * tag_resource()
+            * untag_resource()
+            * update_application()
+            * update_configuration_profile()
+
+    New Methods:
+        * IdentityStore:
+            * create_user()
+            * describe_user()
+            * delete_user()
+            * get_group_id()
+            * delete_group()
+            * create_group_membership()
+            * get_group_memberships()
+            * delete_group_membership()
+
+        * SSM:
+            * create_patch_baseline()
+            * describe_patch_baselines()
+            * delete_patch_baseline()
+            * register_target_with_maintenance_window()
+            * describe_maintenance_window_targets()
+            * deregister_target_from_maintenance_window()
+
+
+    Miscellaneous:
+        * Moto Dashboard no longer fails to load after an S3 file is overwritten
+        * CloudFormation: AWS:SSM::Parameter now exposes the PhysicalResourceId
+        * CloudFront: create_invalidation() now behaves correctly when supplying a single Path
+        * CloudWatch: get_metrics_data() now validates the provided start/end times
+        * CodeBuild: create_project() now accepts all ServiceRole ARN's, not just ARN's that end in /service-role/
+        * Config: put_configuration_recorder() now supports resource type exclusions
+        * DMS: describe_replication_tasks() now returns TableMappings and ReplicationTaskSettings in the correct format
+        * DynamoDB now supports ProjectionExpressions on (nested) lists
+        * EC2: New availability zones have been added for ap-south-1, sa-east-1, ca-central-1, us-west-2
+        * EC2: create_flow_logs() now allows different LogDestinations for a single ResourceId
+        * EC2: replace_route() now returns the appropriate error when called with missing route
+        * EC2: create_volume() now supports the Throughput-parameter
+        * ECR: put_image() now correctly overwrites tags on images with multiple tags
+        * IAM: add_role_to_instance_profile() now validates whether a role was already attached (only one is allowed)
+        * Lambda: delete_layer_version() now also accepts function ARNs
+        * MediaConnect: create_flow_payload() no longer requires the Entitlements-parameter
+        * RDS: Further improve Global Cluster behaviour
+        * S3: GET/PUT requests now return Access-Control headers, if a CORS configuration has been set
+        * S3: put_bucket_lifecycle_configuration() now supports multiple Transitions
+        * SESv2: create_contact_list() now correctly reads Topics with special characters
+        * SESv2: send_email() now correctly reads raw emails
+
+
 4.1.11
 ------
 Docker Digest for 4.1.11: _sha256:0ac1ec726e428bd3134c10c32639d72f814bbe002b9d2010420850aab8bc2550_
diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md
index 42bb497a3..f2baabe83 100644
--- a/IMPLEMENTATION_COVERAGE.md
+++ b/IMPLEMENTATION_COVERAGE.md
@@ -663,8 +663,9 @@
 
 ## cloudformation
 <details>
-<summary>50% implemented</summary>
+<summary>47% implemented</summary>
 
+- [ ] activate_organizations_access
 - [ ] activate_type
 - [ ] batch_describe_type_configurations
 - [ ] cancel_update_stack
@@ -673,6 +674,7 @@
 - [X] create_stack
 - [X] create_stack_instances
 - [X] create_stack_set
+- [ ] deactivate_organizations_access
 - [ ] deactivate_type
 - [X] delete_change_set
 - [X] delete_stack
@@ -682,6 +684,7 @@
 - [ ] describe_account_limits
 - [X] describe_change_set
 - [ ] describe_change_set_hooks
+- [ ] describe_organizations_access
 - [ ] describe_publisher
 - [ ] describe_stack_drift_detection_status
 - [X] describe_stack_events
@@ -1912,6 +1915,7 @@
 - [X] create_flow_logs
 - [ ] create_fpga_image
 - [X] create_image
+- [ ] create_instance_connect_endpoint
 - [ ] create_instance_event_window
 - [ ] create_instance_export_task
 - [X] create_internet_gateway
@@ -1988,6 +1992,7 @@
 - [X] delete_fleets
 - [X] delete_flow_logs
 - [ ] delete_fpga_image
+- [ ] delete_instance_connect_endpoint
 - [ ] delete_instance_event_window
 - [X] delete_internet_gateway
 - [ ] delete_ipam
@@ -2102,6 +2107,7 @@
 - [ ] describe_import_image_tasks
 - [ ] describe_import_snapshot_tasks
 - [X] describe_instance_attribute
+- [ ] describe_instance_connect_endpoints
 - [X] describe_instance_credit_specifications
 - [ ] describe_instance_event_notification_attributes
 - [ ] describe_instance_event_windows
@@ -2853,7 +2859,7 @@
 
 ## emr
 <details>
-<summary>41% implemented</summary>
+<summary>40% implemented</summary>
 
 - [ ] add_instance_fleet
 - [X] add_instance_groups
@@ -2889,6 +2895,7 @@
 - [X] list_steps
 - [ ] list_studio_session_mappings
 - [ ] list_studios
+- [ ] list_supported_instance_types
 - [X] modify_cluster
 - [ ] modify_instance_fleet
 - [X] modify_instance_groups
@@ -3747,22 +3754,22 @@
 
 ## identitystore
 <details>
-<summary>5% implemented</summary>
+<summary>47% implemented</summary>
 
 - [X] create_group
-- [ ] create_group_membership
-- [ ] create_user
-- [ ] delete_group
-- [ ] delete_group_membership
-- [ ] delete_user
+- [X] create_group_membership
+- [X] create_user
+- [X] delete_group
+- [X] delete_group_membership
+- [X] delete_user
 - [ ] describe_group
 - [ ] describe_group_membership
-- [ ] describe_user
-- [ ] get_group_id
+- [X] describe_user
+- [X] get_group_id
 - [ ] get_group_membership_id
 - [ ] get_user_id
 - [ ] is_member_in_groups
-- [ ] list_group_memberships
+- [X] list_group_memberships
 - [ ] list_group_memberships_for_member
 - [ ] list_groups
 - [ ] list_users
@@ -3772,7 +3779,7 @@
 
 ## iot
 <details>
-<summary>33% implemented</summary>
+<summary>32% implemented</summary>
 
 - [ ] accept_certificate_transfer
 - [ ] add_thing_to_billing_group
@@ -3804,6 +3811,8 @@
 - [X] create_keys_and_certificate
 - [ ] create_mitigation_action
 - [ ] create_ota_update
+- [ ] create_package
+- [ ] create_package_version
 - [X] create_policy
 - [X] create_policy_version
 - [ ] create_provisioning_claim
@@ -3834,6 +3843,8 @@
 - [ ] delete_job_template
 - [ ] delete_mitigation_action
 - [ ] delete_ota_update
+- [ ] delete_package
+- [ ] delete_package_version
 - [X] delete_policy
 - [X] delete_policy_version
 - [ ] delete_provisioning_template
@@ -3897,6 +3908,9 @@
 - [X] get_job_document
 - [ ] get_logging_options
 - [ ] get_ota_update
+- [ ] get_package
+- [ ] get_package_configuration
+- [ ] get_package_version
 - [ ] get_percentiles
 - [X] get_policy
 - [X] get_policy_version
@@ -3933,6 +3947,8 @@
 - [ ] list_mitigation_actions
 - [ ] list_ota_updates
 - [ ] list_outgoing_certificates
+- [ ] list_package_versions
+- [ ] list_packages
 - [X] list_policies
 - [X] list_policy_principals
 - [X] list_policy_versions
@@ -4002,6 +4018,9 @@
 - [ ] update_indexing_configuration
 - [ ] update_job
 - [ ] update_mitigation_action
+- [ ] update_package
+- [ ] update_package_configuration
+- [ ] update_package_version
 - [ ] update_provisioning_template
 - [ ] update_role_alias
 - [ ] update_scheduled_audit
@@ -4291,13 +4310,14 @@
 
 ## logs
 <details>
-<summary>52% implemented</summary>
+<summary>49% implemented</summary>
 
 - [ ] associate_kms_key
 - [ ] cancel_export_task
 - [X] create_export_task
 - [X] create_log_group
 - [X] create_log_stream
+- [ ] delete_account_policy
 - [ ] delete_data_protection_policy
 - [ ] delete_destination
 - [X] delete_log_group
@@ -4307,6 +4327,7 @@
 - [X] delete_resource_policy
 - [X] delete_retention_policy
 - [X] delete_subscription_filter
+- [ ] describe_account_policies
 - [ ] describe_destinations
 - [ ] describe_export_tasks
 - [X] describe_log_groups
@@ -4325,6 +4346,7 @@
 - [ ] get_query_results
 - [ ] list_tags_for_resource
 - [X] list_tags_log_group
+- [ ] put_account_policy
 - [ ] put_data_protection_policy
 - [ ] put_destination
 - [ ] put_destination_policy
@@ -4572,7 +4594,7 @@
 
 ## mq
 <details>
-<summary>86% implemented</summary>
+<summary>82% implemented</summary>
 
 - [X] create_broker
 - [X] create_configuration
@@ -4592,6 +4614,7 @@
 - [X] list_configurations
 - [X] list_tags
 - [X] list_users
+- [ ] promote
 - [X] reboot_broker
 - [X] update_broker
 - [X] update_configuration
@@ -5454,7 +5477,7 @@
 
 ## redshift
 <details>
-<summary>25% implemented</summary>
+<summary>24% implemented</summary>
 
 - [ ] accept_reserved_node_exchange
 - [ ] add_partner
@@ -5473,6 +5496,7 @@
 - [X] create_cluster_security_group
 - [X] create_cluster_snapshot
 - [X] create_cluster_subnet_group
+- [ ] create_custom_domain_association
 - [ ] create_endpoint_access
 - [ ] create_event_subscription
 - [ ] create_hsm_client_certificate
@@ -5489,6 +5513,7 @@
 - [X] delete_cluster_security_group
 - [X] delete_cluster_snapshot
 - [X] delete_cluster_subnet_group
+- [ ] delete_custom_domain_association
 - [ ] delete_endpoint_access
 - [ ] delete_event_subscription
 - [ ] delete_hsm_client_certificate
@@ -5510,6 +5535,7 @@
 - [ ] describe_cluster_tracks
 - [ ] describe_cluster_versions
 - [X] describe_clusters
+- [ ] describe_custom_domain_associations
 - [ ] describe_data_shares
 - [ ] describe_data_shares_for_consumer
 - [ ] describe_data_shares_for_producer
@@ -5555,6 +5581,7 @@
 - [ ] modify_cluster_snapshot
 - [ ] modify_cluster_snapshot_schedule
 - [ ] modify_cluster_subnet_group
+- [ ] modify_custom_domain_association
 - [ ] modify_endpoint_access
 - [ ] modify_event_subscription
 - [ ] modify_scheduled_action
@@ -5595,8 +5622,9 @@
 
 ## rekognition
 <details>
-<summary>6% implemented</summary>
+<summary>5% implemented</summary>
 
+- [ ] associate_faces
 - [ ] compare_faces
 - [ ] copy_project_version
 - [ ] create_collection
@@ -5605,6 +5633,7 @@
 - [ ] create_project
 - [ ] create_project_version
 - [ ] create_stream_processor
+- [ ] create_user
 - [ ] delete_collection
 - [ ] delete_dataset
 - [ ] delete_faces
@@ -5612,6 +5641,7 @@
 - [ ] delete_project_policy
 - [ ] delete_project_version
 - [ ] delete_stream_processor
+- [ ] delete_user
 - [ ] describe_collection
 - [ ] describe_dataset
 - [ ] describe_project_versions
@@ -5623,6 +5653,7 @@
 - [ ] detect_moderation_labels
 - [ ] detect_protective_equipment
 - [ ] detect_text
+- [ ] disassociate_faces
 - [ ] distribute_dataset_entries
 - [ ] get_celebrity_info
 - [ ] get_celebrity_recognition
@@ -5642,10 +5673,13 @@
 - [ ] list_project_policies
 - [ ] list_stream_processors
 - [ ] list_tags_for_resource
+- [ ] list_users
 - [ ] put_project_policy
 - [ ] recognize_celebrities
 - [ ] search_faces
 - [ ] search_faces_by_image
+- [ ] search_users
+- [ ] search_users_by_image
 - [ ] start_celebrity_recognition
 - [ ] start_content_moderation
 - [ ] start_face_detection
@@ -6619,11 +6653,12 @@
 
 ## signer
 <details>
-<summary>23% implemented</summary>
+<summary>21% implemented</summary>
 
 - [ ] add_profile_permission
 - [X] cancel_signing_profile
 - [ ] describe_signing_job
+- [ ] get_revocation_status
 - [ ] get_signing_platform
 - [X] get_signing_profile
 - [ ] list_profile_permissions
@@ -6635,6 +6670,7 @@
 - [ ] remove_profile_permission
 - [ ] revoke_signature
 - [ ] revoke_signing_profile
+- [ ] sign_payload
 - [ ] start_signing_job
 - [ ] tag_resource
 - [ ] untag_resource
@@ -6690,9 +6726,10 @@
 
 ## sqs
 <details>
-<summary>100% implemented</summary>
+<summary>86% implemented</summary>
 
 - [X] add_permission
+- [ ] cancel_message_move_task
 - [X] change_message_visibility
 - [X] change_message_visibility_batch
 - [X] create_queue
@@ -6702,6 +6739,7 @@
 - [X] get_queue_attributes
 - [X] get_queue_url
 - [X] list_dead_letter_source_queues
+- [ ] list_message_move_tasks
 - [X] list_queue_tags
 - [X] list_queues
 - [X] purge_queue
@@ -6710,13 +6748,14 @@
 - [X] send_message
 - [X] send_message_batch
 - [X] set_queue_attributes
+- [ ] start_message_move_task
 - [X] tag_queue
 - [X] untag_queue
 </details>
 
 ## ssm
 <details>
-<summary>20% implemented</summary>
+<summary>24% implemented</summary>
 
 - [X] add_tags_to_resource
 - [ ] associate_ops_item_related_item
@@ -6903,24 +6942,31 @@
 
 ## stepfunctions
 <details>
-<summary>50% implemented</summary>
+<summary>38% implemented</summary>
 
 - [ ] create_activity
 - [X] create_state_machine
+- [ ] create_state_machine_alias
 - [ ] delete_activity
 - [X] delete_state_machine
+- [ ] delete_state_machine_alias
+- [ ] delete_state_machine_version
 - [ ] describe_activity
 - [X] describe_execution
 - [ ] describe_map_run
 - [X] describe_state_machine
+- [ ] describe_state_machine_alias
 - [ ] describe_state_machine_for_execution
 - [ ] get_activity_task
 - [X] get_execution_history
 - [ ] list_activities
 - [X] list_executions
 - [ ] list_map_runs
+- [ ] list_state_machine_aliases
+- [ ] list_state_machine_versions
 - [X] list_state_machines
 - [X] list_tags_for_resource
+- [ ] publish_state_machine_version
 - [ ] send_task_failure
 - [ ] send_task_heartbeat
 - [ ] send_task_success
@@ -6931,6 +6977,7 @@
 - [X] untag_resource
 - [ ] update_map_run
 - [X] update_state_machine
+- [ ] update_state_machine_alias
 </details>
 
 ## sts
@@ -7205,6 +7252,7 @@
 - codecatalyst
 - codedeploy
 - codeguru-reviewer
+- codeguru-security
 - codeguruprofiler
 - codestar
 - codestar-connections
@@ -7325,6 +7373,8 @@
 - osis
 - outposts
 - panorama
+- payment-cryptography
+- payment-cryptography-data
 - personalize-events
 - personalize-runtime
 - pi
@@ -7380,6 +7430,7 @@
 - tnb
 - transfer
 - translate
+- verifiedpermissions
 - voice-id
 - vpc-lattice
 - waf
diff --git a/docs/docs/services/cloudformation.rst b/docs/docs/services/cloudformation.rst
index 27f8da9b9..56fdf6aaa 100644
--- a/docs/docs/services/cloudformation.rst
+++ b/docs/docs/services/cloudformation.rst
@@ -27,6 +27,7 @@ cloudformation
 
 |start-h3| Implemented features for this service |end-h3|
 
+- [ ] activate_organizations_access
 - [ ] activate_type
 - [ ] batch_describe_type_configurations
 - [ ] cancel_update_stack
@@ -47,6 +48,7 @@ cloudformation
         The following parameters are not yet implemented: StackId, AdministrationRoleARN, AutoDeployment, ExecutionRoleName, CallAs, ClientRequestToken, ManagedExecution
         
 
+- [ ] deactivate_organizations_access
 - [ ] deactivate_type
 - [X] delete_change_set
 - [X] delete_stack
@@ -60,6 +62,7 @@ cloudformation
 - [ ] describe_account_limits
 - [X] describe_change_set
 - [ ] describe_change_set_hooks
+- [ ] describe_organizations_access
 - [ ] describe_publisher
 - [ ] describe_stack_drift_detection_status
 - [X] describe_stack_events
diff --git a/docs/docs/services/ec2.rst b/docs/docs/services/ec2.rst
index 40068783a..583b6bb80 100644
--- a/docs/docs/services/ec2.rst
+++ b/docs/docs/services/ec2.rst
@@ -97,6 +97,7 @@ ec2
 - [X] create_flow_logs
 - [ ] create_fpga_image
 - [X] create_image
+- [ ] create_instance_connect_endpoint
 - [ ] create_instance_event_window
 - [ ] create_instance_export_task
 - [X] create_internet_gateway
@@ -177,6 +178,7 @@ ec2
 - [X] delete_fleets
 - [X] delete_flow_logs
 - [ ] delete_fpga_image
+- [ ] delete_instance_connect_endpoint
 - [ ] delete_instance_event_window
 - [X] delete_internet_gateway
 - [ ] delete_ipam
@@ -299,6 +301,7 @@ ec2
 - [ ] describe_import_image_tasks
 - [ ] describe_import_snapshot_tasks
 - [X] describe_instance_attribute
+- [ ] describe_instance_connect_endpoints
 - [X] describe_instance_credit_specifications
 - [ ] describe_instance_event_notification_attributes
 - [ ] describe_instance_event_windows
diff --git a/docs/docs/services/emr.rst b/docs/docs/services/emr.rst
index 6c3b3377a..4a1d8fc06 100644
--- a/docs/docs/services/emr.rst
+++ b/docs/docs/services/emr.rst
@@ -59,6 +59,7 @@ emr
 - [X] list_steps
 - [ ] list_studio_session_mappings
 - [ ] list_studios
+- [ ] list_supported_instance_types
 - [X] modify_cluster
 - [ ] modify_instance_fleet
 - [X] modify_instance_groups
diff --git a/docs/docs/services/identitystore.rst b/docs/docs/services/identitystore.rst
index 9a69d8e77..b76932ef0 100644
--- a/docs/docs/services/identitystore.rst
+++ b/docs/docs/services/identitystore.rst
@@ -28,19 +28,19 @@ identitystore
 |start-h3| Implemented features for this service |end-h3|
 
 - [X] create_group
-- [ ] create_group_membership
-- [ ] create_user
-- [ ] delete_group
-- [ ] delete_group_membership
-- [ ] delete_user
+- [X] create_group_membership
+- [X] create_user
+- [X] delete_group
+- [X] delete_group_membership
+- [X] delete_user
 - [ ] describe_group
 - [ ] describe_group_membership
-- [ ] describe_user
-- [ ] get_group_id
+- [X] describe_user
+- [X] get_group_id
 - [ ] get_group_membership_id
 - [ ] get_user_id
 - [ ] is_member_in_groups
-- [ ] list_group_memberships
+- [X] list_group_memberships
 - [ ] list_group_memberships_for_member
 - [ ] list_groups
 - [ ] list_users
diff --git a/docs/docs/services/iot.rst b/docs/docs/services/iot.rst
index 376f21cdb..f6504e44a 100644
--- a/docs/docs/services/iot.rst
+++ b/docs/docs/services/iot.rst
@@ -63,6 +63,8 @@ iot
 - [X] create_keys_and_certificate
 - [ ] create_mitigation_action
 - [ ] create_ota_update
+- [ ] create_package
+- [ ] create_package_version
 - [X] create_policy
 - [X] create_policy_version
 - [ ] create_provisioning_claim
@@ -93,6 +95,8 @@ iot
 - [ ] delete_job_template
 - [ ] delete_mitigation_action
 - [ ] delete_ota_update
+- [ ] delete_package
+- [ ] delete_package_version
 - [X] delete_policy
 - [X] delete_policy_version
 - [ ] delete_provisioning_template
@@ -164,6 +168,9 @@ iot
 - [X] get_job_document
 - [ ] get_logging_options
 - [ ] get_ota_update
+- [ ] get_package
+- [ ] get_package_configuration
+- [ ] get_package_version
 - [ ] get_percentiles
 - [X] get_policy
 - [X] get_policy_version
@@ -212,6 +219,8 @@ iot
 - [ ] list_mitigation_actions
 - [ ] list_ota_updates
 - [ ] list_outgoing_certificates
+- [ ] list_package_versions
+- [ ] list_packages
 - [X] list_policies
 - [X] list_policy_principals
 - [X] list_policy_versions
@@ -301,6 +310,9 @@ iot
 - [ ] update_indexing_configuration
 - [ ] update_job
 - [ ] update_mitigation_action
+- [ ] update_package
+- [ ] update_package_configuration
+- [ ] update_package_version
 - [ ] update_provisioning_template
 - [ ] update_role_alias
 - [ ] update_scheduled_audit
diff --git a/docs/docs/services/logs.rst b/docs/docs/services/logs.rst
index 326d2dc0d..eabd5c0e5 100644
--- a/docs/docs/services/logs.rst
+++ b/docs/docs/services/logs.rst
@@ -30,6 +30,7 @@ logs
 - [X] create_export_task
 - [X] create_log_group
 - [X] create_log_stream
+- [ ] delete_account_policy
 - [ ] delete_data_protection_policy
 - [ ] delete_destination
 - [X] delete_log_group
@@ -41,6 +42,7 @@ logs
 
 - [X] delete_retention_policy
 - [X] delete_subscription_filter
+- [ ] describe_account_policies
 - [ ] describe_destinations
 - [ ] describe_export_tasks
 - [X] describe_log_groups
@@ -71,6 +73,7 @@ logs
 - [ ] get_query_results
 - [ ] list_tags_for_resource
 - [X] list_tags_log_group
+- [ ] put_account_policy
 - [ ] put_data_protection_policy
 - [ ] put_destination
 - [ ] put_destination_policy
diff --git a/docs/docs/services/mq.rst b/docs/docs/services/mq.rst
index d863fd103..8d87185aa 100644
--- a/docs/docs/services/mq.rst
+++ b/docs/docs/services/mq.rst
@@ -53,6 +53,7 @@ mq
 
 - [X] list_tags
 - [X] list_users
+- [ ] promote
 - [X] reboot_broker
 - [X] update_broker
 - [X] update_configuration
diff --git a/docs/docs/services/redshift.rst b/docs/docs/services/redshift.rst
index 41b9c4b7d..28f8c766d 100644
--- a/docs/docs/services/redshift.rst
+++ b/docs/docs/services/redshift.rst
@@ -42,6 +42,7 @@ redshift
 - [X] create_cluster_security_group
 - [X] create_cluster_snapshot
 - [X] create_cluster_subnet_group
+- [ ] create_custom_domain_association
 - [ ] create_endpoint_access
 - [ ] create_event_subscription
 - [ ] create_hsm_client_certificate
@@ -58,6 +59,7 @@ redshift
 - [X] delete_cluster_security_group
 - [X] delete_cluster_snapshot
 - [X] delete_cluster_subnet_group
+- [ ] delete_custom_domain_association
 - [ ] delete_endpoint_access
 - [ ] delete_event_subscription
 - [ ] delete_hsm_client_certificate
@@ -79,6 +81,7 @@ redshift
 - [ ] describe_cluster_tracks
 - [ ] describe_cluster_versions
 - [X] describe_clusters
+- [ ] describe_custom_domain_associations
 - [ ] describe_data_shares
 - [ ] describe_data_shares_for_consumer
 - [ ] describe_data_shares_for_producer
@@ -124,6 +127,7 @@ redshift
 - [ ] modify_cluster_snapshot
 - [ ] modify_cluster_snapshot_schedule
 - [ ] modify_cluster_subnet_group
+- [ ] modify_custom_domain_association
 - [ ] modify_endpoint_access
 - [ ] modify_event_subscription
 - [ ] modify_scheduled_action
diff --git a/docs/docs/services/rekognition.rst b/docs/docs/services/rekognition.rst
index eda6cbfac..56ffbfd51 100644
--- a/docs/docs/services/rekognition.rst
+++ b/docs/docs/services/rekognition.rst
@@ -27,6 +27,7 @@ rekognition
 
 |start-h3| Implemented features for this service |end-h3|
 
+- [ ] associate_faces
 - [ ] compare_faces
 - [ ] copy_project_version
 - [ ] create_collection
@@ -35,6 +36,7 @@ rekognition
 - [ ] create_project
 - [ ] create_project_version
 - [ ] create_stream_processor
+- [ ] create_user
 - [ ] delete_collection
 - [ ] delete_dataset
 - [ ] delete_faces
@@ -42,6 +44,7 @@ rekognition
 - [ ] delete_project_policy
 - [ ] delete_project_version
 - [ ] delete_stream_processor
+- [ ] delete_user
 - [ ] describe_collection
 - [ ] describe_dataset
 - [ ] describe_project_versions
@@ -53,6 +56,7 @@ rekognition
 - [ ] detect_moderation_labels
 - [ ] detect_protective_equipment
 - [ ] detect_text
+- [ ] disassociate_faces
 - [ ] distribute_dataset_entries
 - [ ] get_celebrity_info
 - [ ] get_celebrity_recognition
@@ -80,10 +84,13 @@ rekognition
 - [ ] list_project_policies
 - [ ] list_stream_processors
 - [ ] list_tags_for_resource
+- [ ] list_users
 - [ ] put_project_policy
 - [ ] recognize_celebrities
 - [ ] search_faces
 - [ ] search_faces_by_image
+- [ ] search_users
+- [ ] search_users_by_image
 - [ ] start_celebrity_recognition
 - [ ] start_content_moderation
 - [ ] start_face_detection
diff --git a/docs/docs/services/signer.rst b/docs/docs/services/signer.rst
index fffac2fae..1cd8e9ed5 100644
--- a/docs/docs/services/signer.rst
+++ b/docs/docs/services/signer.rst
@@ -30,6 +30,7 @@ signer
 - [ ] add_profile_permission
 - [X] cancel_signing_profile
 - [ ] describe_signing_job
+- [ ] get_revocation_status
 - [ ] get_signing_platform
 - [X] get_signing_profile
 - [ ] list_profile_permissions
@@ -49,6 +50,7 @@ signer
 - [ ] remove_profile_permission
 - [ ] revoke_signature
 - [ ] revoke_signing_profile
+- [ ] sign_payload
 - [ ] start_signing_job
 - [ ] tag_resource
 - [ ] untag_resource
diff --git a/docs/docs/services/sqs.rst b/docs/docs/services/sqs.rst
index fed16f5ac..24e4d0bc5 100644
--- a/docs/docs/services/sqs.rst
+++ b/docs/docs/services/sqs.rst
@@ -26,6 +26,7 @@ sqs
 |start-h3| Implemented features for this service |end-h3|
 
 - [X] add_permission
+- [ ] cancel_message_move_task
 - [X] change_message_visibility
 - [X] change_message_visibility_batch
 - [X] create_queue
@@ -35,6 +36,7 @@ sqs
 - [X] get_queue_attributes
 - [X] get_queue_url
 - [X] list_dead_letter_source_queues
+- [ ] list_message_move_tasks
 - [X] list_queue_tags
 - [X] list_queues
 - [X] purge_queue
@@ -43,6 +45,7 @@ sqs
 - [X] send_message
 - [X] send_message_batch
 - [X] set_queue_attributes
+- [ ] start_message_move_task
 - [X] tag_queue
 - [X] untag_queue
 
diff --git a/docs/docs/services/ssm.rst b/docs/docs/services/ssm.rst
index 986dc6f11..85694b13f 100644
--- a/docs/docs/services/ssm.rst
+++ b/docs/docs/services/ssm.rst
@@ -42,7 +42,11 @@ ssm
 
 - [ ] create_ops_item
 - [ ] create_ops_metadata
-- [ ] create_patch_baseline
+- [X] create_patch_baseline
+  
+        Registers a patch baseline. No error handling or input validation has been implemented yet.
+        
+
 - [ ] create_resource_data_sync
 - [ ] delete_activation
 - [ ] delete_association
@@ -56,12 +60,20 @@ ssm
 - [ ] delete_ops_metadata
 - [X] delete_parameter
 - [X] delete_parameters
-- [ ] delete_patch_baseline
+- [X] delete_patch_baseline
+  
+        Assumes the provided BaselineId exists. No error handling has been implemented yet.
+        
+
 - [ ] delete_resource_data_sync
 - [ ] delete_resource_policy
 - [ ] deregister_managed_instance
 - [ ] deregister_patch_baseline_for_patch_group
-- [ ] deregister_target_from_maintenance_window
+- [X] deregister_target_from_maintenance_window
+  
+        Deregisters a target from a maintenance window. No error handling has been implemented yet.
+        
+
 - [ ] deregister_task_from_maintenance_window
 - [ ] describe_activations
 - [ ] describe_association
@@ -88,7 +100,11 @@ ssm
 - [ ] describe_maintenance_window_execution_tasks
 - [ ] describe_maintenance_window_executions
 - [ ] describe_maintenance_window_schedule
-- [ ] describe_maintenance_window_targets
+- [X] describe_maintenance_window_targets
+  
+        Describes all targets for a maintenance window. No error handling has been implemented yet.
+        
+
 - [ ] describe_maintenance_window_tasks
 - [X] describe_maintenance_windows
   
@@ -100,7 +116,11 @@ ssm
 - [ ] describe_maintenance_windows_for_target
 - [ ] describe_ops_items
 - [X] describe_parameters
-- [ ] describe_patch_baselines
+- [X] describe_patch_baselines
+  
+        Returns all baselines. No pagination has been implemented yet.
+        
+
 - [ ] describe_patch_group_state
 - [ ] describe_patch_groups
 - [ ] describe_patch_properties
@@ -166,7 +186,11 @@ ssm
 - [ ] put_resource_policy
 - [ ] register_default_patch_baseline
 - [ ] register_patch_baseline_for_patch_group
-- [ ] register_target_with_maintenance_window
+- [X] register_target_with_maintenance_window
+  
+        Registers a target with a maintenance window. No error handling has been implemented yet.
+        
+
 - [ ] register_task_with_maintenance_window
 - [X] remove_tags_from_resource
 - [ ] reset_service_setting
diff --git a/docs/docs/services/stepfunctions.rst b/docs/docs/services/stepfunctions.rst
index c00c0d9e4..e374ca7e1 100644
--- a/docs/docs/services/stepfunctions.rst
+++ b/docs/docs/services/stepfunctions.rst
@@ -27,8 +27,11 @@ stepfunctions
 
 - [ ] create_activity
 - [X] create_state_machine
+- [ ] create_state_machine_alias
 - [ ] delete_activity
 - [X] delete_state_machine
+- [ ] delete_state_machine_alias
+- [ ] delete_state_machine_version
 - [ ] describe_activity
 - [X] describe_execution
   
@@ -42,6 +45,7 @@ stepfunctions
 
 - [ ] describe_map_run
 - [X] describe_state_machine
+- [ ] describe_state_machine_alias
 - [ ] describe_state_machine_for_execution
 - [ ] get_activity_task
 - [X] get_execution_history
@@ -66,8 +70,11 @@ stepfunctions
         
 
 - [ ] list_map_runs
+- [ ] list_state_machine_aliases
+- [ ] list_state_machine_versions
 - [X] list_state_machines
 - [X] list_tags_for_resource
+- [ ] publish_state_machine_version
 - [ ] send_task_failure
 - [ ] send_task_heartbeat
 - [ ] send_task_success
@@ -78,4 +85,5 @@ stepfunctions
 - [X] untag_resource
 - [ ] update_map_run
 - [X] update_state_machine
+- [ ] update_state_machine_alias
 
diff --git a/moto/s3/models.py b/moto/s3/models.py
index 2d9f56a06..318978927 100644
--- a/moto/s3/models.py
+++ b/moto/s3/models.py
@@ -637,6 +637,47 @@ class LifecycleAndFilter(BaseModel):
         return data
 
 
+class LifecycleTransition(BaseModel):
+    def __init__(
+        self,
+        date: Optional[str] = None,
+        days: Optional[int] = None,
+        storage_class: Optional[str] = None,
+    ):
+        self.date = date
+        self.days = days
+        self.storage_class = storage_class
+
+    def to_config_dict(self) -> Dict[str, Any]:
+        config: Dict[str, Any] = {}
+        if self.date is not None:
+            config["date"] = self.date
+        if self.days is not None:
+            config["days"] = self.days
+        if self.storage_class is not None:
+            config["storageClass"] = self.storage_class
+        return config
+
+
+class LifeCycleNoncurrentVersionTransition(BaseModel):
+    def __init__(
+        self, days: int, storage_class: str, newer_versions: Optional[int] = None
+    ):
+        self.newer_versions = newer_versions
+        self.days = days
+        self.storage_class = storage_class
+
+    def to_config_dict(self) -> Dict[str, Any]:
+        config: Dict[str, Any] = {}
+        if self.newer_versions is not None:
+            config["newerNoncurrentVersions"] = self.newer_versions
+        if self.days is not None:
+            config["noncurrentDays"] = self.days
+        if self.storage_class is not None:
+            config["storageClass"] = self.storage_class
+        return config
+
+
 class LifecycleRule(BaseModel):
     def __init__(
         self,
@@ -646,13 +687,12 @@ class LifecycleRule(BaseModel):
         status: Optional[str] = None,
         expiration_days: Optional[str] = None,
         expiration_date: Optional[str] = None,
-        transition_days: Optional[str] = None,
-        transition_date: Optional[str] = None,
-        storage_class: Optional[str] = None,
+        transitions: Optional[List[LifecycleTransition]] = None,
         expired_object_delete_marker: Optional[str] = None,
         nve_noncurrent_days: Optional[str] = None,
-        nvt_noncurrent_days: Optional[str] = None,
-        nvt_storage_class: Optional[str] = None,
+        noncurrent_version_transitions: Optional[
+            List[LifeCycleNoncurrentVersionTransition]
+        ] = None,
         aimu_days: Optional[str] = None,
     ):
         self.id = rule_id
@@ -661,22 +701,15 @@ class LifecycleRule(BaseModel):
         self.status = status
         self.expiration_days = expiration_days
         self.expiration_date = expiration_date
-        self.transition_days = transition_days
-        self.transition_date = transition_date
-        self.storage_class = storage_class
+        self.transitions = transitions
         self.expired_object_delete_marker = expired_object_delete_marker
         self.nve_noncurrent_days = nve_noncurrent_days
-        self.nvt_noncurrent_days = nvt_noncurrent_days
-        self.nvt_storage_class = nvt_storage_class
+        self.noncurrent_version_transitions = noncurrent_version_transitions
         self.aimu_days = aimu_days
 
     def to_config_dict(self) -> Dict[str, Any]:
         """Converts the object to the AWS Config data dict.
 
-        Note: The following are missing that should be added in the future:
-            - transitions (returns None for now)
-            - noncurrentVersionTransitions (returns None for now)
-
         :param kwargs:
         :return:
         """
@@ -691,10 +724,22 @@ class LifecycleRule(BaseModel):
             "expiredObjectDeleteMarker": self.expired_object_delete_marker,
             "noncurrentVersionExpirationInDays": -1 or int(self.nve_noncurrent_days),  # type: ignore
             "expirationDate": self.expiration_date,
-            "transitions": None,  # Replace me with logic to fill in
-            "noncurrentVersionTransitions": None,  # Replace me with logic to fill in
         }
 
+        if self.transitions:
+            lifecycle_dict["transitions"] = [
+                t.to_config_dict() for t in self.transitions
+            ]
+        else:
+            lifecycle_dict["transitions"] = None
+
+        if self.noncurrent_version_transitions:
+            lifecycle_dict["noncurrentVersionTransitions"] = [
+                t.to_config_dict() for t in self.noncurrent_version_transitions
+            ]
+        else:
+            lifecycle_dict["noncurrentVersionTransitions"] = None
+
         if self.aimu_days:
             lifecycle_dict["abortIncompleteMultipartUpload"] = {
                 "daysAfterInitiation": self.aimu_days
@@ -965,7 +1010,19 @@ class FakeBucket(CloudFormationModel):
         for rule in rules:
             # Extract and validate actions from Lifecycle rule
             expiration = rule.get("Expiration")
-            transition = rule.get("Transition")
+
+            transitions_input = rule.get("Transition", [])
+            if transitions_input and not isinstance(transitions_input, list):
+                transitions_input = [rule.get("Transition")]
+
+            transitions = [
+                LifecycleTransition(
+                    date=transition.get("Date"),
+                    days=transition.get("Days"),
+                    storage_class=transition.get("StorageClass"),
+                )
+                for transition in transitions_input
+            ]
 
             try:
                 top_level_prefix = (
@@ -982,17 +1039,21 @@ class FakeBucket(CloudFormationModel):
                     "NoncurrentDays"
                 ]
 
-            nvt_noncurrent_days = None
-            nvt_storage_class = None
-            if rule.get("NoncurrentVersionTransition") is not None:
-                if rule["NoncurrentVersionTransition"].get("NoncurrentDays") is None:
-                    raise MalformedXML()
-                if rule["NoncurrentVersionTransition"].get("StorageClass") is None:
+            nv_transitions_input = rule.get("NoncurrentVersionTransition", [])
+            if nv_transitions_input and not isinstance(nv_transitions_input, list):
+                nv_transitions_input = [rule.get("NoncurrentVersionTransition")]
+
+            noncurrent_version_transitions = []
+            for nvt in nv_transitions_input:
+                if nvt.get("NoncurrentDays") is None or nvt.get("StorageClass") is None:
                     raise MalformedXML()
-                nvt_noncurrent_days = rule["NoncurrentVersionTransition"][
-                    "NoncurrentDays"
-                ]
-                nvt_storage_class = rule["NoncurrentVersionTransition"]["StorageClass"]
+
+                transition = LifeCycleNoncurrentVersionTransition(
+                    newer_versions=nvt.get("NewerNoncurrentVersions"),
+                    days=nvt.get("NoncurrentDays"),
+                    storage_class=nvt.get("StorageClass"),
+                )
+                noncurrent_version_transitions.append(transition)
 
             aimu_days = None
             if rule.get("AbortIncompleteMultipartUpload") is not None:
@@ -1085,15 +1146,10 @@ class FakeBucket(CloudFormationModel):
                     status=rule["Status"],
                     expiration_days=expiration.get("Days") if expiration else None,
                     expiration_date=expiration.get("Date") if expiration else None,
-                    transition_days=transition.get("Days") if transition else None,
-                    transition_date=transition.get("Date") if transition else None,
-                    storage_class=transition.get("StorageClass")
-                    if transition
-                    else None,
+                    transitions=transitions,
                     expired_object_delete_marker=eodm,
                     nve_noncurrent_days=nve_noncurrent_days,
-                    nvt_noncurrent_days=nvt_noncurrent_days,
-                    nvt_storage_class=nvt_storage_class,
+                    noncurrent_version_transitions=noncurrent_version_transitions,
                     aimu_days=aimu_days,
                 )
             )
@@ -2317,7 +2373,6 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
 
                     for key in bucket.keys.getlist(key_name):
                         if str(key.version_id) == str(version_id):
-
                             if (
                                 hasattr(key, "is_locked")
                                 and key.is_locked
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
index 3d8a5a5ec..d9dc5ad77 100644
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -2465,17 +2465,19 @@ S3_BUCKET_LIFECYCLE_CONFIGURATION = """<?xml version="1.0" encoding="UTF-8"?>
             {% endif %}
         {% endif %}
         <Status>{{ rule.status }}</Status>
-        {% if rule.storage_class %}
-        <Transition>
-            {% if rule.transition_days %}
-               <Days>{{ rule.transition_days }}</Days>
-            {% endif %}
-            {% if rule.transition_date %}
-               <Date>{{ rule.transition_date }}</Date>
-            {% endif %}
-           <StorageClass>{{ rule.storage_class }}</StorageClass>
-        </Transition>
-        {% endif %}
+        {% for transition in rule.transitions %}
+            <Transition>
+                {% if transition.days %}
+                <Days>{{ transition.days }}</Days>
+                {% endif %}
+                {% if transition.date %}
+                <Date>{{ transition.date }}</Date>
+                {% endif %}
+                {% if transition.storage_class %}
+                <StorageClass>{{ transition.storage_class }}</StorageClass>
+                {% endif %}
+            </Transition>
+        {% endfor %}
         {% if rule.expiration_days or rule.expiration_date or rule.expired_object_delete_marker %}
         <Expiration>
             {% if rule.expiration_days %}
@@ -2489,12 +2491,19 @@ S3_BUCKET_LIFECYCLE_CONFIGURATION = """<?xml version="1.0" encoding="UTF-8"?>
             {% endif %}
         </Expiration>
         {% endif %}
-        {% if rule.nvt_noncurrent_days and rule.nvt_storage_class %}
-        <NoncurrentVersionTransition>
-           <NoncurrentDays>{{ rule.nvt_noncurrent_days }}</NoncurrentDays>
-           <StorageClass>{{ rule.nvt_storage_class }}</StorageClass>
-        </NoncurrentVersionTransition>
-        {% endif %}
+        {% for nvt in rule.noncurrent_version_transitions %}
+            <NoncurrentVersionTransition>
+                {% if nvt.newer_versions %}
+                <NewerNoncurrentVersions>{{ nvt.newer_versions }}</NewerNoncurrentVersions>
+                {% endif %}
+                {% if nvt.days %}
+                <NoncurrentDays>{{ nvt.days }}</NoncurrentDays>
+                {% endif %}
+                {% if nvt.storage_class %}
+                <StorageClass>{{ nvt.storage_class }}</StorageClass>
+                {% endif %}
+            </NoncurrentVersionTransition>
+        {% endfor %}
         {% if rule.nve_noncurrent_days %}
         <NoncurrentVersionExpiration>
            <NoncurrentDays>{{ rule.nve_noncurrent_days }}</NoncurrentDays>


Test patch:
diff --git a/tests/test_s3/test_s3_config.py b/tests/test_s3/test_s3_config.py
index 50e9ab71c..d38a3eb31 100644
--- a/tests/test_s3/test_s3_config.py
+++ b/tests/test_s3/test_s3_config.py
@@ -12,7 +12,6 @@ s3_config_query_backend = s3_config_query.backends[DEFAULT_ACCOUNT_ID]["global"]
 
 @mock_s3
 def test_s3_public_access_block_to_config_dict():
-
     # With 1 bucket in us-west-2:
     s3_config_query_backend.create_bucket("bucket1", "us-west-2")
 
@@ -48,7 +47,6 @@ def test_s3_public_access_block_to_config_dict():
 
 @mock_s3
 def test_list_config_discovered_resources():
-
     # Without any buckets:
     assert s3_config_query.list_config_service_resources(
         "global", "global", None, None, 100, None
@@ -173,6 +171,18 @@ def test_s3_lifecycle_config_dict():
             "Filter": {"Prefix": ""},
             "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 1},
         },
+        {
+            "ID": "rule5",
+            "Status": "Enabled",
+            "Filter": {"Prefix": ""},
+            "Transition": [{"Days": 10, "StorageClass": "GLACIER"}],
+            "NoncurrentVersionTransition": [
+                {
+                    "NoncurrentDays": 10,
+                    "StorageClass": "GLACIER",
+                }
+            ],
+        },
     ]
     s3_config_query_backend.put_bucket_lifecycle("bucket1", lifecycle)
 
@@ -253,6 +263,22 @@ def test_s3_lifecycle_config_dict():
         "filter": {"predicate": {"type": "LifecyclePrefixPredicate", "prefix": ""}},
     }
 
+    assert lifecycles[4] == {
+        "id": "rule5",
+        "prefix": None,
+        "status": "Enabled",
+        "expirationInDays": None,
+        "expiredObjectDeleteMarker": None,
+        "noncurrentVersionExpirationInDays": -1,
+        "expirationDate": None,
+        "abortIncompleteMultipartUpload": None,
+        "filter": {"predicate": {"type": "LifecyclePrefixPredicate", "prefix": ""}},
+        "transitions": [{"days": 10, "storageClass": "GLACIER"}],
+        "noncurrentVersionTransitions": [
+            {"noncurrentDays": 10, "storageClass": "GLACIER"}
+        ],
+    }
+
 
 @mock_s3
 def test_s3_notification_config_dict():
diff --git a/tests/test_s3/test_s3_lifecycle.py b/tests/test_s3/test_s3_lifecycle.py
index 76df2b405..15dee4a39 100644
--- a/tests/test_s3/test_s3_lifecycle.py
+++ b/tests/test_s3/test_s3_lifecycle.py
@@ -376,6 +376,76 @@ def test_lifecycle_with_nvt():
     assert err.value.response["Error"]["Code"] == "MalformedXML"
 
 
+@mock_s3
+def test_lifecycle_with_multiple_nvt():
+    client = boto3.client("s3")
+    client.create_bucket(
+        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
+    )
+
+    lfc = {
+        "Rules": [
+            {
+                "NoncurrentVersionTransitions": [
+                    {"NoncurrentDays": 30, "StorageClass": "ONEZONE_IA"},
+                    {"NoncurrentDays": 50, "StorageClass": "GLACIER"},
+                ],
+                "ID": "wholebucket",
+                "Filter": {"Prefix": ""},
+                "Status": "Enabled",
+            }
+        ]
+    }
+    client.put_bucket_lifecycle_configuration(
+        Bucket="bucket", LifecycleConfiguration=lfc
+    )
+    result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
+    assert len(result["Rules"]) == 1
+    assert result["Rules"][0]["NoncurrentVersionTransitions"][0] == {
+        "NoncurrentDays": 30,
+        "StorageClass": "ONEZONE_IA",
+    }
+    assert result["Rules"][0]["NoncurrentVersionTransitions"][1] == {
+        "NoncurrentDays": 50,
+        "StorageClass": "GLACIER",
+    }
+
+
+@mock_s3
+def test_lifecycle_with_multiple_transitions():
+    client = boto3.client("s3")
+    client.create_bucket(
+        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
+    )
+
+    lfc = {
+        "Rules": [
+            {
+                "Transitions": [
+                    {"Days": 30, "StorageClass": "ONEZONE_IA"},
+                    {"Days": 50, "StorageClass": "GLACIER"},
+                ],
+                "ID": "wholebucket",
+                "Filter": {"Prefix": ""},
+                "Status": "Enabled",
+            }
+        ]
+    }
+    client.put_bucket_lifecycle_configuration(
+        Bucket="bucket", LifecycleConfiguration=lfc
+    )
+    result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
+    assert len(result["Rules"]) == 1
+    assert result["Rules"][0]["Transitions"][0] == {
+        "Days": 30,
+        "StorageClass": "ONEZONE_IA",
+    }
+    assert result["Rules"][0]["Transitions"][1] == {
+        "Days": 50,
+        "StorageClass": "GLACIER",
+    }
+
+
 @mock_s3
 def test_lifecycle_with_aimu():
     client = boto3.client("s3")