diff --git a/CHANGELOG.md b/CHANGELOG.md index 021002e7..ae9b86c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a Ch - adding support for module-type spec on init of new module `seedfarmer init module -mt cdkv2` ### Fixes +- skip destroy of managed-project-policy if it has roles attached ## v2.10.4 (2023-10-23) diff --git a/seedfarmer/commands/_stack_commands.py b/seedfarmer/commands/_stack_commands.py index 0c77f8e5..04cc2590 100644 --- a/seedfarmer/commands/_stack_commands.py +++ b/seedfarmer/commands/_stack_commands.py @@ -99,10 +99,17 @@ def destroy_managed_policy_stack(account_id: str, region: str) -> None: """ # Determine if managed policy stack already deployed session = SessionManager().get_or_create().get_deployment_session(account_id=account_id, region_name=region) - project_managed_policy_stack_exists, _ = services.cfn.does_stack_exist( + project_managed_policy_stack_exists, stack_outputs = services.cfn.does_stack_exist( stack_name=info.PROJECT_MANAGED_POLICY_CFN_NAME, session=session ) + _logger.debug("project_managed_policy_output is : %s", stack_outputs) + has_roles_attached = False if project_managed_policy_stack_exists: + project_managed_policy_arn = stack_outputs.get("ProjectPolicyARN") + policy = iam.get_policy_info(policy_arn=project_managed_policy_arn, session=session) + has_roles_attached = True if policy and policy["Policy"]["AttachmentCount"] > 0 else False + + if project_managed_policy_stack_exists and not has_roles_attached: _logger.info( "Destroying Stack %s in Account/Region: %s/%s", info.PROJECT_MANAGED_POLICY_CFN_NAME, account_id, region ) @@ -117,6 +124,13 @@ def destroy_managed_policy_stack(account_id: str, region: str) -> None: _logger.info( f"Failed to delete project stack {info.PROJECT_MANAGED_POLICY_CFN_NAME}, ignoring and moving on" ) + else: + _logger.info( + "Stack %s in Account/Region: %s/%s is either not deployed or has roles attached", + info.PROJECT_MANAGED_POLICY_CFN_NAME, + account_id, + region, + ) def destroy_module_stack( diff --git a/seedfarmer/services/_iam.py b/seedfarmer/services/_iam.py index c4479df4..39067cba 100644 --- a/seedfarmer/services/_iam.py +++ b/seedfarmer/services/_iam.py @@ -121,3 +121,14 @@ def detach_inline_policy_from_role(role_name: str, policy_name: str, session: Op iam_resource.RolePolicy(role_name, policy_name).delete() except Exception as e: raise e + + +def get_policy_info(policy_arn: str, session: Optional[Session] = None) -> Dict[str, Any]: + iam_client = boto3_client("iam", session=session) + try: + return iam_client.get_policy(PolicyArn=policy_arn) + except iam_client.exceptions.NoSuchEntityException as ne: + _logger.info("Policy does not exist: %s ", policy_arn) + return {} + except Exception as e: + raise e