Repository: getmoto/moto
Pull request #7958 (2024-08-09 13:42:08)

ACM-PCA: Ensure backend is serialisable
## Background

Changes introduced in https://github.com/getmoto/moto/pull/7950 make the x509 Issuer a part of the `CertificateAuthority` model. Firstly, it is not necesary to retain this attribute in-memory. Secondly, because the x509 Issuer object is natively implemented in Rust, it cannot be serialised with pickle which breaks certain functionality in LocalStack.

## Changes

This PR changes the issuer into a class property which builds the x509 Issuer object on-demand.


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/getmoto/moto/pull/7958?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 94.36%. Comparing base [(`5ee1bdc`)](https://app.codecov.io/gh/getmoto/moto/commit/5ee1bdc5627b263ed4216914da067950151a8f5e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) to head [(`17a0b4a`)](https://app.codecov.io/gh/getmoto/moto/commit/17a0b4ac5d79804cfdc631f2c640d9648070da46?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master    #7958   +/-   ##
=======================================
  Coverage   94.36%   94.36%           
=======================================
  Files        1120     1120           
  Lines       96064    96066    +2     
=======================================
+ Hits        90650    90652    +2     
  Misses       5414     5414           
```

| [Flag](https://app.codecov.io/gh/getmoto/moto/pull/7958/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | Coverage Δ | |
|---|---|---|
| [servertests](https://app.codecov.io/gh/getmoto/moto/pull/7958/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | `28.95% <0.00%> (-0.01%)` | :arrow_down: |
| [unittests](https://app.codecov.io/gh/getmoto/moto/pull/7958/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | `94.33% <100.00%> (+<0.01%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/getmoto/moto/pull/7958?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).


Patch:
diff --git a/docs/docs/configuration/environment_variables.rst b/docs/docs/configuration/environment_variables.rst
index 2cc0382c0..fc7530b9e 100644
--- a/docs/docs/configuration/environment_variables.rst
+++ b/docs/docs/configuration/environment_variables.rst
@@ -34,6 +34,8 @@ The following is a non-exhaustive list of the environment variables that can be
 +-------------------------------+----------+-----------+-------------------------------------------------------------------------------------------------+
 | MOTO_S3_DEFAULT_MAX_KEYS      | str      |           | See :ref:`s3`.                                                                                  |
 +-------------------------------+----------+-----------+-------------------------------------------------------------------------------------------------+
+| S3_IGNORE_SUBDOMAIN_BUCKETNAME| str      |           | See :ref:`s3`.                                                                                  |
++-------------------------------+----------+-----------+-------------------------------------------------------------------------------------------------+
 | MOTO_PRETTIFY_RESPONSES       | bool     | False     | Prettify responses from Moto, making it easier to read and debug.                               |
 +-------------------------------+----------+-----------+-------------------------------------------------------------------------------------------------+
 
diff --git a/docs/docs/server_mode.rst b/docs/docs/server_mode.rst
index 3e8f1fc50..fd9c8c4ba 100644
--- a/docs/docs/server_mode.rst
+++ b/docs/docs/server_mode.rst
@@ -198,6 +198,10 @@ Other languages:
 * `Javascript`_
 
 
+.. warning::
+
+    Note that we use `localhost` everywhere here - 127.0.0.1 is not an adequate replacement, and may not work.
+
 Use ServerMode using the decorators
 -------------------------------------
 
diff --git a/moto/acmpca/models.py b/moto/acmpca/models.py
index 02e0413f8..38d91f9f8 100644
--- a/moto/acmpca/models.py
+++ b/moto/acmpca/models.py
@@ -60,36 +60,7 @@ class CertificateAuthority(BaseModel):
         self.certificate_chain: Optional[bytes] = None
         self.issued_certificates: Dict[str, bytes] = dict()
 
-        subject = self.certificate_authority_configuration.get("Subject", {})
-        name_attributes = []
-        if "Country" in subject:
-            name_attributes.append(
-                x509.NameAttribute(x509.NameOID.COUNTRY_NAME, subject["Country"])
-            )
-        if "State" in subject:
-            name_attributes.append(
-                x509.NameAttribute(
-                    x509.NameOID.STATE_OR_PROVINCE_NAME, subject["State"]
-                )
-            )
-        if "Organization" in subject:
-            name_attributes.append(
-                x509.NameAttribute(
-                    x509.NameOID.ORGANIZATION_NAME, subject["Organization"]
-                )
-            )
-        if "OrganizationalUnit" in subject:
-            name_attributes.append(
-                x509.NameAttribute(
-                    x509.NameOID.ORGANIZATIONAL_UNIT_NAME, subject["OrganizationalUnit"]
-                )
-            )
-        if "CommonName" in subject:
-            name_attributes.append(
-                x509.NameAttribute(x509.NameOID.COMMON_NAME, subject["CommonName"])
-            )
-        self.issuer = x509.Name(name_attributes)
-        self.csr = self._ca_csr(self.issuer)
+        self.subject = self.certificate_authority_configuration.get("Subject", {})
 
     def generate_cert(
         self,
@@ -114,10 +85,43 @@ class CertificateAuthority(BaseModel):
 
         return cert.public_bytes(serialization.Encoding.PEM)
 
-    def _ca_csr(self, issuer: x509.Name) -> bytes:
+    @property
+    def issuer(self) -> x509.Name:
+        name_attributes = []
+        if "Country" in self.subject:
+            name_attributes.append(
+                x509.NameAttribute(x509.NameOID.COUNTRY_NAME, self.subject["Country"])
+            )
+        if "State" in self.subject:
+            name_attributes.append(
+                x509.NameAttribute(
+                    x509.NameOID.STATE_OR_PROVINCE_NAME, self.subject["State"]
+                )
+            )
+        if "Organization" in self.subject:
+            name_attributes.append(
+                x509.NameAttribute(
+                    x509.NameOID.ORGANIZATION_NAME, self.subject["Organization"]
+                )
+            )
+        if "OrganizationalUnit" in self.subject:
+            name_attributes.append(
+                x509.NameAttribute(
+                    x509.NameOID.ORGANIZATIONAL_UNIT_NAME,
+                    self.subject["OrganizationalUnit"],
+                )
+            )
+        if "CommonName" in self.subject:
+            name_attributes.append(
+                x509.NameAttribute(x509.NameOID.COMMON_NAME, self.subject["CommonName"])
+            )
+        return x509.Name(name_attributes)
+
+    @property
+    def csr(self) -> bytes:
         csr = (
             x509.CertificateSigningRequestBuilder()
-            .subject_name(issuer)
+            .subject_name(self.issuer)
             .add_extension(
                 x509.BasicConstraints(ca=True, path_length=None),
                 critical=True,
diff --git a/moto/apigatewaymanagementapi/responses.py b/moto/apigatewaymanagementapi/responses.py
index 093fb81d9..49d45c359 100644
--- a/moto/apigatewaymanagementapi/responses.py
+++ b/moto/apigatewaymanagementapi/responses.py
@@ -3,7 +3,7 @@
 import json
 from typing import Any
 
-from moto.core.responses import BaseResponse
+from moto.core.responses import TYPE_RESPONSE, BaseResponse
 
 from .models import ApiGatewayManagementApiBackend, apigatewaymanagementapi_backends
 
@@ -46,3 +46,16 @@ class ApiGatewayManagementApiResponse(BaseResponse):
             connection_id=connection_id,
         )
         return "{}"
+
+    @staticmethod
+    def connect_to_apigateway(  # type: ignore[misc]
+        request: Any, full_url: str, headers: Any
+    ) -> TYPE_RESPONSE:
+        self = ApiGatewayManagementApiResponse()
+        self.setup_class(request, full_url, headers, use_raw_body=True)
+        if request.method == "GET":
+            return 200, {}, self.get_connection()
+        elif request.method == "DELETE":
+            return 200, {}, self.delete_connection()
+        else:
+            return 200, {}, self.post_to_connection()
diff --git a/moto/apigatewaymanagementapi/urls.py b/moto/apigatewaymanagementapi/urls.py
index f72047201..bbf32b52f 100644
--- a/moto/apigatewaymanagementapi/urls.py
+++ b/moto/apigatewaymanagementapi/urls.py
@@ -2,7 +2,9 @@
 
 from .responses import ApiGatewayManagementApiResponse
 
-url_bases = [r"https?://execute-api\.(.+)\.amazonaws\.com"]
+# execute-api.us-east-1.amazonaws.com
+# api_id.execute-api.us-east-1.amazonaws.com
+url_bases = [r"https?://(.+\.)*execute-api\.(.+)\.amazonaws\.com"]
 
 
 response = ApiGatewayManagementApiResponse()
@@ -10,4 +12,5 @@ response = ApiGatewayManagementApiResponse()
 
 url_paths = {
     "{0}/@connections/(?P<connection_id>[^/]+)$": response.dispatch,
+    "{0}/(?P<stage_name>.+/)+@connections/(?P<connection_id>[^/]+)$": response.connect_to_apigateway,
 }
diff --git a/moto/autoscaling/models.py b/moto/autoscaling/models.py
index 7ff98b502..4880b0a4e 100644
--- a/moto/autoscaling/models.py
+++ b/moto/autoscaling/models.py
@@ -720,6 +720,13 @@ class FakeAutoScalingGroup(CloudFormationModel):
 
         return self.launch_config.security_groups  # type: ignore[union-attr]
 
+    @property
+    def instance_tags(self) -> Dict[str, str]:
+        if self.launch_template:
+            version = self.launch_template.get_version(self.launch_template_version)
+            return version.instance_tags
+        return {}
+
     def update(
         self,
         availability_zones: List[str],
@@ -815,6 +822,7 @@ class FakeAutoScalingGroup(CloudFormationModel):
         self, count_needed: int, propagated_tags: Dict[str, str]
     ) -> None:
         propagated_tags[ASG_NAME_TAG] = self.name
+        propagated_tags.update(self.instance_tags)
 
         # VPCZoneIdentifier:
         # A comma-separated list of subnet IDs for a virtual private cloud (VPC) where instances in the Auto Scaling group can be created.
diff --git a/moto/backend_index.py b/moto/backend_index.py
index 91f12fa51..b7d561b88 100644
--- a/moto/backend_index.py
+++ b/moto/backend_index.py
@@ -8,7 +8,7 @@ backend_url_patterns = [
     ("apigateway", re.compile("https?://apigateway\\.(.+)\\.amazonaws.com")),
     (
         "apigatewaymanagementapi",
-        re.compile("https?://execute-api\\.(.+)\\.amazonaws\\.com"),
+        re.compile("https?://(.+\\.)*execute-api\\.(.+)\\.amazonaws\\.com"),
     ),
     ("appconfig", re.compile("https?://appconfig\\.(.+)\\.amazonaws\\.com")),
     (
diff --git a/moto/ec2/models/elastic_block_store.py b/moto/ec2/models/elastic_block_store.py
index 10b87bf26..cee0558d3 100644
--- a/moto/ec2/models/elastic_block_store.py
+++ b/moto/ec2/models/elastic_block_store.py
@@ -222,6 +222,7 @@ class Snapshot(TaggedEC2Resource):
         volume: Any,
         description: str,
         encrypted: bool = False,
+        kms_key_id: Optional[str] = None,
         owner_id: Optional[str] = None,
         from_ami: Optional[str] = None,
     ):
@@ -233,9 +234,10 @@ class Snapshot(TaggedEC2Resource):
         self.create_volume_permission_userids: Set[str] = set()
         self.ec2_backend = ec2_backend
         self.status = "completed"
-        self.encrypted = encrypted
+        self.encrypted = encrypted or (kms_key_id is not None)
         self.owner_id = owner_id or ec2_backend.account_id
         self.from_ami = from_ami
+        self.kms_key_id = kms_key_id
 
     def get_filter_value(
         self, filter_name: str, method_name: Optional[str] = None
@@ -252,6 +254,8 @@ class Snapshot(TaggedEC2Resource):
             return self.volume.size
         elif filter_name == "encrypted":
             return str(self.encrypted).lower()
+        elif filter_name == "kms-key-id":
+            return self.kms_key_id
         elif filter_name == "status":
             return self.status
         elif filter_name == "owner-id":
@@ -416,12 +420,18 @@ class EBSBackend:
     ) -> Snapshot:
         snapshot_id = random_snapshot_id()
         volume = self.get_volume(volume_id)
-        params = [self, snapshot_id, volume, description, volume.encrypted]
+        params = {
+            "ec2_backend": self,
+            "snapshot_id": snapshot_id,
+            "volume": volume,
+            "description": description,
+            "encrypted": volume.encrypted,
+        }
         if owner_id:
-            params.append(owner_id)
+            params["owner_id"] = owner_id
         if from_ami:
-            params.append(from_ami)
-        snapshot = Snapshot(*params)  # type: ignore[arg-type]
+            params["from_ami"] = from_ami
+        snapshot = Snapshot(**params)  # type: ignore[arg-type]
         self.snapshots[snapshot_id] = snapshot
         return snapshot
 
@@ -463,7 +473,11 @@ class EBSBackend:
         return matches
 
     def copy_snapshot(
-        self, source_snapshot_id: str, source_region: str, description: str
+        self,
+        source_snapshot_id: str,
+        source_region: str,
+        description: str,
+        kms_key_id: Optional[str],
     ) -> Snapshot:
         from ..models import ec2_backends
 
@@ -478,6 +492,7 @@ class EBSBackend:
             volume=source_snapshot.volume,
             description=description,
             encrypted=source_snapshot.encrypted,
+            kms_key_id=kms_key_id,
         )
         self.snapshots[snapshot_id] = snapshot
         return snapshot
diff --git a/moto/ec2/models/elastic_network_interfaces.py b/moto/ec2/models/elastic_network_interfaces.py
index 9c12986d1..8b6b05437 100644
--- a/moto/ec2/models/elastic_network_interfaces.py
+++ b/moto/ec2/models/elastic_network_interfaces.py
@@ -133,9 +133,9 @@ class NetworkInterface(TaggedEC2Resource, CloudFormationModel):
                         group_id,
                         group_id,
                         group_id,
-                        vpc_id=subnet.vpc_id,
+                        vpc_id=self.subnet.vpc_id,
                     )
-                    self.ec2_backend.groups[subnet.vpc_id][group_id] = group
+                    self.ec2_backend.groups[self.subnet.vpc_id][group_id] = group
                 if group:
                     self._group_set.append(group)
         if not group_ids:
diff --git a/moto/ec2/models/launch_templates.py b/moto/ec2/models/launch_templates.py
index bc01434e3..7a1c9d05d 100644
--- a/moto/ec2/models/launch_templates.py
+++ b/moto/ec2/models/launch_templates.py
@@ -32,6 +32,9 @@ class LaunchTemplateVersion:
         self.data = data
         self.description = description
         self.create_time = utc_date_and_time()
+        self.instance_tags = convert_tag_spec(data.get("TagSpecification", [])).get(
+            "instance", {}
+        )
 
     @property
     def image_id(self) -> str:
diff --git a/moto/ec2/responses/elastic_block_store.py b/moto/ec2/responses/elastic_block_store.py
index 6eb57e488..968b4629a 100644
--- a/moto/ec2/responses/elastic_block_store.py
+++ b/moto/ec2/responses/elastic_block_store.py
@@ -19,11 +19,15 @@ class ElasticBlockStore(EC2BaseResponse):
         description = self._get_param("Description")
         tags = self._parse_tag_specification()
         snapshot_tags = tags.get("snapshot", {})
+        kms_key_id = self._get_param("KmsKeyId")
 
         self.error_on_dryrun()
 
         snapshot = self.ec2_backend.copy_snapshot(
-            source_snapshot_id, source_region, description
+            source_snapshot_id=source_snapshot_id,
+            source_region=source_region,
+            description=description,
+            kms_key_id=kms_key_id,
         )
         snapshot.add_tags(snapshot_tags)
         template = self.response_template(COPY_SNAPSHOT_RESPONSE)
@@ -412,6 +416,7 @@ DESCRIBE_SNAPSHOTS_RESPONSE = """<DescribeSnapshotsResponse xmlns="http://ec2.am
             <volumeSize>{{ snapshot.volume.size }}</volumeSize>
              <description>{{ snapshot.description }}</description>
              <encrypted>{{ 'true' if snapshot.encrypted else 'false' }}</encrypted>
+             {% if snapshot.kms_key_id %}<kmsKeyId>{{ snapshot.kms_key_id }}</kmsKeyId>{% endif %}
              <tagSet>
                {% for tag in snapshot.get_tags() %}
                  <item>
diff --git a/moto/s3/exceptions.py b/moto/s3/exceptions.py
index 237096533..e17861a83 100644
--- a/moto/s3/exceptions.py
+++ b/moto/s3/exceptions.py
@@ -203,6 +203,26 @@ class IllegalLocationConstraintException(S3ClientError):
         )
 
 
+class IncompatibleLocationConstraintException(S3ClientError):
+    code = 400
+
+    def __init__(self, location: str) -> None:
+        super().__init__(
+            "IllegalLocationConstraintException",
+            f"The {location} location constraint is incompatible for the region specific endpoint this request was sent to.",
+        )
+
+
+class InvalidLocationConstraintException(S3ClientError):
+    code = 400
+
+    def __init__(self) -> None:
+        super().__init__(
+            "InvalidLocationConstraint",
+            "The specified location-constraint is not valid",
+        )
+
+
 class MalformedXML(S3ClientError):
     code = 400
 
diff --git a/moto/s3/models.py b/moto/s3/models.py
index ce7010700..b63043ebc 100644
--- a/moto/s3/models.py
+++ b/moto/s3/models.py
@@ -1686,6 +1686,20 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
 
     If this dependency is not installed, Moto will fall-back to the CRC32-computation when computing checksums.
 
+    _-_-_-_
+
+    S3 has two endpoint styles, where the bucket name can be either part of the domain (bucket.s3.amazonaws.com) or part of the path (s3.amazonaws.com/bucket).
+
+    If you're running MotoServer on a custom host, for instance on `http://moto.service:5000`, a CreateBucket-request then becomes `http://moto.service:5000/bucketname`.
+
+    However, because Moto tries to get the bucket-name from the domain first, it will think that 'moto' is the bucket name.
+
+    You can disable this behaviour with an environment variable, so that Moto will always look at the path instead:
+
+    .. sourcecode:: bash
+
+        S3_IGNORE_SUBDOMAIN_BUCKETNAME=true
+
     """
 
     def __init__(self, region_name: str, account_id: str):
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
index 90aba14eb..9e4f69399 100644
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -32,8 +32,10 @@ from .exceptions import (
     DuplicateTagKeys,
     HeadOnDeleteMarker,
     IllegalLocationConstraintException,
+    IncompatibleLocationConstraintException,
     InvalidContentMD5,
     InvalidContinuationToken,
+    InvalidLocationConstraintException,
     InvalidMaxPartArgument,
     InvalidMaxPartNumberArgument,
     InvalidNotificationARN,
@@ -736,27 +738,15 @@ class S3Response(BaseResponse):
                 result_folders.append(key)
         return result_keys, result_folders
 
-    def _body_contains_location_constraint(self, body: bytes) -> bool:
-        if body:
-            try:
-                xmltodict.parse(body)["CreateBucketConfiguration"]["LocationConstraint"]
-                return True
-            except KeyError:
-                pass
-        return False
-
-    def _create_bucket_configuration_is_empty(self, body: bytes) -> bool:
-        if body:
-            try:
-                create_bucket_configuration = xmltodict.parse(body)[
-                    "CreateBucketConfiguration"
+    def _get_location_constraint(self) -> Optional[str]:
+        try:
+            if self.body:
+                return xmltodict.parse(self.body)["CreateBucketConfiguration"][
+                    "LocationConstraint"
                 ]
-                del create_bucket_configuration["@xmlns"]
-                if len(create_bucket_configuration) == 0:
-                    return True
-            except KeyError:
-                pass
-        return False
+        except KeyError:
+            pass
+        return None
 
     def _parse_pab_config(self) -> Dict[str, Any]:
         parsed_xml = xmltodict.parse(self.body)
@@ -885,31 +875,20 @@ class S3Response(BaseResponse):
 
         else:
             # us-east-1, the default AWS region behaves a bit differently
-            # - you should not use it as a location constraint --> it fails
-            # - querying the location constraint returns None
-            # - LocationConstraint has to be specified if outside us-east-1
-            if (
-                self.region != DEFAULT_REGION_NAME
-                and not self._body_contains_location_constraint(self.body)
-            ):
-                raise IllegalLocationConstraintException()
-            if self.body:
-                if self._create_bucket_configuration_is_empty(self.body):
-                    raise MalformedXML()
-                try:
-                    forced_region = xmltodict.parse(self.body)[
-                        "CreateBucketConfiguration"
-                    ]["LocationConstraint"]
-
-                    if forced_region == DEFAULT_REGION_NAME:
-                        raise S3ClientError(
-                            "InvalidLocationConstraint",
-                            "The specified location-constraint is not valid",
-                        )
-                    else:
-                        self.region = forced_region
-                except KeyError:
-                    pass
+            # - you should not use any location constraint
+            location_constraint = self._get_location_constraint()
+            if self.region == DEFAULT_REGION_NAME:
+                # REGION = us-east-1 - we should never receive a LocationConstraint
+                if location_constraint:
+                    raise InvalidLocationConstraintException
+            else:
+                # Non-Standard region - the LocationConstraint must be equal to the actual region the request was send to
+                if not location_constraint:
+                    raise IllegalLocationConstraintException()
+                if location_constraint != self.region:
+                    raise IncompatibleLocationConstraintException(location_constraint)
+            if self.body and not location_constraint:
+                raise MalformedXML()
 
             try:
                 new_bucket = self.backend.create_bucket(bucket_name, self.region)


Test patch:
diff --git a/tests/test_apigateway/test_apigateway_integration.py b/tests/test_apigateway/test_apigateway_integration.py
index 8c82ee3c1..8899827cd 100644
--- a/tests/test_apigateway/test_apigateway_integration.py
+++ b/tests/test_apigateway/test_apigateway_integration.py
@@ -112,7 +112,7 @@ def test_aws_integration_dynamodb_multiple_stages():
         f"https://{api_id}.execute-api.us-west-2.amazonaws.com/prod",
         json={"TableName": table_name, "Item": {"name": {"S": "the-key"}}},
     )
-    assert res.status_code == 400
+    assert res.status_code in [400, 404]
 
 
 @mock_aws
diff --git a/tests/test_apigatewaymanagementapi/test_apigatewaymanagementapi.py b/tests/test_apigatewaymanagementapi/test_apigatewaymanagementapi.py
index c461752f7..e1f3e0ec7 100644
--- a/tests/test_apigatewaymanagementapi/test_apigatewaymanagementapi.py
+++ b/tests/test_apigatewaymanagementapi/test_apigatewaymanagementapi.py
@@ -14,8 +14,9 @@ from tests import DEFAULT_ACCOUNT_ID
 @mock_aws
 def test_delete_connection():
     if settings.TEST_SERVER_MODE and not is_werkzeug_2_3_x():
-        # URL matching changed between 2.2.x and 2.3.x
-        # 2.3.x has no problem matching the root path '/@connections', but 2.2.x refuses
+        # URL matching changed in 2.2.x - the root path '/@connections' cannot be found
+        # 2.1.x works, 2.2.x is broken, and 2.3.x (and 3.x) works again
+        # We could only skip 2.2.x - but only supporting >= 2.3.x is easier
         raise SkipTest("Can't test this in older werkzeug versions")
     client = boto3.client("apigatewaymanagementapi", region_name="eu-west-1")
     # NO-OP
@@ -54,3 +55,17 @@ def test_post_to_connection():
     if not settings.TEST_SERVER_MODE:
         backend = apigatewaymanagementapi_backends[DEFAULT_ACCOUNT_ID]["ap-southeast-1"]
         assert backend.connections["anything"].data == b"my first bytesmore bytes"
+
+
+@mock_aws
+def test_post_to_connection_using_endpoint_url():
+    if not settings.TEST_DECORATOR_MODE:
+        raise SkipTest("Can only test this with decorators")
+    client = boto3.client(
+        "apigatewaymanagementapi",
+        "us-west-2",
+        endpoint_url="https://someapiid.execute-api.us-west-2.amazonaws.com/stage",
+    )
+
+    client.get_connection(ConnectionId="anything")
+    client.post_to_connection(ConnectionId="n/a", Data=b"some data")
diff --git a/tests/test_autoscaling/test_autoscaling_groups.py b/tests/test_autoscaling/test_autoscaling_groups.py
index 680c959a7..70fa2504b 100644
--- a/tests/test_autoscaling/test_autoscaling_groups.py
+++ b/tests/test_autoscaling/test_autoscaling_groups.py
@@ -255,3 +255,45 @@ class TestAutoScalingGroup(TestCase):
             LaunchConfigurationName=self.lc_name,
             VPCZoneIdentifier=self.mocked_networking["subnet1"],
         )
+
+
+@mock_aws
+def test_launch_template_with_tags():
+    mocked_networking = setup_networking()
+
+    ec2_client = boto3.client("ec2", region_name="us-east-1")
+    template = ec2_client.create_launch_template(
+        LaunchTemplateName="test_launch_template",
+        LaunchTemplateData={
+            "ImageId": EXAMPLE_AMI_ID,
+            "InstanceType": "t2.micro",
+            "TagSpecifications": [
+                {
+                    "ResourceType": "instance",
+                    "Tags": [{"Key": "from_lt", "Value": "val"}],
+                }
+            ],
+        },
+    )["LaunchTemplate"]
+
+    as_client = boto3.client("autoscaling", region_name="us-east-1")
+    as_client.create_auto_scaling_group(
+        AutoScalingGroupName="myasgroup",
+        MinSize=1,
+        MaxSize=2,
+        LaunchTemplate={"LaunchTemplateId": template["LaunchTemplateId"]},
+        VPCZoneIdentifier=mocked_networking["subnet1"],
+        Tags=[
+            {
+                "PropagateAtLaunch": True,
+                "Key": "TestTagKey1",
+                "Value": "TestTagValue1",
+            }
+        ],
+    )
+
+    instances = ec2_client.describe_instances()
+
+    tags = instances["Reservations"][0]["Instances"][0]["Tags"]
+    assert {"Value": "TestTagValue1", "Key": "TestTagKey1"} in tags
+    assert {"Key": "from_lt", "Value": "val"} in tags
diff --git a/tests/test_awslambda/test_lambda.py b/tests/test_awslambda/test_lambda.py
index 1490cc568..e22c99584 100644
--- a/tests/test_awslambda/test_lambda.py
+++ b/tests/test_awslambda/test_lambda.py
@@ -774,10 +774,7 @@ def test_get_function_code_signing_config(key):
 def test_get_function_by_arn():
     bucket_name = str(uuid4())
     s3_conn = boto3.client("s3", "us-east-1")
-    s3_conn.create_bucket(
-        Bucket=bucket_name,
-        CreateBucketConfiguration={"LocationConstraint": _lambda_region},
-    )
+    s3_conn.create_bucket(Bucket=bucket_name)
 
     zip_content = get_test_zip_file2()
     s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
@@ -860,10 +857,7 @@ def test_delete_function():
 def test_delete_function_by_arn():
     bucket_name = str(uuid4())
     s3_conn = boto3.client("s3", "us-east-1")
-    s3_conn.create_bucket(
-        Bucket=bucket_name,
-        CreateBucketConfiguration={"LocationConstraint": _lambda_region},
-    )
+    s3_conn.create_bucket(Bucket=bucket_name)
 
     zip_content = get_test_zip_file2()
     s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
diff --git a/tests/test_cloudformation/test_cloudformation_stack_integration.py b/tests/test_cloudformation/test_cloudformation_stack_integration.py
index 3b067d6dd..fa9f08a69 100644
--- a/tests/test_cloudformation/test_cloudformation_stack_integration.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_integration.py
@@ -1045,7 +1045,7 @@ def test_stack_dynamodb_resources_integration():
 
 @mock_aws
 def test_create_log_group_using_fntransform():
-    s3_resource = boto3.resource("s3")
+    s3_resource = boto3.resource("s3", "us-west-2")
     s3_resource.create_bucket(
         Bucket="owi-common-cf",
         CreateBucketConfiguration={"LocationConstraint": "us-west-2"},
diff --git a/tests/test_cloudwatch/test_cloudwatch_boto3.py b/tests/test_cloudwatch/test_cloudwatch_boto3.py
index 7de4cb844..a64dc5d7e 100644
--- a/tests/test_cloudwatch/test_cloudwatch_boto3.py
+++ b/tests/test_cloudwatch/test_cloudwatch_boto3.py
@@ -1527,8 +1527,8 @@ def test_cloudwatch_return_s3_metrics():
     cloudwatch = boto3.client("cloudwatch", "eu-west-3")
 
     # given
-    s3 = boto3.resource("s3")
-    s3_client = boto3.client("s3")
+    s3 = boto3.resource("s3", "eu-west-3")
+    s3_client = boto3.client("s3", "eu-west-3")
     bucket = s3.Bucket(bucket_name)
     bucket.create(CreateBucketConfiguration={"LocationConstraint": "eu-west-3"})
     bucket.put_object(Body=b"ABCD", Key="file.txt")
diff --git a/tests/test_ec2/test_elastic_block_store.py b/tests/test_ec2/test_elastic_block_store.py
index 2f9b6ae95..1fdd4d75b 100644
--- a/tests/test_ec2/test_elastic_block_store.py
+++ b/tests/test_ec2/test_elastic_block_store.py
@@ -526,6 +526,14 @@ def test_snapshot_filters():
     assert snapshot1.id in [s["SnapshotId"] for s in snapshots]
     assert snapshot2.id in [s["SnapshotId"] for s in snapshots]
     assert snapshot3.id in [s["SnapshotId"] for s in snapshots]
+    #
+    # Create a copy with a KMS key, and filter on that
+    snapshot4 = client.copy_snapshot(
+        SourceSnapshotId=snapshot1.id,
+        SourceRegion="us-east-1",
+        KmsKeyId="newkmskey",
+    )["SnapshotId"]
+    verify_filter("kms-key-id", "newkmskey", expected=[snapshot4])
 
 
 @mock_aws
diff --git a/tests/test_ecs/test_ecs_boto3.py b/tests/test_ecs/test_ecs_boto3.py
index eb3ea0e13..0aaec121d 100644
--- a/tests/test_ecs/test_ecs_boto3.py
+++ b/tests/test_ecs/test_ecs_boto3.py
@@ -2093,6 +2093,43 @@ def test_run_task_awsvpc_network():
     assert {"name": "macAddress", "value": eni["MacAddress"]} in details
 
 
+@mock_aws
+def test_run_task_awsvpc_network__unknown_sec_group():
+    # Setup
+    client = boto3.client("ecs", region_name=ECS_REGION)
+    ec2_client = boto3.client("ec2", region_name=ECS_REGION)
+    ec2 = boto3.resource("ec2", region_name=ECS_REGION)
+
+    # ECS setup
+    setup_resources = setup_ecs(client, ec2)
+
+    # Execute
+    task = client.run_task(
+        cluster="test_ecs_cluster",
+        overrides={},
+        taskDefinition="test_ecs_task",
+        startedBy="moto",
+        launchType="FARGATE",
+        networkConfiguration={
+            "awsvpcConfiguration": {
+                "subnets": [setup_resources[0].id],
+                "securityGroups": ["unknown_sg"],
+            }
+        },
+    )["tasks"][0]
+    eni_id = next(
+        t["value"]
+        for t in task["attachments"][0]["details"]
+        if t["name"] == "networkInterfaceId"
+    )
+
+    eni = ec2_client.describe_network_interfaces(NetworkInterfaceIds=[eni_id])[
+        "NetworkInterfaces"
+    ][0]
+    # Unknown SecurityGroup is created for us
+    assert eni["Groups"] == [{"GroupId": "unknown_sg", "GroupName": "unknown_sg"}]
+
+
 @mock_aws
 def test_run_task_awsvpc_network_error():
     # Setup
diff --git a/tests/test_firehose/test_firehose_put.py b/tests/test_firehose/test_firehose_put.py
index 87f3e4385..8d58d6ce5 100644
--- a/tests/test_firehose/test_firehose_put.py
+++ b/tests/test_firehose/test_firehose_put.py
@@ -12,8 +12,6 @@ from tests.test_firehose.test_firehose_destination_types import (
     create_redshift_delivery_stream,
 )
 
-S3_LOCATION_CONSTRAINT = "us-west-1"
-
 
 @mock_aws
 def test_put_record_redshift_destination():
@@ -113,10 +111,13 @@ def test_put_record_batch_extended_s3_destination():
     # Create a S3 bucket.
     bucket_name = "firehosetestbucket"
     s3_client = boto3.client("s3", region_name=TEST_REGION)
-    s3_client.create_bucket(
-        Bucket=bucket_name,
-        CreateBucketConfiguration={"LocationConstraint": S3_LOCATION_CONSTRAINT},
-    )
+    if TEST_REGION == "us-east-1":
+        s3_client.create_bucket(Bucket=bucket_name)
+    else:
+        s3_client.create_bucket(
+            Bucket=bucket_name,
+            CreateBucketConfiguration={"LocationConstraint": TEST_REGION},
+        )
 
     stream_name = f"test_put_record_{mock_random.get_random_hex(6)}"
     client.create_delivery_stream(
diff --git a/tests/test_logs/test_integration.py b/tests/test_logs/test_integration.py
index 2d1604f04..5a079686f 100644
--- a/tests/test_logs/test_integration.py
+++ b/tests/test_logs/test_integration.py
@@ -275,10 +275,7 @@ def test_put_subscription_filter_with_firehose():
     # Create a S3 bucket.
     bucket_name = "firehosetestbucket"
     s3_client = boto3.client("s3", region_name=region_name)
-    s3_client.create_bucket(
-        Bucket=bucket_name,
-        CreateBucketConfiguration={"LocationConstraint": "us-west-1"},
-    )
+    s3_client.create_bucket(Bucket=bucket_name)
 
     # Create the Firehose delivery stream that uses that S3 bucket as
     # the destination.
diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py
index 00f43216e..9a9f0c863 100644
--- a/tests/test_s3/test_s3.py
+++ b/tests/test_s3/test_s3.py
@@ -24,7 +24,7 @@ from moto.core.utils import utcnow
 from moto.moto_api import state_manager
 from moto.s3.models import s3_backends
 from moto.s3.responses import DEFAULT_REGION_NAME
-from tests import DEFAULT_ACCOUNT_ID
+from tests import DEFAULT_ACCOUNT_ID, aws_verified
 
 from . import s3_aws_verified
 
@@ -271,6 +271,27 @@ def test_create_existing_bucket():
     )
 
 
+@aws_verified
+@pytest.mark.aws_verified
+@pytest.mark.parametrize(
+    "constraint", ["us-east-1", "us-east-2", "eu-central-1", "us-gov-east-2"]
+)
+def test_create_bucket_with_wrong_location_constraint(constraint):
+    client = boto3.client("s3", region_name="us-west-2")
+    kwargs = {
+        "Bucket": str(uuid.uuid4()),
+        "CreateBucketConfiguration": {"LocationConstraint": constraint},
+    }
+    with pytest.raises(ClientError) as ex:
+        client.create_bucket(**kwargs)
+    err = ex.value.response["Error"]
+    assert err["Code"] == "IllegalLocationConstraintException"
+    assert (
+        err["Message"]
+        == f"The {constraint} location constraint is incompatible for the region specific endpoint this request was sent to."
+    )
+
+
 @mock_aws
 def test_create_existing_bucket_in_us_east_1():
     """Creating a bucket that already exists in us-east-1 returns the bucket.
@@ -934,11 +955,9 @@ def test_put_chunked_with_v4_signature_in_body():
 
 @mock_aws
 def test_s3_object_in_private_bucket():
-    s3_resource = boto3.resource("s3")
+    s3_resource = boto3.resource("s3", "us-east-1")
     bucket = s3_resource.Bucket("test-bucket")
-    bucket.create(
-        ACL="private", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    bucket.create(ACL="private")
     bucket.put_object(ACL="private", Body=b"ABCD", Key="file.txt")
 
     s3_anonymous = boto3.resource("s3")
@@ -1580,7 +1599,8 @@ def test_bucket_create():
     )
 
 
-@mock_aws
+@aws_verified
+@pytest.mark.aws_verified
 def test_bucket_create_force_us_east_1():
     s3_resource = boto3.resource("s3", region_name=DEFAULT_REGION_NAME)
     with pytest.raises(ClientError) as exc:
@@ -1589,6 +1609,10 @@ def test_bucket_create_force_us_east_1():
             CreateBucketConfiguration={"LocationConstraint": DEFAULT_REGION_NAME},
         )
     assert exc.value.response["Error"]["Code"] == "InvalidLocationConstraint"
+    assert (
+        exc.value.response["Error"]["Message"]
+        == "The specified location-constraint is not valid"
+    )
 
 
 @mock_aws
@@ -2696,11 +2720,8 @@ def test_can_suspend_bucket_acceleration():
 @mock_aws
 def test_suspending_acceleration_on_not_configured_bucket_does_nothing():
     bucket_name = "some_bucket"
-    s3_client = boto3.client("s3")
-    s3_client.create_bucket(
-        Bucket=bucket_name,
-        CreateBucketConfiguration={"LocationConstraint": "us-west-1"},
-    )
+    s3_client = boto3.client("s3", DEFAULT_REGION_NAME)
+    s3_client.create_bucket(Bucket=bucket_name)
     resp = s3_client.put_bucket_accelerate_configuration(
         Bucket=bucket_name, AccelerateConfiguration={"Status": "Suspended"}
     )
diff --git a/tests/test_s3/test_s3_acl.py b/tests/test_s3/test_s3_acl.py
index 9dd998c12..2b4f65a6f 100644
--- a/tests/test_s3/test_s3_acl.py
+++ b/tests/test_s3/test_s3_acl.py
@@ -81,11 +81,9 @@ def test_acl_switching_nonexistent_key():
 
 @mock_aws
 def test_s3_object_in_public_bucket():
-    s3_resource = boto3.resource("s3")
+    s3_resource = boto3.resource("s3", DEFAULT_REGION_NAME)
     bucket = s3_resource.Bucket("test-bucket")
-    bucket.create(
-        ACL="public-read", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    bucket.create(ACL="public-read")
     bucket.put_object(Body=b"ABCD", Key="file.txt")
 
     s3_anonymous = boto3.resource("s3")
@@ -107,11 +105,9 @@ def test_s3_object_in_public_bucket():
 
 @mock_aws
 def test_s3_object_in_public_bucket_using_multiple_presigned_urls():
-    s3_resource = boto3.resource("s3")
+    s3_resource = boto3.resource("s3", DEFAULT_REGION_NAME)
     bucket = s3_resource.Bucket("test-bucket")
-    bucket.create(
-        ACL="public-read", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    bucket.create(ACL="public-read")
     bucket.put_object(Body=b"ABCD", Key="file.txt")
 
     params = {"Bucket": "test-bucket", "Key": "file.txt"}
@@ -128,11 +124,9 @@ def test_s3_object_in_public_bucket_using_multiple_presigned_urls():
 
 @mock_aws
 def test_s3_object_in_private_bucket():
-    s3_resource = boto3.resource("s3")
+    s3_resource = boto3.resource("s3", DEFAULT_REGION_NAME)
     bucket = s3_resource.Bucket("test-bucket")
-    bucket.create(
-        ACL="private", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    bucket.create(ACL="private")
     bucket.put_object(ACL="private", Body=b"ABCD", Key="file.txt")
 
     s3_anonymous = boto3.resource("s3")
diff --git a/tests/test_s3/test_s3_copyobject.py b/tests/test_s3/test_s3_copyobject.py
index 08ea47521..a75f18cc4 100644
--- a/tests/test_s3/test_s3_copyobject.py
+++ b/tests/test_s3/test_s3_copyobject.py
@@ -392,12 +392,8 @@ def test_copy_object_with_versioning(bucket_name=None):
 def test_copy_object_from_unversioned_to_versioned_bucket():
     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
 
-    client.create_bucket(
-        Bucket="src", CreateBucketConfiguration={"LocationConstraint": "eu-west-1"}
-    )
-    client.create_bucket(
-        Bucket="dest", CreateBucketConfiguration={"LocationConstraint": "eu-west-1"}
-    )
+    client.create_bucket(Bucket="src")
+    client.create_bucket(Bucket="dest")
     client.put_bucket_versioning(
         Bucket="dest", VersioningConfiguration={"Status": "Enabled"}
     )
@@ -459,9 +455,7 @@ def test_copy_object_with_kms_encryption():
     kms_client = boto3.client("kms", region_name=DEFAULT_REGION_NAME)
     kms_key = kms_client.create_key()["KeyMetadata"]["KeyId"]
 
-    client.create_bucket(
-        Bucket="blah", CreateBucketConfiguration={"LocationConstraint": "eu-west-1"}
-    )
+    client.create_bucket(Bucket="blah")
 
     client.put_object(Bucket="blah", Key="test1", Body=b"test1")
 
diff --git a/tests/test_s3/test_s3_lifecycle.py b/tests/test_s3/test_s3_lifecycle.py
index b43789139..569c7c74f 100644
--- a/tests/test_s3/test_s3_lifecycle.py
+++ b/tests/test_s3/test_s3_lifecycle.py
@@ -5,14 +5,13 @@ import pytest
 from botocore.exceptions import ClientError
 
 from moto import mock_aws
+from moto.s3.responses import DEFAULT_REGION_NAME
 
 
 @mock_aws
 def test_lifecycle_with_filters():
-    client = boto3.client("s3")
-    client.create_bucket(
-        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    client = boto3.client("s3", DEFAULT_REGION_NAME)
+    client.create_bucket(Bucket="bucket")
 
     # Create a lifecycle rule with a Filter (no tags):
     lfc = {
@@ -223,10 +222,8 @@ def test_lifecycle_with_filters():
 
 @mock_aws
 def test_lifecycle_with_eodm():
-    client = boto3.client("s3")
-    client.create_bucket(
-        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    client = boto3.client("s3", DEFAULT_REGION_NAME)
+    client.create_bucket(Bucket="bucket")
 
     lfc = {
         "Rules": [
@@ -273,10 +270,8 @@ def test_lifecycle_with_eodm():
 
 @mock_aws
 def test_lifecycle_with_nve():
-    client = boto3.client("s3")
-    client.create_bucket(
-        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    client = boto3.client("s3", DEFAULT_REGION_NAME)
+    client.create_bucket(Bucket="bucket")
 
     lfc = {
         "Rules": [
@@ -309,10 +304,8 @@ def test_lifecycle_with_nve():
 
 @mock_aws
 def test_lifecycle_with_nvt():
-    client = boto3.client("s3")
-    client.create_bucket(
-        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    client = boto3.client("s3", DEFAULT_REGION_NAME)
+    client.create_bucket(Bucket="bucket")
 
     lfc = {
         "Rules": [
@@ -377,10 +370,8 @@ def test_lifecycle_with_nvt():
 
 @mock_aws
 def test_lifecycle_with_multiple_nvt():
-    client = boto3.client("s3")
-    client.create_bucket(
-        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    client = boto3.client("s3", DEFAULT_REGION_NAME)
+    client.create_bucket(Bucket="bucket")
 
     lfc = {
         "Rules": [
@@ -412,10 +403,8 @@ def test_lifecycle_with_multiple_nvt():
 
 @mock_aws
 def test_lifecycle_with_multiple_transitions():
-    client = boto3.client("s3")
-    client.create_bucket(
-        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    client = boto3.client("s3", DEFAULT_REGION_NAME)
+    client.create_bucket(Bucket="bucket")
 
     lfc = {
         "Rules": [
@@ -447,10 +436,8 @@ def test_lifecycle_with_multiple_transitions():
 
 @mock_aws
 def test_lifecycle_with_aimu():
-    client = boto3.client("s3")
-    client.create_bucket(
-        Bucket="bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    client = boto3.client("s3", DEFAULT_REGION_NAME)
+    client.create_bucket(Bucket="bucket")
 
     lfc = {
         "Rules": [
diff --git a/tests/test_s3/test_s3_logging.py b/tests/test_s3/test_s3_logging.py
index d0a4c39d9..a728f3547 100644
--- a/tests/test_s3/test_s3_logging.py
+++ b/tests/test_s3/test_s3_logging.py
@@ -19,13 +19,14 @@ from tests.test_s3 import empty_bucket, s3_aws_verified
 @mock_aws
 def test_put_bucket_logging():
     s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
+    wrong_region_client = boto3.client("s3", region_name="us-west-2")
     bucket_name = "mybucket"
     log_bucket = "logbucket"
     wrong_region_bucket = "wrongregionlogbucket"
     s3_client.create_bucket(Bucket=bucket_name)
     # Adding the ACL for log-delivery later...
     s3_client.create_bucket(Bucket=log_bucket)
-    s3_client.create_bucket(
+    wrong_region_client.create_bucket(
         Bucket=wrong_region_bucket,
         CreateBucketConfiguration={"LocationConstraint": "us-west-2"},
     )
diff --git a/tests/test_s3/test_s3_storageclass.py b/tests/test_s3/test_s3_storageclass.py
index f2c202373..f40c97ee6 100644
--- a/tests/test_s3/test_s3_storageclass.py
+++ b/tests/test_s3/test_s3_storageclass.py
@@ -3,11 +3,12 @@ import pytest
 from botocore.exceptions import ClientError
 
 from moto import mock_aws
+from moto.s3.responses import DEFAULT_REGION_NAME
 
 
 @mock_aws
 def test_s3_storage_class_standard():
-    s3_client = boto3.client("s3", region_name="us-east-1")
+    s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
     s3_client.create_bucket(Bucket="Bucket")
 
     # add an object to the bucket with standard storage
@@ -21,10 +22,8 @@ def test_s3_storage_class_standard():
 
 @mock_aws
 def test_s3_storage_class_infrequent_access():
-    s3_client = boto3.client("s3")
-    s3_client.create_bucket(
-        Bucket="Bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-2"}
-    )
+    s3_client = boto3.client("s3", DEFAULT_REGION_NAME)
+    s3_client.create_bucket(Bucket="Bucket")
 
     # add an object to the bucket with standard storage
 
@@ -42,11 +41,9 @@ def test_s3_storage_class_infrequent_access():
 
 @mock_aws
 def test_s3_storage_class_intelligent_tiering():
-    s3_client = boto3.client("s3")
+    s3_client = boto3.client("s3", DEFAULT_REGION_NAME)
 
-    s3_client.create_bucket(
-        Bucket="Bucket", CreateBucketConfiguration={"LocationConstraint": "us-east-2"}
-    )
+    s3_client.create_bucket(Bucket="Bucket")
     s3_client.put_object(
         Bucket="Bucket",
         Key="my_key_infrequent",
@@ -118,10 +115,8 @@ def test_s3_invalid_copied_storage_class():
 
 @mock_aws
 def test_s3_invalid_storage_class():
-    s3_client = boto3.client("s3")
-    s3_client.create_bucket(
-        Bucket="Bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    s3_client = boto3.client("s3", DEFAULT_REGION_NAME)
+    s3_client.create_bucket(Bucket="Bucket")
 
     # Try to add an object with an invalid storage class
     with pytest.raises(ClientError) as err:
@@ -138,10 +133,8 @@ def test_s3_invalid_storage_class():
 
 @mock_aws
 def test_s3_default_storage_class():
-    s3_client = boto3.client("s3")
-    s3_client.create_bucket(
-        Bucket="Bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    s3_client = boto3.client("s3", DEFAULT_REGION_NAME)
+    s3_client.create_bucket(Bucket="Bucket")
 
     s3_client.put_object(Bucket="Bucket", Key="First_Object", Body="Body")
 
@@ -153,10 +146,8 @@ def test_s3_default_storage_class():
 
 @mock_aws
 def test_s3_copy_object_error_for_glacier_storage_class_not_restored():
-    s3_client = boto3.client("s3")
-    s3_client.create_bucket(
-        Bucket="Bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    s3_client = boto3.client("s3", DEFAULT_REGION_NAME)
+    s3_client.create_bucket(Bucket="Bucket")
 
     s3_client.put_object(
         Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="GLACIER"
@@ -174,10 +165,8 @@ def test_s3_copy_object_error_for_glacier_storage_class_not_restored():
 
 @mock_aws
 def test_s3_copy_object_error_for_deep_archive_storage_class_not_restored():
-    s3_client = boto3.client("s3")
-    s3_client.create_bucket(
-        Bucket="Bucket", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
-    )
+    s3_client = boto3.client("s3", DEFAULT_REGION_NAME)
+    s3_client.create_bucket(Bucket="Bucket")
 
     s3_client.put_object(
         Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="DEEP_ARCHIVE"
diff --git a/tests/test_sagemaker/test_sagemaker_pipeline.py b/tests/test_sagemaker/test_sagemaker_pipeline.py
index 30adf5540..862dc629e 100644
--- a/tests/test_sagemaker/test_sagemaker_pipeline.py
+++ b/tests/test_sagemaker/test_sagemaker_pipeline.py
@@ -26,7 +26,7 @@ TEST_REGION_NAME = "us-west-1"
 
 @contextmanager
 def setup_s3_pipeline_definition(bucket_name, object_key, pipeline_definition):
-    client = boto3.client("s3")
+    client = boto3.client("s3", TEST_REGION_NAME)
     client.create_bucket(
         Bucket=bucket_name,
         CreateBucketConfiguration={"LocationConstraint": TEST_REGION_NAME},