Repository: getmoto/moto
Pull request #7180 (2024-01-03 13:32:17)

Cloudformation: broken changeset update
Closes https://github.com/getmoto/moto/issues/7155


Patch:
diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py
index 296919853..1d6e18053 100644
--- a/moto/cloudformation/models.py
+++ b/moto/cloudformation/models.py
@@ -384,11 +384,12 @@ class FakeStack(CloudFormationModel):
         self.name = name
         self.account_id = account_id
         self.template = template
+        self.template_dict: Dict[str, Any]
         if template != {}:
             self._parse_template()
             self.description = self.template_dict.get("Description")
         else:
-            self.template_dict: Dict[str, Any] = {}
+            self.template_dict = {}
             self.description = None
         self.parameters = parameters
         self.region_name = region_name
@@ -412,12 +413,8 @@ class FakeStack(CloudFormationModel):
         self.status = "CREATE_PENDING"
 
     def has_template(self, other_template: str) -> bool:
-        our_template = (
-            self.template
-            if isinstance(self.template, dict)
-            else json.loads(self.template)
-        )
-        return our_template == json.loads(other_template)
+        self._parse_template()
+        return self.template_dict == self.parse_template(other_template)
 
     def has_parameters(self, other_parameters: Dict[str, Any]) -> bool:
         return self.parameters == other_parameters
@@ -465,11 +462,15 @@ class FakeStack(CloudFormationModel):
         self.events.append(event)
 
     def _parse_template(self) -> None:
+        self.template_dict = self.parse_template(self.template)  # type: ignore[arg-type]
+
+    @staticmethod
+    def parse_template(template: str) -> Dict[str, Any]:  # type: ignore[misc]
         yaml.add_multi_constructor("", yaml_tag_constructor)
         try:
-            self.template_dict = yaml.load(self.template, Loader=yaml.Loader)  # type: ignore[arg-type]
+            return yaml.load(template, Loader=yaml.Loader)
         except (ParserError, ScannerError):
-            self.template_dict = json.loads(self.template)  # type: ignore[arg-type]
+            return json.loads(template)
 
     @property
     def stack_parameters(self) -> Dict[str, Any]:  # type: ignore[misc]
diff --git a/moto/s3control/config.py b/moto/s3control/config.py
index 0f17b4a88..203b5e845 100644
--- a/moto/s3control/config.py
+++ b/moto/s3control/config.py
@@ -131,7 +131,7 @@ class S3AccountPublicAccessBlockConfigQuery(ConfigQueryModel[S3ControlBackend]):
 
         # Format the PAB to the AWS Config format:
         creation_time = utcnow()
-        config_data = {
+        config_data: Dict[str, Any] = {
             "version": "1.3",
             "accountId": account_id,
             "configurationItemCaptureTime": str(creation_time),
diff --git a/moto/ssoadmin/exceptions.py b/moto/ssoadmin/exceptions.py
index 990eaa5de..a5f5df6e2 100644
--- a/moto/ssoadmin/exceptions.py
+++ b/moto/ssoadmin/exceptions.py
@@ -2,6 +2,10 @@
 from moto.core.exceptions import JsonRESTError
 
 
-class ResourceNotFound(JsonRESTError):
-    def __init__(self) -> None:
-        super().__init__("ResourceNotFound", "Account not found")
+class ResourceNotFoundException(JsonRESTError):
+    def __init__(self, message: str = "Account not found") -> None:
+        super().__init__(
+            error_type="ResourceNotFoundException",
+            message=message,
+            code="ResourceNotFoundException",
+        )
diff --git a/moto/ssoadmin/models.py b/moto/ssoadmin/models.py
index 4a5097525..5cb410868 100644
--- a/moto/ssoadmin/models.py
+++ b/moto/ssoadmin/models.py
@@ -5,7 +5,7 @@ from moto.core.utils import unix_time
 from moto.moto_api._internal import mock_random as random
 from moto.utilities.paginator import paginate
 
-from .exceptions import ResourceNotFound
+from .exceptions import ResourceNotFoundException
 from .utils import PAGINATION_MODEL
 
 
@@ -59,6 +59,7 @@ class PermissionSet(BaseModel):
         self.relay_state = relay_state
         self.tags = tags
         self.created_date = unix_time()
+        self.inline_policy = ""
 
     def to_json(self, include_creation_date: bool = False) -> Dict[str, Any]:
         summary: Dict[str, Any] = {
@@ -155,14 +156,12 @@ class SSOAdminBackend(BaseBackend):
                 and principal_id_match
             ):
                 return account
-        raise ResourceNotFound
+        raise ResourceNotFoundException
 
+    @paginate(PAGINATION_MODEL)  # type: ignore[misc]
     def list_account_assignments(
         self, instance_arn: str, account_id: str, permission_set_arn: str
     ) -> List[Dict[str, Any]]:
-        """
-        Pagination has not yet been implemented
-        """
         account_assignments = []
         for assignment in self.account_assignments:
             if (
@@ -172,7 +171,7 @@ class SSOAdminBackend(BaseBackend):
             ):
                 account_assignments.append(
                     {
-                        "AccountId": account_id,
+                        "AccountId": assignment.target_id,
                         "PermissionSetArn": assignment.permission_set_arn,
                         "PrincipalType": assignment.principal_type,
                         "PrincipalId": assignment.principal_id,
@@ -275,7 +274,10 @@ class SSOAdminBackend(BaseBackend):
             )
             if instance_arn_match and permission_set_match:
                 return permission_set
-        raise ResourceNotFound
+        ps_id = permission_set_arn.split("/")[-1]
+        raise ResourceNotFoundException(
+            message=f"Could not find PermissionSet with id {ps_id}"
+        )
 
     @paginate(pagination_model=PAGINATION_MODEL)  # type: ignore[misc]
     def list_permission_sets(self, instance_arn: str) -> List[PermissionSet]:
@@ -285,5 +287,32 @@ class SSOAdminBackend(BaseBackend):
                 permission_sets.append(permission_set)
         return permission_sets
 
+    def put_inline_policy_to_permission_set(
+        self, instance_arn: str, permission_set_arn: str, inline_policy: str
+    ) -> None:
+        permission_set = self._find_permission_set(
+            instance_arn,
+            permission_set_arn,
+        )
+        permission_set.inline_policy = inline_policy
+
+    def get_inline_policy_for_permission_set(
+        self, instance_arn: str, permission_set_arn: str
+    ) -> str:
+        permission_set = self._find_permission_set(
+            instance_arn,
+            permission_set_arn,
+        )
+        return permission_set.inline_policy
+
+    def delete_inline_policy_from_permission_set(
+        self, instance_arn: str, permission_set_arn: str
+    ) -> None:
+        permission_set = self._find_permission_set(
+            instance_arn,
+            permission_set_arn,
+        )
+        permission_set.inline_policy = ""
+
 
 ssoadmin_backends = BackendDict(SSOAdminBackend, "sso")
diff --git a/moto/ssoadmin/responses.py b/moto/ssoadmin/responses.py
index e89ca0e89..dec1cb94c 100644
--- a/moto/ssoadmin/responses.py
+++ b/moto/ssoadmin/responses.py
@@ -62,12 +62,18 @@ class SSOAdminResponse(BaseResponse):
         instance_arn = params.get("InstanceArn")
         account_id = params.get("AccountId")
         permission_set_arn = params.get("PermissionSetArn")
-        assignments = self.ssoadmin_backend.list_account_assignments(
+        max_results = self._get_param("MaxResults")
+        next_token = self._get_param("NextToken")
+
+        assignments, next_token = self.ssoadmin_backend.list_account_assignments(
             instance_arn=instance_arn,
             account_id=account_id,
             permission_set_arn=permission_set_arn,
+            next_token=next_token,
+            max_results=max_results,
         )
-        return json.dumps({"AccountAssignments": assignments})
+
+        return json.dumps(dict(AccountAssignments=assignments, NextToken=next_token))
 
     def list_account_assignments_for_principal(self) -> str:
         filter_ = self._get_param("Filter", {})
@@ -160,3 +166,32 @@ class SSOAdminResponse(BaseResponse):
         if next_token:
             response["NextToken"] = next_token
         return json.dumps(response)
+
+    def put_inline_policy_to_permission_set(self) -> str:
+        instance_arn = self._get_param("InstanceArn")
+        permission_set_arn = self._get_param("PermissionSetArn")
+        inline_policy = self._get_param("InlinePolicy")
+        self.ssoadmin_backend.put_inline_policy_to_permission_set(
+            instance_arn=instance_arn,
+            permission_set_arn=permission_set_arn,
+            inline_policy=inline_policy,
+        )
+        return json.dumps({})
+
+    def get_inline_policy_for_permission_set(self) -> str:
+        instance_arn = self._get_param("InstanceArn")
+        permission_set_arn = self._get_param("PermissionSetArn")
+        inline_policy = self.ssoadmin_backend.get_inline_policy_for_permission_set(
+            instance_arn=instance_arn,
+            permission_set_arn=permission_set_arn,
+        )
+        return json.dumps({"InlinePolicy": inline_policy})
+
+    def delete_inline_policy_from_permission_set(self) -> str:
+        instance_arn = self._get_param("InstanceArn")
+        permission_set_arn = self._get_param("PermissionSetArn")
+        self.ssoadmin_backend.delete_inline_policy_from_permission_set(
+            instance_arn=instance_arn,
+            permission_set_arn=permission_set_arn,
+        )
+        return json.dumps({})
diff --git a/moto/ssoadmin/utils.py b/moto/ssoadmin/utils.py
index 45fc457f2..e7c3230ed 100644
--- a/moto/ssoadmin/utils.py
+++ b/moto/ssoadmin/utils.py
@@ -10,7 +10,19 @@ PAGINATION_MODEL = {
         "input_token": "next_token",
         "limit_key": "max_results",
         "limit_default": 100,
-        "result_key": "PermissionSets",
+        "result_key": "AccountAssignments",
+        "unique_attribute": [
+            "AccountId",
+            "PermissionSetArn",
+            "PrincipalId",
+            "PrincipalType",
+        ],
+    },
+    "list_account_assignments": {
+        "input_token": "next_token",
+        "limit_key": "max_results",
+        "limit_default": 100,
+        "result_key": "AccountAssignments",
         "unique_attribute": [
             "AccountId",
             "PermissionSetArn",


Test patch:
diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
index fcbfac2c0..9e3002b5d 100644
--- a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
@@ -24,6 +24,9 @@ from moto.cloudformation import cloudformation_backends
 from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 from tests import EXAMPLE_AMI_ID
 
+TEST_STACK_NAME = "test_stack"
+REGION_NAME = "us-east-1"
+
 dummy_template = {
     "AWSTemplateFormatVersion": "2010-09-09",
     "Description": "Stack 1",
@@ -120,6 +123,21 @@ Resources:
     Parameters:
 """
 
+dummy_update_template_yaml = """---
+AWSTemplateFormatVersion: '2010-09-09'
+Parameters:
+  KeyName:
+    Description: Name of an existing EC2 KeyPair
+    Type: AWS::EC2::KeyPair::KeyName
+    ConstraintDescription: must be the name of an existing EC2 KeyPair.
+Resources:
+  Instance:
+    Type: AWS::EC2::Instance
+    Properties:
+      ImageId: ami-12c6146b
+
+"""
+
 dummy_template_yaml_with_short_form_func = """---
 AWSTemplateFormatVersion: 2010-09-09
 Description: Stack1 with yaml template
@@ -310,27 +328,27 @@ dummy_unknown_template_json = json.dumps(dummy_unknown_template)
 @mock_cloudformation
 @mock_ec2
 def test_create_stack():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
     stack = cf.describe_stacks()["Stacks"][0]
-    assert stack["StackName"] == "test_stack"
+    assert stack["StackName"] == TEST_STACK_NAME
     assert stack["EnableTerminationProtection"] is False
 
-    template = cf.get_template(StackName="test_stack")["TemplateBody"]
+    template = cf.get_template(StackName=TEST_STACK_NAME)["TemplateBody"]
     assert template == dummy_template
 
 
 @mock_cloudformation
 def test_create_stack_with_additional_properties():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=dummy_template_json,
         EnableTerminationProtection=True,
         TimeoutInMinutes=25,
     )
     stack = cf.describe_stacks()["Stacks"][0]
-    assert stack["StackName"] == "test_stack"
+    assert stack["StackName"] == TEST_STACK_NAME
     assert stack["EnableTerminationProtection"] is True
     assert stack["TimeoutInMinutes"] == 25
 
@@ -338,7 +356,7 @@ def test_create_stack_with_additional_properties():
 @mock_cloudformation
 @mock_ec2
 def test_describe_stack_instances():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     cf.create_stack_instances(
         StackSetName="teststackset",
@@ -366,7 +384,7 @@ def test_describe_stack_instances():
 
 @mock_cloudformation
 def test_list_stacksets_length():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     cf.create_stack_set(StackSetName="teststackset2", TemplateBody=dummy_template_yaml)
     stacksets = cf.list_stack_sets()
@@ -375,10 +393,10 @@ def test_list_stacksets_length():
 
 @mock_cloudformation
 def test_filter_stacks():
-    conn = boto3.client("cloudformation", region_name="us-east-1")
-    conn.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    conn = boto3.client("cloudformation", region_name=REGION_NAME)
+    conn.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
     conn.create_stack(StackName="test_stack2", TemplateBody=dummy_template_json)
-    conn.update_stack(StackName="test_stack", TemplateBody=dummy_template_json2)
+    conn.update_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json2)
 
     stacks = conn.list_stacks(StackStatusFilter=["CREATE_COMPLETE"])
     assert len(stacks.get("StackSummaries")) == 1
@@ -388,7 +406,7 @@ def test_filter_stacks():
 
 @mock_cloudformation
 def test_list_stacksets_contents():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     stacksets = cf.list_stack_sets()
     assert stacksets["Summaries"][0]["StackSetName"] == "teststackset"
@@ -397,7 +415,7 @@ def test_list_stacksets_contents():
 
 @mock_cloudformation
 def test_stop_stack_set_operation():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     cf.create_stack_instances(
         StackSetName="teststackset",
@@ -414,7 +432,7 @@ def test_stop_stack_set_operation():
 
 @mock_cloudformation
 def test_describe_stack_set_operation():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="name", TemplateBody=dummy_template_json)
     operation_id = cf.create_stack_instances(
         StackSetName="name",
@@ -443,7 +461,7 @@ def test_describe_stack_set_operation():
 
 @mock_cloudformation
 def test_list_stack_set_operation_results():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     cf.create_stack_instances(
         StackSetName="teststackset",
@@ -466,7 +484,7 @@ def test_list_stack_set_operation_results():
 
 @mock_cloudformation
 def test_update_stack_instances():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     param = [
         {"ParameterKey": "TagDescription", "ParameterValue": "StackSetValue"},
         {"ParameterKey": "TagName", "ParameterValue": "StackSetValue2"},
@@ -524,7 +542,7 @@ def test_update_stack_instances():
 
 @mock_cloudformation
 def test_delete_stack_instances():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     tss = "teststackset"
     cf.create_stack_set(StackSetName=tss, TemplateBody=dummy_template_json)
     cf.create_stack_instances(
@@ -565,7 +583,7 @@ def test_delete_stack_instances():
 
 @mock_cloudformation
 def test_create_stack_instances():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     cf.create_stack_instances(
         StackSetName="teststackset",
@@ -580,7 +598,7 @@ def test_create_stack_instances():
 
 @mock_cloudformation
 def test_create_stack_instances_with_param_overrides():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     param = [
         {"ParameterKey": "TagDescription", "ParameterValue": "StackSetValue"},
         {"ParameterKey": "TagName", "ParameterValue": "StackSetValue2"},
@@ -615,7 +633,7 @@ def test_create_stack_instances_with_param_overrides():
 
 @mock_cloudformation
 def test_update_stack_set():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     param = [
         {"ParameterKey": "TagDescription", "ParameterValue": "StackSetValue"},
         {"ParameterKey": "TagName", "ParameterValue": "StackSetValue2"},
@@ -645,7 +663,7 @@ def test_update_stack_set():
 
 @mock_cloudformation
 def test_update_stack_set_with_previous_value():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     param = [
         {"ParameterKey": "TagDescription", "ParameterValue": "StackSetValue"},
         {"ParameterKey": "TagName", "ParameterValue": "StackSetValue2"},
@@ -675,7 +693,7 @@ def test_update_stack_set_with_previous_value():
 
 @mock_cloudformation
 def test_list_stack_set_operations():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     cf.create_stack_instances(
         StackSetName="teststackset",
@@ -695,7 +713,7 @@ def test_list_stack_set_operations():
 
 @mock_cloudformation
 def test_bad_list_stack_resources():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
 
     with pytest.raises(ClientError):
         cf.list_stack_resources(StackName="teststackset")
@@ -703,7 +721,7 @@ def test_bad_list_stack_resources():
 
 @mock_cloudformation
 def test_delete_stack_set_by_name():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="teststackset", TemplateBody=dummy_template_json)
     cf.delete_stack_set(StackSetName="teststackset")
 
@@ -721,7 +739,7 @@ def test_delete_stack_set_by_name():
 
 @mock_cloudformation
 def test_delete_stack_set_by_id():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     response = cf.create_stack_set(
         StackSetName="teststackset", TemplateBody=dummy_template_json
     )
@@ -736,7 +754,7 @@ def test_delete_stack_set_by_id():
 
 @mock_cloudformation
 def test_delete_stack_set__while_instances_are_running():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="a", TemplateBody=json.dumps(dummy_template3))
     cf.create_stack_instances(
         StackSetName="a",
@@ -762,7 +780,7 @@ def test_delete_stack_set__while_instances_are_running():
 
 @mock_cloudformation
 def test_create_stack_set():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     response = cf.create_stack_set(
         StackSetName="teststackset",
         TemplateBody=dummy_template_json,
@@ -780,7 +798,7 @@ def test_create_stack_set():
 @mock_cloudformation
 @pytest.mark.parametrize("name", ["1234", "stack_set", "-set"])
 def test_create_stack_set__invalid_name(name):
-    client = boto3.client("cloudformation", region_name="us-east-1")
+    client = boto3.client("cloudformation", region_name=REGION_NAME)
     with pytest.raises(ClientError) as exc:
         client.create_stack_set(StackSetName=name)
     err = exc.value.response["Error"]
@@ -793,7 +811,7 @@ def test_create_stack_set__invalid_name(name):
 
 @mock_cloudformation
 def test_create_stack_set_with_yaml():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack_set(StackSetName="tss", TemplateBody=dummy_template_yaml)
 
     tmplt = cf.describe_stack_set(StackSetName="tss")["StackSet"]["TemplateBody"]
@@ -803,8 +821,8 @@ def test_create_stack_set_with_yaml():
 @mock_cloudformation
 @mock_s3
 def test_create_stack_set_from_s3_url():
-    s3 = boto3.client("s3", region_name="us-east-1")
-    s3_conn = boto3.resource("s3", region_name="us-east-1")
+    s3 = boto3.client("s3", region_name=REGION_NAME)
+    s3_conn = boto3.resource("s3", region_name=REGION_NAME)
     s3_conn.create_bucket(Bucket="foobar")
 
     s3_conn.Object("foobar", "template-key").put(Body=dummy_template_json)
@@ -820,7 +838,7 @@ def test_create_stack_set_from_s3_url():
 
 @mock_cloudformation
 def test_create_stack_set_with_ref_yaml():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     params = [
         {"ParameterKey": "TagDescription", "ParameterValue": "desc_ref"},
         {"ParameterKey": "TagName", "ParameterValue": "name_ref"},
@@ -837,7 +855,7 @@ def test_create_stack_set_with_ref_yaml():
 
 @mock_cloudformation
 def test_describe_stack_set_params():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     params = [
         {"ParameterKey": "TagDescription", "ParameterValue": "desc_ref"},
         {"ParameterKey": "TagName", "ParameterValue": "name_ref"},
@@ -854,7 +872,7 @@ def test_describe_stack_set_params():
 
 @mock_cloudformation
 def test_describe_stack_set_by_id():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     ss_id = cf.create_stack_set(StackSetName="s", TemplateBody=dummy_template_json)[
         "StackSetId"
     ]
@@ -865,7 +883,7 @@ def test_describe_stack_set_by_id():
 
 @mock_cloudformation
 def test_create_stack_fail_missing_parameter():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
 
     with pytest.raises(ClientError, match="Missing parameter KeyName"):
         cf.create_stack(StackName="ts", TemplateBody=dummy_parametrized_template_json)
@@ -873,7 +891,7 @@ def test_create_stack_fail_missing_parameter():
 
 @mock_cloudformation
 def test_create_stack_s3_long_name():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
 
     stack_name = "MyLongStackName01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"
 
@@ -897,7 +915,7 @@ def test_create_stack_s3_long_name():
 
 @mock_cloudformation
 def test_create_stack_with_yaml():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(StackName="ts", TemplateBody=dummy_template_yaml)
 
     assert cf.get_template(StackName="ts")["TemplateBody"] == dummy_template_yaml
@@ -905,7 +923,7 @@ def test_create_stack_with_yaml():
 
 @mock_cloudformation
 def test_create_stack_with_short_form_func_yaml():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="ts", TemplateBody=dummy_template_yaml_with_short_form_func
     )
@@ -917,11 +935,11 @@ def test_create_stack_with_short_form_func_yaml():
 @mock_s3
 @mock_cloudformation
 def test_get_template_summary():
-    s3 = boto3.client("s3", region_name="us-east-1")
-    s3_conn = boto3.resource("s3", region_name="us-east-1")
+    s3 = boto3.client("s3", region_name=REGION_NAME)
+    s3_conn = boto3.resource("s3", region_name=REGION_NAME)
 
     # json template
-    conn = boto3.client("cloudformation", region_name="us-east-1")
+    conn = boto3.client("cloudformation", region_name=REGION_NAME)
     result = conn.get_template_summary(TemplateBody=json.dumps(dummy_template3))
     assert result["ResourceTypes"] == ["AWS::EC2::VPC"]
     assert result["Version"] == "2010-09-09"
@@ -929,8 +947,10 @@ def test_get_template_summary():
     assert result["Parameters"] == []
 
     # existing stack
-    conn.create_stack(StackName="test_stack", TemplateBody=json.dumps(dummy_template3))
-    result = conn.get_template_summary(StackName="test_stack")
+    conn.create_stack(
+        StackName=TEST_STACK_NAME, TemplateBody=json.dumps(dummy_template3)
+    )
+    result = conn.get_template_summary(StackName=TEST_STACK_NAME)
     assert result["ResourceTypes"] == ["AWS::EC2::VPC"]
     assert result["Version"] == "2010-09-09"
     assert result["Description"] == "Stack 3"
@@ -949,7 +969,7 @@ def test_get_template_summary():
     assert result["Description"] == "Stack 3"
 
     # yaml template
-    conn = boto3.client("cloudformation", region_name="us-east-1")
+    conn = boto3.client("cloudformation", region_name=REGION_NAME)
     result = conn.get_template_summary(TemplateBody=dummy_template_yaml)
     assert result["ResourceTypes"] == ["AWS::EC2::Instance"]
     assert result["Version"] == "2010-09-09"
@@ -958,7 +978,7 @@ def test_get_template_summary():
 
 @mock_cloudformation
 def test_get_template_summary_for_stack_created_by_changeset_execution():
-    conn = boto3.client("cloudformation", region_name="us-east-1")
+    conn = boto3.client("cloudformation", region_name=REGION_NAME)
     conn.create_change_set(
         StackName="stack_from_changeset",
         TemplateBody=json.dumps(dummy_template3),
@@ -980,11 +1000,12 @@ def test_get_template_summary_for_stack_created_by_changeset_execution():
 @mock_s3
 @mock_cloudformation
 def test_get_template_summary_for_template_containing_parameters():
-    conn = boto3.client("cloudformation", region_name="us-east-1")
+    conn = boto3.client("cloudformation", region_name=REGION_NAME)
     conn.create_stack(
-        StackName="test_stack", TemplateBody=json.dumps(dummy_template_with_parameters)
+        StackName=TEST_STACK_NAME,
+        TemplateBody=json.dumps(dummy_template_with_parameters),
     )
-    result = conn.get_template_summary(StackName="test_stack")
+    result = conn.get_template_summary(StackName=TEST_STACK_NAME)
     del result["ResponseMetadata"]
     assert result == {
         "Parameters": [
@@ -1021,18 +1042,18 @@ def test_get_template_summary_for_template_containing_parameters():
 
 @mock_cloudformation
 def test_create_stack_with_ref_yaml():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     params = [
         {"ParameterKey": "TagDescription", "ParameterValue": "desc_ref"},
         {"ParameterKey": "TagName", "ParameterValue": "name_ref"},
     ]
     cf.create_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=dummy_template_yaml_with_ref,
         Parameters=params,
     )
 
-    template_body = cf.get_template(StackName="test_stack")["TemplateBody"]
+    template_body = cf.get_template(StackName=TEST_STACK_NAME)["TemplateBody"]
     assert template_body == dummy_template_yaml_with_ref
 
 
@@ -1040,8 +1061,8 @@ def test_create_stack_with_ref_yaml():
 def test_creating_stacks_across_regions():
     west1_cf = boto3.resource("cloudformation", region_name="us-west-1")
     west2_cf = boto3.resource("cloudformation", region_name="us-west-2")
-    west1_cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
-    west2_cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    west1_cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
+    west2_cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
     west1_stacks = list(west1_cf.stacks.all())
     west2_stacks = list(west2_cf.stacks.all())
@@ -1060,17 +1081,17 @@ def test_creating_stacks_across_regions():
 @mock_sns
 @mock_sqs
 def test_create_stack_with_notification_arn():
-    sqs = boto3.resource("sqs", region_name="us-east-1")
+    sqs = boto3.resource("sqs", region_name=REGION_NAME)
     queue = sqs.create_queue(QueueName="fake-queue")
     queue_arn = queue.attributes["QueueArn"]
 
-    sns = boto3.client("sns", region_name="us-east-1")
+    sns = boto3.client("sns", region_name=REGION_NAME)
     topic = sns.create_topic(Name="fake-topic")
     topic_arn = topic["TopicArn"]
 
     sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=queue_arn)
 
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="test_stack_with_notifications",
         TemplateBody=dummy_template_json,
@@ -1120,7 +1141,7 @@ def test_create_stack_with_notification_arn():
 
 @mock_cloudformation
 def test_create_stack_with_role_arn():
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="test_stack_with_notifications",
         TemplateBody=dummy_template_json,
@@ -1133,8 +1154,8 @@ def test_create_stack_with_role_arn():
 @mock_cloudformation
 @mock_s3
 def test_create_stack_from_s3_url():
-    s3 = boto3.client("s3", region_name="us-east-1")
-    s3_conn = boto3.resource("s3", region_name="us-east-1")
+    s3 = boto3.client("s3", region_name=REGION_NAME)
+    s3_conn = boto3.resource("s3", region_name=REGION_NAME)
     s3_conn.create_bucket(Bucket="foobar")
 
     s3_conn.Object("foobar", "template-key").put(Body=dummy_template_json)
@@ -1152,7 +1173,7 @@ def test_create_stack_from_s3_url():
 def test_update_stack_fail_missing_new_parameter():
     name = "update_stack_fail_missing_new_parameter"
 
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
 
     cf.create_stack(StackName=name, TemplateBody=dummy_empty_template_json)
 
@@ -1163,7 +1184,7 @@ def test_update_stack_fail_missing_new_parameter():
 @mock_cloudformation
 def test_update_stack_fail_update_same_template_body():
     name = "update_stack_with_previous_value"
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     params = [
         {"ParameterKey": "TagName", "ParameterValue": "foo"},
         {"ParameterKey": "TagDescription", "ParameterValue": "bar"},
@@ -1198,7 +1219,7 @@ def test_update_stack_fail_update_same_template_body():
 def test_update_stack_deleted_resources_can_reference_deleted_parameters():
     name = "update_stack_deleted_resources_can_reference_deleted_parameters"
 
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
 
     template_json = json.dumps(
         {
@@ -1228,7 +1249,7 @@ def test_update_stack_deleted_resources_can_reference_deleted_parameters():
 def test_update_stack_deleted_resources_can_reference_deleted_resources():
     name = "update_stack_deleted_resources_can_reference_deleted_resources"
 
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
 
     template_json = json.dumps(
         {
@@ -1261,7 +1282,7 @@ def test_update_stack_deleted_resources_can_reference_deleted_resources():
 @mock_cloudformation
 def test_update_stack_with_previous_value():
     name = "update_stack_with_previous_value"
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName=name,
         TemplateBody=dummy_template_yaml_with_ref,
@@ -1297,10 +1318,10 @@ def test_update_stack_with_previous_value():
 @mock_s3
 @mock_ec2
 def test_update_stack_from_s3_url():
-    s3 = boto3.client("s3", region_name="us-east-1")
-    s3_conn = boto3.resource("s3", region_name="us-east-1")
+    s3 = boto3.client("s3", region_name=REGION_NAME)
+    s3_conn = boto3.resource("s3", region_name=REGION_NAME)
 
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="update_stack_from_url",
         TemplateBody=dummy_template_json,
@@ -1329,8 +1350,8 @@ def test_update_stack_from_s3_url():
 @mock_cloudformation
 @mock_s3
 def test_create_change_set_from_s3_url():
-    s3 = boto3.client("s3", region_name="us-east-1")
-    s3_conn = boto3.resource("s3", region_name="us-east-1")
+    s3 = boto3.client("s3", region_name=REGION_NAME)
+    s3_conn = boto3.resource("s3", region_name=REGION_NAME)
     s3_conn.create_bucket(Bucket="foobar")
 
     s3_conn.Object("foobar", "template-key").put(Body=dummy_template_json)
@@ -1355,13 +1376,21 @@ def test_create_change_set_from_s3_url():
     )
 
 
+@pytest.mark.parametrize(
+    "stack_template,change_template",
+    [
+        pytest.param(dummy_template_yaml, dummy_update_template_json),
+        pytest.param(dummy_template_json, dummy_update_template_json),
+        pytest.param(dummy_template_yaml, dummy_update_template_yaml),
+    ],
+)
 @mock_cloudformation
 @mock_ec2
-def test_describe_change_set():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+def test_describe_change_set(stack_template, change_template):
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_change_set(
         StackName="NewStack",
-        TemplateBody=dummy_template_json,
+        TemplateBody=stack_template,
         ChangeSetName="NewChangeSet",
         ChangeSetType="CREATE",
     )
@@ -1390,7 +1419,7 @@ def test_describe_change_set():
     cf.execute_change_set(ChangeSetName="NewChangeSet")
 
     # Verify that the changes have been applied
-    ec2 = boto3.client("ec2", region_name="us-east-1")
+    ec2 = boto3.client("ec2", region_name=REGION_NAME)
     assert len(ec2.describe_instances()["Reservations"]) == 1
 
     change_set = cf.describe_change_set(ChangeSetName="NewChangeSet")
@@ -1403,7 +1432,7 @@ def test_describe_change_set():
     # create another change set to update the stack
     cf.create_change_set(
         StackName="NewStack",
-        TemplateBody=dummy_update_template_json,
+        TemplateBody=change_template,
         ChangeSetName="NewChangeSet2",
         ChangeSetType="UPDATE",
         Parameters=[{"ParameterKey": "KeyName", "ParameterValue": "value"}],
@@ -1425,8 +1454,8 @@ def test_describe_change_set():
 @mock_cloudformation
 @mock_ec2
 def test_execute_change_set_w_arn():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    ec2 = boto3.client("ec2", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    ec2 = boto3.client("ec2", region_name=REGION_NAME)
     # Verify no instances exist at the moment
     assert len(ec2.describe_instances()["Reservations"]) == 0
     # Create a Change set, and verify no resources have been created yet
@@ -1447,7 +1476,7 @@ def test_execute_change_set_w_arn():
 
 @mock_cloudformation
 def test_execute_change_set_w_name():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_change_set(
         StackName="NewStack",
         TemplateBody=dummy_template_json,
@@ -1459,7 +1488,7 @@ def test_execute_change_set_w_name():
 
 @mock_cloudformation
 def test_describe_stack_pagination():
-    conn = boto3.client("cloudformation", region_name="us-east-1")
+    conn = boto3.client("cloudformation", region_name=REGION_NAME)
     for i in range(100):
         conn.create_stack(StackName=f"test_stack_{i}", TemplateBody=dummy_template_json)
 
@@ -1476,10 +1505,10 @@ def test_describe_stack_pagination():
 
 @mock_cloudformation
 def test_describe_stack_resource():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
 
     response = cf.describe_stack_resource(
         StackName=stack["StackName"], LogicalResourceId="EC2Instance1"
@@ -1494,10 +1523,10 @@ def test_describe_stack_resource():
 
 @mock_cloudformation
 def test_describe_stack_resource_when_resource_does_not_exist():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
 
     with pytest.raises(ClientError, match="does not exist for stack"):
         cf.describe_stack_resource(
@@ -1507,10 +1536,10 @@ def test_describe_stack_resource_when_resource_does_not_exist():
 
 @mock_cloudformation
 def test_describe_stack_resources():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
 
     response = cf.describe_stack_resources(StackName=stack["StackName"])
     resource = response["StackResources"][0]
@@ -1522,11 +1551,11 @@ def test_describe_stack_resources():
 
 @mock_cloudformation
 def test_describe_stack_by_name():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
-    assert stack["StackName"] == "test_stack"
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
+    assert stack["StackName"] == TEST_STACK_NAME
     two_secs_ago = datetime.now(tz=timezone.utc) - timedelta(seconds=2)
     assert (
         two_secs_ago < stack["CreationTime"] < datetime.now(tz=timezone.utc)
@@ -1535,19 +1564,19 @@ def test_describe_stack_by_name():
 
 @mock_cloudformation
 def test_describe_stack_by_stack_id():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
     stack_by_id = cf.describe_stacks(StackName=stack["StackId"])["Stacks"][0]
 
     assert stack_by_id["StackId"] == stack["StackId"]
-    assert stack_by_id["StackName"] == "test_stack"
+    assert stack_by_id["StackName"] == TEST_STACK_NAME
 
 
 @mock_cloudformation
 def test_list_change_sets():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_change_set(
         StackName="NewStack2",
         TemplateBody=dummy_template_json,
@@ -1561,21 +1590,21 @@ def test_list_change_sets():
 
 @mock_cloudformation
 def test_list_stacks():
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
     cf.create_stack(StackName="test_stack2", TemplateBody=dummy_template_json)
 
     stacks = list(cf.stacks.all())
     assert len(stacks) == 2
     stack_names = [stack.stack_name for stack in stacks]
-    assert "test_stack" in stack_names
+    assert TEST_STACK_NAME in stack_names
     assert "test_stack2" in stack_names
 
 
 @mock_cloudformation
 def test_delete_stack_from_resource():
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
-    stack = cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
+    stack = cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
     assert len(list(cf.stacks.all())) == 1
     stack.delete()
@@ -1585,7 +1614,7 @@ def test_delete_stack_from_resource():
 @mock_cloudformation
 @mock_ec2
 def test_delete_change_set():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_change_set(
         StackName="NewStack",
         TemplateBody=dummy_template_json,
@@ -1611,7 +1640,7 @@ def test_delete_change_set():
 @mock_cloudformation
 @mock_ec2
 def test_create_change_set_twice__no_changes():
-    cf_client = boto3.client("cloudformation", region_name="us-east-1")
+    cf_client = boto3.client("cloudformation", region_name=REGION_NAME)
 
     # Execute once
     change_set_id = cf_client.create_change_set(
@@ -1644,9 +1673,9 @@ def test_create_change_set_twice__no_changes():
 @mock_ec2
 @mock_s3
 def test_create_change_set_twice__using_s3__no_changes():
-    cf_client = boto3.client("cloudformation", region_name="us-east-1")
-    s3 = boto3.client("s3", region_name="us-east-1")
-    s3_conn = boto3.resource("s3", region_name="us-east-1")
+    cf_client = boto3.client("cloudformation", region_name=REGION_NAME)
+    s3 = boto3.client("s3", region_name=REGION_NAME)
+    s3_conn = boto3.resource("s3", region_name=REGION_NAME)
     s3_conn.create_bucket(Bucket="foobar")
 
     s3_conn.Object("foobar", "template-key").put(Body=dummy_template_json)
@@ -1690,24 +1719,24 @@ def test_create_change_set_twice__using_s3__no_changes():
 @mock_cloudformation
 @mock_ec2
 def test_delete_stack_by_name():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
     assert len(cf.describe_stacks()["Stacks"]) == 1
-    cf.delete_stack(StackName="test_stack")
+    cf.delete_stack(StackName=TEST_STACK_NAME)
     assert len(cf.describe_stacks()["Stacks"]) == 0
 
 
 @mock_cloudformation
 @mock_ec2
 def test_delete_stack():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    ec2 = boto3.client("ec2", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    ec2 = boto3.client("ec2", region_name=REGION_NAME)
 
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
     state = ec2.describe_instances()["Reservations"][0]["Instances"][0]["State"]
 
-    cf.delete_stack(StackName="test_stack")
+    cf.delete_stack(StackName=TEST_STACK_NAME)
     stacks = cf.list_stacks()
     assert stacks["StackSummaries"][0]["StackStatus"] == "DELETE_COMPLETE"
     assert ec2.describe_instances()["Reservations"][0]["Instances"][0]["State"] != state
@@ -1725,14 +1754,14 @@ def test_delete_stack_delete_not_implemented(monkeypatch):
     )
     monkeypatch.delattr("moto.ec2.models.instances.Instance.delete")
 
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    ec2 = boto3.client("ec2", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    ec2 = boto3.client("ec2", region_name=REGION_NAME)
 
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
     state = ec2.describe_instances()["Reservations"][0]["Instances"][0]["State"]
 
     # Mock stack deletion succeeds
-    cf.delete_stack(StackName="test_stack")
+    cf.delete_stack(StackName=TEST_STACK_NAME)
     stacks = cf.list_stacks()
     assert stacks["StackSummaries"][0]["StackStatus"] == "DELETE_COMPLETE"
     # But the underlying resource is untouched
@@ -1741,21 +1770,21 @@ def test_delete_stack_delete_not_implemented(monkeypatch):
 
 @mock_cloudformation
 def test_describe_deleted_stack():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
     stack_id = stack["StackId"]
     cf.delete_stack(StackName=stack["StackId"])
     stack_by_id = cf.describe_stacks(StackName=stack_id)["Stacks"][0]
     assert stack_by_id["StackId"] == stack["StackId"]
-    assert stack_by_id["StackName"] == "test_stack"
+    assert stack_by_id["StackName"] == TEST_STACK_NAME
     assert stack_by_id["StackStatus"] == "DELETE_COMPLETE"
 
 
 @mock_cloudformation
 def test_describe_stack_with_special_chars():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="test_stack_spl",
         TemplateBody=dummy_template_special_chars_in_description_json,
@@ -1769,53 +1798,53 @@ def test_describe_stack_with_special_chars():
 @mock_cloudformation
 @mock_ec2
 def test_describe_updated_stack():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=dummy_template_json,
         Tags=[{"Key": "foo", "Value": "bar"}],
     )
 
     cf.update_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         RoleARN=f"arn:aws:iam::{ACCOUNT_ID}:role/moto",
         TemplateBody=dummy_update_template_json,
         Tags=[{"Key": "foo", "Value": "baz"}],
         Parameters=[{"ParameterKey": "KeyName", "ParameterValue": "value"}],
     )
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
     stack_id = stack["StackId"]
     stack_by_id = cf.describe_stacks(StackName=stack_id)["Stacks"][0]
     assert stack_by_id["StackId"] == stack["StackId"]
-    assert stack_by_id["StackName"] == "test_stack"
+    assert stack_by_id["StackName"] == TEST_STACK_NAME
     assert stack_by_id["StackStatus"] == "UPDATE_COMPLETE"
     assert stack_by_id["RoleARN"] == f"arn:aws:iam::{ACCOUNT_ID}:role/moto"
     assert stack_by_id["Tags"] == [{"Key": "foo", "Value": "baz"}]
 
     # Verify the updated template is persisted
-    template = cf.get_template(StackName="test_stack")["TemplateBody"]
+    template = cf.get_template(StackName=TEST_STACK_NAME)["TemplateBody"]
     assert template == dummy_update_template
 
 
 @mock_cloudformation
 def test_update_stack_with_previous_template():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
-    cf.update_stack(StackName="test_stack", UsePreviousTemplate=True)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
+    cf.update_stack(StackName=TEST_STACK_NAME, UsePreviousTemplate=True)
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
-    assert stack["StackName"] == "test_stack"
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
+    assert stack["StackName"] == TEST_STACK_NAME
     assert stack["StackStatus"] == "UPDATE_COMPLETE"
 
     # Verify the original template is persisted
-    template = cf.get_template(StackName="test_stack")["TemplateBody"]
+    template = cf.get_template(StackName=TEST_STACK_NAME)["TemplateBody"]
     assert template == dummy_template
 
 
 @mock_cloudformation
 def test_bad_describe_stack():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     with pytest.raises(ClientError) as exc:
         cf.describe_stacks(StackName="non_existent_stack")
     err = exc.value.response["Error"]
@@ -1839,9 +1868,9 @@ def test_cloudformation_params():
     }
     dummy_template_with_params_json = json.dumps(dummy_template_with_params)
 
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
     stack = cf.create_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=dummy_template_with_params_json,
         Parameters=[{"ParameterKey": "APPNAME", "ParameterValue": "testing123"}],
     )
@@ -1867,19 +1896,19 @@ def test_update_stack_with_parameters():
         "Parameters": {"Bar": {"Type": "String"}},
     }
     template_json = json.dumps(template)
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=template_json,
         Parameters=[{"ParameterKey": "Bar", "ParameterValue": "192.168.0.0/16"}],
     )
     cf.update_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=template_json,
         Parameters=[{"ParameterKey": "Bar", "ParameterValue": "192.168.0.1/16"}],
     )
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
     assert len(stack["Parameters"]) == 1
     assert stack["Parameters"][0] == {
         "ParameterKey": "Bar",
@@ -1890,19 +1919,19 @@ def test_update_stack_with_parameters():
 @mock_cloudformation
 @mock_ec2
 def test_update_stack_replace_tags():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=dummy_template_json,
         Tags=[{"Key": "foo", "Value": "bar"}],
     )
     cf.update_stack(
-        StackName="test_stack",
+        StackName=TEST_STACK_NAME,
         TemplateBody=dummy_template_json,
         Tags=[{"Key": "foo", "Value": "baz"}],
     )
 
-    stack = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
+    stack = cf.describe_stacks(StackName=TEST_STACK_NAME)["Stacks"][0]
     assert stack["StackStatus"] == "UPDATE_COMPLETE"
     assert stack["Tags"] == [{"Key": "foo", "Value": "baz"}]
 
@@ -1911,8 +1940,8 @@ def test_update_stack_replace_tags():
 def test_update_stack_when_rolled_back():
     if settings.TEST_SERVER_MODE:
         raise SkipTest("Cant manipulate backend in server mode")
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    stack = cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    stack = cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
     stack_id = stack["StackId"]
 
     cloudformation_backends[ACCOUNT_ID]["us-east-1"].stacks[
@@ -1920,7 +1949,7 @@ def test_update_stack_when_rolled_back():
     ].status = "ROLLBACK_COMPLETE"
 
     with pytest.raises(ClientError) as ex:
-        cf.update_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+        cf.update_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
     err = ex.value.response["Error"]
     assert err["Code"] == "ValidationError"
@@ -1951,7 +1980,7 @@ def test_cloudformation_params_conditions_and_resources_are_distinct():
         },
     }
     template_with_conditions = json.dumps(template_with_conditions)
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="test_stack1",
         TemplateBody=template_with_conditions,
@@ -1968,7 +1997,7 @@ def test_cloudformation_params_conditions_and_resources_are_distinct():
 @mock_cloudformation
 @mock_ec2
 def test_cloudformation_conditions_yaml_equals():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="teststack2",
         TemplateBody=dummy_yaml_template_with_equals,
@@ -1987,7 +2016,7 @@ def test_cloudformation_conditions_yaml_equals():
 def test_cloudformation_conditions_yaml_equals_shortform():
     _template = dummy_yaml_template_with_equals
     _template = _template.replace("Fn::Equals:", "!Equals")
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     cf.create_stack(
         StackName="teststack2",
         TemplateBody=_template,
@@ -2004,9 +2033,9 @@ def test_cloudformation_conditions_yaml_equals_shortform():
 @mock_cloudformation
 def test_stack_tags():
     tags = [{"Key": "foo", "Value": "bar"}, {"Key": "baz", "Value": "bleh"}]
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
     stack = cf.create_stack(
-        StackName="test_stack", TemplateBody=dummy_template_json, Tags=tags
+        StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json, Tags=tags
     )
     observed_tag_items = set(
         item for items in [tag.items() for tag in stack.tags] for item in items
@@ -2020,8 +2049,8 @@ def test_stack_tags():
 @mock_cloudformation
 @mock_ec2
 def test_stack_events():
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
-    stack = cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
+    stack = cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
     stack.update(
         TemplateBody=dummy_update_template_json,
         Parameters=[{"ParameterKey": "KeyName", "ParameterValue": "value"}],
@@ -2049,10 +2078,10 @@ def test_stack_events():
     try:
         for event in events:
             assert event.stack_id == stack.stack_id
-            assert event.stack_name == "test_stack"
+            assert event.stack_name == TEST_STACK_NAME
 
             if event.resource_type == "AWS::CloudFormation::Stack":
-                assert event.logical_resource_id == "test_stack"
+                assert event.logical_resource_id == TEST_STACK_NAME
                 assert event.physical_resource_id == stack.stack_id
 
                 status_to_look_for, reason_to_look_for = next(stack_events_to_look_for)
@@ -2078,10 +2107,10 @@ def test_stack_events():
 
 @mock_cloudformation
 def test_list_exports():
-    cf_client = boto3.client("cloudformation", region_name="us-east-1")
-    cf_resource = boto3.resource("cloudformation", region_name="us-east-1")
+    cf_client = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf_resource = boto3.resource("cloudformation", region_name=REGION_NAME)
     stack = cf_resource.create_stack(
-        StackName="test_stack", TemplateBody=dummy_output_template_json
+        StackName=TEST_STACK_NAME, TemplateBody=dummy_output_template_json
     )
     output_value = "VPCID"
     exports = cf_client.list_exports()["Exports"]
@@ -2097,7 +2126,7 @@ def test_list_exports():
 
 @mock_cloudformation
 def test_list_exports_with_token():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     for i in range(101):
         # Add index to ensure name is unique
         dummy_output_template["Outputs"]["StackVPC"]["Export"]["Name"] += str(i)
@@ -2116,9 +2145,9 @@ def test_list_exports_with_token():
 
 @mock_cloudformation
 def test_delete_stack_with_export():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     stack = cf.create_stack(
-        StackName="test_stack", TemplateBody=dummy_output_template_json
+        StackName=TEST_STACK_NAME, TemplateBody=dummy_output_template_json
     )
 
     stack_id = stack["StackId"]
@@ -2131,17 +2160,19 @@ def test_delete_stack_with_export():
 
 @mock_cloudformation
 def test_export_names_must_be_unique():
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_output_template_json)
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_output_template_json)
     with pytest.raises(ClientError):
-        cf.create_stack(StackName="test_stack", TemplateBody=dummy_output_template_json)
+        cf.create_stack(
+            StackName=TEST_STACK_NAME, TemplateBody=dummy_output_template_json
+        )
 
 
 @mock_sqs
 @mock_cloudformation
 def test_stack_with_imports():
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
-    ec2_resource = boto3.resource("sqs", region_name="us-east-1")
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
+    ec2_resource = boto3.resource("sqs", region_name=REGION_NAME)
 
     output_stack = cf.create_stack(
         StackName="test_stack1", TemplateBody=dummy_output_template_json
@@ -2156,7 +2187,7 @@ def test_stack_with_imports():
 @mock_sqs
 @mock_cloudformation
 def test_non_json_redrive_policy():
-    cf = boto3.resource("cloudformation", region_name="us-east-1")
+    cf = boto3.resource("cloudformation", region_name=REGION_NAME)
 
     stack = cf.create_stack(
         StackName="test_stack1", TemplateBody=dummy_redrive_template_json
@@ -2168,25 +2199,25 @@ def test_non_json_redrive_policy():
 
 @mock_cloudformation
 def test_create_duplicate_stack():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
-    cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
+    cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
     with pytest.raises(ClientError):
-        cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
+        cf.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json)
 
 
 @mock_dynamodb
 @mock_cloudformation
 def test_delete_stack_dynamo_template():
-    conn = boto3.client("cloudformation", region_name="us-east-1")
-    dynamodb_client = boto3.client("dynamodb", region_name="us-east-1")
-    conn.create_stack(StackName="test_stack", TemplateBody=dummy_template_json4)
+    conn = boto3.client("cloudformation", region_name=REGION_NAME)
+    dynamodb_client = boto3.client("dynamodb", region_name=REGION_NAME)
+    conn.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json4)
     table_desc = dynamodb_client.list_tables()
     assert len(table_desc.get("TableNames")) == 1
-    conn.delete_stack(StackName="test_stack")
+    conn.delete_stack(StackName=TEST_STACK_NAME)
     table_desc = dynamodb_client.list_tables()
     assert len(table_desc.get("TableNames")) == 0
-    conn.create_stack(StackName="test_stack", TemplateBody=dummy_template_json4)
+    conn.create_stack(StackName=TEST_STACK_NAME, TemplateBody=dummy_template_json4)
 
 
 @mock_dynamodb
@@ -2195,7 +2226,7 @@ def test_delete_stack_dynamo_template():
 def test_create_stack_lambda_and_dynamodb():
     if settings.TEST_SERVER_MODE:
         raise SkipTest("Cant set environment variables in server mode")
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     template = {
         "AWSTemplateFormatVersion": "2010-09-09",
         "Description": "Stack Lambda Test 1",
@@ -2267,40 +2298,42 @@ def test_create_stack_lambda_and_dynamodb():
 @mock_cloudformation
 @mock_ec2
 def test_create_and_update_stack_with_unknown_resource():
-    cf = boto3.client("cloudformation", region_name="us-east-1")
+    cf = boto3.client("cloudformation", region_name=REGION_NAME)
     # Creating a stack with an unknown resource should throw a warning
     expected_err = "Tried to parse AWS::Cloud9::EnvironmentEC2 but it's not supported by moto's CloudFormation implementation"
     if settings.TEST_SERVER_MODE:
         # Can't verify warnings in ServerMode though
         cf.create_stack(
-            StackName="test_stack", TemplateBody=dummy_unknown_template_json
+            StackName=TEST_STACK_NAME, TemplateBody=dummy_unknown_template_json
         )
     else:
         with pytest.warns(UserWarning, match=expected_err):
             cf.create_stack(
-                StackName="test_stack", TemplateBody=dummy_unknown_template_json
+                StackName=TEST_STACK_NAME, TemplateBody=dummy_unknown_template_json
             )
 
     # The stack should exist though
     stacks = cf.describe_stacks()["Stacks"]
     assert len(stacks) == 1
-    assert stacks[0]["StackName"] == "test_stack"
+    assert stacks[0]["StackName"] == TEST_STACK_NAME
 
     # Updating an unknown resource should throw a warning, but not fail
     new_template = copy.deepcopy(dummy_unknown_template)
     new_template["Resources"]["UnknownResource"]["Properties"]["Sth"] = "other"
     if settings.TEST_SERVER_MODE:
-        cf.update_stack(StackName="test_stack", TemplateBody=json.dumps(new_template))
+        cf.update_stack(
+            StackName=TEST_STACK_NAME, TemplateBody=json.dumps(new_template)
+        )
     else:
         with pytest.warns(UserWarning, match=expected_err):
             cf.update_stack(
-                StackName="test_stack", TemplateBody=json.dumps(new_template)
+                StackName=TEST_STACK_NAME, TemplateBody=json.dumps(new_template)
             )
 
 
 def get_role_name():
     with mock_iam():
-        iam = boto3.client("iam", region_name="us-east-1")
+        iam = boto3.client("iam", region_name=REGION_NAME)
         try:
             return iam.get_role(RoleName="my-role")["Role"]["Arn"]
         except ClientError:
diff --git a/tests/test_ssoadmin/test_server.py b/tests/test_ssoadmin/test_server.py
index 51623d78a..5e76e1b69 100644
--- a/tests/test_ssoadmin/test_server.py
+++ b/tests/test_ssoadmin/test_server.py
@@ -23,4 +23,4 @@ def test_ssoadmin_list():
     resp = test_client.post("/", headers=headers, data=json.dumps(data))
 
     assert resp.status_code == 200
-    assert json.loads(resp.data) == {"AccountAssignments": []}
+    assert json.loads(resp.data) == {"AccountAssignments": [], "NextToken": None}
diff --git a/tests/test_ssoadmin/test_ssoadmin.py b/tests/test_ssoadmin/test_ssoadmin.py
index ab1e88a17..e3a134814 100644
--- a/tests/test_ssoadmin/test_ssoadmin.py
+++ b/tests/test_ssoadmin/test_ssoadmin.py
@@ -118,7 +118,7 @@ def test_delete_account_assignment_unknown():
             PrincipalId=principal_id,
         )
     err = exc.value.response["Error"]
-    assert err["Code"] == "ResourceNotFound"
+    assert err["Code"] == "ResourceNotFoundException"
 
 
 @mock_ssoadmin
@@ -190,6 +190,66 @@ def test_list_account_assignments():
     ]
 
 
+@mock_ssoadmin
+def test_list_account_assignments_pagination():
+    client = boto3.client("sso-admin", region_name="ap-southeast-1")
+    DUMMY_AWS_ACCOUNT_ID = "111111111111"
+
+    dummy_account_assignments = []
+    for _ in range(3):
+        dummy_account_assignments.append(
+            {
+                "InstanceArn": DUMMY_INSTANCE_ARN,
+                "TargetId": DUMMY_AWS_ACCOUNT_ID,
+                "TargetType": "AWS_ACCOUNT",
+                "PermissionSetArn": DUMMY_PERMISSIONSET_ID,
+                "PrincipalType": "USER",
+                "PrincipalId": str(uuid4()),
+            },
+        )
+
+    for dummy_account_assignment in dummy_account_assignments:
+        client.create_account_assignment(**dummy_account_assignment)
+
+    account_assignments = []
+
+    response = client.list_account_assignments(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        AccountId=DUMMY_AWS_ACCOUNT_ID,
+        PermissionSetArn=DUMMY_PERMISSIONSET_ID,
+        MaxResults=2,
+    )
+
+    assert len(response["AccountAssignments"]) == 2
+    account_assignments.extend(response["AccountAssignments"])
+
+    next_token = response["NextToken"]
+
+    response = client.list_account_assignments(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        AccountId=DUMMY_AWS_ACCOUNT_ID,
+        PermissionSetArn=DUMMY_PERMISSIONSET_ID,
+        MaxResults=2,
+        NextToken=next_token,
+    )
+
+    assert len(response["AccountAssignments"]) == 1
+    account_assignments.extend(response["AccountAssignments"])
+
+    # ensure 3 unique assignments returned
+    assert (
+        len(
+            set(
+                [
+                    account_assignment["PrincipalId"]
+                    for account_assignment in account_assignments
+                ]
+            )
+        )
+        == 3
+    )
+
+
 @mock_ssoadmin
 def test_list_account_assignments_for_principal():
     client = boto3.client("sso-admin", region_name="us-west-2")
@@ -391,7 +451,7 @@ def test_update_permission_set_unknown():
             RelayState="https://console.aws.amazon.com/s3",
         )
     err = exc.value.response["Error"]
-    assert err["Code"] == "ResourceNotFound"
+    assert err["Code"] == "ResourceNotFoundException"
 
 
 @mock_ssoadmin
@@ -428,7 +488,7 @@ def test_describe_permission_set_unknown():
             PermissionSetArn="arn:aws:sso:::permissionSet/ins-eeeeffffgggghhhh/ps-hhhhkkkkppppoooo",
         )
     err = exc.value.response["Error"]
-    assert err["Code"] == "ResourceNotFound"
+    assert err["Code"] == "ResourceNotFoundException"
 
 
 @mock_ssoadmin
@@ -451,7 +511,7 @@ def test_delete_permission_set():
             PermissionSetArn=permission_set["PermissionSetArn"],
         )
     err = exc.value.response["Error"]
-    assert err["Code"] == "ResourceNotFound"
+    assert err["Code"] == "ResourceNotFoundException"
 
 
 @mock_ssoadmin
@@ -464,7 +524,7 @@ def test_delete_permission_set_unknown():
             PermissionSetArn="arn:aws:sso:::permissionSet/ins-eeeeffffgggghhhh/ps-hhhhkkkkppppoooo",
         )
     err = exc.value.response["Error"]
-    assert err["Code"] == "ResourceNotFound"
+    assert err["Code"] == "ResourceNotFoundException"
 
 
 @mock_ssoadmin
diff --git a/tests/test_ssoadmin/test_ssoadmin_policies.py b/tests/test_ssoadmin/test_ssoadmin_policies.py
new file mode 100644
index 000000000..7eee8260c
--- /dev/null
+++ b/tests/test_ssoadmin/test_ssoadmin_policies.py
@@ -0,0 +1,132 @@
+import json
+
+import boto3
+import pytest
+from botocore.exceptions import ClientError
+
+from moto import mock_ssoadmin
+
+# 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
+
+DUMMY_PERMISSIONSET_ID = (
+    "arn:aws:sso:::permissionSet/ins-eeeeffffgggghhhh/ps-hhhhkkkkppppoooo"
+)
+DUMMY_INSTANCE_ARN = "arn:aws:sso:::instance/ins-aaaabbbbccccdddd"
+
+
+def create_permissionset(client) -> str:
+    """Helper function to create a dummy permission set and returns the arn."""
+
+    response = client.create_permission_set(
+        Name="test-permission-set",
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        Description="test permission set",
+    )
+
+    return response["PermissionSet"]["PermissionSetArn"]
+
+
+@mock_ssoadmin
+def test_put_inline_policy_to_permission_set():
+    """
+    Tests putting and getting an inline policy to a permission set.
+    """
+    client = boto3.client("sso-admin", region_name="us-east-1")
+
+    permission_set_arn = create_permissionset(client)
+    dummy_policy = {
+        "Version": "2012-10-17",
+        "Statement": [
+            {
+                "Effect": "Allow",
+                "Action": "s3:GetObject",
+                "Resource": "arn:aws:s3:::your-bucket-name/*",
+            }
+        ],
+    }
+
+    # Happy path
+    response = client.put_inline_policy_to_permission_set(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        PermissionSetArn=permission_set_arn,
+        InlinePolicy=json.dumps(dummy_policy),
+    )
+
+    response = client.get_inline_policy_for_permission_set(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        PermissionSetArn=permission_set_arn,
+    )
+
+    assert response["InlinePolicy"] == json.dumps(dummy_policy)
+
+    # Invalid permission set arn
+    not_create_ps_arn = (
+        "arn:aws:sso:::permissionSet/ins-eeeeffffgggghhhh/ps-hhhhkkkkppppoxyz"
+    )
+    with pytest.raises(ClientError) as e:
+        client.put_inline_policy_to_permission_set(
+            InstanceArn=DUMMY_INSTANCE_ARN,
+            PermissionSetArn=not_create_ps_arn,
+            InlinePolicy=json.dumps(dummy_policy),
+        )
+    err = e.value.response["Error"]
+    assert err["Code"] == "ResourceNotFoundException"
+    assert err["Message"] == "Could not find PermissionSet with id ps-hhhhkkkkppppoxyz"
+
+
+@mock_ssoadmin
+def test_get_inline_policy_to_permission_set_no_policy():
+    client = boto3.client("sso-admin", region_name="us-east-1")
+
+    permission_set_arn = create_permissionset(client)
+
+    response = client.get_inline_policy_for_permission_set(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        PermissionSetArn=permission_set_arn,
+    )
+
+    assert response["InlinePolicy"] == ""
+
+
+@mock_ssoadmin
+def test_delete_inline_policy_to_permissionset():
+    client = boto3.client("sso-admin", region_name="us-east-1")
+
+    permission_set_arn = create_permissionset(client)
+
+    dummy_policy = {
+        "Version": "2012-10-17",
+        "Statement": [
+            {
+                "Effect": "Allow",
+                "Action": "s3:GetObject",
+                "Resource": "arn:aws:s3:::your-bucket-name/*",
+            }
+        ],
+    }
+
+    client.put_inline_policy_to_permission_set(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        PermissionSetArn=permission_set_arn,
+        InlinePolicy=json.dumps(dummy_policy),
+    )
+
+    response = client.get_inline_policy_for_permission_set(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        PermissionSetArn=permission_set_arn,
+    )
+
+    assert response["InlinePolicy"] == json.dumps(dummy_policy)
+
+    client.delete_inline_policy_from_permission_set(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        PermissionSetArn=permission_set_arn,
+    )
+
+    response = client.get_inline_policy_for_permission_set(
+        InstanceArn=DUMMY_INSTANCE_ARN,
+        PermissionSetArn=permission_set_arn,
+    )
+
+    assert response["InlinePolicy"] == ""