Repository: getmoto/moto
Pull request #8902 (2025-05-15 13:00:09)

SQS: Return MessageGroupId (and similar attributes) on receive_messages
In our tests we were missing the MessageGroupId which AWS SQS returns when specified in the `MessageSystemAttributeNames` parameters of `receive_message`. See [boto3 documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs/client/receive_message.html).

We added support for returning the MessageGroupId and several other system attributes and added tests for those as well.


Patch:
diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md
index ec9c35299..38c0c03d9 100644
--- a/IMPLEMENTATION_COVERAGE.md
+++ b/IMPLEMENTATION_COVERAGE.md
@@ -22,7 +22,7 @@
 
 ## acm-pca
 <details>
-<summary>69% implemented</summary>
+<summary>73% implemented</summary>
 
 - [X] create_certificate_authority
 - [ ] create_certificate_authority_audit_report
@@ -38,7 +38,7 @@
 - [X] get_policy
 - [X] import_certificate_authority_certificate
 - [X] issue_certificate
-- [ ] list_certificate_authorities
+- [X] list_certificate_authorities
 - [ ] list_permissions
 - [X] list_tags
 - [X] put_policy
@@ -51,7 +51,7 @@
 
 ## amp
 <details>
-<summary>62% implemented</summary>
+<summary>58% implemented</summary>
 
 - [ ] create_alert_manager_definition
 - [X] create_logging_configuration
@@ -68,6 +68,7 @@
 - [X] describe_rule_groups_namespace
 - [ ] describe_scraper
 - [X] describe_workspace
+- [ ] describe_workspace_configuration
 - [ ] get_default_scraper_configuration
 - [X] list_rule_groups_namespaces
 - [ ] list_scrapers
@@ -80,6 +81,7 @@
 - [X] update_logging_configuration
 - [ ] update_scraper
 - [X] update_workspace_alias
+- [ ] update_workspace_configuration
 </details>
 
 ## apigateway
@@ -1169,20 +1171,25 @@
 
 ## cloudfront
 <details>
-<summary>18% implemented</summary>
+<summary>15% implemented</summary>
 
 - [ ] associate_alias
+- [ ] associate_distribution_tenant_web_acl
+- [ ] associate_distribution_web_acl
 - [ ] copy_distribution
 - [ ] create_anycast_ip_list
 - [ ] create_cache_policy
 - [ ] create_cloud_front_origin_access_identity
+- [ ] create_connection_group
 - [ ] create_continuous_deployment_policy
 - [X] create_distribution
+- [ ] create_distribution_tenant
 - [X] create_distribution_with_tags
 - [ ] create_field_level_encryption_config
 - [ ] create_field_level_encryption_profile
 - [ ] create_function
 - [X] create_invalidation
+- [ ] create_invalidation_for_distribution_tenant
 - [X] create_key_group
 - [ ] create_key_value_store
 - [ ] create_monitoring_subscription
@@ -1197,8 +1204,10 @@
 - [ ] delete_anycast_ip_list
 - [ ] delete_cache_policy
 - [ ] delete_cloud_front_origin_access_identity
+- [ ] delete_connection_group
 - [ ] delete_continuous_deployment_policy
 - [X] delete_distribution
+- [ ] delete_distribution_tenant
 - [ ] delete_field_level_encryption_config
 - [ ] delete_field_level_encryption_profile
 - [ ] delete_function
@@ -1214,23 +1223,31 @@
 - [ ] delete_vpc_origin
 - [ ] describe_function
 - [ ] describe_key_value_store
+- [ ] disassociate_distribution_tenant_web_acl
+- [ ] disassociate_distribution_web_acl
 - [ ] get_anycast_ip_list
 - [ ] get_cache_policy
 - [ ] get_cache_policy_config
 - [ ] get_cloud_front_origin_access_identity
 - [ ] get_cloud_front_origin_access_identity_config
+- [ ] get_connection_group
+- [ ] get_connection_group_by_routing_endpoint
 - [ ] get_continuous_deployment_policy
 - [ ] get_continuous_deployment_policy_config
 - [X] get_distribution
 - [X] get_distribution_config
+- [ ] get_distribution_tenant
+- [ ] get_distribution_tenant_by_domain
 - [ ] get_field_level_encryption
 - [ ] get_field_level_encryption_config
 - [ ] get_field_level_encryption_profile
 - [ ] get_field_level_encryption_profile_config
 - [ ] get_function
 - [X] get_invalidation
+- [ ] get_invalidation_for_distribution_tenant
 - [X] get_key_group
 - [ ] get_key_group_config
+- [ ] get_managed_certificate_details
 - [ ] get_monitoring_subscription
 - [X] get_origin_access_control
 - [ ] get_origin_access_control_config
@@ -1248,20 +1265,26 @@
 - [ ] list_cache_policies
 - [ ] list_cloud_front_origin_access_identities
 - [ ] list_conflicting_aliases
+- [ ] list_connection_groups
 - [ ] list_continuous_deployment_policies
+- [ ] list_distribution_tenants
+- [ ] list_distribution_tenants_by_customization
 - [X] list_distributions
 - [ ] list_distributions_by_anycast_ip_list_id
 - [ ] list_distributions_by_cache_policy_id
+- [ ] list_distributions_by_connection_mode
 - [ ] list_distributions_by_key_group
 - [ ] list_distributions_by_origin_request_policy_id
 - [ ] list_distributions_by_realtime_log_config
 - [ ] list_distributions_by_response_headers_policy_id
 - [ ] list_distributions_by_vpc_origin_id
 - [ ] list_distributions_by_web_acl_id
+- [ ] list_domain_conflicts
 - [ ] list_field_level_encryption_configs
 - [ ] list_field_level_encryption_profiles
 - [ ] list_functions
 - [X] list_invalidations
+- [ ] list_invalidations_for_distribution_tenant
 - [X] list_key_groups
 - [ ] list_key_value_stores
 - [X] list_origin_access_controls
@@ -1278,9 +1301,12 @@
 - [ ] untag_resource
 - [ ] update_cache_policy
 - [ ] update_cloud_front_origin_access_identity
+- [ ] update_connection_group
 - [ ] update_continuous_deployment_policy
 - [X] update_distribution
+- [ ] update_distribution_tenant
 - [ ] update_distribution_with_staging_config
+- [ ] update_domain_association
 - [ ] update_field_level_encryption_config
 - [ ] update_field_level_encryption_profile
 - [ ] update_function
@@ -1293,6 +1319,7 @@
 - [ ] update_response_headers_policy
 - [ ] update_streaming_distribution
 - [ ] update_vpc_origin
+- [ ] verify_dns_configuration
 </details>
 
 ## cloudhsmv2
@@ -1779,6 +1806,7 @@
 - [ ] get_identity_provider_by_identifier
 - [ ] get_log_delivery_configuration
 - [ ] get_signing_certificate
+- [ ] get_tokens_from_refresh_token
 - [ ] get_ui_customization
 - [X] get_user
 - [ ] get_user_attribute_verification_code
@@ -2020,6 +2048,34 @@
 - [X] untag_resource
 </details>
 
+## connectcampaigns
+<details>
+<summary>22% implemented</summary>
+
+- [X] create_campaign
+- [X] delete_campaign
+- [ ] delete_connect_instance_config
+- [ ] delete_instance_onboarding_job
+- [X] describe_campaign
+- [ ] get_campaign_state
+- [ ] get_campaign_state_batch
+- [X] get_connect_instance_config
+- [ ] get_instance_onboarding_job_status
+- [ ] list_campaigns
+- [ ] list_tags_for_resource
+- [ ] pause_campaign
+- [ ] put_dial_request_batch
+- [ ] resume_campaign
+- [ ] start_campaign
+- [X] start_instance_onboarding_job
+- [ ] stop_campaign
+- [ ] tag_resource
+- [ ] untag_resource
+- [ ] update_campaign_dialer_config
+- [ ] update_campaign_name
+- [ ] update_campaign_outbound_call_config
+</details>
+
 ## databrew
 <details>
 <summary>54% implemented</summary>
@@ -2459,13 +2515,14 @@
 
 ## dsql
 <details>
-<summary>20% implemented</summary>
+<summary>18% implemented</summary>
 
 - [X] create_cluster
 - [ ] create_multi_region_clusters
 - [ ] delete_cluster
 - [ ] delete_multi_region_clusters
 - [X] get_cluster
+- [ ] get_vpc_endpoint_service_name
 - [ ] list_clusters
 - [ ] list_tags_for_resource
 - [ ] tag_resource
@@ -2560,7 +2617,7 @@
 
 ## ec2
 <details>
-<summary>31% implemented</summary>
+<summary>30% implemented</summary>
 
 - [ ] accept_address_transfer
 - [ ] accept_capacity_reservation_billing_ownership
@@ -2655,6 +2712,8 @@
 - [ ] create_local_gateway_route_table
 - [ ] create_local_gateway_route_table_virtual_interface_group_association
 - [ ] create_local_gateway_route_table_vpc_association
+- [ ] create_local_gateway_virtual_interface
+- [ ] create_local_gateway_virtual_interface_group
 - [X] create_managed_prefix_list
 - [X] create_nat_gateway
 - [X] create_network_acl
@@ -2736,6 +2795,8 @@
 - [ ] delete_local_gateway_route_table
 - [ ] delete_local_gateway_route_table_virtual_interface_group_association
 - [ ] delete_local_gateway_route_table_vpc_association
+- [ ] delete_local_gateway_virtual_interface
+- [ ] delete_local_gateway_virtual_interface_group
 - [X] delete_managed_prefix_list
 - [X] delete_nat_gateway
 - [X] delete_network_acl
@@ -2888,6 +2949,7 @@
 - [ ] describe_network_interface_attribute
 - [ ] describe_network_interface_permissions
 - [X] describe_network_interfaces
+- [ ] describe_outpost_lags
 - [ ] describe_placement_groups
 - [ ] describe_prefix_lists
 - [ ] describe_principal_id_format
@@ -2908,6 +2970,7 @@
 - [X] describe_security_group_rules
 - [ ] describe_security_group_vpc_associations
 - [X] describe_security_groups
+- [ ] describe_service_link_virtual_interfaces
 - [ ] describe_snapshot_attribute
 - [ ] describe_snapshot_tier_status
 - [X] describe_snapshots
@@ -3304,7 +3367,7 @@
 
 ## ecs
 <details>
-<summary>74% implemented</summary>
+<summary>73% implemented</summary>
 
 - [X] create_capacity_provider
 - [X] create_cluster
@@ -3350,6 +3413,7 @@
 - [X] register_task_definition
 - [X] run_task
 - [X] start_task
+- [ ] stop_service_deployment
 - [X] stop_task
 - [ ] submit_attachment_state_changes
 - [ ] submit_container_state_change
@@ -5213,7 +5277,7 @@
 
 ## kinesis
 <details>
-<summary>93% implemented</summary>
+<summary>85% implemented</summary>
 
 - [X] add_tags_to_stream
 - [X] create_stream
@@ -5234,6 +5298,7 @@
 - [X] list_shards
 - [X] list_stream_consumers
 - [X] list_streams
+- [ ] list_tags_for_resource
 - [X] list_tags_for_stream
 - [X] merge_shards
 - [X] put_record
@@ -5245,6 +5310,8 @@
 - [X] start_stream_encryption
 - [X] stop_stream_encryption
 - [ ] subscribe_to_shard
+- [ ] tag_resource
+- [ ] untag_resource
 - [X] update_shard_count
 - [X] update_stream_mode
 </details>
@@ -6079,13 +6146,14 @@
 
 ## mq
 <details>
-<summary>82% implemented</summary>
+<summary>79% implemented</summary>
 
 - [X] create_broker
 - [X] create_configuration
 - [X] create_tags
 - [X] create_user
 - [X] delete_broker
+- [ ] delete_configuration
 - [X] delete_tags
 - [X] delete_user
 - [X] describe_broker
@@ -7115,7 +7183,7 @@
 
 ## ram
 <details>
-<summary>14% implemented</summary>
+<summary>17% implemented</summary>
 
 - [ ] accept_resource_share_invitation
 - [ ] associate_resource_share
@@ -7131,7 +7199,7 @@
 - [X] enable_sharing_with_aws_organization
 - [ ] get_permission
 - [ ] get_resource_policies
-- [ ] get_resource_share_associations
+- [X] get_resource_share_associations
 - [ ] get_resource_share_invitations
 - [X] get_resource_shares
 - [ ] list_pending_invitation_resources
@@ -8156,7 +8224,7 @@
 
 ## s3tables
 <details>
-<summary>53% implemented</summary>
+<summary>46% implemented</summary>
 
 - [X] create_namespace
 - [X] create_table
@@ -8164,13 +8232,16 @@
 - [X] delete_namespace
 - [X] delete_table
 - [X] delete_table_bucket
+- [ ] delete_table_bucket_encryption
 - [ ] delete_table_bucket_policy
 - [ ] delete_table_policy
 - [X] get_namespace
 - [X] get_table
 - [X] get_table_bucket
+- [ ] get_table_bucket_encryption
 - [ ] get_table_bucket_maintenance_configuration
 - [ ] get_table_bucket_policy
+- [ ] get_table_encryption
 - [ ] get_table_maintenance_configuration
 - [ ] get_table_maintenance_job_status
 - [ ] get_table_metadata_location
@@ -8178,6 +8249,7 @@
 - [X] list_namespaces
 - [X] list_table_buckets
 - [X] list_tables
+- [ ] put_table_bucket_encryption
 - [ ] put_table_bucket_maintenance_configuration
 - [ ] put_table_bucket_policy
 - [ ] put_table_maintenance_configuration
@@ -9293,6 +9365,7 @@
 - [ ] describe_patch_properties
 - [ ] describe_sessions
 - [ ] disassociate_ops_item_related_item
+- [ ] get_access_token
 - [ ] get_automation_execution
 - [ ] get_calendar_state
 - [X] get_command_invocation
@@ -9352,6 +9425,7 @@
 - [ ] resume_session
 - [ ] send_automation_signal
 - [X] send_command
+- [ ] start_access_request
 - [ ] start_associations_once
 - [ ] start_automation_execution
 - [ ] start_change_request_execution
@@ -10098,7 +10172,6 @@
 - compute-optimizer
 - connect
 - connect-contact-lens
-- connectcampaigns
 - connectcampaignsv2
 - connectcases
 - connectparticipant
@@ -10264,6 +10337,7 @@
 - snowball
 - socialmessaging
 - ssm-contacts
+- ssm-guiconnect
 - ssm-incidents
 - ssm-quicksetup
 - ssm-sap
diff --git a/docs/docs/services/acm-pca.rst b/docs/docs/services/acm-pca.rst
index ab2cf0d00..1079e8fdb 100644
--- a/docs/docs/services/acm-pca.rst
+++ b/docs/docs/services/acm-pca.rst
@@ -51,7 +51,11 @@ acm-pca
         Some fields of the resulting certificate will have default values, instead of using the CSR
         
 
-- [ ] list_certificate_authorities
+- [X] list_certificate_authorities
+  
+        Lists the private certificate authorities that you created by using the CreateCertificateAuthority action.
+        
+
 - [ ] list_permissions
 - [X] list_tags
   
diff --git a/docs/docs/services/amp.rst b/docs/docs/services/amp.rst
index 016e4dbfb..471e3ec1a 100644
--- a/docs/docs/services/amp.rst
+++ b/docs/docs/services/amp.rst
@@ -47,6 +47,7 @@ amp
 - [X] describe_rule_groups_namespace
 - [ ] describe_scraper
 - [X] describe_workspace
+- [ ] describe_workspace_configuration
 - [ ] get_default_scraper_configuration
 - [X] list_rule_groups_namespaces
 - [ ] list_scrapers
@@ -67,4 +68,5 @@ amp
         The ClientToken-parameter is not yet implemented
         
 
+- [ ] update_workspace_configuration
 
diff --git a/docs/docs/services/cloudfront.rst b/docs/docs/services/cloudfront.rst
index 4a9c0f636..93bdaf7bf 100644
--- a/docs/docs/services/cloudfront.rst
+++ b/docs/docs/services/cloudfront.rst
@@ -15,10 +15,13 @@ cloudfront
 |start-h3| Implemented features for this service |end-h3|
 
 - [ ] associate_alias
+- [ ] associate_distribution_tenant_web_acl
+- [ ] associate_distribution_web_acl
 - [ ] copy_distribution
 - [ ] create_anycast_ip_list
 - [ ] create_cache_policy
 - [ ] create_cloud_front_origin_access_identity
+- [ ] create_connection_group
 - [ ] create_continuous_deployment_policy
 - [X] create_distribution
   
@@ -27,11 +30,13 @@ cloudfront
         use-case.
         
 
+- [ ] create_distribution_tenant
 - [X] create_distribution_with_tags
 - [ ] create_field_level_encryption_config
 - [ ] create_field_level_encryption_profile
 - [ ] create_function
 - [X] create_invalidation
+- [ ] create_invalidation_for_distribution_tenant
 - [X] create_key_group
 - [ ] create_key_value_store
 - [ ] create_monitoring_subscription
@@ -46,6 +51,7 @@ cloudfront
 - [ ] delete_anycast_ip_list
 - [ ] delete_cache_policy
 - [ ] delete_cloud_front_origin_access_identity
+- [ ] delete_connection_group
 - [ ] delete_continuous_deployment_policy
 - [X] delete_distribution
   
@@ -53,6 +59,7 @@ cloudfront
         Calling this function without a value is invalid, per AWS' behaviour
         
 
+- [ ] delete_distribution_tenant
 - [ ] delete_field_level_encryption_config
 - [ ] delete_field_level_encryption_profile
 - [ ] delete_function
@@ -76,23 +83,31 @@ cloudfront
 - [ ] delete_vpc_origin
 - [ ] describe_function
 - [ ] describe_key_value_store
+- [ ] disassociate_distribution_tenant_web_acl
+- [ ] disassociate_distribution_web_acl
 - [ ] get_anycast_ip_list
 - [ ] get_cache_policy
 - [ ] get_cache_policy_config
 - [ ] get_cloud_front_origin_access_identity
 - [ ] get_cloud_front_origin_access_identity_config
+- [ ] get_connection_group
+- [ ] get_connection_group_by_routing_endpoint
 - [ ] get_continuous_deployment_policy
 - [ ] get_continuous_deployment_policy_config
 - [X] get_distribution
 - [X] get_distribution_config
+- [ ] get_distribution_tenant
+- [ ] get_distribution_tenant_by_domain
 - [ ] get_field_level_encryption
 - [ ] get_field_level_encryption_config
 - [ ] get_field_level_encryption_profile
 - [ ] get_field_level_encryption_profile_config
 - [ ] get_function
 - [X] get_invalidation
+- [ ] get_invalidation_for_distribution_tenant
 - [X] get_key_group
 - [ ] get_key_group_config
+- [ ] get_managed_certificate_details
 - [ ] get_monitoring_subscription
 - [X] get_origin_access_control
 - [ ] get_origin_access_control_config
@@ -110,7 +125,10 @@ cloudfront
 - [ ] list_cache_policies
 - [ ] list_cloud_front_origin_access_identities
 - [ ] list_conflicting_aliases
+- [ ] list_connection_groups
 - [ ] list_continuous_deployment_policies
+- [ ] list_distribution_tenants
+- [ ] list_distribution_tenants_by_customization
 - [X] list_distributions
   
         Pagination is not supported yet.
@@ -118,12 +136,14 @@ cloudfront
 
 - [ ] list_distributions_by_anycast_ip_list_id
 - [ ] list_distributions_by_cache_policy_id
+- [ ] list_distributions_by_connection_mode
 - [ ] list_distributions_by_key_group
 - [ ] list_distributions_by_origin_request_policy_id
 - [ ] list_distributions_by_realtime_log_config
 - [ ] list_distributions_by_response_headers_policy_id
 - [ ] list_distributions_by_vpc_origin_id
 - [ ] list_distributions_by_web_acl_id
+- [ ] list_domain_conflicts
 - [ ] list_field_level_encryption_configs
 - [ ] list_field_level_encryption_profiles
 - [ ] list_functions
@@ -132,6 +152,7 @@ cloudfront
         Pagination is not yet implemented
         
 
+- [ ] list_invalidations_for_distribution_tenant
 - [X] list_key_groups
   
         Pagination is not yet implemented
@@ -160,6 +181,7 @@ cloudfront
 - [ ] untag_resource
 - [ ] update_cache_policy
 - [ ] update_cloud_front_origin_access_identity
+- [ ] update_connection_group
 - [ ] update_continuous_deployment_policy
 - [X] update_distribution
   
@@ -167,7 +189,9 @@ cloudfront
         Calling this function without a value is invalid, per AWS' behaviour
         
 
+- [ ] update_distribution_tenant
 - [ ] update_distribution_with_staging_config
+- [ ] update_domain_association
 - [ ] update_field_level_encryption_config
 - [ ] update_field_level_encryption_profile
 - [ ] update_function
@@ -184,4 +208,5 @@ cloudfront
 - [ ] update_response_headers_policy
 - [ ] update_streaming_distribution
 - [ ] update_vpc_origin
+- [ ] verify_dns_configuration
 
diff --git a/docs/docs/services/cognito-idp.rst b/docs/docs/services/cognito-idp.rst
index b36f71d62..564919126 100644
--- a/docs/docs/services/cognito-idp.rst
+++ b/docs/docs/services/cognito-idp.rst
@@ -94,6 +94,7 @@ cognito-idp
 - [ ] get_identity_provider_by_identifier
 - [ ] get_log_delivery_configuration
 - [ ] get_signing_certificate
+- [ ] get_tokens_from_refresh_token
 - [ ] get_ui_customization
 - [X] get_user
 - [ ] get_user_attribute_verification_code
diff --git a/docs/docs/services/connectcampaigns.rst b/docs/docs/services/connectcampaigns.rst
new file mode 100644
index 000000000..3b10d80e7
--- /dev/null
+++ b/docs/docs/services/connectcampaigns.rst
@@ -0,0 +1,39 @@
+.. _implementedservice_connectcampaigns:
+
+.. |start-h3| raw:: html
+
+    <h3>
+
+.. |end-h3| raw:: html
+
+    </h3>
+
+================
+connectcampaigns
+================
+
+|start-h3| Implemented features for this service |end-h3|
+
+- [X] create_campaign
+- [X] delete_campaign
+- [ ] delete_connect_instance_config
+- [ ] delete_instance_onboarding_job
+- [X] describe_campaign
+- [ ] get_campaign_state
+- [ ] get_campaign_state_batch
+- [X] get_connect_instance_config
+- [ ] get_instance_onboarding_job_status
+- [ ] list_campaigns
+- [ ] list_tags_for_resource
+- [ ] pause_campaign
+- [ ] put_dial_request_batch
+- [ ] resume_campaign
+- [ ] start_campaign
+- [X] start_instance_onboarding_job
+- [ ] stop_campaign
+- [ ] tag_resource
+- [ ] untag_resource
+- [ ] update_campaign_dialer_config
+- [ ] update_campaign_name
+- [ ] update_campaign_outbound_call_config
+
diff --git a/docs/docs/services/dsql.rst b/docs/docs/services/dsql.rst
index 02bdadf65..06a589c17 100644
--- a/docs/docs/services/dsql.rst
+++ b/docs/docs/services/dsql.rst
@@ -21,6 +21,7 @@ dsql
 - [ ] delete_cluster
 - [ ] delete_multi_region_clusters
 - [X] get_cluster
+- [ ] get_vpc_endpoint_service_name
 - [ ] list_clusters
 - [ ] list_tags_for_resource
 - [ ] tag_resource
diff --git a/docs/docs/services/ec2.rst b/docs/docs/services/ec2.rst
index 70dbc12ad..96ae2907b 100644
--- a/docs/docs/services/ec2.rst
+++ b/docs/docs/services/ec2.rst
@@ -109,6 +109,8 @@ ec2
 - [ ] create_local_gateway_route_table
 - [ ] create_local_gateway_route_table_virtual_interface_group_association
 - [ ] create_local_gateway_route_table_vpc_association
+- [ ] create_local_gateway_virtual_interface
+- [ ] create_local_gateway_virtual_interface_group
 - [X] create_managed_prefix_list
 - [X] create_nat_gateway
 - [X] create_network_acl
@@ -194,6 +196,8 @@ ec2
 - [ ] delete_local_gateway_route_table
 - [ ] delete_local_gateway_route_table_virtual_interface_group_association
 - [ ] delete_local_gateway_route_table_vpc_association
+- [ ] delete_local_gateway_virtual_interface
+- [ ] delete_local_gateway_virtual_interface_group
 - [X] delete_managed_prefix_list
 - [X] delete_nat_gateway
 - [X] delete_network_acl
@@ -359,6 +363,7 @@ ec2
 - [ ] describe_network_interface_attribute
 - [ ] describe_network_interface_permissions
 - [X] describe_network_interfaces
+- [ ] describe_outpost_lags
 - [ ] describe_placement_groups
 - [ ] describe_prefix_lists
 - [ ] describe_principal_id_format
@@ -379,6 +384,7 @@ ec2
 - [X] describe_security_group_rules
 - [ ] describe_security_group_vpc_associations
 - [X] describe_security_groups
+- [ ] describe_service_link_virtual_interfaces
 - [ ] describe_snapshot_attribute
 - [ ] describe_snapshot_tier_status
 - [X] describe_snapshots
diff --git a/docs/docs/services/ecs.rst b/docs/docs/services/ecs.rst
index 325e1fd41..91f6b1a5e 100644
--- a/docs/docs/services/ecs.rst
+++ b/docs/docs/services/ecs.rst
@@ -86,6 +86,7 @@ ecs
 - [X] register_task_definition
 - [X] run_task
 - [X] start_task
+- [ ] stop_service_deployment
 - [X] stop_task
 - [ ] submit_attachment_state_changes
 - [ ] submit_container_state_change
diff --git a/docs/docs/services/kinesis.rst b/docs/docs/services/kinesis.rst
index cae31fc63..eff51d9b6 100644
--- a/docs/docs/services/kinesis.rst
+++ b/docs/docs/services/kinesis.rst
@@ -45,6 +45,7 @@ kinesis
         
 
 - [X] list_streams
+- [ ] list_tags_for_resource
 - [X] list_tags_for_stream
 - [X] merge_shards
 - [X] put_record
@@ -60,6 +61,8 @@ kinesis
 - [X] start_stream_encryption
 - [X] stop_stream_encryption
 - [ ] subscribe_to_shard
+- [ ] tag_resource
+- [ ] untag_resource
 - [X] update_shard_count
 - [X] update_stream_mode
 
diff --git a/docs/docs/services/mq.rst b/docs/docs/services/mq.rst
index 41b08faaf..a3970df21 100644
--- a/docs/docs/services/mq.rst
+++ b/docs/docs/services/mq.rst
@@ -21,6 +21,7 @@ mq
 - [X] create_tags
 - [X] create_user
 - [X] delete_broker
+- [ ] delete_configuration
 - [X] delete_tags
 - [X] delete_user
 - [X] describe_broker
diff --git a/docs/docs/services/ram.rst b/docs/docs/services/ram.rst
index f78561123..546f9704d 100644
--- a/docs/docs/services/ram.rst
+++ b/docs/docs/services/ram.rst
@@ -28,7 +28,7 @@ ram
 - [X] enable_sharing_with_aws_organization
 - [ ] get_permission
 - [ ] get_resource_policies
-- [ ] get_resource_share_associations
+- [X] get_resource_share_associations
 - [ ] get_resource_share_invitations
 - [X] get_resource_shares
 - [ ] list_pending_invitation_resources
diff --git a/docs/docs/services/s3tables.rst b/docs/docs/services/s3tables.rst
index 4ad3d48ca..03e0a72fd 100644
--- a/docs/docs/services/s3tables.rst
+++ b/docs/docs/services/s3tables.rst
@@ -22,13 +22,16 @@ s3tables
 - [X] delete_namespace
 - [X] delete_table
 - [X] delete_table_bucket
+- [ ] delete_table_bucket_encryption
 - [ ] delete_table_bucket_policy
 - [ ] delete_table_policy
 - [X] get_namespace
 - [X] get_table
 - [X] get_table_bucket
+- [ ] get_table_bucket_encryption
 - [ ] get_table_bucket_maintenance_configuration
 - [ ] get_table_bucket_policy
+- [ ] get_table_encryption
 - [ ] get_table_maintenance_configuration
 - [ ] get_table_maintenance_job_status
 - [ ] get_table_metadata_location
@@ -36,6 +39,7 @@ s3tables
 - [X] list_namespaces
 - [X] list_table_buckets
 - [X] list_tables
+- [ ] put_table_bucket_encryption
 - [ ] put_table_bucket_maintenance_configuration
 - [ ] put_table_bucket_policy
 - [ ] put_table_maintenance_configuration
diff --git a/docs/docs/services/ssm.rst b/docs/docs/services/ssm.rst
index 89ad40030..6a710fce6 100644
--- a/docs/docs/services/ssm.rst
+++ b/docs/docs/services/ssm.rst
@@ -117,6 +117,7 @@ ssm
 - [ ] describe_patch_properties
 - [ ] describe_sessions
 - [ ] disassociate_ops_item_related_item
+- [ ] get_access_token
 - [ ] get_automation_execution
 - [ ] get_calendar_state
 - [X] get_command_invocation
@@ -190,6 +191,7 @@ ssm
 - [ ] resume_session
 - [ ] send_automation_signal
 - [X] send_command
+- [ ] start_access_request
 - [ ] start_associations_once
 - [ ] start_automation_execution
 - [ ] start_change_request_execution
diff --git a/docs/docs/services/textract.rst b/docs/docs/services/textract.rst
index df84f8847..7ca7df723 100644
--- a/docs/docs/services/textract.rst
+++ b/docs/docs/services/textract.rst
@@ -45,7 +45,7 @@ textract
 
 - [X] start_document_text_detection
   
-        The following parameters have not yet been implemented: ClientRequestToken, JobTag, NotificationChannel, OutputConfig, KmsKeyID
+        The following parameters have not yet been implemented: ClientRequestToken, JobTag, OutputConfig, KmsKeyID
         
 
 - [ ] start_expense_analysis
diff --git a/moto/acmpca/models.py b/moto/acmpca/models.py
index 428fb2037..a5351271b 100644
--- a/moto/acmpca/models.py
+++ b/moto/acmpca/models.py
@@ -1,6 +1,7 @@
 """ACMPCABackend class with methods for supported APIs."""
 
 import base64
+import contextlib
 import datetime
 from typing import Any, Dict, List, Optional, Tuple, cast
 
@@ -248,13 +249,16 @@ class CertificateAuthority(BaseModel):
                 ]
             )
 
-        cn = csr.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME)
-        if cn:
+        # Subject Alternative Name passthrough from CSR to the new certificate
+        with contextlib.suppress(x509.ExtensionNotFound):
+            san = csr.extensions.get_extension_for_oid(
+                x509.ExtensionOID.SUBJECT_ALTERNATIVE_NAME
+            )
             extensions.append(
                 (
-                    x509.SubjectAlternativeName([x509.DNSName(cn[0].value)]),  # type: ignore[arg-type]
-                    False,
-                ),
+                    san.value,
+                    san.critical,
+                )
             )
 
         return extensions
diff --git a/moto/apigateway/models.py b/moto/apigateway/models.py
index 438f126f2..2f8562b87 100644
--- a/moto/apigateway/models.py
+++ b/moto/apigateway/models.py
@@ -2198,10 +2198,14 @@ class APIGatewayBackend(BaseBackend):
         return self.keys[api_key_id]
 
     def update_api_key(self, api_key_id: str, patch_operations: Any) -> ApiKey:
+        if api_key_id not in self.keys:
+            raise ApiKeyNotFoundException()
         key = self.keys[api_key_id]
         return key.update_operations(patch_operations)
 
     def delete_api_key(self, api_key_id: str) -> None:
+        if api_key_id not in self.keys:
+            raise ApiKeyNotFoundException()
         self.keys.pop(api_key_id)
 
     def create_usage_plan(self, payload: Any) -> UsagePlan:
diff --git a/moto/backend_index.py b/moto/backend_index.py
index 6fa4b41e2..4ce527433 100644
--- a/moto/backend_index.py
+++ b/moto/backend_index.py
@@ -42,6 +42,10 @@ backend_url_patterns = [
     ("cognitoidp", re.compile("https?://cognito-idp\\.(.+)\\.amazonaws.com")),
     ("comprehend", re.compile("https?://comprehend\\.(.+)\\.amazonaws\\.com")),
     ("config", re.compile("https?://config\\.(.+)\\.amazonaws\\.com")),
+    (
+        "connectcampaigns",
+        re.compile("https?://connect-campaigns\\.(.+)\\.amazonaws\\.com"),
+    ),
     ("databrew", re.compile("https?://databrew\\.(.+)\\.amazonaws.com")),
     ("datapipeline", re.compile("https?://datapipeline\\.(.+)\\.amazonaws\\.com")),
     ("datasync", re.compile("https?://(.*\\.)?(datasync)\\.(.+)\\.amazonaws.com")),
diff --git a/moto/cloudwatch/models.py b/moto/cloudwatch/models.py
index c98dd9d6b..150871f97 100644
--- a/moto/cloudwatch/models.py
+++ b/moto/cloudwatch/models.py
@@ -24,7 +24,11 @@ from .exceptions import (
     ValidationError,
 )
 from .metric_data_expression_parser import parse_expression
-from .utils import make_arn_for_alarm, make_arn_for_dashboard
+from .utils import (
+    make_arn_for_alarm,
+    make_arn_for_dashboard,
+    make_arn_for_rule,
+)
 
 _EMPTY_LIST: Any = tuple()
 
@@ -433,6 +437,25 @@ class Statistics:
         )
 
 
+class InsightRule(BaseModel):
+    def __init__(
+        self,
+        account_id: str,
+        region_name: str,
+        definition: str,
+        name: str,
+        state: str,
+        schema: Optional[str],
+        managed_rule: Optional[bool],
+    ):
+        self.definition = definition
+        self.name = name
+        self.schema = schema or '{"Name" : "CloudWatchLogRule", "Version" : 1}'
+        self.state = state
+        self.managed_rule = managed_rule or False
+        self.rule_arn = make_arn_for_rule(region_name, account_id, name)
+
+
 class CloudWatchBackend(BaseBackend):
     def __init__(self, region_name: str, account_id: str):
         super().__init__(region_name, account_id)
@@ -440,6 +463,7 @@ class CloudWatchBackend(BaseBackend):
         self.dashboards: Dict[str, Dashboard] = {}
         self.metric_data: List[MetricDatumBase] = []
         self.paged_metric_data: Dict[str, List[MetricDatumBase]] = {}
+        self.insight_rules: Dict[str, InsightRule] = {}
         self.tagger = TaggingService()
 
     @property
@@ -1012,5 +1036,97 @@ class CloudWatchBackend(BaseBackend):
                         f'Missing required parameter in MetricData[{query_num}].StatisticValues: "{stat}"'
                     )
 
+    def put_insight_rule(
+        self,
+        name: str,
+        state: str,
+        definition: str,
+        tags: Optional[List[Dict[str, str]]] = None,
+    ) -> InsightRule:
+        rule = InsightRule(
+            account_id=self.account_id,
+            region_name=self.region_name,
+            definition=definition,
+            name=name,
+            state=state,
+            schema='{"Name" : "CloudWatchLogRule", "Version" : 1}',
+            managed_rule=False,
+        )
+        if tags:
+            self.tagger.tag_resource(rule.rule_arn, tags)
+
+        self.insight_rules[name] = rule
+
+        return rule
+
+    def describe_insight_rules(
+        self,
+        next_token: Optional[str] = "",
+        max_results: Optional[int] = 500,
+    ) -> List[InsightRule]:
+        rules = list(self.insight_rules.values())
+
+        if max_results is None or len(rules) <= max_results:
+            return rules
+
+        return rules[:max_results]
+
+    def delete_insight_rules(self, rule_names: List[str]) -> List[Dict[str, Any]]:
+        failures = []
+        for rule_name in list(self.insight_rules.keys()):
+            if rule_name in rule_names:
+                rule = self.insight_rules.get(rule_name)
+                if rule and rule.managed_rule:
+                    failures.append(
+                        {
+                            "FailureResource": rule_name,
+                            "ExceptionType": "InvalidParameterValue",
+                            "FailureCode": 400,
+                            "FailureDescription": "The value of an input parameter is bad or out-of-range.",
+                        }
+                    )
+                else:
+                    del self.insight_rules[rule_name]
+
+        return failures
+
+    def disable_insight_rules(self, rule_names: List[str]) -> List[Dict[str, Any]]:
+        failures = []
+        for rule_name in list(self.insight_rules.keys()):
+            if rule_name in rule_names:
+                rule = self.insight_rules.get(rule_name)
+                if rule and rule.managed_rule:
+                    failures.append(
+                        {
+                            "FailureResource": rule_name,
+                            "ExceptionType": "InvalidParameterValue",
+                            "FailureCode": 400,
+                            "FailureDescription": "The value of an input parameter is bad or out-of-range.",
+                        }
+                    )
+                else:
+                    self.insight_rules[rule_name].state = "DISABLED"
+
+        return failures
+
+    def enable_insight_rules(self, rule_names: List[str]) -> List[Dict[str, Any]]:
+        failures = []
+        for rule_name in list(self.insight_rules.keys()):
+            if rule_name in rule_names:
+                rule = self.insight_rules.get(rule_name)
+                if rule and rule.managed_rule:
+                    failures.append(
+                        {
+                            "FailureResource": rule_name,
+                            "ExceptionType": "InvalidParameterValue",
+                            "FailureCode": 400,
+                            "FailureDescription": "The value of an input parameter is bad or out-of-range.",
+                        }
+                    )
+                else:
+                    self.insight_rules[rule_name].state = "ENABLED"
+
+        return failures
+
 
 cloudwatch_backends = BackendDict(CloudWatchBackend, "cloudwatch")
diff --git a/moto/cloudwatch/responses.py b/moto/cloudwatch/responses.py
index 40d7d3c9c..0f646f117 100644
--- a/moto/cloudwatch/responses.py
+++ b/moto/cloudwatch/responses.py
@@ -340,6 +340,54 @@ class CloudWatchResponse(BaseResponse):
         template = self.response_template(UNTAG_RESOURCE_TEMPLATE)
         return template.render()
 
+    def put_insight_rule(self) -> str:
+        name = self._get_param("RuleName")
+        state = self._get_param("RuleState")
+        definition = self._get_param("RuleDefinition")
+        tags = self._get_multi_param("Tags.member")
+
+        rule = self.cloudwatch_backend.put_insight_rule(
+            name=name,
+            state=state,
+            definition=definition,
+            tags=tags,
+        )
+
+        template = self.response_template(PUT_INSIGHT_RULE_TEMPLATE)
+        return template.render(rule=rule)
+
+    def describe_insight_rules(self) -> str:
+        rules = self.cloudwatch_backend.describe_insight_rules()
+        next_token = self._get_param("NextToken")
+
+        template = self.response_template(DESCRIBE_INSIGHT_RULES_TEMPLATE)
+
+        return template.render(next_token=next_token, rules=rules)
+
+    def delete_insight_rules(self) -> str:
+        names = self._get_multi_param("RuleNames.member")
+        failures = self.cloudwatch_backend.delete_insight_rules(rule_names=names)
+
+        template = self.response_template(DELETE_INSIGHT_RULES_TEMPLATE)
+
+        return template.render(failures=failures)
+
+    def disable_insight_rules(self) -> str:
+        names = self._get_multi_param("RuleNames.member")
+        rule_names = self.cloudwatch_backend.disable_insight_rules(rule_names=names)
+
+        template = self.response_template(DISABLE_INSIGHT_RULES_TEMPLATE)
+
+        return template.render(rule_names=rule_names)
+
+    def enable_insight_rules(self) -> str:
+        names = self._get_multi_param("RuleNames.member")
+        rule_names = self.cloudwatch_backend.enable_insight_rules(rule_names=names)
+
+        template = self.response_template(ENABLE_INSIGHT_RULES_TEMPLATE)
+
+        return template.render(rule_names=rule_names)
+
 
 PUT_METRIC_ALARM_TEMPLATE = """<PutMetricAlarmResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
    <ResponseMetadata>
@@ -736,3 +784,72 @@ UNTAG_RESOURCE_TEMPLATE = """<UntagResourceResponse xmlns="http://monitoring.ama
     <RequestId>{{ request_id }}</RequestId>
   </ResponseMetadata>
 </UntagResourceResponse>"""
+
+PUT_INSIGHT_RULE_TEMPLATE = """<PutInsightRuleResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
+   <PutInsightRuleResult></PutInsightRuleResult>
+   <ResponseMetadata>
+      <RequestId>{{ request_id }}</RequestId>
+   </ResponseMetadata>
+</PutInsightRuleResponse>"""
+
+DESCRIBE_INSIGHT_RULES_TEMPLATE = """<DescribeInsightRulesResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
+    <DescribeInsightRulesResult>
+        <NextToken> {{next_token}} </NextToken>
+        <InsightRules>
+            {% for rule in rules %}
+            <member>
+                <Name>{{ rule.name }}</Name>
+                <State>{{ rule.state }}</State>
+                <Schema>{{ rule.schema }}</Schema>
+                <Definition>{{ rule.definition }}</Definition>
+                <ManagedRule>{{ rule.managed_rule }}</ManagedRule>
+            </member>
+            {% endfor %}
+        </InsightRules>
+    </DescribeInsightRulesResult>
+</DescribeInsightRulesResponse>"""
+
+DELETE_INSIGHT_RULES_TEMPLATE = """<DeleteInsightRulesResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
+    <DeleteInsightRulesResult>
+        <Failures>
+            {% for failure in failures %}
+            <member>
+                <FailureResource>{{ failure.FailureResource }}</FailureResource>
+                <ExceptionType>{{ failure.ExceptionType }}</ExceptionType>
+                <FailureCode>{{ failure.FailureCode }}</FailureCode>
+                <FailureDescription>{{ failure.FailureDescription }}</FailureDescription>
+            </member>
+            {% endfor %}
+        </Failures>
+    </DeleteInsightRulesResult>
+</DeleteInsightRulesResponse>"""
+
+DISABLE_INSIGHT_RULES_TEMPLATE = """<DisableInsightRulesResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
+    <DisableInsightRulesResult>
+        <Failures>
+            {% for failure in failures %}
+            <member>
+                <FailureResource>{{ failure.FailureResource }}</FailureResource>
+                <ExceptionType>{{ failure.ExceptionType }}</ExceptionType>
+                <FailureCode>{{ failure.FailureCode }}</FailureCode>
+                <FailureDescription>{{ failure.FailureDescription }}</FailureDescription>
+            </member>
+            {% endfor %}
+        </Failures>
+    </DisableInsightRulesResult>
+</DisableInsightRulesResponse>"""
+
+ENABLE_INSIGHT_RULES_TEMPLATE = """<EnableInsightRulesResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
+    <EnableInsightRulesResult>
+        <Failures>
+            {% for failure in failures %}
+            <member>
+                <FailureResource>{{ failure.FailureResource }}</FailureResource>
+                <ExceptionType>{{ failure.ExceptionType }}</ExceptionType>
+                <FailureCode>{{ failure.FailureCode }}</FailureCode>
+                <FailureDescription>{{ failure.FailureDescription }}</FailureDescription>
+            </member>
+            {% endfor %}
+        </Failures>
+    </EnableInsightRulesResult>
+</EnableInsightRulesResponse>"""
diff --git a/moto/cloudwatch/utils.py b/moto/cloudwatch/utils.py
index 539410446..4b70e7ba0 100644
--- a/moto/cloudwatch/utils.py
+++ b/moto/cloudwatch/utils.py
@@ -7,3 +7,7 @@ def make_arn_for_dashboard(account_id: str, region_name: str, name: str) -> str:
 
 def make_arn_for_alarm(region: str, account_id: str, alarm_name: str) -> str:
     return f"arn:{get_partition(region)}:cloudwatch:{region}:{account_id}:alarm:{alarm_name}"
+
+
+def make_arn_for_rule(region: str, account_id: str, rule_name: str) -> str:
+    return f"arn:{get_partition(region)}:cloudwatch:{region}:{account_id}:insight-rule/{rule_name}"
diff --git a/moto/codedeploy/models.py b/moto/codedeploy/models.py
index 14976f5e6..80199a9e0 100644
--- a/moto/codedeploy/models.py
+++ b/moto/codedeploy/models.py
@@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional
 from moto.core.base_backend import BackendDict, BaseBackend
 from moto.core.common_models import BaseModel
 from moto.core.utils import iso_8601_datetime_with_milliseconds
+from moto.utilities.tagging_service import TaggingService
 
 from .exceptions import (
     ApplicationAlreadyExistsException,
@@ -109,7 +110,7 @@ class DeploymentGroup(BaseModel):
         self.ec2_tag_set = ec2_tag_set or {}
         self.ecs_services = ecs_services or []
         self.on_premises_tag_set = on_premises_tag_set or {}
-        self.tags = tags
+        self.tags = tags or []
         self.termination_hook_enabled = termination_hook_enabled
         self.deployment_group_id = str(uuid.uuid4())
 
@@ -242,6 +243,7 @@ class CodeDeployBackend(BaseBackend):
         self.applications: Dict[str, Application] = {}
         self.deployments: Dict[str, DeploymentInfo] = {}
         self.deployment_groups: Dict[str, Dict[str, DeploymentGroup]] = {}
+        self.tagger = TaggingService()
 
     def get_application(self, application_name: str) -> Application:
         if application_name not in self.applications:
@@ -302,6 +304,11 @@ class CodeDeployBackend(BaseBackend):
 
         app = Application(application_name, compute_platform, tags)
         self.applications[app.application_name] = app
+
+        if tags:
+            app_arn = f"arn:aws:codedeploy:{self.region_name}:{self.account_id}:application:{application_name}"
+            self.tagger.tag_resource(app_arn, tags)
+
         return app.id
 
     def create_deployment(
@@ -362,6 +369,14 @@ class CodeDeployBackend(BaseBackend):
         )
 
         self.deployments[deployment.deployment_id] = deployment
+
+        deployment_arn = f"arn:aws:codedeploy:{self.region_name}:{self.account_id}:deployment:{deployment.deployment_id}"
+        if self.deployment_groups[application_name][deployment_group_name].tags:
+            self.tagger.tag_resource(
+                deployment_arn,
+                self.deployment_groups[application_name][deployment_group_name].tags,
+            )
+
         return deployment.deployment_id
 
     # TODO support all optional fields
@@ -427,6 +442,10 @@ class CodeDeployBackend(BaseBackend):
             self.deployment_groups[application_name] = {}
         self.deployment_groups[application_name][dg.deployment_group_name] = dg
 
+        if tags:
+            dg_arn = f"arn:aws:codedeploy:{self.region_name}:{self.account_id}:deploymentgroup:{application_name}/{deployment_group_name}"
+            self.tagger.tag_resource(dg_arn, tags)
+
         return dg.deployment_group_id
 
     # TODO: implement pagination
@@ -492,5 +511,20 @@ class CodeDeployBackend(BaseBackend):
             for deployment_group in self.deployment_groups[application_name].values()
         ]
 
+    def list_tags_for_resource(
+        self, resource_arn: str
+    ) -> Dict[str, List[Dict[str, str]]]:
+        return self.tagger.list_tags_for_resource(resource_arn)
+
+    def tag_resource(
+        self, resource_arn: str, tags: List[Dict[str, str]]
+    ) -> Dict[str, Any]:
+        self.tagger.tag_resource(resource_arn, tags)
+        return {}
+
+    def untag_resource(self, resource_arn: str, tag_keys: List[str]) -> Dict[str, Any]:
+        self.tagger.untag_resource_using_names(resource_arn, tag_keys)
+        return {}
+
 
 codedeploy_backends = BackendDict(CodeDeployBackend, "codedeploy")
diff --git a/moto/codedeploy/responses.py b/moto/codedeploy/responses.py
index 24f4df486..5d523dabb 100644
--- a/moto/codedeploy/responses.py
+++ b/moto/codedeploy/responses.py
@@ -185,3 +185,23 @@ class CodeDeployResponse(BaseResponse):
                 nextToken=next_token,
             )
         )
+
+    def list_tags_for_resource(self) -> str:
+        """Handler for list_tags_for_resource API call."""
+        resource_arn = self._get_param("ResourceArn")
+        tags_response = self.codedeploy_backend.list_tags_for_resource(resource_arn)
+        return json.dumps(tags_response)
+
+    def tag_resource(self) -> str:
+        """Handler for tag_resource API call."""
+        resource_arn = self._get_param("ResourceArn")
+        tags = self._get_param("Tags")
+        response = self.codedeploy_backend.tag_resource(resource_arn, tags)
+        return json.dumps(response)
+
+    def untag_resource(self) -> str:
+        """Handler for untag_resource API call."""
+        resource_arn = self._get_param("ResourceArn")
+        tag_keys = self._get_param("TagKeys")
+        response = self.codedeploy_backend.untag_resource(resource_arn, tag_keys)
+        return json.dumps(response)
diff --git a/moto/codedeploy/urls.py b/moto/codedeploy/urls.py
index afd141339..f37d6c967 100644
--- a/moto/codedeploy/urls.py
+++ b/moto/codedeploy/urls.py
@@ -8,4 +8,7 @@ url_bases = [
 
 url_paths = {
     "{0}/$": CodeDeployResponse.dispatch,
+    "{0}/list-tags-for-resource$": CodeDeployResponse.list_tags_for_resource,
+    "{0}/tag-resource$": CodeDeployResponse.tag_resource,
+    "{0}/untag-resource$": CodeDeployResponse.untag_resource,
 }
diff --git a/moto/connectcampaigns/__init__.py b/moto/connectcampaigns/__init__.py
new file mode 100644
index 000000000..d83b5f7d2
--- /dev/null
+++ b/moto/connectcampaigns/__init__.py
@@ -0,0 +1,1 @@
+from .models import connectcampaigns_backends  # noqa: F401
diff --git a/moto/connectcampaigns/exceptions.py b/moto/connectcampaigns/exceptions.py
new file mode 100644
index 000000000..06f065ea6
--- /dev/null
+++ b/moto/connectcampaigns/exceptions.py
@@ -0,0 +1,21 @@
+"""Exceptions raised by the connectcampaigns service."""
+
+from moto.core.exceptions import JsonRESTError
+
+
+class ResourceNotFoundException(JsonRESTError):
+    """When a resource is not found."""
+
+    code = 404
+
+    def __init__(self, message: str) -> None:
+        super().__init__("ResourceNotFoundException", message)
+
+
+class ValidationException(JsonRESTError):
+    """When validation fails on input parameters."""
+
+    code = 400
+
+    def __init__(self, message: str) -> None:
+        super().__init__("ValidationException", message)
diff --git a/moto/connectcampaigns/models.py b/moto/connectcampaigns/models.py
new file mode 100644
index 000000000..3dc5c29c5
--- /dev/null
+++ b/moto/connectcampaigns/models.py
@@ -0,0 +1,189 @@
+"""ConnectCampaignServiceBackend class with methods for supported APIs."""
+
+import uuid
+from typing import Any, Dict, Optional, Tuple
+
+from moto.core import DEFAULT_ACCOUNT_ID
+from moto.core.base_backend import BackendDict, BaseBackend
+from moto.core.common_models import BaseModel
+
+from .exceptions import ResourceNotFoundException, ValidationException
+
+
+class ConnectCampaign(BaseModel):
+    def __init__(
+        self,
+        name: str,
+        connect_instance_id: str,
+        dialer_config: Dict[str, Any],
+        outbound_call_config: Dict[str, Any],
+        region: str,
+        tags: Optional[Dict[str, str]] = None,
+    ) -> None:
+        self.id = str(uuid.uuid4())
+        self.name = name
+        self.connect_instance_id = connect_instance_id
+        self.dialer_config = dialer_config
+        self.outbound_call_config = outbound_call_config
+        self.region = region
+        self.tags = tags or {}
+        self.arn = f"arn:aws:connectcampaigns:{self.region}:{DEFAULT_ACCOUNT_ID}:campaign/{self.id}"
+
+    def to_dict(self) -> Dict[str, Any]:
+        return {
+            "id": self.id,
+            "arn": self.arn,
+            "name": self.name,
+            "connectInstanceId": self.connect_instance_id,
+            "dialerConfig": self.dialer_config,
+            "outboundCallConfig": self.outbound_call_config,
+            "tags": self.tags,
+        }
+
+
+class ConnectInstanceConfig(BaseModel):
+    def __init__(
+        self, connect_instance_id: str, region: str, encryption_enabled: bool = False
+    ) -> None:
+        self.connect_instance_id = connect_instance_id
+        self.region = region
+        self.service_linked_role_arn = f"arn:aws:iam::{DEFAULT_ACCOUNT_ID}:role/aws-service-role/connectcampaigns.amazonaws.com/AWSServiceRoleForConnectCampaigns"
+
+        self.encryption_config = {
+            "enabled": encryption_enabled,
+            "encryptionType": "KMS",
+        }
+
+        if encryption_enabled:
+            self.encryption_config["keyArn"] = (
+                f"arn:aws:kms:{region}:{DEFAULT_ACCOUNT_ID}:key/1234abcd-12ab-34cd-56ef-1234567890ab"
+            )
+
+    def to_dict(self) -> Dict[str, Any]:
+        return {
+            "connectInstanceId": self.connect_instance_id,
+            "serviceLinkedRoleArn": self.service_linked_role_arn,
+            "encryptionConfig": self.encryption_config,
+        }
+
+
+class ConnectInstanceOnboardingJobStatus(BaseModel):
+    def __init__(
+        self,
+        connect_instance_id: str,
+        status: str = "SUCCEEDED",
+        failure_code: Optional[str] = None,
+    ) -> None:
+        self.connect_instance_id = connect_instance_id
+        self.status = status
+        self.failure_code = failure_code
+
+    def to_dict(self) -> Dict[str, Any]:
+        result = {"connectInstanceId": self.connect_instance_id, "status": self.status}
+
+        if self.failure_code and self.status == "FAILED":
+            result["failureCode"] = self.failure_code
+
+        return result
+
+
+class ConnectCampaignServiceBackend(BaseBackend):
+    def __init__(self, region_name: str, account_id: str) -> None:
+        super().__init__(region_name, account_id)
+        self.campaigns: Dict[str, ConnectCampaign] = {}
+        self.instance_configs: Dict[str, ConnectInstanceConfig] = {}
+        self.onboarding_jobs: Dict[str, ConnectInstanceOnboardingJobStatus] = {}
+
+    def create_campaign(
+        self,
+        name: str,
+        connect_instance_id: str,
+        dialer_config: Dict[str, Any],
+        outbound_call_config: Dict[str, Any],
+        tags: Optional[Dict[str, str]],
+    ) -> Tuple[str, str, Dict[str, str]]:
+        campaign = ConnectCampaign(
+            name=name,
+            connect_instance_id=connect_instance_id,
+            dialer_config=dialer_config,
+            outbound_call_config=outbound_call_config,
+            region=self.region_name,
+            tags=tags,
+        )
+        self.campaigns[campaign.id] = campaign
+        return campaign.id, campaign.arn, campaign.tags
+
+    def delete_campaign(self, id: str) -> None:
+        del self.campaigns[id]
+
+    def describe_campaign(self, id: str) -> Dict[str, Any]:
+        if id not in self.campaigns:
+            raise ResourceNotFoundException(f"Campaign with id {id} not found")
+
+        campaign = self.campaigns[id]
+        return campaign.to_dict()
+
+    def get_connect_instance_config(self, connect_instance_id: str) -> Dict[str, Any]:
+        if not connect_instance_id:
+            raise ValidationException("connectInstanceId is a required parameter")
+
+        if connect_instance_id == "invalid-id":
+            raise ResourceNotFoundException(
+                f"Connect instance with id {connect_instance_id} not found"
+            )
+
+        if connect_instance_id in self.instance_configs:
+            return self.instance_configs[connect_instance_id].to_dict()
+
+        instance_config = ConnectInstanceConfig(
+            connect_instance_id=connect_instance_id, region=self.region_name
+        )
+        self.instance_configs[connect_instance_id] = instance_config
+
+        return instance_config.to_dict()
+
+    def start_instance_onboarding_job(
+        self, connect_instance_id: str, encryption_config: Dict[str, Any]
+    ) -> Dict[str, Any]:
+        if not connect_instance_id:
+            raise ValidationException("connectInstanceId is a required parameter")
+
+        if connect_instance_id == "invalid-id":
+            raise ResourceNotFoundException(
+                f"Connect instance with id {connect_instance_id} not found"
+            )
+
+        if not encryption_config:
+            raise ValidationException("encryptionConfig is a required parameter")
+
+        if "enabled" not in encryption_config:
+            raise ValidationException(
+                "enabled is a required parameter in encryptionConfig"
+            )
+
+        if encryption_config.get("enabled") and "keyArn" not in encryption_config:
+            raise ValidationException("keyArn is required when encryption is enabled")
+
+        job_status = ConnectInstanceOnboardingJobStatus(
+            connect_instance_id=connect_instance_id
+        )
+
+        self.onboarding_jobs[connect_instance_id] = job_status
+
+        instance_config = ConnectInstanceConfig(
+            connect_instance_id=connect_instance_id,
+            region=self.region_name,
+            encryption_enabled=encryption_config.get("enabled", False),
+        )
+
+        if encryption_config.get("enabled") and "keyArn" in encryption_config:
+            instance_config.encryption_config["keyArn"] = encryption_config["keyArn"]
+
+        self.instance_configs[connect_instance_id] = instance_config
+
+        return job_status.to_dict()
+
+
+connectcampaigns_backends = BackendDict(
+    ConnectCampaignServiceBackend, "connectcampaigns"
+)
diff --git a/moto/connectcampaigns/responses.py b/moto/connectcampaigns/responses.py
new file mode 100644
index 000000000..91bdc0336
--- /dev/null
+++ b/moto/connectcampaigns/responses.py
@@ -0,0 +1,87 @@
+"""Handles incoming connectcampaigns requests, invokes methods, returns responses."""
+
+import json
+
+from moto.core.responses import BaseResponse
+
+from .models import ConnectCampaignServiceBackend, connectcampaigns_backends
+
+
+class ConnectCampaignServiceResponse(BaseResponse):
+    """Handler for ConnectCampaignService requests and responses."""
+
+    def __init__(self) -> None:
+        super().__init__(service_name="connectcampaigns")
+
+    @property
+    def connectcampaigns_backend(self) -> ConnectCampaignServiceBackend:
+        """Return backend instance specific for this region."""
+        return connectcampaigns_backends[self.current_account][self.region]
+
+    def create_campaign(self) -> str:
+        params = json.loads(self.body)
+        name = params.get("name")
+        connect_instance_id = params.get("connectInstanceId")
+        dialer_config = params.get("dialerConfig")
+        outbound_call_config = params.get("outboundCallConfig")
+        tags = params.get("tags", {})
+
+        id, arn, tags = self.connectcampaigns_backend.create_campaign(
+            name=name,
+            connect_instance_id=connect_instance_id,
+            dialer_config=dialer_config,
+            outbound_call_config=outbound_call_config,
+            tags=tags,
+        )
+
+        response = {"id": id, "arn": arn, "tags": tags}
+
+        return json.dumps(response)
+
+    def delete_campaign(self) -> str:
+        id = self.path.split("/")[-1]
+
+        self.connectcampaigns_backend.delete_campaign(
+            id=id,
+        )
+
+        return "{}"
+
+    def describe_campaign(self) -> str:
+        id = self.path.split("/")[-1]
+
+        campaign_details = self.connectcampaigns_backend.describe_campaign(
+            id=id,
+        )
+
+        response = {"campaign": campaign_details}
+
+        return json.dumps(response)
+
+    def get_connect_instance_config(self) -> str:
+        connect_instance_id = self.path.split("/")[-2]
+
+        connect_instance_config = (
+            self.connectcampaigns_backend.get_connect_instance_config(
+                connect_instance_id=connect_instance_id,
+            )
+        )
+
+        response = {"connectInstanceConfig": connect_instance_config}
+
+        return json.dumps(response)
+
+    def start_instance_onboarding_job(self) -> str:
+        connect_instance_id = self.path.split("/")[-2]
+
+        params = json.loads(self.body) if self.body else {}
+        encryption_config = params.get("encryptionConfig", {})
+
+        job_status = self.connectcampaigns_backend.start_instance_onboarding_job(
+            connect_instance_id=connect_instance_id,
+            encryption_config=encryption_config,
+        )
+
+        response = {"connectInstanceOnboardingJobStatus": job_status}
+
+        return json.dumps(response)
diff --git a/moto/connectcampaigns/urls.py b/moto/connectcampaigns/urls.py
new file mode 100644
index 000000000..fd20423f7
--- /dev/null
+++ b/moto/connectcampaigns/urls.py
@@ -0,0 +1,14 @@
+"""connectcampaigns base URL and path."""
+
+from .responses import ConnectCampaignServiceResponse
+
+url_bases = [
+    r"https?://connect-campaigns\.(.+)\.amazonaws\.com",
+]
+
+url_paths = {
+    "{0}/campaigns$": ConnectCampaignServiceResponse.dispatch,
+    "{0}/campaigns/(?P<id>[^/]+)$": ConnectCampaignServiceResponse.dispatch,
+    "{0}/connect-instance/(?P<connectInstanceId>[^/]+)/config$": ConnectCampaignServiceResponse.dispatch,
+    "{0}/connect-instance/(?P<connectInstanceId>[^/]+)/onboarding$": ConnectCampaignServiceResponse.dispatch,
+}
diff --git a/moto/ec2/resources/instance_type_offerings/availability-zone-id/ap-southeast-2.json b/moto/ec2/resources/instance_type_offerings/availability-zone-id/ap-southeast-2.json
index ba315692a..38f783825 100644
--- a/moto/ec2/resources/instance_type_offerings/availability-zone-id/ap-southeast-2.json
+++ b/moto/ec2/resources/instance_type_offerings/availability-zone-id/ap-southeast-2.json
@@ -6431,6 +6431,30 @@
   "InstanceType": "i3en.xlarge",
   "Location": "apse2-az3"
  },
+ {
+  "InstanceType": "i4g.16xlarge",
+  "Location": "apse2-az3"
+ },
+ {
+  "InstanceType": "i4g.2xlarge",
+  "Location": "apse2-az3"
+ },
+ {
+  "InstanceType": "i4g.4xlarge",
+  "Location": "apse2-az3"
+ },
+ {
+  "InstanceType": "i4g.8xlarge",
+  "Location": "apse2-az3"
+ },
+ {
+  "InstanceType": "i4g.large",
+  "Location": "apse2-az3"
+ },
+ {
+  "InstanceType": "i4g.xlarge",
+  "Location": "apse2-az3"
+ },
  {
   "InstanceType": "i4i.12xlarge",
   "Location": "apse2-az3"
diff --git a/moto/ec2/resources/instance_type_offerings/availability-zone-id/eu-south-2.json b/moto/ec2/resources/instance_type_offerings/availability-zone-id/eu-south-2.json
index 86b9c70d6..a1877271d 100644
--- a/moto/ec2/resources/instance_type_offerings/availability-zone-id/eu-south-2.json
+++ b/moto/ec2/resources/instance_type_offerings/availability-zone-id/eu-south-2.json
@@ -1031,6 +1031,10 @@
   "InstanceType": "m8g.xlarge",
   "Location": "eus2-az1"
  },
+ {
+  "InstanceType": "p5en.48xlarge",
+  "Location": "eus2-az1"
+ },
  {
   "InstanceType": "r5.12xlarge",
   "Location": "eus2-az1"
diff --git a/moto/ec2/resources/instance_type_offerings/availability-zone-id/us-west-2.json b/moto/ec2/resources/instance_type_offerings/availability-zone-id/us-west-2.json
index 3bea3b779..7dd485534 100644
--- a/moto/ec2/resources/instance_type_offerings/availability-zone-id/us-west-2.json
+++ b/moto/ec2/resources/instance_type_offerings/availability-zone-id/us-west-2.json
@@ -12547,6 +12547,10 @@
   "InstanceType": "p5en.48xlarge",
   "Location": "usw2-az4"
  },
+ {
+  "InstanceType": "p6-b200.48xlarge",
+  "Location": "usw2-az4"
+ },
  {
   "InstanceType": "r5.12xlarge",
   "Location": "usw2-az4"
diff --git a/moto/ec2/resources/instance_type_offerings/availability-zone/ap-southeast-2.json b/moto/ec2/resources/instance_type_offerings/availability-zone/ap-southeast-2.json
index 45b32162f..c25366c0d 100644
--- a/moto/ec2/resources/instance_type_offerings/availability-zone/ap-southeast-2.json
+++ b/moto/ec2/resources/instance_type_offerings/availability-zone/ap-southeast-2.json
@@ -831,6 +831,30 @@
   "InstanceType": "i3en.xlarge",
   "Location": "ap-southeast-2a"
  },
+ {
+  "InstanceType": "i4g.16xlarge",
+  "Location": "ap-southeast-2a"
+ },
+ {
+  "InstanceType": "i4g.2xlarge",
+  "Location": "ap-southeast-2a"
+ },
+ {
+  "InstanceType": "i4g.4xlarge",
+  "Location": "ap-southeast-2a"
+ },
+ {
+  "InstanceType": "i4g.8xlarge",
+  "Location": "ap-southeast-2a"
+ },
+ {
+  "InstanceType": "i4g.large",
+  "Location": "ap-southeast-2a"
+ },
+ {
+  "InstanceType": "i4g.xlarge",
+  "Location": "ap-southeast-2a"
+ },
  {
   "InstanceType": "i4i.12xlarge",
   "Location": "ap-southeast-2a"
diff --git a/moto/ec2/resources/instance_type_offerings/availability-zone/eu-south-2.json b/moto/ec2/resources/instance_type_offerings/availability-zone/eu-south-2.json
index ad9231706..ee407ea09 100644
--- a/moto/ec2/resources/instance_type_offerings/availability-zone/eu-south-2.json
+++ b/moto/ec2/resources/instance_type_offerings/availability-zone/eu-south-2.json
@@ -1031,6 +1031,10 @@
   "InstanceType": "m8g.xlarge",
   "Location": "eu-south-2a"
  },
+ {
+  "InstanceType": "p5en.48xlarge",
+  "Location": "eu-south-2a"
+ },
  {
   "InstanceType": "r5.12xlarge",
   "Location": "eu-south-2a"
diff --git a/moto/ec2/resources/instance_type_offerings/availability-zone/us-west-2.json b/moto/ec2/resources/instance_type_offerings/availability-zone/us-west-2.json
index 97fc31e0b..c7d5264c9 100644
--- a/moto/ec2/resources/instance_type_offerings/availability-zone/us-west-2.json
+++ b/moto/ec2/resources/instance_type_offerings/availability-zone/us-west-2.json
@@ -12547,6 +12547,10 @@
   "InstanceType": "p5en.48xlarge",
   "Location": "us-west-2d"
  },
+ {
+  "InstanceType": "p6-b200.48xlarge",
+  "Location": "us-west-2d"
+ },
  {
   "InstanceType": "r5.12xlarge",
   "Location": "us-west-2d"
diff --git a/moto/ec2/resources/instance_type_offerings/region/us-west-2.json b/moto/ec2/resources/instance_type_offerings/region/us-west-2.json
index 9a9698f85..44fd62d7c 100644
--- a/moto/ec2/resources/instance_type_offerings/region/us-west-2.json
+++ b/moto/ec2/resources/instance_type_offerings/region/us-west-2.json
@@ -2379,6 +2379,10 @@
   "InstanceType": "p5en.48xlarge",
   "Location": "us-west-2"
  },
+ {
+  "InstanceType": "p6-b200.48xlarge",
+  "Location": "us-west-2"
+ },
  {
   "InstanceType": "r3.2xlarge",
   "Location": "us-west-2"
diff --git a/moto/ec2/resources/instance_types.json b/moto/ec2/resources/instance_types.json
index cd510c218..58883f55d 100644
--- a/moto/ec2/resources/instance_types.json
+++ b/moto/ec2/resources/instance_types.json
@@ -71816,6 +71816,237 @@
    ]
   }
  },
+ "p6-b200.48xlarge": {
+  "AutoRecoverySupported": false,
+  "BareMetal": false,
+  "BurstablePerformanceSupported": false,
+  "CurrentGeneration": true,
+  "DedicatedHostsSupported": false,
+  "EbsInfo": {
+   "EbsOptimizedInfo": {
+    "BaselineBandwidthInMbps": 100000,
+    "BaselineIops": 400000,
+    "BaselineThroughputInMBps": 12500.0,
+    "MaximumBandwidthInMbps": 100000,
+    "MaximumIops": 400000,
+    "MaximumThroughputInMBps": 12500.0
+   },
+   "EbsOptimizedSupport": "default",
+   "EncryptionSupport": "supported",
+   "NvmeSupport": "required"
+  },
+  "FreeTierEligible": false,
+  "GpuInfo": {
+   "Gpus": [
+    {
+     "Count": 8,
+     "Manufacturer": "NVIDIA",
+     "MemoryInfo": {
+      "SizeInMiB": 183359
+     },
+     "Name": "NVIDIA"
+    }
+   ],
+   "TotalGpuMemoryInMiB": 1466872
+  },
+  "HibernationSupported": false,
+  "Hypervisor": "nitro",
+  "InstanceStorageInfo": {
+   "Disks": [
+    {
+     "Count": 8,
+     "SizeInGB": 3800,
+     "Type": "ssd"
+    }
+   ],
+   "EncryptionSupport": "required",
+   "NvmeSupport": "required",
+   "TotalSizeInGB": 30400
+  },
+  "InstanceStorageSupported": true,
+  "InstanceType": "p6-b200.48xlarge",
+  "MemoryInfo": {
+   "SizeInMiB": 2097152
+  },
+  "NetworkInfo": {
+   "DefaultNetworkCardIndex": 0,
+   "EfaInfo": {
+    "MaximumEfaInterfaces": 8
+   },
+   "EfaSupported": true,
+   "EnaSrdSupported": true,
+   "EnaSupport": "required",
+   "EncryptionInTransitSupported": true,
+   "FlexibleEnaQueuesSupport": "unsupported",
+   "Ipv4AddressesPerInterface": 50,
+   "Ipv6AddressesPerInterface": 50,
+   "Ipv6Supported": true,
+   "MaximumNetworkCards": 8,
+   "MaximumNetworkInterfaces": 32,
+   "NetworkCards": [
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 0,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    },
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 1,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    },
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 2,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    },
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 3,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    },
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 4,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    },
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 5,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    },
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 6,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    },
+    {
+     "BaselineBandwidthInGbps": 200.0,
+     "DefaultEnaQueueCountPerInterface": 32,
+     "MaximumNetworkInterfaces": 4,
+     "NetworkCardIndex": 7,
+     "NetworkPerformance": "200 Gigabit",
+     "PeakBandwidthInGbps": 200.0
+    }
+   ],
+   "NetworkPerformance": "3200 Gigabit"
+  },
+  "NitroEnclavesSupport": "unsupported",
+  "NitroTpmInfo": {
+   "SupportedVersions": [
+    "2.0"
+   ]
+  },
+  "NitroTpmSupport": "supported",
+  "PhcSupport": "supported",
+  "PlacementGroupInfo": {
+   "SupportedStrategies": [
+    "cluster",
+    "partition",
+    "spread"
+   ]
+  },
+  "ProcessorInfo": {
+   "Manufacturer": "Intel",
+   "SupportedArchitectures": [
+    "x86_64"
+   ],
+   "SustainedClockSpeedInGhz": 2.4
+  },
+  "SupportedBootModes": [
+   "legacy-bios",
+   "uefi"
+  ],
+  "SupportedRootDeviceTypes": [
+   "ebs"
+  ],
+  "SupportedUsageClasses": [
+   "capacity-block",
+   "on-demand",
+   "spot"
+  ],
+  "SupportedVirtualizationTypes": [
+   "hvm"
+  ],
+  "VCpuInfo": {
+   "DefaultCores": 96,
+   "DefaultThreadsPerCore": 2,
+   "DefaultVCpus": 192,
+   "ValidCores": [
+    4,
+    6,
+    8,
+    10,
+    12,
+    14,
+    16,
+    18,
+    20,
+    22,
+    24,
+    26,
+    28,
+    30,
+    32,
+    34,
+    36,
+    38,
+    40,
+    42,
+    44,
+    46,
+    48,
+    50,
+    52,
+    54,
+    56,
+    58,
+    60,
+    62,
+    64,
+    66,
+    68,
+    70,
+    72,
+    74,
+    76,
+    78,
+    80,
+    82,
+    84,
+    86,
+    88,
+    90,
+    92,
+    94,
+    96
+   ],
+   "ValidThreadsPerCore": [
+    1,
+    2
+   ]
+  }
+ },
  "r3.2xlarge": {
   "AutoRecoverySupported": true,
   "BareMetal": false,
@@ -101347,7 +101578,12 @@
    "NetworkPerformance": "100 Gigabit"
   },
   "NitroEnclavesSupport": "unsupported",
-  "NitroTpmSupport": "unsupported",
+  "NitroTpmInfo": {
+   "SupportedVersions": [
+    "2.0"
+   ]
+  },
+  "NitroTpmSupport": "supported",
   "PhcSupport": "unsupported",
   "PlacementGroupInfo": {
    "SupportedStrategies": [
@@ -101451,12 +101687,12 @@
   "DedicatedHostsSupported": true,
   "EbsInfo": {
    "EbsOptimizedInfo": {
-    "BaselineBandwidthInMbps": 60000,
-    "BaselineIops": 420000,
-    "BaselineThroughputInMBps": 7500.0,
-    "MaximumBandwidthInMbps": 60000,
-    "MaximumIops": 420000,
-    "MaximumThroughputInMBps": 7500.0
+    "BaselineBandwidthInMbps": 100000,
+    "BaselineIops": 560000,
+    "BaselineThroughputInMBps": 12500.0,
+    "MaximumBandwidthInMbps": 100000,
+    "MaximumIops": 560000,
+    "MaximumThroughputInMBps": 12500.0
    },
    "EbsOptimizedSupport": "default",
    "EncryptionSupport": "supported",
@@ -101607,12 +101843,12 @@
   "DedicatedHostsSupported": true,
   "EbsInfo": {
    "EbsOptimizedInfo": {
-    "BaselineBandwidthInMbps": 60000,
-    "BaselineIops": 420000,
-    "BaselineThroughputInMBps": 7500.0,
-    "MaximumBandwidthInMbps": 60000,
-    "MaximumIops": 420000,
-    "MaximumThroughputInMBps": 7500.0
+    "BaselineBandwidthInMbps": 100000,
+    "BaselineIops": 560000,
+    "BaselineThroughputInMBps": 12500.0,
+    "MaximumBandwidthInMbps": 100000,
+    "MaximumIops": 560000,
+    "MaximumThroughputInMBps": 12500.0
    },
    "EbsOptimizedSupport": "default",
    "EncryptionSupport": "supported",
@@ -101818,7 +102054,12 @@
    "NetworkPerformance": "200 Gigabit"
   },
   "NitroEnclavesSupport": "unsupported",
-  "NitroTpmSupport": "unsupported",
+  "NitroTpmInfo": {
+   "SupportedVersions": [
+    "2.0"
+   ]
+  },
+  "NitroTpmSupport": "supported",
   "PhcSupport": "unsupported",
   "PlacementGroupInfo": {
    "SupportedStrategies": [
@@ -101977,7 +102218,12 @@
    "NetworkPerformance": "200 Gigabit"
   },
   "NitroEnclavesSupport": "unsupported",
-  "NitroTpmSupport": "unsupported",
+  "NitroTpmInfo": {
+   "SupportedVersions": [
+    "2.0"
+   ]
+  },
+  "NitroTpmSupport": "supported",
   "PhcSupport": "unsupported",
   "PlacementGroupInfo": {
    "SupportedStrategies": [
@@ -102136,7 +102382,12 @@
    "NetworkPerformance": "200 Gigabit"
   },
   "NitroEnclavesSupport": "unsupported",
-  "NitroTpmSupport": "unsupported",
+  "NitroTpmInfo": {
+   "SupportedVersions": [
+    "2.0"
+   ]
+  },
+  "NitroTpmSupport": "supported",
   "PhcSupport": "unsupported",
   "PlacementGroupInfo": {
    "SupportedStrategies": [
diff --git a/moto/events/models.py b/moto/events/models.py
index f0281837f..bbcc74c22 100644
--- a/moto/events/models.py
+++ b/moto/events/models.py
@@ -376,6 +376,9 @@ class EventBus(CloudFormationModel):
         account_id: str,
         region_name: str,
         name: str,
+        description: Optional[str] = None,
+        kms_key_identifier: Optional[str] = None,
+        dead_letter_config: Optional[Dict[str, str]] = None,
         tags: Optional[List[Dict[str, str]]] = None,
     ):
         self.account_id = account_id
@@ -384,6 +387,13 @@ class EventBus(CloudFormationModel):
         self.arn = f"arn:{get_partition(self.region)}:events:{self.region}:{account_id}:event-bus/{name}"
         self.tags = tags or []
 
+        self.description = description
+        self.kms_key_identifier = kms_key_identifier
+        self.dead_letter_config = dead_letter_config
+
+        self.creation_time = unix_time()
+        self.last_modified_time = self.creation_time
+
         self._statements: Dict[str, EventBusPolicyStatement] = {}
         self.rules: Dict[str, Rule] = OrderedDict()
 
@@ -1526,6 +1536,9 @@ class EventsBackend(BaseBackend):
         self,
         name: str,
         event_source_name: Optional[str] = None,
+        description: Optional[str] = None,
+        kms_key_identifier: Optional[str] = None,
+        dead_letter_config: Optional[Dict[str, str]] = None,
         tags: Optional[List[Dict[str, str]]] = None,
     ) -> EventBus:
         if name in self.event_buses:
@@ -1544,7 +1557,15 @@ class EventsBackend(BaseBackend):
                 f"Event source {event_source_name} does not exist.",
             )
 
-        event_bus = EventBus(self.account_id, self.region_name, name, tags=tags)
+        event_bus = EventBus(
+            self.account_id,
+            self.region_name,
+            name,
+            description=description,
+            kms_key_identifier=kms_key_identifier,
+            dead_letter_config=dead_letter_config,
+            tags=tags,
+        )
         self.event_buses[name] = event_bus
         if tags:
             self.tagger.tag_resource(event_bus.arn, tags)
diff --git a/moto/events/responses.py b/moto/events/responses.py
index 027687e74..c45cb0e26 100644
--- a/moto/events/responses.py
+++ b/moto/events/responses.py
@@ -239,7 +239,21 @@ class EventsHandler(BaseResponse):
         name = self._get_param("Name")
 
         event_bus = self.events_backend.describe_event_bus(name)
-        response = {"Name": event_bus.name, "Arn": event_bus.arn}
+        response = {
+            "Arn": event_bus.arn,
+            "CreationTime": event_bus.creation_time,
+            "Name": event_bus.name,
+            "LastModifiedTime": event_bus.last_modified_time,
+        }
+
+        if event_bus.dead_letter_config:
+            response["DeadLetterConfig"] = event_bus.dead_letter_config
+
+        if event_bus.description:
+            response["Description"] = event_bus.description
+
+        if event_bus.kms_key_identifier:
+            response["KmsKeyIdentifier"] = event_bus.kms_key_identifier
 
         if event_bus.policy:
             response["Policy"] = event_bus.policy
@@ -249,9 +263,19 @@ class EventsHandler(BaseResponse):
     def create_event_bus(self) -> Tuple[str, Dict[str, Any]]:
         name = self._get_param("Name")
         event_source_name = self._get_param("EventSourceName")
+        description = self._get_param("Description")
+        kms_key_identifier = self._get_param("KmsKeyIdentifier")
+        dead_letter_config = self._get_param("DeadLetterConfig")
         tags = self._get_param("Tags")
 
-        event_bus = self.events_backend.create_event_bus(name, event_source_name, tags)
+        event_bus = self.events_backend.create_event_bus(
+            name=name,
+            event_source_name=event_source_name,
+            description=description,
+            kms_key_identifier=kms_key_identifier,
+            dead_letter_config=dead_letter_config,
+            tags=tags,
+        )
         return json.dumps({"EventBusArn": event_bus.arn}), self.response_headers
 
     def list_event_buses(self) -> Tuple[str, Dict[str, Any]]:
diff --git a/moto/resourcegroups/exceptions.py b/moto/resourcegroups/exceptions.py
index 9a74f4651..63f084aae 100644
--- a/moto/resourcegroups/exceptions.py
+++ b/moto/resourcegroups/exceptions.py
@@ -6,3 +6,12 @@ class BadRequestException(JsonRESTError):
 
     def __init__(self, message: str):
         super().__init__(error_type="BadRequestException", message=message)
+
+
+class NotFoundException(JsonRESTError):
+    code = 404
+
+    def __init__(
+        self, message: str = "One or more of the specified resources don't exist."
+    ):
+        super().__init__(error_type="NotFoundException", message=message)
diff --git a/moto/resourcegroups/models.py b/moto/resourcegroups/models.py
index b4b45b7b3..98297bc34 100644
--- a/moto/resourcegroups/models.py
+++ b/moto/resourcegroups/models.py
@@ -6,7 +6,7 @@ from moto.core.base_backend import BackendDict, BaseBackend
 from moto.core.common_models import BaseModel
 from moto.utilities.utils import ARN_PARTITION_REGEX, get_partition
 
-from .exceptions import BadRequestException
+from .exceptions import BadRequestException, NotFoundException
 
 
 class FakeResourceGroup(BaseModel):
@@ -209,15 +209,22 @@ class ResourceGroups:
         self.by_arn: Dict[str, FakeResourceGroup] = {}
 
     def __contains__(self, item: str) -> bool:
-        return item in self.by_name
+        return item in self.by_name or item in self.by_arn
+
+    def __getitem__(self, item: str) -> FakeResourceGroup:
+        if item in self.by_name:
+            return self.by_name[item]
+        if item in self.by_arn:
+            return self.by_arn[item]
+        raise KeyError(f"Resource group '{item}' not found")
 
     def append(self, resource_group: FakeResourceGroup) -> None:
         self.by_name[resource_group.name] = resource_group
         self.by_arn[resource_group.arn] = resource_group
 
     def delete(self, name: str) -> FakeResourceGroup:
-        group = self.by_name[name]
-        del self.by_name[name]
+        group = self[name]
+        del self.by_name[group.name]
         del self.by_arn[group.arn]
         return group
 
@@ -330,10 +337,15 @@ class ResourceGroupsBackend(BaseBackend):
         return group
 
     def delete_group(self, group_name: str) -> FakeResourceGroup:
-        return self.groups.delete(name=group_name)
+        group = self.get_group(group_name)
+        return self.groups.delete(name=group.name)
 
     def get_group(self, group_name: str) -> FakeResourceGroup:
-        return self.groups.by_name[group_name]
+        try:
+            group = self.groups[group_name]
+        except KeyError:
+            raise NotFoundException()
+        return group
 
     def get_tags(self, arn: str) -> Dict[str, str]:
         return self.groups.by_arn[arn].tags
diff --git a/moto/resourcegroupstaggingapi/models.py b/moto/resourcegroupstaggingapi/models.py
index 2685528d9..3c38c0ec9 100644
--- a/moto/resourcegroupstaggingapi/models.py
+++ b/moto/resourcegroupstaggingapi/models.py
@@ -6,6 +6,7 @@ from moto.awslambda.models import LambdaBackend, lambda_backends
 from moto.backup.models import BackupBackend, backup_backends
 from moto.clouddirectory import CloudDirectoryBackend, clouddirectory_backends
 from moto.cloudfront.models import CloudFrontBackend, cloudfront_backends
+from moto.cloudwatch.models import CloudWatchBackend, cloudwatch_backends
 from moto.core.base_backend import BackendDict, BaseBackend
 from moto.core.exceptions import RESTError
 from moto.dms.models import DatabaseMigrationServiceBackend, dms_backends
@@ -205,6 +206,10 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
     def cloudfront_backend(self) -> CloudFrontBackend:
         return cloudfront_backends[self.account_id][self.partition]
 
+    @property
+    def cloudwatch_backend(self) -> CloudWatchBackend:
+        return cloudwatch_backends[self.account_id][self.region_name]
+
     def _get_resources_generator(
         self,
         tag_filters: Optional[List[Dict[str, Any]]] = None,
@@ -354,6 +359,35 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
                     continue
                 yield {"ResourceARN": f"{dist.arn}", "Tags": tags}
 
+        if self.cloudwatch_backend:
+            cloudwatch_resource_map: Dict[str, Dict[str, Any]] = {
+                "cloudwatch:alarm": self.cloudwatch_backend.alarms,
+                "cloudwatch:insight-rule": self.cloudwatch_backend.insight_rules,
+            }
+            for resource_type, resource_source in cloudwatch_resource_map.items():
+                if (
+                    not resource_type_filters
+                    or "cloudwatch" in resource_type_filters
+                    or resource_type in resource_type_filters
+                ):
+                    for resource in resource_source.values():
+                        if resource_type == "cloudwatch:alarm":
+                            end_of_arn = f"alarm:{resource.name}"
+                        elif resource_type == "cloudwatch:insight-rule":
+                            end_of_arn = f"insight-rule/{resource.name}"
+
+                        arn = f"arn:{get_partition(self.region_name)}:cloudwatch:{self.region_name}:{self.account_id}:{end_of_arn}"
+
+                        cw_tags = self.cloudwatch_backend.list_tags_for_resource(arn)
+
+                        tags = format_tags(cw_tags)
+                        if not tags or not tag_filter(tags):
+                            continue
+                        yield {
+                            "ResourceARN": arn,
+                            "Tags": tags,
+                        }
+
         # DMS
         if not resource_type_filters or "dms:endpoint" in resource_type_filters:
             for endpoint in self.dms_backend.endpoints.values():
diff --git a/moto/s3control/models.py b/moto/s3control/models.py
index 381eb745e..6b664989b 100644
--- a/moto/s3control/models.py
+++ b/moto/s3control/models.py
@@ -1,6 +1,6 @@
 from collections import defaultdict
 from datetime import datetime
-from typing import Any, Dict, Optional
+from typing import Any, Dict, List, Optional
 
 from moto.core.base_backend import BackendDict, BaseBackend
 from moto.core.common_models import BaseModel
@@ -11,10 +11,20 @@ from moto.s3.exceptions import (
     WrongPublicAccessBlockAccountIdError,
 )
 from moto.s3.models import PublicAccessBlock
+from moto.utilities.paginator import paginate
+from moto.utilities.tagging_service import TaggingService
 from moto.utilities.utils import PARTITION_NAMES, get_partition
 
 from .exceptions import AccessPointNotFound, AccessPointPolicyNotFound
 
+PAGINATION_MODEL = {
+    "list_storage_lens_configurations": {
+        "input_token": "next_token",
+        "limit_default": 100,
+        "unique_attribute": "id",
+    },
+}
+
 
 class AccessPoint(BaseModel):
     def __init__(
@@ -52,11 +62,28 @@ class AccessPoint(BaseModel):
         return self.policy is not None
 
 
+class StorageLensConfiguration(BaseModel):
+    def __init__(
+        self,
+        account_id: str,
+        config_id: str,
+        storage_lens_configuration: Dict[str, Any],
+        tags: Optional[Dict[str, str]] = None,
+    ):
+        self.account_id = account_id
+        self.config_id = config_id
+        self.config = storage_lens_configuration
+        self.tags = tags or {}
+        self.arn = f"arn:{get_partition('us-east-1')}:s3:us-east-1:{account_id}:storage-lens/{config_id}"
+
+
 class S3ControlBackend(BaseBackend):
     def __init__(self, region_name: str, account_id: str):
         super().__init__(region_name, account_id)
         self.public_access_block: Optional[PublicAccessBlock] = None
         self.access_points: Dict[str, Dict[str, AccessPoint]] = defaultdict(dict)
+        self.storage_lens_configs: Dict[str, StorageLensConfiguration] = {}
+        self.tagger = TaggingService()
 
     def get_public_access_block(self, account_id: str) -> PublicAccessBlock:
         # The account ID should equal the account id that is set for Moto:
@@ -140,6 +167,41 @@ class S3ControlBackend(BaseBackend):
         self.get_access_point_policy(account_id, name)
         return True
 
+    def put_storage_lens_configuration(
+        self,
+        config_id: str,
+        account_id: str,
+        storage_lens_configuration: Dict[str, Any],
+        tags: Optional[Dict[str, str]] = None,
+    ) -> None:
+        # The account ID should equal the account id that is set for Moto:
+        if account_id != self.account_id:
+            raise WrongPublicAccessBlockAccountIdError()
+
+        # Create a new Storage Lens configuration
+        storage_lens = StorageLensConfiguration(
+            account_id=account_id,
+            config_id=config_id,
+            storage_lens_configuration=storage_lens_configuration,
+            tags=tags,
+        )
+        self.storage_lens_configs[config_id] = storage_lens
+
+    def get_storage_lens_configuration(
+        self, config_id: str, account_id: str
+    ) -> StorageLensConfiguration:
+        if config_id not in self.storage_lens_configs:
+            raise AccessPointNotFound(config_id)
+        storage_lens_configuration = self.storage_lens_configs[config_id]
+        return storage_lens_configuration
+
+    @paginate(pagination_model=PAGINATION_MODEL)
+    def list_storage_lens_configurations(
+        self, account_id: str
+    ) -> List[StorageLensConfiguration]:
+        storage_lens_configuration_list = list(self.storage_lens_configs.values())
+        return storage_lens_configuration_list
+
 
 s3control_backends = BackendDict(
     S3ControlBackend,
diff --git a/moto/s3control/responses.py b/moto/s3control/responses.py
index 175892b89..85eb6fb8c 100644
--- a/moto/s3control/responses.py
+++ b/moto/s3control/responses.py
@@ -115,6 +115,47 @@ class S3ControlResponse(BaseResponse):
         name = self.path.split("/")[-2]
         return account_id, name
 
+    def put_storage_lens_configuration(self) -> str:
+        account_id = self.headers.get("x-amz-account-id")
+        config_id = self.path.split("/")[-1]
+        request = xmltodict.parse(self.body)["PutStorageLensConfigurationRequest"]
+        storage_lens_configuration = request.get("StorageLensConfiguration")
+        tags = request.get("Tags")
+        self.backend.put_storage_lens_configuration(
+            config_id=config_id,
+            account_id=account_id,
+            storage_lens_configuration=storage_lens_configuration,
+            tags=tags,
+        )
+        return ""
+
+    def get_storage_lens_configuration(self) -> str:
+        account_id = self.headers.get("x-amz-account-id")
+        config_id = self.path.split("/")[-1]
+        storage_lens_configuration = self.backend.get_storage_lens_configuration(
+            config_id=config_id,
+            account_id=account_id,
+        )
+        # TODO: Add support for all fields in the response
+        # https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_GetStorageLensConfiguration.html
+        template = self.response_template(GET_STORAGE_LENS_CONFIGURATION_TEMPLATE)
+        return template.render(config=storage_lens_configuration.config)
+
+    def list_storage_lens_configurations(self) -> str:
+        account_id = self.headers.get("x-amz-account-id")
+        params = self._get_params()
+        next_token = params.get("nextToken")
+        storage_lens_configuration_list, next_token = (
+            self.backend.list_storage_lens_configurations(
+                account_id=account_id,
+                next_token=next_token,
+            )
+        )
+        template = self.response_template(LIST_STORAGE_LENS_CONFIGURATIONS_TEMPLATE)
+        return template.render(
+            next_token=next_token, configs=storage_lens_configuration_list
+        )
+
 
 CREATE_ACCESS_POINT_TEMPLATE = """<CreateAccessPointResult>
   <ResponseMetadata>
@@ -187,3 +228,51 @@ GET_ACCESS_POINT_POLICY_STATUS_TEMPLATE = """<GetAccessPointPolicyResult>
   </PolicyStatus>
 </GetAccessPointPolicyResult>
 """
+
+
+GET_STORAGE_LENS_CONFIGURATION_TEMPLATE = """
+<StorageLensConfiguration>
+   <Id>{{config.get("Id")}}</Id>
+   {% if config.get("DataExport") %}
+   <DataExport>
+      {% if config["DataExport"]["S3BucketDestination"] %}
+      <S3BucketDestination>
+         <AccountId>{{config["DataExport"]["S3BucketDestination"]["AccountId"]}}</AccountId>
+         <Arn>{{config["DataExport"]["S3BucketDestination"]["Arn"]}}</Arn>
+         {% if config["DataExport"]["S3BucketDestination"].get("Encryption") %}
+         <Encryption>
+            {% if config["DataExport"]["S3BucketDestination"]["Encryption"].get("SSEKMS") %}
+            <SSE-KMS>
+               <KeyId>config["DataExport"]["S3BucketDestination"]["Encryption"]["KeyId"]</KeyId>
+            </SSE-KMS>
+            {% endif %}
+            {% if "SSE-S3" in config["DataExport"]["S3BucketDestination"]["Encryption"] %}
+            <SSE-S3>
+            </SSE-S3>
+            {% endif %}
+         </Encryption>
+         {% endif %}
+      </S3BucketDestination>
+      {% endif %}
+   </DataExport>
+   {% endif %}
+   <IsEnabled>{{config["IsEnabled"]}}</IsEnabled>
+</StorageLensConfiguration>
+"""
+
+
+LIST_STORAGE_LENS_CONFIGURATIONS_TEMPLATE = """
+<ListStorageLensConfigurationsResult>
+   {% if next_token %}
+   <NextToken>{{ next_token }}</NextToken>
+   {% endif %}
+   {% for config in configs %}
+   <StorageLensConfiguration>
+      <HomeRegion></HomeRegion>
+      <Id>{{ config.config.get("Id") }}</Id>
+      <IsEnabled>{{ config.config.get("IsEnabled") }}</IsEnabled>
+      <StorageLensArn>{{ config.arn }}</StorageLensArn>
+    </StorageLensConfiguration>
+    {% endfor %}
+</ListStorageLensConfigurationsResult>
+"""
diff --git a/moto/s3control/urls.py b/moto/s3control/urls.py
index 0f4f9a487..4e87cb488 100644
--- a/moto/s3control/urls.py
+++ b/moto/s3control/urls.py
@@ -12,4 +12,6 @@ url_paths = {
     r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)$": S3ControlResponse.dispatch,
     r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)/policy$": S3ControlResponse.dispatch,
     r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)/policyStatus$": S3ControlResponse.dispatch,
+    "{0}/v20180820/storagelens/(?P<storagelensid>[^/]+)$": S3ControlResponse.dispatch,
+    "{0}/v20180820/storagelens$": S3ControlResponse.dispatch,
 }
diff --git a/moto/sqs/responses.py b/moto/sqs/responses.py
index af546aa63..23ab7a6c2 100644
--- a/moto/sqs/responses.py
+++ b/moto/sqs/responses.py
@@ -531,6 +531,14 @@ class SQSResponse(BaseResponse):
             message_attributes = self._get_multi_param("message_attributes")
         if not message_attributes:
             message_attributes = extract_input_message_attributes(self.querystring)
+        if self.is_json():
+            message_system_attributes = self._get_param("MessageSystemAttributeNames")
+        else:
+            message_system_attributes = self._get_multi_param(
+                "message_system_attributes"
+            )
+        if not message_system_attributes:
+            message_system_attributes = set()
 
         if self.is_json():
             attribute_names = self._get_param("AttributeNames", [])
@@ -587,15 +595,29 @@ class SQSResponse(BaseResponse):
         )
 
         attributes = {
-            "approximate_first_receive_timestamp": False,
-            "approximate_receive_count": False,
-            "message_deduplication_id": False,
-            "message_group_id": False,
-            "sender_id": False,
-            "sent_timestamp": False,
-            "sequence_number": False,
+            "approximate_first_receive_timestamp": "ApproximateFirstReceiveTimestamp"
+            in message_system_attributes,
+            "approximate_receive_count": "ApproximateReceiveCount"
+            in message_system_attributes,
+            "message_deduplication_id": "MessageDeduplicationId"
+            in message_system_attributes,
+            "message_group_id": "MessageGroupId" in message_system_attributes,
+            "sender_id": "SenderId" in message_system_attributes,
+            "sent_timestamp": "SentTimestamp" in message_system_attributes,
+            "sequence_number": "SequenceNumber" in message_system_attributes,
         }
 
+        if "All" in message_system_attributes:
+            attributes = {
+                "approximate_first_receive_timestamp": True,
+                "approximate_receive_count": True,
+                "message_deduplication_id": True,
+                "message_group_id": True,
+                "sender_id": True,
+                "sent_timestamp": True,
+                "sequence_number": True,
+            }
+
         for attribute in attributes:
             pascalcase_name = camelcase_to_pascal(underscores_to_camelcase(attribute))
             if any(x in ["All", pascalcase_name] for x in attribute_names):
diff --git a/moto/ssm/resources/regions.json b/moto/ssm/resources/regions.json
index 55bb17196..f75d9ed27 100644
--- a/moto/ssm/resources/regions.json
+++ b/moto/ssm/resources/regions.json
@@ -688,6 +688,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "entityresolution": {
+                "Value": "entityresolution",
+                "endpoint": {
+                  "Value": "entityresolution.af-south-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "es": {
                 "Value": "es",
                 "endpoint": {
@@ -10025,6 +10034,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "opensearchserverless": {
+                "Value": "opensearchserverless",
+                "endpoint": {
+                  "Value": "aoss.ap-northeast-3.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "organizations": {
                 "Value": "organizations",
                 "endpoint": {
@@ -24511,6 +24529,42 @@
                   "Value": "HTTPS"
                 }
               },
+              "fsx-lustre": {
+                "Value": "fsx-lustre",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
+              "fsx-ontap": {
+                "Value": "fsx-ontap",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
+              "fsx-openzfs": {
+                "Value": "fsx-openzfs",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
+              "fsx-windows": {
+                "Value": "fsx-windows",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "glue": {
                 "Value": "glue",
                 "endpoint": {
@@ -24556,6 +24610,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "kafka": {
+                "Value": "kafka",
+                "endpoint": {
+                  "Value": "kafka.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "kinesis": {
                 "Value": "kinesis",
                 "endpoint": {
@@ -50148,6 +50211,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "scheduler": {
+                "Value": "scheduler",
+                "endpoint": {
+                  "Value": "scheduler.il-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "secretsmanager": {
                 "Value": "secretsmanager",
                 "endpoint": {
@@ -54069,6 +54141,42 @@
                   "Value": "HTTPS"
                 }
               },
+              "fsx-lustre": {
+                "Value": "fsx-lustre",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
+              "fsx-ontap": {
+                "Value": "fsx-ontap",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
+              "fsx-openzfs": {
+                "Value": "fsx-openzfs",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
+              "fsx-windows": {
+                "Value": "fsx-windows",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "glue": {
                 "Value": "glue",
                 "endpoint": {
@@ -54105,6 +54213,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "kafka": {
+                "Value": "kafka",
+                "endpoint": {
+                  "Value": "kafka.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "kinesis": {
                 "Value": "kinesis",
                 "endpoint": {
@@ -69217,6 +69334,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "dsql": {
+                "Value": "dsql",
+                "endpoint": {
+                  "Value": "dsql.us-west-2.api.aws"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "dynamodb": {
                 "Value": "dynamodb",
                 "endpoint": {
diff --git a/moto/ssm/resources/services.json b/moto/ssm/resources/services.json
index 7d5f24a26..151333280 100644
--- a/moto/ssm/resources/services.json
+++ b/moto/ssm/resources/services.json
@@ -21133,6 +21133,15 @@
                 "protocols": {
                   "Value": "HTTPS"
                 }
+              },
+              "us-west-2": {
+                "Value": "us-west-2",
+                "endpoint": {
+                  "Value": "dsql.us-west-2.api.aws"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
               }
             }
           },
@@ -26060,6 +26069,15 @@
               "Value": "https://aws.amazon.com/entity-resolution"
             },
             "regions": {
+              "af-south-1": {
+                "Value": "af-south-1",
+                "endpoint": {
+                  "Value": "entityresolution.af-south-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "ap-northeast-1": {
                 "Value": "ap-northeast-1",
                 "endpoint": {
@@ -29421,6 +29439,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "ap-southeast-7": {
+                "Value": "ap-southeast-7",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "ca-central-1": {
                 "Value": "ca-central-1",
                 "endpoint": {
@@ -29556,6 +29583,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "mx-central-1": {
+                "Value": "mx-central-1",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "sa-east-1": {
                 "Value": "sa-east-1",
                 "endpoint": {
@@ -29738,6 +29774,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "ap-southeast-7": {
+                "Value": "ap-southeast-7",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "ca-central-1": {
                 "Value": "ca-central-1",
                 "endpoint": {
@@ -29873,6 +29918,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "mx-central-1": {
+                "Value": "mx-central-1",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "sa-east-1": {
                 "Value": "sa-east-1",
                 "endpoint": {
@@ -30046,6 +30100,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "ap-southeast-7": {
+                "Value": "ap-southeast-7",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "ca-central-1": {
                 "Value": "ca-central-1",
                 "endpoint": {
@@ -30181,6 +30244,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "mx-central-1": {
+                "Value": "mx-central-1",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "sa-east-1": {
                 "Value": "sa-east-1",
                 "endpoint": {
@@ -30363,6 +30435,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "ap-southeast-7": {
+                "Value": "ap-southeast-7",
+                "endpoint": {
+                  "Value": "fsx.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "ca-central-1": {
                 "Value": "ca-central-1",
                 "endpoint": {
@@ -30498,6 +30579,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "mx-central-1": {
+                "Value": "mx-central-1",
+                "endpoint": {
+                  "Value": "fsx.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "sa-east-1": {
                 "Value": "sa-east-1",
                 "endpoint": {
@@ -36984,6 +37074,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "ap-southeast-7": {
+                "Value": "ap-southeast-7",
+                "endpoint": {
+                  "Value": "kafka.ap-southeast-7.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "ca-central-1": {
                 "Value": "ca-central-1",
                 "endpoint": {
@@ -37119,6 +37218,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "mx-central-1": {
+                "Value": "mx-central-1",
+                "endpoint": {
+                  "Value": "kafka.mx-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "sa-east-1": {
                 "Value": "sa-east-1",
                 "endpoint": {
@@ -48312,6 +48420,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "ap-northeast-3": {
+                "Value": "ap-northeast-3",
+                "endpoint": {
+                  "Value": "aoss.ap-northeast-3.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "ap-south-1": {
                 "Value": "ap-south-1",
                 "endpoint": {
@@ -60448,6 +60565,15 @@
                   "Value": "HTTPS"
                 }
               },
+              "il-central-1": {
+                "Value": "il-central-1",
+                "endpoint": {
+                  "Value": "scheduler.il-central-1.amazonaws.com"
+                },
+                "protocols": {
+                  "Value": "HTTPS"
+                }
+              },
               "me-central-1": {
                 "Value": "me-central-1",
                 "endpoint": {


Test patch:
diff --git a/.github/workflows/tests_sdk_ruby.yml b/.github/workflows/tests_sdk_ruby.yml
index e28b0226c..26d85d51f 100644
--- a/.github/workflows/tests_sdk_ruby.yml
+++ b/.github/workflows/tests_sdk_ruby.yml
@@ -13,7 +13,7 @@ jobs:
     steps:
       - uses: actions/checkout@v4
       - name: Set up Ruby ${{ matrix.ruby-version }}
-        uses: ruby/setup-ruby@eaecf785f6a34567a6d97f686bbb7bccc1ac1e5c
+        uses: ruby/setup-ruby@c95ae3725f6ebdd095f2bd19caed7ebc14435ba5
         with:
           ruby-version: ${{ matrix.ruby-version }}
       - name: Set up Python 3.12
diff --git a/tests/test_acmpca/test_acmpca.py b/tests/test_acmpca/test_acmpca.py
index ec98ae770..2fb446d49 100644
--- a/tests/test_acmpca/test_acmpca.py
+++ b/tests/test_acmpca/test_acmpca.py
@@ -480,11 +480,25 @@ def test_end_entity_certificate_issuance():
     )
     builder = cryptography.x509.verification.PolicyBuilder().store(store)
     verifier = builder.build_server_verifier(DNSName("bezoscorp.com"))
-    chain = verifier.verify(
-        cryptography.x509.load_pem_x509_certificate(ee_cert.encode("utf-8")), []
-    )
+    ee_x509 = cryptography.x509.load_pem_x509_certificate(ee_cert.encode("utf-8"))
+    chain = verifier.verify(ee_x509, [])
     assert len(chain) == 2
 
+    # Ensure extensions are passed through
+    san_extension = ee_x509.extensions.get_extension_for_oid(
+        cryptography.x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME
+    )
+    assert san_extension.value.get_values_for_type(cryptography.x509.OtherName)
+    assert san_extension.value.get_values_for_type(cryptography.x509.RFC822Name) == [
+        "hello@moto.com"
+    ]
+    assert san_extension.value.get_values_for_type(cryptography.x509.DNSName) == [
+        "bezoscorp.com"
+    ]
+    assert san_extension.value.get_values_for_type(
+        cryptography.x509.UniformResourceIdentifier
+    ) == ["https://github.com/getmoto/moto"]
+
 
 @mock_aws
 def test_tag_certificate_authority():
@@ -597,6 +611,22 @@ def create_csr(private_key, country, state, org, cn):
             cryptography.x509.BasicConstraints(ca=False, path_length=None),
             critical=True,
         )
+        .add_extension(
+            cryptography.x509.SubjectAlternativeName(
+                [
+                    cryptography.x509.DNSName(cn),
+                    cryptography.x509.RFC822Name("hello@moto.com"),
+                    cryptography.x509.OtherName(
+                        type_id=cryptography.x509.ObjectIdentifier("2.5.4.3"),
+                        value=b"\x13\x02mo",
+                    ),
+                    cryptography.x509.UniformResourceIdentifier(
+                        "https://github.com/getmoto/moto"
+                    ),
+                ]
+            ),
+            critical=False,
+        )
         .sign(private_key, hashes.SHA256())
     )
     return csr.public_bytes(serialization.Encoding.PEM)
diff --git a/tests/test_apigateway/test_apigateway.py b/tests/test_apigateway/test_apigateway.py
index ba2ca674e..f678c8586 100644
--- a/tests/test_apigateway/test_apigateway.py
+++ b/tests/test_apigateway/test_apigateway.py
@@ -1953,6 +1953,27 @@ def test_get_api_key_unknown_apikey():
     assert err["Code"] == "NotFoundException"
 
 
+@mock_aws
+def test_update_api_key_unknown_apikey():
+    client = boto3.client("apigateway", region_name="us-east-1")
+    patch_operations = [{"op": "replace", "path": "/name", "value": "test"}]
+    with pytest.raises(ClientError) as ex:
+        client.update_api_key(apiKey="unknown", patchOperations=patch_operations)
+    err = ex.value.response["Error"]
+    assert err["Message"] == "Invalid API Key identifier specified"
+    assert err["Code"] == "NotFoundException"
+
+
+@mock_aws
+def test_delete_api_key_unknown_apikey():
+    client = boto3.client("apigateway", region_name="us-east-1")
+    with pytest.raises(ClientError) as ex:
+        client.delete_api_key(apiKey="unknown")
+    err = ex.value.response["Error"]
+    assert err["Message"] == "Invalid API Key identifier specified"
+    assert err["Code"] == "NotFoundException"
+
+
 @mock_aws
 def test_get_rest_api_without_id():
     client = boto3.client("apigateway", region_name="us-east-1")
diff --git a/tests/test_cloudwatch/test_cloudwatch_insight_rules.py b/tests/test_cloudwatch/test_cloudwatch_insight_rules.py
new file mode 100644
index 000000000..dbdeda965
--- /dev/null
+++ b/tests/test_cloudwatch/test_cloudwatch_insight_rules.py
@@ -0,0 +1,154 @@
+import boto3
+import pytest
+
+from moto import mock_aws
+
+
+@mock_aws
+@pytest.mark.parametrize(
+    "region,partition", [("eu-west-1", "aws"), ("cn-north-1", "aws-cn")]
+)
+def test_put_insight_rule(region, partition):
+    cloudwatch = boto3.client("cloudwatch", region)
+
+    rule_name = "MySampleInsightRule"
+    log_group_name = "my-log-group"
+    rule_body = f"""
+    {{
+      "Schema": "CloudWatchLogRule",
+      "LogGroupNames": ["{log_group_name}"],
+      "LogFormat": "JSON",
+      "Filter": "[timestamp, request, statusCode = *]",
+      "Contribution": {{
+        "Keys": ["statusCode"],
+        "ValueOf": "Count"
+      }}
+    }}
+    """
+    cloudwatch.put_insight_rule(
+        RuleName=rule_name, RuleDefinition=rule_body, RuleState="ENABLED"
+    )
+
+    rules = cloudwatch.describe_insight_rules()["InsightRules"]
+    assert len(rules) == 1
+    rule = rules[0]
+    assert rule["Name"] == "MySampleInsightRule"
+    assert rule["State"] == "ENABLED"
+    assert rule["Schema"] == '{"Name" : "CloudWatchLogRule", "Version" : 1}'
+    assert rule["Definition"] == rule_body
+    assert rule["ManagedRule"] is not True
+
+
+@mock_aws
+def test_delete_insight_rules():
+    cloudwatch = boto3.client("cloudwatch", region_name="eu-central-1")
+
+    rule_name = "MySampleInsightRule"
+    log_group_name = "my-log-group"
+    rule_body = f"""
+    {{
+      "Schema": "CloudWatchLogRule",
+      "LogGroupNames": ["{log_group_name}"],
+      "LogFormat": "JSON",
+      "Filter": "[timestamp, request, statusCode = *]",
+      "Contribution": {{
+        "Keys": ["statusCode"],
+        "ValueOf": "Count"
+      }}
+    }}
+    """
+
+    cloudwatch.put_insight_rule(
+        RuleName=rule_name, RuleDefinition=rule_body, RuleState="ENABLED"
+    )
+
+    cloudwatch.put_insight_rule(
+        RuleName=f"{rule_name}_Backup", RuleDefinition=rule_body, RuleState="ENABLED"
+    )
+    rules = cloudwatch.describe_insight_rules()["InsightRules"]
+    assert len(rules) == 2
+
+    cloudwatch.delete_insight_rules(RuleNames=[rule_name])
+    rules = cloudwatch.describe_insight_rules()["InsightRules"]
+    assert len(rules) == 1
+
+    rule = rules[0]
+    assert rule["Name"] == "MySampleInsightRule_Backup"
+
+
+@mock_aws
+def test_disable_insight_rules():
+    cloudwatch = boto3.client("cloudwatch", region_name="eu-central-1")
+
+    rule_name = "MySampleInsightRule"
+    log_group_name = "my-log-group"
+    rule_body = f"""
+    {{
+      "Schema": "CloudWatchLogRule",
+      "LogGroupNames": ["{log_group_name}"],
+      "LogFormat": "JSON",
+      "Filter": "[timestamp, request, statusCode = *]",
+      "Contribution": {{
+        "Keys": ["statusCode"],
+        "ValueOf": "Count"
+      }}
+    }}
+    """
+
+    cloudwatch.put_insight_rule(
+        RuleName=rule_name, RuleDefinition=rule_body, RuleState="ENABLED"
+    )
+
+    cloudwatch.put_insight_rule(
+        RuleName=f"{rule_name}_Backup", RuleDefinition=rule_body, RuleState="ENABLED"
+    )
+
+    cloudwatch.disable_insight_rules(RuleNames=[rule_name])
+
+    rules = cloudwatch.describe_insight_rules()
+
+    # Ensuring correct rule was disabled, other should remain enabled
+    for r in rules["InsightRules"]:
+        if r["Name"] == rule_name:
+            assert r["State"] == "DISABLED"
+        else:
+            assert r["State"] == "ENABLED"
+
+
+@mock_aws
+def test_enable_insight_rules():
+    cloudwatch = boto3.client("cloudwatch", region_name="eu-central-1")
+
+    rule_name = "MySampleInsightRule"
+    log_group_name = "my-log-group"
+    rule_body = f"""
+    {{
+      "Schema": "CloudWatchLogRule",
+      "LogGroupNames": ["{log_group_name}"],
+      "LogFormat": "JSON",
+      "Filter": "[timestamp, request, statusCode = *]",
+      "Contribution": {{
+        "Keys": ["statusCode"],
+        "ValueOf": "Count"
+      }}
+    }}
+    """
+
+    cloudwatch.put_insight_rule(
+        RuleName=rule_name, RuleDefinition=rule_body, RuleState="DISABLED"
+    )
+
+    cloudwatch.put_insight_rule(
+        RuleName=f"{rule_name}_Backup", RuleDefinition=rule_body, RuleState="DISABLED"
+    )
+
+    cloudwatch.enable_insight_rules(RuleNames=[rule_name])
+
+    rules = cloudwatch.describe_insight_rules()
+
+    # Ensuring correct rule was enabled, other should remain disabled
+    for r in rules["InsightRules"]:
+        if r["Name"] == rule_name:
+            assert r["State"] == "ENABLED"
+        else:
+            assert r["State"] == "DISABLED"
diff --git a/tests/test_cloudwatch/test_cloudwatch_tags.py b/tests/test_cloudwatch/test_cloudwatch_tags.py
index 4eac59820..8bc7ca612 100644
--- a/tests/test_cloudwatch/test_cloudwatch_tags.py
+++ b/tests/test_cloudwatch/test_cloudwatch_tags.py
@@ -199,3 +199,37 @@ def test_untag_resource_error_not_exists():
     assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 404
     assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
     assert ex.response["Error"]["Message"] == "Unknown"
+
+
+@mock_aws
+def test_tag_insight_rules_resource():
+    client = boto3.client("cloudwatch", region_name="eu-central-1")
+
+    rule_name = "MySampleInsightRule"
+    log_group_name = "my-log-group"
+    rule_body = f"""
+    {{
+      "Schema": "CloudWatchLogRule",
+      "LogGroupNames": ["{log_group_name}"],
+      "LogFormat": "JSON",
+      "Filter": "[timestamp, request, statusCode = *]",
+      "Contribution": {{
+        "Keys": ["statusCode"],
+        "ValueOf": "Count"
+      }}
+    }}
+    """
+    tags = [{"Key": "ThisIsAKey", "Value": "ThisIsAValue"}]
+
+    client.put_insight_rule(
+        RuleName=rule_name, RuleDefinition=rule_body, RuleState="ENABLED", Tags=tags
+    )
+
+    arn = (
+        "arn:aws:cloudwatch:eu-central-1:123456789012:insight-rule/MySampleInsightRule"
+    )
+
+    response = client.list_tags_for_resource(ResourceARN=arn)
+    assert sorted(response["Tags"], key=itemgetter("Key")) == [
+        {"Key": "ThisIsAKey", "Value": "ThisIsAValue"},
+    ]
diff --git a/tests/test_codedeploy/test_codedeploy.py b/tests/test_codedeploy/test_codedeploy.py
index dce81e18d..a35fa52d6 100644
--- a/tests/test_codedeploy/test_codedeploy.py
+++ b/tests/test_codedeploy/test_codedeploy.py
@@ -553,3 +553,91 @@ def test_list_deployment_groups():
 
     resp = client.list_deployment_groups(applicationName=application_name)
     assert len(resp["deploymentGroups"]) == 2
+
+
+@mock_aws
+def test_application_tagging():
+    client = boto3.client("codedeploy", region_name="us-west-2")
+    app_name = "test-tag-application"
+    initial_tags = [{"Key": "Environment", "Value": "Test"}]
+
+    response = client.create_application(
+        applicationName=app_name, computePlatform="Server", tags=initial_tags
+    )
+
+    app_arn = f"arn:aws:codedeploy:us-west-2:123456789012:application:{app_name}"
+
+    response = client.list_tags_for_resource(ResourceArn=app_arn)
+    assert "Tags" in response
+    assert len(response["Tags"]) == 1
+    assert response["Tags"][0]["Key"] == "Environment"
+    assert response["Tags"][0]["Value"] == "Test"
+
+
+@mock_aws
+def test_deployment_group_tagging():
+    client = boto3.client("codedeploy", region_name="us-west-2")
+    app_name = "test-tag-dg-app"
+    dg_name = "test-tag-deployment-group"
+    service_role_arn = "arn:aws:iam::123456789012:role/CodeDeployDemoRole"
+
+    client.create_application(applicationName=app_name, computePlatform="Server")
+
+    initial_tags = [{"Key": "Team", "Value": "Platform"}]
+    response = client.create_deployment_group(
+        applicationName=app_name,
+        deploymentGroupName=dg_name,
+        serviceRoleArn=service_role_arn,
+        tags=initial_tags,
+    )
+
+    dg_arn = f"arn:aws:codedeploy:us-west-2:123456789012:deploymentgroup:{app_name}/{dg_name}"
+
+    response = client.list_tags_for_resource(ResourceArn=dg_arn)
+    assert "Tags" in response
+    assert len(response["Tags"]) == 1
+    assert response["Tags"][0]["Key"] == "Team"
+    assert response["Tags"][0]["Value"] == "Platform"
+
+
+@mock_aws
+def test_deployment_inherits_tags():
+    """Test that deployments inherit tags from deployment groups."""
+    client = boto3.client("codedeploy", region_name="us-west-2")
+    app_name = "test-tag-inherit-app"
+    dg_name = "test-tag-inherit-group"
+    service_role_arn = "arn:aws:iam::123456789012:role/CodeDeployDemoRole"
+
+    client.create_application(applicationName=app_name, computePlatform="Server")
+
+    dg_tags = [{"Key": "Environment", "Value": "Production"}]
+    client.create_deployment_group(
+        applicationName=app_name,
+        deploymentGroupName=dg_name,
+        serviceRoleArn=service_role_arn,
+        tags=dg_tags,
+    )
+
+    response = client.create_deployment(
+        applicationName=app_name,
+        deploymentGroupName=dg_name,
+        revision={
+            "revisionType": "S3",
+            "s3Location": {
+                "bucket": "my-bucket",
+                "key": "my-key",
+                "bundleType": "zip",
+                "version": "1",
+                "eTag": "my-etag",
+            },
+        },
+    )
+    deployment_id = response["deploymentId"]
+
+    deployment_arn = (
+        f"arn:aws:codedeploy:us-west-2:123456789012:deployment:{deployment_id}"
+    )
+
+    response = client.list_tags_for_resource(ResourceArn=deployment_arn)
+    assert "Tags" in response
+    assert len(response["Tags"]) == 1
diff --git a/tests/test_connectcampaigns/__init__.py b/tests/test_connectcampaigns/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_connectcampaigns/test_connectcampaigns.py b/tests/test_connectcampaigns/test_connectcampaigns.py
new file mode 100644
index 000000000..21da781db
--- /dev/null
+++ b/tests/test_connectcampaigns/test_connectcampaigns.py
@@ -0,0 +1,177 @@
+"""Unit tests for connectcampaigns-supported APIs."""
+
+import boto3
+import pytest
+
+from moto import mock_aws
+
+# See our Development Tips on writing tests for hints on how to write good tests:
+# http://docs.getmoto.org/en/latest/docs/contributing/development_tips/tests.html
+
+
+@mock_aws
+def test_create_campaign():
+    client = boto3.client("connectcampaigns", region_name="us-east-1")
+
+    response = client.create_campaign(
+        name="TestCampaign",
+        connectInstanceId="12345678-1234-1234-1234-123456789012",
+        dialerConfig={
+            "progressiveDialerConfig": {
+                "bandwidthAllocation": 1.0,
+                "dialingCapacity": 2.0,
+            }
+        },
+        outboundCallConfig={
+            "connectContactFlowId": "12345678-1234-1234-1234-123456789012",
+            "connectSourcePhoneNumber": "+12065550100",
+            "connectQueueId": "12345678-1234-1234-1234-123456789012",
+            "answerMachineDetectionConfig": {
+                "enableAnswerMachineDetection": True,
+                "awaitAnswerMachinePrompt": False,
+            },
+        },
+        tags={"Department": "Marketing", "Project": "Outreach"},
+    )
+
+    assert "id" in response
+    assert "arn" in response
+    assert "tags" in response
+    assert response["tags"]["Department"] == "Marketing"
+    assert response["tags"]["Project"] == "Outreach"
+
+
+@mock_aws
+def test_delete_campaign():
+    client = boto3.client("connectcampaigns", region_name="us-east-1")
+
+    create_response = client.create_campaign(
+        name="CampaignToDelete",
+        connectInstanceId="12345678-1234-1234-1234-123456789012",
+        dialerConfig={
+            "progressiveDialerConfig": {
+                "bandwidthAllocation": 1.0,
+                "dialingCapacity": 2.0,
+            }
+        },
+        outboundCallConfig={
+            "connectContactFlowId": "12345678-1234-1234-1234-123456789012",
+        },
+    )
+
+    campaign_id = create_response["id"]
+
+    client.delete_campaign(id=campaign_id)
+
+
+@mock_aws
+def test_describe_campaign():
+    client = boto3.client("connectcampaigns", region_name="us-east-1")
+
+    create_response = client.create_campaign(
+        name="CampaignToDescribe",
+        connectInstanceId="12345678-1234-1234-1234-123456789012",
+        dialerConfig={
+            "progressiveDialerConfig": {
+                "bandwidthAllocation": 1.0,
+                "dialingCapacity": 2.0,
+            }
+        },
+        outboundCallConfig={
+            "connectContactFlowId": "12345678-1234-1234-1234-123456789012",
+            "connectSourcePhoneNumber": "+12065550100",
+            "connectQueueId": "12345678-1234-1234-1234-123456789012",
+        },
+    )
+
+    campaign_id = create_response["id"]
+
+    describe_response = client.describe_campaign(id=campaign_id)
+
+    assert "campaign" in describe_response
+    campaign = describe_response["campaign"]
+
+    assert campaign["id"] == campaign_id
+    assert "arn" in campaign
+    assert campaign["name"] == "CampaignToDescribe"
+    assert campaign["connectInstanceId"] == "12345678-1234-1234-1234-123456789012"
+    assert "progressiveDialerConfig" in campaign["dialerConfig"]
+    assert (
+        campaign["dialerConfig"]["progressiveDialerConfig"]["bandwidthAllocation"]
+        == 1.0
+    )
+    assert (
+        campaign["outboundCallConfig"]["connectContactFlowId"]
+        == "12345678-1234-1234-1234-123456789012"
+    )
+
+    with pytest.raises(client.exceptions.ResourceNotFoundException):
+        client.describe_campaign(id="non-existent-id")
+
+
+@mock_aws
+def test_get_connect_instance_config():
+    client = boto3.client("connectcampaigns", region_name="us-east-1")
+
+    connect_instance_id = "12345678-1234-1234-1234-123456789012"
+
+    response = client.get_connect_instance_config(connectInstanceId=connect_instance_id)
+
+    assert "connectInstanceConfig" in response
+    config = response["connectInstanceConfig"]
+
+    assert config["connectInstanceId"] == connect_instance_id
+    assert "serviceLinkedRoleArn" in config
+    assert "encryptionConfig" in config
+    assert "enabled" in config["encryptionConfig"]
+    assert "encryptionType" in config["encryptionConfig"]
+    assert config["encryptionConfig"]["encryptionType"] == "KMS"
+
+    with pytest.raises(client.exceptions.ResourceNotFoundException):
+        client.get_connect_instance_config(connectInstanceId="invalid-id")
+
+
+@mock_aws
+def test_start_instance_onboarding_job():
+    client = boto3.client("connectcampaigns", region_name="us-east-1")
+
+    connect_instance_id = "12345678-1234-1234-1234-123456789012"
+
+    response = client.start_instance_onboarding_job(
+        connectInstanceId=connect_instance_id,
+        encryptionConfig={"enabled": False, "encryptionType": "KMS"},
+    )
+
+    assert "connectInstanceOnboardingJobStatus" in response
+    job_status = response["connectInstanceOnboardingJobStatus"]
+
+    assert job_status["connectInstanceId"] == connect_instance_id
+    assert job_status["status"] == "SUCCEEDED"
+    assert "failureCode" not in job_status
+
+    response = client.start_instance_onboarding_job(
+        connectInstanceId=connect_instance_id,
+        encryptionConfig={
+            "enabled": True,
+            "encryptionType": "KMS",
+            "keyArn": "arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab",
+        },
+    )
+
+    assert "connectInstanceOnboardingJobStatus" in response
+    job_status = response["connectInstanceOnboardingJobStatus"]
+
+    assert job_status["connectInstanceId"] == connect_instance_id
+    assert job_status["status"] == "SUCCEEDED"
+
+    with pytest.raises(client.exceptions.ResourceNotFoundException):
+        client.start_instance_onboarding_job(
+            connectInstanceId="invalid-id",
+            encryptionConfig={"enabled": False, "encryptionType": "KMS"},
+        )
+
+    with pytest.raises(client.exceptions.ValidationException):
+        client.start_instance_onboarding_job(
+            connectInstanceId=connect_instance_id,
+            encryptionConfig={"enabled": True, "encryptionType": "KMS"},
+        )
diff --git a/tests/test_ec2/test_elastic_network_interfaces.py b/tests/test_ec2/test_elastic_network_interfaces.py
index e6e869a3d..1198e0b6f 100644
--- a/tests/test_ec2/test_elastic_network_interfaces.py
+++ b/tests/test_ec2/test_elastic_network_interfaces.py
@@ -499,22 +499,28 @@ def test_elastic_network_interfaces_describe_network_interfaces_with_filter():
     waiter = ec2client.get_waiter("network_interface_available")
     waiter.wait(NetworkInterfaceIds=[eni1.id])
 
+    def assert_network_interface_found(resp):
+        assert len(resp["NetworkInterfaces"]) >= 1
+        for ni in resp["NetworkInterfaces"]:
+            if eni1.id == ni["NetworkInterfaceId"]:
+                break
+        else:
+            raise AssertionError("NetworkInterfaceId not found in response!")
+        assert ni["NetworkInterfaceId"] == eni1.id
+        assert ni["PrivateIpAddress"] == eni1.private_ip_address
+        assert ni["Description"] == eni1.description
+
     # Filter by network-interface-id
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "network-interface-id", "Values": [eni1.id]}]
     )
-    assert len(response["NetworkInterfaces"]) == 1
-    interface = response["NetworkInterfaces"][0]
-    assert interface["NetworkInterfaceId"] == eni1.id
-    assert interface["PrivateIpAddress"] == eni1.private_ip_address
-    assert interface["Description"] == eni1.description
+    assert_network_interface_found(response)
 
     # Filter by network-interface-id
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "group-id", "Values": [sg_id]}]
     )
-    assert len(response["NetworkInterfaces"]) == 1
-    assert response["NetworkInterfaces"][0]["NetworkInterfaceId"] == eni1.id
+    assert_network_interface_found(response)
 
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "network-interface-id", "Values": ["bad-id"]}]
@@ -525,27 +531,18 @@ def test_elastic_network_interfaces_describe_network_interfaces_with_filter():
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "private-ip-address", "Values": [eni1.private_ip_address]}]
     )
-    assert len(response["NetworkInterfaces"]) == 1
-    interface = response["NetworkInterfaces"][0]
-    assert interface["NetworkInterfaceId"] == eni1.id
-    assert interface["PrivateIpAddress"] == eni1.private_ip_address
-    assert interface["Description"] == eni1.description
+    assert_network_interface_found(response)
 
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "private-ip-address", "Values": ["11.11.11.11"]}]
     )
     assert len(response["NetworkInterfaces"]) == 0
 
-    # Filter by sunet-id
+    # Filter by subnet-id
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "subnet-id", "Values": [eni1.subnet.id]}]
     )
-    assert len(response["NetworkInterfaces"]) == 1
-    assert response["NetworkInterfaces"][0]["NetworkInterfaceId"] == eni1.id
-    assert (
-        response["NetworkInterfaces"][0]["PrivateIpAddress"] == eni1.private_ip_address
-    )
-    assert response["NetworkInterfaces"][0]["Description"] == eni1.description
+    assert_network_interface_found(response)
 
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "subnet-id", "Values": ["sn-bad-id"]}]
@@ -556,12 +553,7 @@ def test_elastic_network_interfaces_describe_network_interfaces_with_filter():
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "description", "Values": [eni1.description]}]
     )
-    assert len(response["NetworkInterfaces"]) == 1
-    assert response["NetworkInterfaces"][0]["NetworkInterfaceId"] == eni1.id
-    assert (
-        response["NetworkInterfaces"][0]["PrivateIpAddress"] == eni1.private_ip_address
-    )
-    assert response["NetworkInterfaces"][0]["Description"] == eni1.description
+    assert_network_interface_found(response)
 
     response = ec2client.describe_network_interfaces(
         Filters=[{"Name": "description", "Values": ["bad description"]}]
@@ -576,12 +568,7 @@ def test_elastic_network_interfaces_describe_network_interfaces_with_filter():
             {"Name": "subnet-id", "Values": [eni1.subnet.id]},
         ]
     )
-    assert len(response["NetworkInterfaces"]) == 1
-    assert response["NetworkInterfaces"][0]["NetworkInterfaceId"] == eni1.id
-    assert (
-        response["NetworkInterfaces"][0]["PrivateIpAddress"] == eni1.private_ip_address
-    )
-    assert response["NetworkInterfaces"][0]["Description"] == eni1.description
+    assert_network_interface_found(response)
 
 
 @mock_aws
diff --git a/tests/test_events/test_events.py b/tests/test_events/test_events.py
index aeb6fa5a1..1ecb2b7ee 100644
--- a/tests/test_events/test_events.py
+++ b/tests/test_events/test_events.py
@@ -853,25 +853,35 @@ def test_describe_event_bus():
     client = boto3.client("events", "us-east-1")
 
     response = client.describe_event_bus()
-
     assert response["Name"] == "default"
     assert response["Arn"] == f"arn:aws:events:us-east-1:{ACCOUNT_ID}:event-bus/default"
     assert "Policy" not in response
+    assert "CreationTime" in response
+    assert "LastModifiedTime" in response
+
+    bus_name = "test-bus"
+    client.create_event_bus(
+        Name=bus_name,
+        Description="Test description",
+        KmsKeyIdentifier="arn:aws:kms:us-east-1:123456789012:key/test",
+        DeadLetterConfig={"Arn": "arn:aws:sqs:us-east-1:123456789012:dlq"},
+    )
 
-    client.create_event_bus(Name="test-bus")
     client.put_permission(
-        EventBusName="test-bus",
+        EventBusName=bus_name,
         Action="events:PutEvents",
         Principal="111111111111",
         StatementId="test",
     )
 
-    response = client.describe_event_bus(Name="test-bus")
+    response = client.describe_event_bus(Name=bus_name)
 
-    assert response["Name"] == "test-bus"
+    assert response["Name"] == bus_name
     assert (
-        response["Arn"] == f"arn:aws:events:us-east-1:{ACCOUNT_ID}:event-bus/test-bus"
+        response["Arn"] == f"arn:aws:events:us-east-1:{ACCOUNT_ID}:event-bus/{bus_name}"
     )
+    assert "CreationTime" in response
+    assert "LastModifiedTime" in response
     assert json.loads(response["Policy"]) == {
         "Version": "2012-10-17",
         "Statement": [
@@ -880,11 +890,17 @@ def test_describe_event_bus():
                 "Effect": "Allow",
                 "Principal": {"AWS": "arn:aws:iam::111111111111:root"},
                 "Action": "events:PutEvents",
-                "Resource": f"arn:aws:events:us-east-1:{ACCOUNT_ID}:event-bus/test-bus",
+                "Resource": f"arn:aws:events:us-east-1:{ACCOUNT_ID}:event-bus/{bus_name}",
             }
         ],
     }
 
+    assert response["Description"] == "Test description"
+    assert response["KmsKeyIdentifier"] == "arn:aws:kms:us-east-1:123456789012:key/test"
+    assert response["DeadLetterConfig"] == {
+        "Arn": "arn:aws:sqs:us-east-1:123456789012:dlq"
+    }
+
 
 @mock_aws
 def test_describe_event_bus_errors():
diff --git a/tests/test_resourcegroups/test_resourcegroups.py b/tests/test_resourcegroups/test_resourcegroups.py
index 800de6ddc..41e3f1b5a 100644
--- a/tests/test_resourcegroups/test_resourcegroups.py
+++ b/tests/test_resourcegroups/test_resourcegroups.py
@@ -1,6 +1,8 @@
 import json
 
 import boto3
+import pytest
+from botocore.exceptions import ClientError
 
 from moto import mock_aws
 
@@ -48,14 +50,35 @@ def test_delete_group():
     assert len(response["Groups"]) == 0
 
 
+@mock_aws
+def test_delete_group_by_arn():
+    resource_groups = boto3.client("resource-groups", region_name="us-east-1")
+
+    response = create_group(client=resource_groups)
+    group_arn = response["Group"]["GroupArn"]
+
+    response = resource_groups.delete_group(GroupName=group_arn)
+    assert group_arn == response["Group"]["GroupArn"]
+
+    with pytest.raises(ClientError) as exc:
+        resource_groups.get_group(GroupName=group_arn)
+    error = exc.value.response["Error"]
+    assert error["Code"] == "NotFoundException"
+
+
 @mock_aws
 def test_get_group():
     resource_groups = boto3.client("resource-groups", region_name="us-east-1")
 
-    create_group(client=resource_groups)
+    response = create_group(client=resource_groups)
+    group_name = response["Group"]["Name"]
+    group_arn = response["Group"]["GroupArn"]
 
-    response = resource_groups.get_group(GroupName="test_resource_group")
-    assert "description" in response["Group"]["Description"]
+    response = resource_groups.get_group(GroupName=group_name)
+    assert response["Group"]["GroupArn"] == group_arn
+
+    response = resource_groups.get_group(GroupName=group_arn)
+    assert response["Group"]["Name"] == group_name
 
 
 @mock_aws
diff --git a/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py b/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py
index 1437df8ee..32d175790 100644
--- a/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py
+++ b/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py
@@ -605,6 +605,59 @@ def test_get_tag_values_lexv2_models():
     ]
 
 
+@mock_aws
+def test_get_tag_values_cloudwatch():
+    cloudwatch = boto3.client("cloudwatch", "us-east-1")
+
+    name = "tester"
+    cloudwatch.put_metric_alarm(
+        AlarmActions=["arn:alarm"],
+        AlarmDescription="A test",
+        AlarmName=name,
+        ComparisonOperator="GreaterThanOrEqualToThreshold",
+        Dimensions=[{"Name": "InstanceId", "Value": "i-0123457"}],
+        EvaluationPeriods=5,
+        InsufficientDataActions=["arn:insufficient"],
+        Namespace=f"{name}_namespace",
+        MetricName=f"{name}_metric",
+        OKActions=["arn:ok"],
+        Period=60,
+        Statistic="Average",
+        Threshold=2,
+        Unit="Seconds",
+        Tags=[{"Key": "key-1", "Value": "value-1"}],
+    )
+
+    cloudwatch.put_insight_rule(
+        RuleName=name,
+        RuleDefinition="""{"Schema": "CloudWatchLogRule}""",
+        RuleState="ENABLED",
+        Tags=[{"Key": "key-2", "Value": "value-2"}],
+    )
+    rtapi = boto3.client("resourcegroupstaggingapi", "us-east-1")
+
+    # Test alarm tag filtering
+    resp = rtapi.get_resources(
+        ResourceTypeFilters=["cloudwatch:alarm"],
+        TagFilters=[{"Key": "key-1", "Values": ["value-1"]}],
+    )
+    assert len(resp["ResourceTagMappingList"]) == 1
+    assert {"Key": "key-1", "Value": "value-1"} in resp["ResourceTagMappingList"][0][
+        "Tags"
+    ]
+
+    # Test insight-rule tag filtering
+    resp = rtapi.get_resources(
+        ResourceTypeFilters=["cloudwatch:insight-rule"],
+        TagFilters=[{"Key": "key-2", "Values": ["value-2"]}],
+    )
+
+    assert len(resp["ResourceTagMappingList"]) == 1
+    assert {"Key": "key-2", "Value": "value-2"} in resp["ResourceTagMappingList"][0][
+        "Tags"
+    ]
+
+
 @mock_aws
 def test_get_many_resources():
     elbv2 = boto3.client("elbv2", region_name="us-east-1")
diff --git a/tests/test_s3control/test_s3control.py b/tests/test_s3control/test_s3control.py
index 3d3ee982f..c3c88edc6 100644
--- a/tests/test_s3control/test_s3control.py
+++ b/tests/test_s3control/test_s3control.py
@@ -4,12 +4,11 @@ from boto3 import Session
 from botocore.client import ClientError
 
 from moto import mock_aws
+from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 
 
 @mock_aws
 def test_get_public_access_block_for_account():
-    from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
-
     client = boto3.client("s3control", region_name="us-west-2")
 
     # With an invalid account ID:
@@ -80,3 +79,109 @@ def test_get_public_access_block_for_account():
     assert (
         ce_err.value.response["Error"]["Code"] == "NoSuchPublicAccessBlockConfiguration"
     )
+
+
+@mock_aws
+def test_storage_lens_configuration():
+    client = boto3.client("s3control", region_name="us-east-2")
+    config_id = "my-test-config-id"
+    config = {
+        "Id": "id-test",
+        "AccountLevel": {
+            "ActivityMetrics": {"IsEnabled": True},
+            "BucketLevel": {
+                "ActivityMetrics": {"IsEnabled": True},
+                "PrefixLevel": {
+                    "StorageMetrics": {
+                        "IsEnabled": True,
+                        "SelectionCriteria": {
+                            "Delimiter": "string",
+                            "MaxDepth": 123,
+                            "MinStorageBytesPercentage": 100,
+                        },
+                    }
+                },
+                "AdvancedCostOptimizationMetrics": {"IsEnabled": True},
+                "AdvancedDataProtectionMetrics": {"IsEnabled": True},
+                "DetailedStatusCodesMetrics": {"IsEnabled": True},
+            },
+            "AdvancedCostOptimizationMetrics": {"IsEnabled": True},
+            "AdvancedDataProtectionMetrics": {"IsEnabled": True},
+            "DetailedStatusCodesMetrics": {"IsEnabled": True},
+            "StorageLensGroupLevel": {
+                "SelectionCriteria": {
+                    "Include": [
+                        "string",
+                    ],
+                    "Exclude": [
+                        "string",
+                    ],
+                }
+            },
+        },
+        "Include": {
+            "Buckets": [
+                "string",
+            ],
+            "Regions": [
+                "string",
+            ],
+        },
+        "Exclude": {
+            "Buckets": [
+                "string",
+            ],
+            "Regions": [
+                "string",
+            ],
+        },
+        "DataExport": {
+            "S3BucketDestination": {
+                "Format": "CSV",
+                "OutputSchemaVersion": "V_1",
+                "AccountId": ACCOUNT_ID,
+                "Arn": "arn:aws:s3:::bucket_name",
+                "Prefix": "/prefix",
+                "Encryption": {"SSES3": {}},
+            },
+            "CloudWatchMetrics": {"IsEnabled": True},
+        },
+        "IsEnabled": True,
+        "AwsOrg": {"Arn": "string"},
+        "StorageLensArn": "string",
+    }
+    tags = [
+        {
+            "Key": "string",
+            "Value": "string",
+        },
+    ]
+
+    resp = client.put_storage_lens_configuration(
+        AccountId=ACCOUNT_ID,
+        ConfigId=config_id,
+        StorageLensConfiguration=config,
+        Tags=tags,
+    )
+    assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
+
+    # Get the configuration:
+    resp = client.get_storage_lens_configuration(
+        AccountId=ACCOUNT_ID, ConfigId=config_id
+    )
+    assert "StorageLensConfiguration" in resp
+    assert resp["StorageLensConfiguration"]["Id"] == "id-test"
+    s3_dest = resp["StorageLensConfiguration"]["DataExport"]["S3BucketDestination"]
+    assert s3_dest["AccountId"] == ACCOUNT_ID
+    assert s3_dest["Arn"] == "arn:aws:s3:::bucket_name"
+    assert "Encryption" in s3_dest
+    assert s3_dest["Encryption"]["SSES3"] == {}
+
+    # List the configurations
+    resp = client.list_storage_lens_configurations(AccountId=ACCOUNT_ID)
+    assert len(resp["StorageLensConfigurationList"]) == 1
+    # Note the ID is NOT the config ID from the put request
+    # but the ID from the config itself
+    assert resp["StorageLensConfigurationList"][0]["Id"] == "id-test"
+    assert "StorageLensArn" in resp["StorageLensConfigurationList"][0]
+    assert resp["StorageLensConfigurationList"][0]["IsEnabled"] is True
diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py
index 4f1b8fb4b..d8f1ace24 100644
--- a/tests/test_sqs/test_sqs.py
+++ b/tests/test_sqs/test_sqs.py
@@ -3138,6 +3138,84 @@ def test_message_attributes_contains_trace_header():
     )
 
 
+@mock_aws
+@pytest.mark.parametrize(
+    "attribute",
+    [
+        "MessageGroupId",
+        "MessageDeduplicationId",
+        "ApproximateFirstReceiveTimestamp",
+        "ApproximateReceiveCount",
+        "SenderId",
+        "SentTimestamp",
+        "SequenceNumber",
+    ],
+)
+def test_message_system_attributes_contains_system_attribute(attribute):
+    sqs = boto3.resource("sqs", region_name=REGION)
+    conn = boto3.client("sqs", region_name=REGION)
+    q_name = str(uuid4())[0:6] + ".fifo"
+    q_resp = conn.create_queue(
+        QueueName=q_name,
+        Attributes={
+            "FifoQueue": "true",
+            "ContentBasedDeduplication": "true",
+        },
+    )
+    queue = sqs.Queue(q_resp["QueueUrl"])
+    body_one = "this is a test message"
+
+    queue.send_message(
+        MessageBody=body_one,
+        MessageGroupId="group1",
+        MessageDeduplicationId="dedup1",
+    )
+
+    messages = conn.receive_message(
+        QueueUrl=queue.url,
+        MaxNumberOfMessages=2,
+        MessageSystemAttributeNames=[attribute],
+    )["Messages"]
+
+    assert messages[0]["Attributes"].get(attribute) is not None
+
+
+@mock_aws
+def test_message_system_attributes_contains_all_attributes():
+    sqs = boto3.resource("sqs", region_name=REGION)
+    conn = boto3.client("sqs", region_name=REGION)
+    q_name = str(uuid4())[0:6] + ".fifo"
+    q_resp = conn.create_queue(
+        QueueName=q_name,
+        Attributes={
+            "FifoQueue": "true",
+            "ContentBasedDeduplication": "true",
+        },
+    )
+    queue = sqs.Queue(q_resp["QueueUrl"])
+    body_one = "this is a test message"
+
+    queue.send_message(
+        MessageBody=body_one,
+        MessageGroupId="group1",
+        MessageDeduplicationId="dedup1",
+    )
+
+    messages = conn.receive_message(
+        QueueUrl=queue.url,
+        MaxNumberOfMessages=2,
+        MessageSystemAttributeNames=["All"],
+    )["Messages"]
+
+    assert messages[0]["Attributes"]["MessageGroupId"] == "group1"
+    assert messages[0]["Attributes"]["MessageDeduplicationId"] == "dedup1"
+    assert messages[0]["Attributes"]["ApproximateFirstReceiveTimestamp"] is not None
+    assert messages[0]["Attributes"]["ApproximateReceiveCount"] == "1"
+    assert messages[0]["Attributes"]["SenderId"] is not None
+    assert messages[0]["Attributes"]["SentTimestamp"] is not None
+    assert messages[0]["Attributes"]["SequenceNumber"] is not None
+
+
 @mock_aws
 def test_receive_message_again_preserves_attributes():
     sqs = boto3.resource("sqs", region_name=REGION)