Skip to content

Instantly share code, notes, and snippets.

@yumminhuang
Last active October 20, 2022 12:09
Show Gist options
  • Select an option

  • Save yumminhuang/5e928e526d7b3de8c55ee142624b37a4 to your computer and use it in GitHub Desktop.

Select an option

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: "*"
@yumminhuang
Copy link
Copy Markdown
Author

Setting Password Policies to Follow Check 1.5 --- Check 1.11 of CIS Benchmark

See: Setting Password Policies via CloudFormation

Copy link
Copy Markdown

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
Copy Markdown
Author

Hello @FolkertsHeiko, Feel free to use it

Copy link
Copy Markdown

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