3

I am trying to delete a policy with multiple versions of the command line like so:

function iam-list-versions () {
  aws iam list-policy-versions --query "Versions[].VersionId" --policy-arn $1 --output text 
}

function iam-delete-policy-versions () {
  iam-list-versions $1 | xargs -n 1 -I{} aws iam delete-policy-version --policy-arn $1 --version-id {}
}

function iam-delete-policy () {
  iam-delete-policy-versions $1
  aws iam delete-policy --policy-arn $1
}

And then run iam-delete-policy arn:aws:iam::123456789012:policy/... But I keep getting the error:

An error occurred (DeleteConflict) when calling the DeletePolicyVersion operation: Cannot delete the default version of a policy.

An error occurred (DeleteConflict) when calling the DeletePolicy operation: This policy has more than one version. Before you delete a policy, you must delete the policy's versions. The default version is deleted with the policy.

Looks like my iam-delete-policy-versions function is not working. Wish they would simply add a --force flag.

Derrops
  • 7,651
  • 5
  • 30
  • 60

3 Answers3

3

The error messages are suggesting that:

  • You can't delete the default version of a policy. Instead, delete the policy itself.
  • You can't delete a policy while there is more than one version.

I also notice that list-policy-versions returns a field called IsDefaultVersion that indicates whether a policy is the default version.

Therefore, you would need to do something like:

  • Call list-policy-versions
  • For every response where IsDefaultVersion = False, call delete-policy-version
  • After deleting all the versions, call delete-policy for each policy (or, for each IsDefaultVersion = True)

This would probably be easier in a Python script.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
2

@John Rotenstein actually gave me the answer to this question here: How to I loop through AWS CLI output?

Because the versions weren't iterating correctly due to needing: setopt shwordsplit in my zshell, this delete version command would run as such: aws iam delete-policy-version --policy-arn $1 --version-id v3 v2 v1 which would only try and delete v3.

Because v3 was the default version for the role, this command would fail resulting in:

An error occurred (DeleteConflict) when calling the DeletePolicyVersion operation: Cannot delete the default version of a policy.

The subsequent deletion of the policy would then fail, because there were still other versions on the policy, as the previous command had no effect.

I will accept John's answer because he deserves all the points! Final script below:

setopt shwordsplit

function iam-list-versions () {
  aws iam list-policy-versions --query "Versions[?@.IsDefaultVersion == \`false\`].VersionId" --policy-arn $1 --output text
}

function iam-delete-policy-versions () {
  iam-list-versions $1 | xargs -n 1 -I{} aws iam delete-policy-version --policy-arn $1 --version-id {}
}

function iam-delete-policy () {
  iam-delete-policy-versions $1
  aws iam delete-policy --policy-arn $1
}


Derrops
  • 7,651
  • 5
  • 30
  • 60
0

Please use the following boto3 code to delete the list of policies at once. Please pass the list of policies in variable pol_list=[]. Also do not forget to add your account ID in policy ARN. This script will delete the policy along with its all versions.

import boto3
client = boto3.client("iam")
###Pass the list of IAM policy name on the following variable
pol_list=[]
for arn in pol_list:
    print(arn)
    try:
        response = client.list_policy_versions(
            PolicyArn="arn:aws:iam::accountID:policy/" + arn

        )

        # print(response)
        for ver in response['Versions']:
            # print(ver['VersionId'])
            if ver['IsDefaultVersion'] is True:
                pass
            else:
                delete = client.delete_policy_version(
                    PolicyArn="arn:aws:iam::accountID:policy/" + arn,
                    VersionId=ver['VersionId']
                )
                print(delete)

        pol_delete = client.delete_policy(
            PolicyArn="arn:aws:iam::accountID:policy/" + arn
        )
        print("Policy Deleted Successfully!!")
    except Exception as E:
        print("Already Deleted!")
Kc Bickey
  • 1,166
  • 12
  • 11