diff --git a/AutomatedTesting/Config/aws_resource_mappings.json b/AutomatedTesting/Config/aws_resource_mappings.json
new file mode 100644
index 0000000000..03a611b749
--- /dev/null
+++ b/AutomatedTesting/Config/aws_resource_mappings.json
@@ -0,0 +1,6 @@
+{
+ "AWSResourceMappings": {},
+ "AccountId": "",
+ "Region": "us-west-2",
+ "Version": "1.0.0"
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake
index 280c25bcf7..33c2bf8d5f 100644
--- a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake
+++ b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake
@@ -45,4 +45,7 @@ set(GEM_DEPENDENCIES
Gem::Atom_AtomBridge
Gem::NvCloth
Gem::Blast
+ Gem::AWSCore
+ Gem::AWSClientAuth
+ Gem::AWSMetrics
)
diff --git a/AutomatedTesting/Gem/Code/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/tool_dependencies.cmake
index fc50707c12..d4a49bfad5 100644
--- a/AutomatedTesting/Gem/Code/tool_dependencies.cmake
+++ b/AutomatedTesting/Gem/Code/tool_dependencies.cmake
@@ -55,4 +55,7 @@ set(GEM_DEPENDENCIES
Gem::Atom_AtomBridge.Editor
Gem::NvCloth.Editor
Gem::Blast.Editor
+ Gem::AWSCore.Editor
+ Gem::AWSClientAuth
+ Gem::AWSMetrics
)
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
new file mode 100644
index 0000000000..b406ea77de
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
@@ -0,0 +1,31 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+################################################################################
+# AWS Automated Tests
+# Runs AWS Gems automation tests.
+################################################################################
+
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+ # Enable after installing NodeJS and CDK on jenkins Windows AMI.
+ #ly_add_pytest(
+ # NAME AutomatedTesting::AWSTests
+ # TEST_SUITE periodic
+ # TEST_SERIAL
+ # PATH ${CMAKE_CURRENT_LIST_DIR}/AWS/${PAL_PLATFORM_NAME}/
+ # RUNTIME_DEPENDENCIES
+ # Legacy::Editor
+ # AZ::AssetProcessor
+ # AutomatedTesting.Assets
+ # COMPONENT
+ # AWS
+ #)
+endif()
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py
new file mode 100644
index 0000000000..455b3f94cb
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py
@@ -0,0 +1,155 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+import os
+import pytest
+import boto3
+
+import ly_test_tools.environment.process_utils as process_utils
+from typing import List
+
+
+class Cdk:
+ """
+ Cdk class that provides methods to run cdk application commands.
+ Expects system to have NodeJS, AWS CLI and CDK installed globally and have their paths setup as env variables.
+ """
+ def __init__(self, cdk_path: str, project: str, account_id: str,
+ workspace: pytest.fixture, session: boto3.session.Session):
+ """
+ :param cdk_path: Path where cdk app.py is stored.
+ :param project: Project name used for cdk project name env variable.
+ :param account_id: AWS account id to use with cdk application.
+ :param workspace: ly_test_tools workspace fixture.
+ """
+ self._cdk_env = os.environ.copy()
+ self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project
+ self._cdk_env['O3DE_AWS_DEPLOY_REGION'] = session.region_name
+ self._cdk_env['O3DE_AWS_DEPLOY_ACCOUNT'] = account_id
+ self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH']
+
+ credentials = session.get_credentials().get_frozen_credentials()
+ self._cdk_env['AWS_ACCESS_KEY_ID'] = credentials.access_key
+ self._cdk_env['AWS_SECRET_ACCESS_KEY'] = credentials.secret_key
+ self._cdk_env['AWS_SESSION_TOKEN'] = credentials.token
+ self._stacks = []
+ self._cdk_path = cdk_path
+
+ output = process_utils.check_output(
+ 'python -m pip install -r requirements.txt',
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ def list(self) -> List[str]:
+ """
+ lists cdk stack names
+ :return List of cdk stack names
+ """
+
+ if not self._cdk_path:
+ return []
+
+ list_cdk_application_cmd = ['cdk', 'list']
+ output = process_utils.check_output(
+ list_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ return output.splitlines()
+
+ def synthesize(self) -> None:
+ """
+ Synthesizes all cdk stacks
+ """
+ if not self._cdk_path:
+ return
+
+ list_cdk_application_cmd = ['cdk', 'synth']
+
+ process_utils.check_output(
+ list_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ def deploy(self, context_variable: str = '') -> List[str]:
+ """
+ Deploys all the CDK stacks.
+ :param context_variable: Context variable for enabling optional features.
+ :return List of deployed stack arns.
+ """
+ if not self._cdk_path:
+ return []
+
+ deploy_cdk_application_cmd = ['cdk', 'deploy', '--require-approval', 'never']
+ if context_variable:
+ deploy_cdk_application_cmd.extend(['-c', f'{context_variable}'])
+
+ output = process_utils.check_output(
+ deploy_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ stacks = []
+ for line in output.splitlines():
+ line_sections = line.split('/')
+ assert len(line_sections), 3
+ stacks.append(line.split('/')[-2])
+
+ return stacks
+
+ def destroy(self) -> None:
+ """
+ Destroys the cdk application.
+ """
+ destroy_cdk_application_cmd = ['cdk', 'destroy', '-f']
+ process_utils.check_output(
+ destroy_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ self._stacks = []
+ self._cdk_path = ''
+
+
+@pytest.fixture(scope='function')
+def cdk(
+ request: pytest.fixture,
+ project: str,
+ feature_name: str,
+ workspace: pytest.fixture,
+ aws_utils: pytest.fixture,
+ destroy_stacks_on_teardown: bool = True) -> Cdk:
+ """
+ Fixture for setting up a Cdk
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param project: Project name used for cdk project name env variable.
+ :param feature_name: Feature gem name to expect cdk folder in.
+ :param workspace: ly_test_tools workspace fixture.
+ :param aws_utils: aws_utils fixture.
+ :param destroy_stacks_on_teardown: option to control calling destroy ot the end of test.
+ :return Cdk class object.
+ """
+
+ cdk_path = f'{workspace.paths.engine_root()}/Gems/{feature_name}/cdk'
+ cdk_obj = Cdk(cdk_path, project, aws_utils.assume_account_id(), workspace, aws_utils.assume_session())
+
+ def teardown():
+ if destroy_stacks_on_teardown:
+ cdk_obj.destroy()
+ request.addfinalizer(teardown)
+
+ return cdk_obj
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
new file mode 100644
index 0000000000..5997701870
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
@@ -0,0 +1,78 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+import pytest
+import os
+import logging
+import ly_test_tools.log.log_monitor
+
+from AWS.Windows.resource_mappings.resource_mappings import resource_mappings
+from AWS.Windows.cdk.cdk import cdk
+from AWS.common.aws_utils import aws_utils
+from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
+
+AWS_PROJECT_NAME = 'AWS-AutomationTest'
+AWS_CLIENT_AUTH_FEATURE_NAME = 'AWSClientAuth'
+AWS_CLIENT_AUTH_DEFAULT_PROFILE_NAME = 'default'
+
+GAME_LOG_NAME = 'Game.log'
+
+logger = logging.getLogger(__name__)
+
+
+@pytest.mark.SUITE_periodic
+@pytest.mark.usefixtures('automatic_process_killer')
+@pytest.mark.usefixtures('asset_processor')
+@pytest.mark.usefixtures('workspace')
+@pytest.mark.parametrize('project', ['AutomatedTesting'])
+@pytest.mark.parametrize('level', ['AWS/ClientAuth'])
+@pytest.mark.usefixtures('cdk')
+@pytest.mark.parametrize('feature_name', [AWS_CLIENT_AUTH_FEATURE_NAME])
+@pytest.mark.usefixtures('resource_mappings')
+@pytest.mark.parametrize('resource_mappings_filename', ['aws_resource_mappings.json'])
+@pytest.mark.usefixtures('aws_utils')
+@pytest.mark.parametrize('region_name', ['us-west-2'])
+@pytest.mark.parametrize('assume_role_arn', ['arn:aws:iam::645075835648:role/o3de-automation-tests'])
+@pytest.mark.parametrize('session_name', ['o3de-Automation-session'])
+class TestAWSClientAuthAnonymousCredentials(object):
+ """
+ Test class to verify AWS Cognito Identity pool anonymous authorization.
+ """
+
+ def test_anonymous_credentials(self,
+ level: str,
+ launcher: pytest.fixture,
+ cdk: pytest.fixture,
+ resource_mappings: pytest.fixture,
+ workspace: pytest.fixture,
+ asset_processor: pytest.fixture
+ ):
+ """
+ Setup: Deploys cdk and updates resource mapping file.
+ Tests: Getting AWS credentials for no signed in user.
+ Verification: Log monitor looks for success credentials log.
+ """
+ logger.info(f'Cdk stack names:\n{cdk.list()}')
+ stacks = cdk.deploy()
+ resource_mappings.populate_output_keys(stacks)
+ asset_processor.start()
+ asset_processor.wait_for_idle()
+
+ file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME)
+ log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
+
+ launcher.args = ['+LoadLevel', level]
+
+ with launcher.start(launch_ap=False):
+ result = log_monitor.monitor_log_for_lines(
+ expected_lines=['(Script) - Success anonymous credentials'],
+ unexpected_lines=['(Script) - Fail anonymous credentials'],
+ halt_on_unexpected=True,
+ )
+ assert result, 'Anonymous credentials fetched successfully.'
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py
new file mode 100644
index 0000000000..6ed3dc4bda
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py
@@ -0,0 +1,10 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py
new file mode 100644
index 0000000000..c8d8cff828
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py
@@ -0,0 +1,137 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+import os
+import pytest
+import json
+
+AWS_RESOURCE_MAPPINGS_KEY = 'AWSResourceMappings'
+AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY = 'AccountId'
+AWS_RESOURCE_MAPPINGS_REGION_KEY = 'Region'
+
+
+class ResourceMappings:
+ """
+ ResourceMappings class that handles writing Cloud formation outputs to resource mappings json file in a project.
+ """
+
+ def __init__(self, file_path: str, region: str, feature_name: str, account_id: str, workspace: pytest.fixture,
+ cloud_formation_client):
+ """
+ :param file_path: Path for the resource mapping file.
+ :param region: Region value for the resource mapping file.
+ :param feature_name: Feature gem name to use to append name to mappings key.
+ :param account_id: AWS account id value for the resource mapping file.
+ :param workspace: ly_test_tools workspace fixture.
+ :param cloud_formation_client: AWS cloud formation client.
+ """
+ self._cdk_env = os.environ.copy()
+ self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH']
+ self._resource_mapping_file_path = file_path
+ self._region = region
+ self._feature_name = feature_name
+ self._account_id = account_id
+
+ assert os.path.exists(self._resource_mapping_file_path), \
+ f'Invalid resource mapping file path {self._resource_mapping_file_path}'
+ self._client = cloud_formation_client
+
+ def populate_output_keys(self, stacks=[]) -> None:
+ """
+ Calls describe stacks on cloud formation service and persists outputs to resource mappings file.
+ :param stacks List of stack arns to describe and populate resource mappings with.
+ """
+ for stack_name in stacks:
+ response = self._client.describe_stacks(
+ StackName=stack_name
+ )
+ stacks = response.get('Stacks', [])
+ assert len(stacks) == 1, f'{stack_name} is invalid.'
+
+ self.__write_resource_mappings(stacks[0].get('Outputs', []))
+
+ def __write_resource_mappings(self, outputs, append_feature_name = True) -> None:
+ with open(self._resource_mapping_file_path) as file_content:
+ resource_mappings = json.load(file_content)
+
+ resource_mappings[AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY] = self._account_id
+ resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = self._region
+
+ # Append new mappings.
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = resource_mappings.get(AWS_RESOURCE_MAPPINGS_KEY, {})
+
+ for output in outputs:
+ if append_feature_name:
+ resource_key = f'{self._feature_name}.{output.get("OutputKey", "InvalidKey")}'
+ else:
+ resource_key = output.get("OutputKey", "InvalidKey")
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key] = resource_mappings[
+ AWS_RESOURCE_MAPPINGS_KEY].get(resource_key, {})
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Type'] = 'AutomationTestType'
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Name/ID'] = output.get('OutputValue',
+ 'InvalidId')
+
+ with open(self._resource_mapping_file_path, 'w') as file_content:
+ json.dump(resource_mappings, file_content, indent=4)
+
+ def clear_output_keys(self) -> None:
+ """
+ Clears values of all resource mapping keys. Sets region to default to us-west-2
+ """
+ with open(self._resource_mapping_file_path) as file_content:
+ resource_mappings = json.load(file_content)
+
+ resource_mappings[AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY] = ''
+ resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = 'us-west-2'
+
+ # Append new mappings.
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = resource_mappings.get(AWS_RESOURCE_MAPPINGS_KEY, {})
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = {}
+
+ with open(self._resource_mapping_file_path, 'w') as file_content:
+ json.dump(resource_mappings, file_content, indent=4)
+
+ self._resource_mapping_file_path = ''
+ self._region = ''
+ self._client = None
+
+
+@pytest.fixture(scope='function')
+def resource_mappings(
+ request: pytest.fixture,
+ project: str,
+ feature_name: str,
+ resource_mappings_filename: str,
+ workspace: pytest.fixture,
+ aws_utils: pytest.fixture) -> ResourceMappings:
+ """
+ Fixture for setting up resource mappings file.
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param project: Project to find resource mapping file.
+ :param feature_name: AWS Gem name that is prepended to resource mapping keys.
+ :param resource_mappings_filename: Name of resource mapping file.
+ :param workspace: ly_test_tools workspace fixture.
+ :param aws_utils: AWS utils fixture.
+ :return: ResourceMappings class object.
+ """
+
+ path = f'{workspace.paths.engine_root()}\\{project}\\Config\\{resource_mappings_filename}'
+ resource_mappings_obj = ResourceMappings(path, aws_utils.assume_session().region_name, feature_name,
+ aws_utils.assume_account_id(), workspace,
+ aws_utils.client('cloudformation'))
+
+ def teardown():
+ resource_mappings_obj.clear_output_keys()
+
+ request.addfinalizer(teardown)
+
+ return resource_mappings_obj
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/__init__.py
new file mode 100644
index 0000000000..8caef52682
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/__init__.py
@@ -0,0 +1,11 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
new file mode 100644
index 0000000000..7a15ba0abe
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
@@ -0,0 +1,82 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+import boto3
+import pytest
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+class AwsUtils:
+
+ def __init__(self, arn: str, session_name: str, region_name: str):
+ local_session = boto3.Session(profile_name='default')
+ local_sts_client = local_session.client('sts')
+ self._local_account_id = local_sts_client.get_caller_identity()["Account"]
+ logger.info(f'Local Account Id: {self._local_account_id}')
+
+ response = local_sts_client.assume_role(RoleArn=arn, RoleSessionName=session_name)
+
+ self._assume_session = boto3.Session(aws_access_key_id=response['Credentials']['AccessKeyId'],
+ aws_secret_access_key=response['Credentials']['SecretAccessKey'],
+ aws_session_token=response['Credentials']['SessionToken'],
+ region_name=region_name)
+
+ assume_sts_client = self._assume_session.client('sts')
+ assume_account_id = assume_sts_client.get_caller_identity()["Account"]
+ logger.info(f'Assume Account Id: {assume_account_id}')
+ self._assume_account_id = assume_account_id
+
+ def client(self, service: str):
+ """
+ Get the client for a specific AWS service from configured session
+ :return: Client for the AWS service.
+ """
+ return self._assume_session.client(service)
+
+ def assume_session(self):
+ return self._assume_session
+
+ def local_account_id(self):
+ return self._local_account_id
+
+ def assume_account_id(self):
+ return self._assume_account_id
+
+ def destroy(self) -> None:
+ """
+ clears stored session
+ """
+ self._assume_session = None
+
+
+@pytest.fixture(scope='function')
+def aws_utils(
+ request: pytest.fixture,
+ assume_role_arn: str,
+ session_name: str,
+ region_name: str):
+ """
+ Fixture for setting up a Cdk
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param assume_role_arn: Role used to fetch temporary aws credentials, configure service clients with obtained credentials.
+ :param session_name: Session name to set.
+ :param region_name: AWS account region to set for session.
+ :return AWSUtils class object.
+ """
+ aws_utils_obj = AwsUtils(assume_role_arn, session_name, region_name)
+
+ def teardown():
+ aws_utils_obj.destroy()
+
+ request.addfinalizer(teardown)
+
+ return aws_utils_obj
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index d6f9ecff4b..c6ed6c7538 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -56,5 +56,8 @@ add_subdirectory(editor)
## Streaming ##
add_subdirectory(streaming)
-## Streaming ##
+## Smoke ##
add_subdirectory(smoke)
+
+## AWS ##
+add_subdirectory(AWS)
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly
new file mode 100644
index 0000000000..af8a7f5c8e
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f0f4d4e0155feaa76c80a14128000a0fd9570ab76e79f4847eaef9006324a4d2
+size 9084
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas
new file mode 100644
index 0000000000..ef03c66b16
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas
@@ -0,0 +1,2313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml
new file mode 100644
index 0000000000..d4e3d33551
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml
@@ -0,0 +1 @@
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml
new file mode 100644
index 0000000000..d827d4da29
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml
@@ -0,0 +1 @@
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml
new file mode 100644
index 0000000000..f69a99fe37
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/level.pak b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak
new file mode 100644
index 0000000000..1ae0bb1f7a
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4900bdf28654e21032e69957f2762fa0a3b93a4b82163267a1f10f19f6d78692
+size 3795
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/Registry/awscoreconfiguration.setreg b/AutomatedTesting/Registry/awscoreconfiguration.setreg
new file mode 100644
index 0000000000..ca110eb103
--- /dev/null
+++ b/AutomatedTesting/Registry/awscoreconfiguration.setreg
@@ -0,0 +1,10 @@
+{
+ "Amazon":
+ {
+ "AWSCore":
+ {
+ "ProfileName": "default",
+ "ResourceMappingConfigFileName": "aws_resource_mappings.json"
+ }
+ }
+}
\ No newline at end of file