diff --git a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/cloudformation.py b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/cloudformation.py index dbff7e07b..fcaf84ef9 100644 --- a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/cloudformation.py +++ b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/cloudformation.py @@ -28,6 +28,7 @@ # and hyphens. CFN_UNACCEPTED_CHARS = re.compile(r"[^-a-zA-Z0-9]") ADF_GLOBAL_IAM_STACK_NAME = 'adf-global-base-iam' +ADF_GLOBAL_BOOTSTRAP_STACK_NAME = 'adf-global-base-bootstrap' ADF_GLOBAL_ADF_BUILD_STACK_NAME = 'adf-global-base-adf-build' @@ -146,6 +147,7 @@ def _get_valid_stack_names(self): valid_stack_names = [self._get_stack_name()] if self.region == self.deployment_account_region: valid_stack_names.append(ADF_GLOBAL_IAM_STACK_NAME) + valid_stack_names.append(ADF_GLOBAL_BOOTSTRAP_STACK_NAME) valid_stack_names.append(ADF_GLOBAL_ADF_BUILD_STACK_NAME) return valid_stack_names diff --git a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/parameter_store.py b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/parameter_store.py index 690656dbf..7709fb8f4 100644 --- a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/parameter_store.py +++ b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/parameter_store.py @@ -94,7 +94,7 @@ def _build_param_name(name, adf_only=True): slash_name = name if name.startswith('/') else f"/{name}" add_prefix = ( adf_only - and not slash_name.startswith(PARAMETER_PREFIX) + and not slash_name.startswith(f"{PARAMETER_PREFIX}/") ) param_prefix = PARAMETER_PREFIX if add_prefix else '' return f"{param_prefix}{slash_name}" diff --git a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_cloudformation.py b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_cloudformation.py index c3118079c..173c68e45 100644 --- a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_cloudformation.py +++ b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_cloudformation.py @@ -351,6 +351,66 @@ def test_delete_deprecated_base_stacks_some_deletions(paginator_mock, logger, gl ]) +@patch('cloudformation.LOGGER') +@patch("cloudformation.paginator") +def test_delete_deprecated_base_stacks_mgmt_account_adf_build(paginator_mock, logger): + global_cls = CloudFormation( + region='us-east-1', + deployment_account_region='us-east-1', + role=boto3, + wait=False, + stack_name=None, + template_url='https://some/path/global.yml', + s3=None, + s3_key_path='adf-build', + account_id=123 + ) + global_cls.client = Mock() + paginator_mock.return_value = stub_cloudformation.list_stacks.get('StackSummaries') + global_cls.client.describe_stacks.return_value = { + "Stacks": [ + { + 'StackName': 'adf-global-base-iam', + 'StackStatus': 'CREATE_COMPLETE', + }, + ], + } + global_cls.delete_deprecated_base_stacks() + global_cls.client.delete_stack.assert_has_calls([ + call(StackName='adf-global-base-iam'), + call(StackName='adf-regional-base-bootstrap'), + # ^ We are deploying in a global region, not regional + call(StackName='adf-global-base-deployment'), + # ^ We are not in the deployment OU with this CloudFormation instance + call(StackName='adf-global-base-deployment-SomeOtherStack'), + call(StackName='adf-global-base-dev'), + call(StackName='adf-global-base-test'), + call(StackName='adf-global-base-acceptance'), + call(StackName='adf-global-base-prod'), + ]) + assert global_cls.client.delete_stack.call_count == 8 + logger.warning.assert_has_calls([ + call('Removing stack: %s', 'adf-global-base-iam'), + # ^ As we delete a bootstrap stack we need to recreate the IAM stack, + # hence deleting it. + call('Removing stack: %s', 'adf-regional-base-bootstrap'), + # ^ We are deploying in a global region, not regional + call('Removing stack: %s', 'adf-global-base-deployment'), + # ^ We are not in the deployment OU with this CloudFormation instance + call('Removing stack: %s', 'adf-global-base-deployment-SomeOtherStack'), + call('Removing stack: %s', 'adf-global-base-dev'), + call('Removing stack: %s', 'adf-global-base-test'), + call('Removing stack: %s', 'adf-global-base-acceptance'), + call('Removing stack: %s', 'adf-global-base-prod'), + call( + 'Please remove stack %s manually, state %s implies that it ' + 'cannot be deleted automatically', + 'adf-global-base-some-ou', + 'CREATE_IN_PROGRESS', + ), + ]) + + @patch('cloudformation.LOGGER') @patch("cloudformation.paginator") def test_delete_deprecated_base_stacks_no_iam(paginator_mock, logger, global_cls): diff --git a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_parameter_store.py b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_parameter_store.py index f8e3d277a..aaf0c4e0f 100644 --- a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_parameter_store.py +++ b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/tests/test_parameter_store.py @@ -26,6 +26,7 @@ def cls(): [ ('/adf/test', '/adf/test'), ('adf/test', '/adf/test'), + ('/adf_version', '/adf_version'), ('/test', '/test'), ('test', '/test'), ('/other/test', '/other/test'), @@ -44,6 +45,7 @@ def test_build_param_name_not_adf_only(input_name, output_path): [ ('/adf/test', '/adf/test'), ('adf/test', '/adf/test'), + ('/adf_version', '/adf/adf_version'), ('/test', '/adf/test'), ('test', '/adf/test'), ('/other/test', '/adf/other/test'),