A Config rule that ensures that IAM policies are attached only to groups or roles.

 
Items
4
Size
4.9 KB
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  CustomConfigRule:
    Type: 'AWS::Config::ConfigRule'
    Properties:
      ConfigRuleName: iam_users_no_policies_attached
      Description: >-
        A Config rule that ensures that IAM policies are attached only to groups
        or roles.
      InputParameters: {}
      Scope:
        ComplianceResourceTypes:
          - 'AWS::IAM::User'
      Source:
        Owner: CUSTOM_LAMBDA
        SourceIdentifier:
          'Fn::GetAtt':
            - LambdaFunction
            - Arn
        SourceDetails:
          - EventSource: aws.config
            MessageType: ConfigurationItemChangeNotification
          - EventSource: aws.config
            MessageType: OversizedConfigurationItemChangeNotification
    DependsOn: LambdaInvokePermissions
  LambdaInvokePermissions:
    Type: 'AWS::Lambda::Permission'
    Properties:
      FunctionName:
        'Fn::GetAtt':
          - LambdaFunction
          - Arn
      Action: 'lambda:InvokeFunction'
      Principal: config.amazonaws.com
  LambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: LambdaForiam_users_no_policies_attached
      Handler: index.lambda_handler
      Role:
        'Fn::GetAtt':
          - LambdaIamRole
          - Arn
      Runtime: python2.7
      Code:
        ZipFile:
          'Fn::Join':
            - |+

            - - >-
                #==================================================================================================
              - '# Function: EvaluateUserPolicyAssociations'
              - >-
                # Purpose:  Evaluates whether users have policies associated
                with them. Users should inherit permissions from groups instead.
              - >-
                #==================================================================================================
              - import json
              - import boto3
              - 'APPLICABLE_RESOURCES = [''AWS::IAM::User'']'
              - annotation = ''
              - 'def evaluate_compliance(configuration_item):'
              - '  global annotation'
              - '  annotation='''''
              - '  if configuration_item[''resourceType''] not in APPLICABLE_RESOURCES:'
              - '    return ''NOT_APPLICABLE'''
              - '  user_name = configuration_item[''resourceName'']'
              - '  iam = boto3.client(''iam'')'
              - '  # lists all user inline attached policies'
              - '  if iam.list_user_policies(UserName=user_name)[''PolicyNames'']:'
              - '    annotation = annotation + ''The user has inline policies attached! '''
              - '    return ''NON_COMPLIANT'''
              - '  # lists all user managed attached policies'
              - '  elif iam.list_attached_user_policies(UserName=user_name)[''AttachedPolicies'']:'
              - '    annotation=annotation + ''The user has managed policies attached! '''
              - '    return ''NON_COMPLIANT'''
              - '  else:'
              - '    annotation=annotation + ''The user does not have inline or managed policies attached! '''
              - '    return ''COMPLIANT'''
              - 'def lambda_handler(event, context):'
              - '  invoking_event = json.loads(event[''invokingEvent''])'
              - '  configuration_item = invoking_event[''configurationItem'']'
              - '  result_token = ''No token found.'''
              - '  if ''resultToken'' in event: result_token = event[''resultToken'']'
              - '  config = boto3.client(''config'')'
              - '  config.put_evaluations('
              - '    Evaluations=['
              - '      {'
              - '        ''ComplianceResourceType'': configuration_item[''resourceType''],'
              - '        ''ComplianceResourceId'': configuration_item[''resourceId''],'
              - '        ''ComplianceType'': evaluate_compliance(configuration_item),'
              - '        ''Annotation'': annotation,'
              - '        ''OrderingTimestamp'': configuration_item[''configurationItemCaptureTime'']'
              - '      },'
              - '    ],'
              - '    ResultToken=result_token'
              - '  )'
              - ''
      Timeout: 300
    DependsOn: LambdaIamRole
  LambdaIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: IAMRoleForiam_users_no_policies_attached
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/IAMReadOnlyAccess'
        - 'arn:aws:iam::aws:policy/service-role/AWSConfigRulesExecutionRole'
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      Policies: []
Parameters: {}
Metadata: {}
Conditions: {}

Customize Cf Template

Rule Parameters

No rule paramters
 
* Required field
Additional Attributes
Lambda Code (Python)