Use scripts to bulk migrate your policies to use fine-grained IAM actions
Note
The following Amazon Identity and Access Management (IAM) actions have reached the end of standard support:
-
aws-portal
namespace -
purchase-orders:ViewPurchaseOrders
-
purchase-orders:ModifyPurchaseOrders
If you're using Amazon Organizations, you can use the bulk policy migrator scripts or bulk policy migrator to update polices from your payer account. You can also use the old to granular action mapping reference to verify the IAM actions that need to be added.
If you have an Amazon Web Services account, or are a part of an Amazon Organizations created on or after November 16, 2023, 11:00 AM (PDT), the fine-grained actions are already in effect in your organization.
To help migrate your IAM policies to use new actions, known as fine-grained actions, you
can use scripts from the Amazon
Samples
You run these scripts from the payer account of your organization to identify the following affected policies in your organization that use the old IAM actions:
-
Customer managed IAM policies
-
Role, group, and user IAM inline policies
-
Service control policies (SCPs) (applies to the payer account only)
-
Permission sets
The scripts generate suggestions for new actions that correspond to existing actions that are used in the policy. You then review the suggestions and use the scripts to add the new actions across all affected policies in your organization. You don't need to update Amazon managed policies or Amazon managed SCPs (for example, Amazon Control Tower and Amazon Organizations SCPs).
You use these scripts to:
-
Streamline the policy updates to help you manage the affected policies from the payer account.
-
Reduce the amount of time that you need to update the policies. You don't need to sign into each member account and manually update the policies.
-
Group identical policies from different member accounts together. You can then review and apply the same updates across all identical policies, instead of reviewing them one by one.
-
Ensure that user access remains unaffected after Amazon retires the old IAM actions on July 6, 2023.
For more information about policies and service control policies (SCPs), see the following topics:
-
Managing IAM policies in the IAM User Guide
-
Service control policies (SCPs) in the Amazon Organizations User Guide
-
Custom permissions in the IAM Identity Center User Guide
Overview
Follow this topic to complete the following steps:
Topics
Prerequisites
To get started, you must do the following:
-
Download and install Python 3
-
Sign in to your payer account and verify that you have an IAM principal that has the following IAM permissions:
"iam:GetAccountAuthorizationDetails", "iam:GetPolicy", "iam:GetPolicyVersion", "iam:GetUserPolicy", "iam:GetGroupPolicy", "iam:GetRole", "iam:GetRolePolicy", "iam:CreatePolicyVersion", "iam:DeletePolicyVersion", "iam:ListAttachedRolePolicies", "iam:ListPolicyVersions", "iam:PutUserPolicy", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:SetDefaultPolicyVersion", "organizations:ListAccounts", "organizations:ListPolicies", "organizations:DescribePolicy", "organizations:UpdatePolicy", "organizations:DescribeOrganization", "sso:DescribePermissionSet", "sso:DescribePermissionSetProvisioningStatus", "sso:GetInlinePolicyForPermissionSet", "sso:ListInstances", "sso:ListPermissionSets", "sso:ProvisionPermissionSet", "sso:PutInlinePolicyToPermissionSet", "sts:AssumeRole"
Tip
To get started, we recommend that you use a subset of an account, such as a test account, to verify that the suggested changes are expected.
You can then run the scripts again for remaining accounts in your organization.
Step 1: Set up your environment
To get started, download the required files from the Amazon
Samples
To set up your environment
-
Clone the repository from the Amazon Samples
website. In a command line window, you can use the following command: git clone https://github.com/aws-samples/bulk-policy-migrator-scripts-for-account-cost-billing-consoles.git
-
Navigate to the directory where you downloaded the files. You can use the following command:
cd bulk-policy-migrator-scripts-for-account-cost-billing-consoles
In the repository, you can find the following scripts and resources:
-
billing_console_policy_migrator_role.json
– The CloudFormation template that creates the
IAM role in member accounts of your organization. This role allows the scripts to assume the role, and then read and update the affected policies.BillingConsolePolicyMigratorRole
-
action_mapping_config.json
– Contains the one-to-many mapping of the old actions to the new actions. The scripts use this file to suggest the new actions for each affected policy that contains the old actions.Each old action corresponds to multiple fine-grained actions. The new actions suggested in the file provide users access to the same Amazon Web Services services before the migration.
-
identify_affected_policies.py
– Scans and identifies affected policies in your organization. This script generates aaffected_policies_and_suggestions.json
file that lists the affected policies along with the suggested new actions.Affected policies that use the same set of old actions are grouped together in the JSON file, so that you can review or update the suggested new actions.
-
update_affected_policies.py
– Updates the affected policies in your organization. The script inputs theaffected_policies_and_suggestions.json
file, and then adds the suggested new actions to the policies. -
rollback_affected_policies.py
– (Optional) Reverts changes made to the affected policies. This script removes the new fine-grained actions from the affected policies.
-
-
Run the following commands to set up and activate the virtual environment.
python3 -m venv venv
source venv/bin/activate
-
Run the following command to install the Amazon SDK for Python (Boto3) dependency.
pip install -r requirements.txt
Note
You must configure your Amazon credentials to use the Amazon Command Line Interface (Amazon CLI). For more information, see Amazon SDK for Python (Boto3)
.
For more information, see the README.md
Step 2: Create the CloudFormation StackSet
Follow this procedure to create a CloudFormation stack set. This stack
set then creates the BillingConsolePolicyMigratorRole
IAM role for all member accounts in your
organization.
Note
You only need to complete this step once from the management account (payer account).
To create the CloudFormation StackSet
-
In a text editor, open the
billing_console_policy_migrator_role.json
file, and replace each instance of
with the account ID of the payer account (for example,<management_account>
123456789012
). -
Save the file.
-
Sign in to the Amazon Web Services Management Console as the payer account.
-
In the CloudFormation console, create a stack set with the
billing_console_policy_migrator_role.json
file that you updated.For more information, see Creating a stack set on the Amazon CloudFormation console in the Amazon CloudFormation User Guide.
After CloudFormation creates the stack set, each member account in your organization has an
BillingConsolePolicyMigratorRole
IAM role.
The IAM role contains the following permissions:
"iam:GetAccountAuthorizationDetails", "iam:GetPolicy", "iam:GetPolicyVersion", "iam:GetUserPolicy", "iam:GetGroupPolicy", "iam:GetRolePolicy", "iam:CreatePolicyVersion", "iam:DeletePolicyVersion", "iam:ListPolicyVersions", "iam:PutUserPolicy", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:SetDefaultPolicyVersion"
Notes
For each member account, the scripts call the AssumeRole API operation to get temporary credentials to assume the
BillingConsolePolicyMigratorRole
IAM role.The scripts call the ListAccounts API operation to get all member accounts.
The scripts also call IAM API operations to perform the read and write permissions to the policies.
Step 3: Identify the affected policies
After you create the stack set and downloaded the files, run the identify_affected_policies.py
script.
This script assumes the BillingConsolePolicyMigratorRole
IAM role for each member account, and then identifies
the affected policies.
To identify the affected policies
-
Navigate to the directory where you downloaded the scripts.
cd policy_migration_scripts/scripts
-
Run the
identify_affected_policies.py
script.
You can use the following input parameters:
-
Amazon Web Services accounts that you want the script to scan. To specify accounts, use the following input parameters:
-
--all
– Scans all member accounts in your organization.python3
identify_affected_policies.py
--all -
--accounts
– Scans a subset of member accounts in your organization.python3
identify_affected_policies.py
--accounts 111122223333, 444455556666, 777788889999 -
--exclude-accounts
– Excludes specific member accounts in your organization.python3
identify_affected_policies.py
--all --exclude-accounts 111111111111, 222222222222, 333333333333
-
-
–-action-mapping-config-file
– (Optional) Specify the path to theaction_mapping_config.json
file. The script uses this file to generate suggested updates for affected policies. If you don't specify the path, the script uses theaction_mapping_config.json
file in the folder.python3
identify_affected_policies.py
–-action-mapping-config-file c:\Users\username\Desktop\Scripts\action_mapping_config.json
–-all
Note
You can't specify organizational units (OUs) with this script.
After you run the script, it creates two JSON files in a
Affected_Policies_
folder:<Timestamp>
-
affected_policies_and_suggestions.json
-
detailed_affected_policies.json
affected_policies_and_suggestions.json
-
Lists the affected policies with the suggested new actions. Affected policies that use the same set of old actions are grouped together in the file.
This file contains the following sections:
-
Metadata that provides an overview of the accounts that you specified in the script, including:
-
Accounts scanned and the input parameter used for the
identify_affected_policies.py
script -
Number of affected accounts
-
Number of affected policies
-
Number of similar policy groups
-
-
Similar policy groups – Includes the list of accounts and policy details, including the following sections:
-
ImpactedPolicies
– Specifies which policies are affected and included in the group -
ImpactedPolicyStatements
– Provides information about theSid
blocks that currently use the old actions in the affected policy. This section includes the old actions and IAM elements, such asEffect
,Principal
,NotPrincipal
,NotAction
, andCondition
.
-
-
SuggestedPolicyStatementsToAppend
– Provides the suggested new actions that are added as newSID
block.When you update the policies, this block is appended at the end of the policies.
Example
affected_policies_and_suggestions.json
fileThis file groups together policies that are similar based on the following criteria:
-
Same old actions used – Policies that have the same old actions across all
SID
blocks. -
Matching details – In addition to affected actions, the policies have identical IAM elements,such as:
-
Effect
(Allow
/Deny
) -
Principal
(who is allowed or denied access) -
NotAction
(what actions are not allowed) -
NotPrincipal
(who is explicitly denied access) -
Resource
(which Amazon resources the policy applies to) -
Condition
(any specific conditions under which the policy applies)
-
Note
For more information, see IAM policy examples.
Example
affected_policies_and_suggestions.json
[{ "AccountsScanned": [ "111111111111", "222222222222" ], "TotalAffectedAccounts": 2, "TotalAffectedPolicies": 2, "TotalSimilarPolicyGroups": 2 }, { "GroupName": "Group1", "ImpactedPolicies": [{ "Account": "111111111111", "PolicyType": "UserInlinePolicy", "PolicyName": "Inline-Test-Policy-Allow", "PolicyIdentifier": "1111111_1-user:Inline-Test-Policy-Allow" }, { "Account": "222222222222", "PolicyType": "UserInlinePolicy", "PolicyName": "Inline-Test-Policy-Allow", "PolicyIdentifier": "222222_1-group:Inline-Test-Policy-Allow" } ], "ImpactedPolicyStatements": [ [{ "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "aws-portal:ViewAccounts" ], "Resource": "*" }] ], "SuggestedPolicyStatementsToAppend": [{ "Sid": "BillingConsolePolicyMigrator0", "Effect": "Allow", "Action": [ "account:GetAccountInformation", "account:GetAlternateContact", "account:GetChallengeQuestions", "account:GetContactInformation", "billing:GetContractInformation", "billing:GetIAMAccessPreference", "billing:GetSellerOfRecord", "payments:ListPaymentPreferences" ], "Resource": "*" }] }, { "GroupName": "Group2", "ImpactedPolicies": [{ "Account": "111111111111", "PolicyType": "UserInlinePolicy", "PolicyName": "Inline-Test-Policy-deny", "PolicyIdentifier": "1111111_2-user:Inline-Test-Policy-deny" }, { "Account": "222222222222", "PolicyType": "UserInlinePolicy", "PolicyName": "Inline-Test-Policy-deny", "PolicyIdentifier": "222222_2-group:Inline-Test-Policy-deny" } ], "ImpactedPolicyStatements": [ [{ "Sid": "VisualEditor0", "Effect": "deny", "Action": [ "aws-portal:ModifyAccount" ], "Resource": "*" }] ], "SuggestedPolicyStatementsToAppend": [{ "Sid": "BillingConsolePolicyMigrator1", "Effect": "Deny", "Action": [ "account:CloseAccount", "account:DeleteAlternateContact", "account:PutAlternateContact", "account:PutChallengeQuestions", "account:PutContactInformation", "billing:PutContractInformation", "billing:UpdateIAMAccessPreference", "payments:UpdatePaymentPreferences" ], "Resource": "*" }] } ]
-
detailed_affected_policies.json
-
Contains the definition of all affected policies that the
identify_affected_policies.py
script identified for member accounts.The file groups similar policies together. You can use this file as reference, so that you can review and manage policy changes without needing to sign in to each member account to review the updates for each policy and account individually.
You can search the file for the policy name (for example,
) and then review the affected policy definitions.YourCustomerManagedReadOnlyAccessBillingUser
Example:
detailed_affected_policies.json
[{ "Account": "111111111111", "PolicyType": "CustomerManagedPolicy", "PolicyName": "AwsPortalviewAccount", "PolicyIdentifier": "arn:aws:iam::111111111111:policy/AwsPortalviewAccount", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "aws-portal:ViewAccount" ], "Resource": "*" }] } }, { "Account": "222222222222", "PolicyType": "CustomerManagedPolicy", "PolicyName": "AwsPortalviewAccount", "PolicyIdentifier": "arn:aws:iam::222222222222:policy/AwsPortalviewAccount", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "aws-portal:ViewAccount" ], "Resource": "*" }] } }, { "Account": "111111111111", "PolicyType": "CustomerManagedPolicy", "PolicyName": "AwsPortalModifyAccount", "PolicyIdentifier": "arn:aws:iam::111111111111:policy/AwsPortalModifyAccount", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Sid": "VisualEditor0", "Effect": "Deny", "Action": [ "aws-portal:ModifyAccount" ], "Resource": "*" }] } }, { "Account": "222222222222", "PolicyType": "CustomerManagedPolicy", "PolicyName": "AwsPortalModifyAccount", "PolicyIdentifier": "arn:aws:iam::222222222222:policy/AwsPortalModifyAccount", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Sid": "VisualEditor0", "Effect": "Deny", "Action": [ "aws-portal:ModifyAccount" ], "Resource": "*" }] } } ]
Step 4: Review the suggested changes
After the script creates the affected_policies_and_suggestions.json
file, review it and make any changes.
To review the affected policies
-
In a text editor, open the
affected_policies_and_suggestions.json
file. -
In the
AccountsScanned
section, verify that the number of similar groups identified across the scanned accounts is expected. -
Review the suggested fine-grained actions that will be added to the affected policies.
-
Update your file as needed and then save it.
Example 1: Update the
action_mapping_config.json
file
You can update the suggested mappings in the action_mapping_config.json
. After you update the file,
you can rerun the identify_affected_policies.py
script. This script generates updated suggestions for
the affected policies.
You can make multiple versions of the action_mapping_config.json
file to change the policies for
different accounts with different permissions. For example, you might create one file named
action_mapping_config_testing.json
to migrate permissions for your
test accounts and action_mapping_config_production.json
for your
production accounts.
Example 2: Update the
affected_policies_and_suggestions.json
file
To make changes to the suggested replacements for a specific affected policy group, you
can directly edit the suggested replacements section within the affected_policies_and_suggestions.json
file.
Any changes that you make in this section are applied to all policies within that specific affected policy group.
Example 3: Customize a specific policy
If you find that a policy within an affected policy group that needs different changes than the suggested updates, you can do the following:
-
Exclude specific accounts from the
identify_affected_policies.py
script. You can then review those excluded accounts separately. -
Update the affected
Sid
blocks by removing the affected policies and accounts that need different permissions. Create a JSON block that includes only the specific accounts or excludes them from the current update affected policy run.When you rerun the
identify_affected_policies.py
script, only the relevant accounts appear in the updated block. You can then refine the suggested replacements for that specificSid
block.
Step 5: Update the affected policies
After you review and refine the suggested replacements, run the update_affected_policies.py
script.
The script takes the affected_policies_and_suggestions.json
file as input. This script assumes the BillingConsolePolicyMigratorRole
IAM role to update the affected policies listed in the
affected_policies_and_suggestions.json
file.
To update the affected policies
-
If you haven't already, open a command line window for the Amazon CLI.
-
Enter the following command to run the
update_affected_policies.py
script. You can enter the following input parameter:
-
The directory path of the
affected_policies_and_suggestions.json
file that contains a list of the affected policies to be updated. This file is an output of the previous step.
python3
update_affected_policies.py
--affected-policies-directory Affected_Policies_<Timestamp>
The update_affected_policies.py
script updates the affected policies within the affected_policies_and_suggestions.json
file
with the suggested new actions. The script adds a Sid
block to the policies,
identified as BillingConsolePolicyMigrator
, where
#
#
corresponds to an incremental counter (for example, 1, 2, 3).
For example, if there are multiple Sid
blocks in the affected policy that use
old actions, the script adds multiple Sid
blocks that appear as
BillingConsolePolicyMigrator
to correspond to
each #
Sid
block.
Important
-
The script doesn't remove old IAM actions from the policies, and or change existing
Sid
blocks in the policies. Instead, it createsSid
blocks and appends them to the end of the policy. These newSid
blocks have the suggested new actions from the JSON file. This ensures that the permissions of the original policies aren't changed. -
We recommend that you do not change the name of the
BillingConsolePolicyMigrator
#
Sid
blocks in case you need to revert your changes.
Example: Policy with appended Sid
blocks
See the appended Sid
blocks in the
BillingConsolePolicyMigrator1
and BillingConsolePolicyMigrator2
blocks.
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ce:*", "aws-portal:ViewAccount" ], "Resource": "*", "Principal": { "AWS": "arn:aws:iam::111111111111:BillingRole" }, "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "true" } } }, { "Sid": "BillingConsolePolicyMigrator1", "Effect": "Allow", "Action": [ "account:GetAccountInformation", "account:GetAlternateContact", "account:GetChallengeQuestions", "account:GetContactInformation", "billing:GetContractInformation", "billing:GetIAMAccessPreference", "billing:GetSellerOfRecord", "payments:ListPaymentPreferences" ], "Resource": "*", "Principal": { "AWS": "arn:aws:iam::111111111111:BillingRole" }, "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "true" } } }, { "Sid": "BillingConsolePolicyMigrator2", "Effect": "Deny", "Action": [ "account:CloseAccount", "account:DeleteAlternateContact", "account:PutAlternateContact", "account:PutChallengeQuestions", "account:PutContactInformation", "billing:PutContractInformation", "billing:UpdateIAMAccessPreference", "payments:UpdatePaymentPreferences" ], "Resource": "*" } ] }
The script generates a status report that contains unsuccessful operations and outputs the JSON file locally.
Example: Status report
[{ "Account": "111111111111", "PolicyType": "Customer Managed Policy" "PolicyName": "AwsPortalViewPaymentMethods", "PolicyIdentifier": "identifier", "Status": "FAILURE", // FAILURE or SKIPPED "ErrorMessage": "Error message details" }]
Important
-
If you re-run the
identify_affected_policies.py
andupdate_affected_policies.py
scripts , they skip all policies that contain theBillingConsolePolicyMigratorRole
#
Sid
block. The scripts assume that those policies were previously scanned and updated, and that they don't require additional updates. This prevents the script from duplicating the same actions in the policy. -
After you update the affected policies, you can use the new IAM by using the affected policies tool. If you identify any issues, you can use the tool to switch back to the previous actions. You can also use a script to revert your policy updates.
For more information, see How to use the affected policies tool and the Changes to Amazon Billing, Cost Management, and Account Consoles Permissions
blog post. -
To manage your updates, you can:
-
Run the scripts for each account individually.
-
Run the script in batches for similar accounts, such as testing, QA, and production accounts.
-
Run the script for all accounts.
-
Choose a mix between updating some accounts in batches, and then updating others individually.
-
Step 6: Revert your changes (Optional)
The rollback_affected_policies.py
script reverts the changes applied to each affected policy for the
specified accounts. The script removes all Sid
blocks that the update_affected_policies.py
script appended. These Sid
blocks have the
format.BillingConsolePolicyMigratorRole
#
To revert your changes
-
If you haven't already, open a command line window for the Amazon CLI.
-
Enter the following command to run the
rollback_affected_policies.py
script. You can enter the following input parameters:
-
--accounts
-
Specifies a comma-separated list of the Amazon Web Services account IDs that you want to include in the rollback.
-
The following example scans the policies in the specified Amazon Web Services accounts, and removes any statements with the
BillingConsolePolicyMigrator
#
Sid
block.python3
rollback_affected_policies.py
–-accounts 111122223333, 555555555555, 666666666666
-
-
--all
-
Includes all Amazon Web Services account IDs in your organization.
-
The following example scans all policies in your organization, and removes any statements with the
BillingConsolePolicyMigratorRole
#
Sid
block.
python3
rollback_affected_policies.py
–-all -
-
--exclude-accounts
-
Specifies a comma-separated list of the Amazon Web Services account IDs that you want to exclude from the rollback.
You can use this parameter only when you also specify the
--all
parameter. -
The following example scans the policies for all Amazon Web Services accounts in your organization, except for the specified accounts.
python3
rollback_affected_policies.py
--all --exclude-accounts 777777777777, 888888888888, 999999999999
-
IAM policy examples
Policies are considered similar if they have identical:
-
Affected actions across all
Sid
blocks. -
Details in the following IAM elements:
-
Effect
(Allow
/Deny
) -
Principal
(who is allowed or denied access) -
NotAction
(what actions are not allowed) -
NotPrincipal
(who is explicitly denied access) -
Resource
(which Amazon resources the policy applies to) -
Condition
(any specific conditions under which the policy applies)
-
The following examples show policies which IAM might or might not consider similar based on the differences between them.
Example 1: Policies are considered similar
Each policy type is different, but both policies contain one Sid
block with
the same affected Action
.
Example 2: Policies are considered similar
Both policies contain one Sid
block with the same affected
Action
. Policy 2 contains additional actions, but these actions aren't
affected.
Example 3: Policies aren't considered similar
Both policies contain one Sid
block with the same affected
Action
. However, policy 2 contains a Condition
element that
isn't present in policy 1.
Example 4: Policies are considered similar
Policy 1 has a single Sid
block with an affected Action
.
Policy 2 has multiple Sid
blocks, but the affected Action
appears
in only one block.
Example 5: Policies aren't considered similar
Policy 1 has a single Sid
block with an affected Action
.
Policy 2 has multiple Sid
blocks, and the affected Action
appears
in multiple blocks.
Example 6: Policies are considered similar
Both policies have multiple Sid
blocks, with the same affected
Action
in each Sid
block.
Example 7
The following two policies aren't considered similar.
Policy 1 has a single Sid
block with an affected Action
.
Policy 2 has a Sid
block with the same affected Action
. However,
policy 2 also contains another Sid
block with different actions.