Skip to content

Instantly share code, notes, and snippets.

@yumminhuang
Last active October 20, 2022 12:09
Show Gist options
  • Save yumminhuang/5e928e526d7b3de8c55ee142624b37a4 to your computer and use it in GitHub Desktop.
Save yumminhuang/5e928e526d7b3de8c55ee142624b37a4 to your computer and use it in GitHub Desktop.
Setting Password Policies to Follow CIS Benchmark via CloudFormation
---
AWSTemplateFormatVersion: '2010-09-09'
Description:
This CloudFormation stack sets an IAM Password Policy for an account. It uses
a custom resource to manage the policy. Note that IAM password policies are
global, and this will apply to all regions--not just the region you create
the stack in.
Parameters:
# CIS Benchmark Check 1.5
RequireUppercaseChars:
Type: 'String'
Description: 'Password requirement of at least one uppercase character.'
Default: 'True'
AllowedValues:
- 'True'
- 'False'
# CIS Benchmark Check 1.6
RequireLowercaseChars:
Type: 'String'
Description: 'Password requirement of at least one lowercase character.'
Default: 'True'
AllowedValues:
- 'True'
- 'False'
# CIS Benchmark Check 1.7
RequireSymbols:
Type: 'String'
Description: 'Password requirement of at least one nonalphanumeric character.'
Default: 'True'
AllowedValues:
- 'True'
- 'False'
# CIS Benchmark Check 1.8
RequireNumbers:
Type: 'String'
Description: 'Password requirement of at least one number.'
Default: 'True'
AllowedValues:
- 'True'
- 'False'
# CIS Benchmark Check 1.9
MinPasswordLength:
Type: 'Number'
Description: 'Minimum password length.'
Default: 14
ConstraintDescription: '(8-128 characters)'
MinValue: 8
MaxValue: 128
# CIS Benchmark Check 1.10
PasswordHistory:
Type: 'Number'
Description: 'Number of previous passwords to remember.'
Default: 24
ConstraintDescription: '(1-24 passwords)'
MinValue: 1
MaxValue: 24
# CIS Benchmark Check 1.11
MaxPasswordAge:
Type: 'Number'
Description: 'Maximum age for passwords, in number of days.'
Default: 90
ConstraintDescription: '(90-365 days)'
MinValue: 90
MaxValue: 365
Resources:
IAMPasswordPolicy:
Type: 'Custom::IAMPolicyResource'
Properties:
ServiceToken: !GetAtt IAMPasswordPolicyResource.Arn
Region: !Ref "AWS::Region"
IAMPasswordPolicyResource:
Type: "AWS::Lambda::Function"
Properties:
Runtime: python3.7
Handler: index.lambda_handler
MemorySize: 128
Timeout: 30
Role: !GetAtt IAMPasswordPolicyResourceExecutionRole.Arn
Code:
ZipFile: !Sub |
import json
import boto3
from botocore.exceptions import ClientError
import cfnresponse
iam = boto3.client("iam")
# Lambda entry point
def lambda_handler(event, context):
if event['RequestType'] == 'Create' or event['RequestType'] == 'Update':
res, reason = update_policy()
elif event['RequestType'] == 'Delete':
res, reason = delete_policy()
else:
res = False
reason = "Unknown operation: " + event['RequestType']
responseData = {}
responseData['Reason'] = reason
if res:
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
else:
cfnresponse.send(event, context, cfnresponse.FAILED, responseData)
def update_policy():
try:
response = iam.update_account_password_policy(
AllowUsersToChangePassword=True,
HardExpiry=False,
MaxPasswordAge=${MaxPasswordAge},
MinimumPasswordLength=${MinPasswordLength},
RequireLowercaseCharacters=${RequireLowercaseChars},
RequireNumbers=${RequireNumbers},
RequireSymbols=${RequireSymbols},
RequireUppercaseCharacters=${RequireUppercaseChars},
PasswordReusePrevention=${PasswordHistory})
return (True, response)
except Exception as e:
return (False, "Cannot update policy: " + str(e))
def delete_policy():
try:
policy = iam.get_account_password_policy()
response = iam.delete_account_password_policy()
return (True, response)
except Exception as e:
return (False, "Cannot delete policy: " + str(e))
IAMPasswordPolicyResourceExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: IAMPasswordCreatorPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: '*'
- Effect: Allow
Action:
- iam:GetAccountPasswordPolicy
- iam:UpdateAccountPasswordPolicy
- iam:DeleteAccountPasswordPolicy
Resource: "*"
Copy link

ghost commented Oct 21, 2020

Good Morning,

great work, thank you!
Are there any copyright restrictions on your code?

Happy coding,
Heiko.

@yumminhuang
Copy link
Author

Hello @FolkertsHeiko, Feel free to use it

Copy link

ghost commented Oct 21, 2020

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment