AWS announced breaking changes to the Python SDK that may require action before March 31 2021.
aws-cfnresponse-checker
is a command line tool to check AWS accounts for custom cloud formation resources that need updating.
There are two modes:
- Using AssumeRole and temporary credentials: intended for multi account environments
- Using environment credentials: intended for single accounts or testing purposes.
Run these scripts from an environment with the correct permissions to assume the account's role and perform read only operations on Cloudformation.
For example output, refer to the feature file.
The tool can identify three things:
- Stacks that have not been updated recently and MUST be updated to continue working
- Functions that use inline code and refer to the deprecated library. These MUST be updated.
- Functions that use externally packaged lambda code. These may/may not need to be updated - it is outside the scope of this tool to determine whether external function code needs updating. But this tool should help to avoid things falling through the cracks.
This tool locates any stacks using lambda backed Custom Resources, where the lambda function is defined in the same stack
If your lambda functions are defined externally (e.g. in a separate CloudFormation stack), this tool cannot identify them directly. It identifies the custom resources, but you will need to perform additional investigation to determine whether the lambda functions themselves are affected.
If you package your lambda functions externally, opposed to inline then this tool cannot determine if the function has been updated
Ensure that boto3 installed in a python3 environment
pipenv install && pipenv shell
OR
# For testing
pipenv install --pre --dev
- Cross-account trust must have been configured using IAM roles
- The trusting account role should grant read only permissions to CloudFormation, e.g. by applying the AWS Managed Policy -
AWSCloudFormationReadOnlyAccess
:arn:aws:iam::aws:policy/AWSCloudFormationReadOnlyAccess
- The trusting account role should grant read only permissions to CloudFormation, e.g. by applying the AWS Managed Policy -
- The tool supports auto-discovering accounts using AWS Organizations. NOTE: if you wish to use this functionality, the trusted account needs to be the root Organizations management account
- The tool should be run using appropriate credentials from the trusted account
- For Control Tower users, consider deploying as a lambda function in the Audit Account
If you want to test accounts individually:
python3 single_account.py --role-arn 'arn:aws:iam::${ROLE_ID}:role/${ROLE_NAME}' \
--regions us-east-1,ap-southeast-2 \
--clean-print
--regions
is optional, default is all regions--role-arn
is arn of the role to assume in the trusting accountRemove
--clean-print
to print region
python3 cross_accounts.py --role-name ${ROLE_NAME} \
--regions us-east-1,ap-southeast-2 \
--accounts 111111111111,222222222222 \
--clean-print
--regions
is optional, default is all regions.--accounts
is optional, will get all organization accounts by default (NOTE: for auto-discovery, it must be run from your root Organization account context).Remove
--clean-print
to print accounts and regions
Test a single account using your configured SDK credentials
python3 principle_account.py \
--regions us-east-1,ap-southeast-2 \
--clean-print
--regions
is optional, default is all regions.Remove
--clean-print
to print accounts and regions
If you are using the AssumeRole
mechanism, you can configure a test to identify issues and validate that you have fixed any problems
-
Create a
accounts.json
file like so in the tests folder.[ { "account_id": "111111111111", "regions": ["us-east-1", "us-east-2", "ap-southeast-2"], "role_name": "MyRoleForAccount" }, { "account_id": "222222222222", "regions": ["us-east-1", "us-east-2"], "role_name": "MyRoleForAccount" } ]
-
Then run pytest to test your accounts programatically before and after you've resolved them.
pytest ====================== 5 failed, 1 passed in 15.54s ============
There's two main methods to update the cfn-response module in your lambda functions:
ZipFile: |
import cfnresponse
def handler(event, context):
+ # This comment was added to force an update on this function's code
responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])}
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
Handler: index.handler
Role: !GetAtt MyRole.Arn
- Runtime: python3.6
+ Runtime: python3.7
Code:
ZipFile: |
import cfnresponse
def handler(event, context):
responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])}
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
Then after updating your templates, run the tests again to see if your account still has stale inline CloudFormation response lambdas.
pytest
====================== 5 passed in 22.86s ======================