Skip to content

Commit

Permalink
skip deletion of managed policy if in use
Browse files Browse the repository at this point in the history
  • Loading branch information
dgraeber committed Oct 30, 2023
1 parent 99b4bce commit eb835a2
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 15 additions & 1 deletion seedfarmer/commands/_stack_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand All @@ -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(
Expand Down
11 changes: 11 additions & 0 deletions seedfarmer/services/_iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 cast(Dict[str, Any], iam_client.get_policy(PolicyArn=policy_arn))
except iam_client.exceptions.NoSuchEntityException as ne:
_logger.info("Policy does not exist: %s ", policy_arn)
raise ne
except Exception as e:
raise e
16 changes: 16 additions & 0 deletions test/unit-test/test_commands_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,21 @@ def session_manager(sts_client):
"""
)

manage_policy_json={
"Policy": {
"PolicyName": "addf-managed-policy-ProjectPolicy-7PSXY0GVW23I",
"PolicyId": "ANPAY667V3NQ3CYB253RG",
"Arn": "arn:aws:iam::123456789012:policy/addf-managed-policy-ProjectPolicy-7PSXY0GVW23I",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": True,
"Description": "Managed Policy granting access to build a project",
"Tags": []
}
}


@pytest.mark.commands
@pytest.mark.commands_stack
Expand Down Expand Up @@ -93,6 +108,7 @@ def test_destroy_managed_policy_stack_not_exists(session_manager, mocker):
def test_destroy_managed_policy_stack(session_manager, mocker):
mocker.patch("seedfarmer.commands._stack_commands.services.cfn.does_stack_exist", return_value=[True, {}])
mocker.patch("seedfarmer.commands._stack_commands.services.cfn.destroy_stack", return_value=None)
mocker.patch("seedfarmer.commands._stack_commands.iam.get_policy_info", return_value=manage_policy_json)
sc.destroy_managed_policy_stack(account_id="123456789012", region="us-east-1")


Expand Down

0 comments on commit eb835a2

Please sign in to comment.