AWSTemplateFormatVersion: '2010-09-09' Description: 'Remediation of IAM Password Policy' Resources: IAMPasswordLambdaCustom: Type: AWS::CloudFormation::CustomResource Properties: ServiceToken: !GetAtt IAMPasswordLambdaFunction.Arn IAMPasswordLambdaPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - iam:DeleteAccountPasswordPolicy Resource: '*' IAMPasswordLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - !Ref 'IAMPasswordLambdaPolicy' IAMPasswordLambdaFunction: Type: AWS::Lambda::Function Properties: Description: Reset IAM Password Policy for AWS Account Handler: index.lambda_handler Runtime: python3.9 Role: !GetAtt 'IAMPasswordLambdaRole.Arn' MemorySize: 128 Timeout: 10 Code: ZipFile: | from __future__ import print_function import json import boto3 import urllib3 SUCCESS = 'SUCCESS' FAILED = 'FAILED' http = urllib3.PoolManager() # cfn-response module def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False, reason=None): responseUrl = event['ResponseURL'] print('responseUrl: ' + responseUrl) responseBody = { 'Status' : responseStatus, 'Reason' : reason or "See the details in CloudWatch Log Stream: {}".format(context.log_stream_name), 'PhysicalResourceId' : physicalResourceId or context.log_stream_name, 'StackId' : event['StackId'], 'RequestId' : event['RequestId'], 'LogicalResourceId' : event['LogicalResourceId'], 'NoEcho' : noEcho, 'Data' : responseData } json_responseBody = json.dumps(responseBody) print("Response body:") print(json_responseBody) headers = { 'content-type' : '', 'content-length' : str(len(json_responseBody)) } try: response = http.request('PUT', responseUrl, headers=headers, body=json_responseBody) print("Status code:", response.status) except Exception as e: print("send(..) failed executing http.request(..):", e) # lambda handler for IAM password policy remediator def lambda_handler(event, context): print('lambda_handler() received event: ' + json.dumps(event)) result = FAILED try: if event['RequestType'] == 'Create' or event['RequestType'] == 'Update': response = reset_iam_password_policy() print('iam password policy update completion response: ' + str(response)) result = SUCCESS elif event['RequestType'] == 'Delete': print('deletion of CloudFormation stack has no impact on current password policy') result = SUCCESS except Exception as e: print('lambda_handler error: ' + str(e)) result = FAILED send(event, context, result, {}) return # Reset IAM Password Policy for AWS Account according # def reset_iam_password_policy(): iam = boto3.client('iam') response = iam.delete_account_password_policy() return 'reset_account_password_policy() completion response: ' + str(response)