A Config rule that checks that EC2 Instances have desired tenancy.

 
Items
4
Size
7.3 KB
Missing Parameters
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  CustomConfigRule:
    Type: 'AWS::Config::ConfigRule'
    Properties:
      ConfigRuleName: instance_desired_tenancy
      Description: A Config rule that checks that EC2 Instances have desired tenancy.
      InputParameters:
        DesiredTenancy: ''
      Scope:
        ComplianceResourceTypes:
          - 'AWS::EC2::Instance'
      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: LambdaForinstance_desired_tenancy
      Handler: index.handler
      Role:
        'Fn::GetAtt':
          - LambdaIamRole
          - Arn
      Runtime: nodejs6.10
      Code:
        ZipFile:
          'Fn::Join':
            - |+

            - - ''
              - //
              - >-
                // This file made available under CC0 1.0 Universal
                (https://creativecommons.org/publicdomain/zero/1.0/legalcode)
              - //
              - // Ensure EC2 Instances have desired tenancy
              - '// Description: Checks that EC2 Instances have desired tenancy'
              - //
              - '// Trigger Type: Change Triggered'
              - '// Scope of Changes: EC2:Instance'
              - '// Required Parameter: DesiredTenancy'
              - '// Example Value: dedicated'
              - ''
              - var aws = require('aws-sdk');
              - var config = new aws.ConfigService();
              - >-
                // This is where it's determined whether the resource is
                compliant or not.
              - >-
                // In this example, we look at the tenancy of the EC2 instance
                and determine whether it matches 
              - >-
                // the "DesiredTenancy" parameter that is passed to the rule. If
                the tenancy is not of the DesiredTenancy type, the 
              - >-
                // instance is marked non-compliant. Otherwise, it is marked
                complaint. 
              - ''
              - >-
                function evaluateCompliance(configurationItem, ruleParameters,
                context) {
              - '    checkDefined(configurationItem, "configurationItem");'
              - '    checkDefined(configurationItem.configuration, "configurationItem.configuration");'
              - '    checkDefined(ruleParameters, "ruleParameters");'
              - '    if (''AWS::EC2::Instance'' !== configurationItem.resourceType) {'
              - '        return ''NOT_APPLICABLE'';'
              - '    } if (ruleParameters.DesiredTenancy === configurationItem.configuration.placement.tenancy) {'
              - '        return ''COMPLIANT'';'
              - '    } else {'
              - '        return ''NON_COMPLIANT'';'
              - '    }'
              - '}'
              - // Helper function used to validate input
              - 'function checkDefined(reference, referenceName) {'
              - '    if (!reference) {'
              - '        console.log("Error: " + referenceName + " is not defined");'
              - '        throw referenceName;'
              - '    }'
              - '    return reference;'
              - '}'
              - >-
                // Check whether the the resource has been deleted. If it has,
                then the evaluation is unnecessary.
              - 'function isApplicable(configurationItem, event) {'
              - '    checkDefined(configurationItem, "configurationItem");'
              - '    checkDefined(event, "event");'
              - '    var status = configurationItem.configurationItemStatus;'
              - '    var eventLeftScope = event.eventLeftScope;'
              - '    return (''OK'' === status || ''ResourceDiscovered'' === status) && false === eventLeftScope;'
              - '}'
              - // This is the handler that's invoked by Lambda
              - // Most of this code is boilerplate; use as is
              - 'exports.handler = function(event, context) {'
              - '    event = checkDefined(event, "event");'
              - '    var invokingEvent = JSON.parse(event.invokingEvent);'
              - '    var ruleParameters = JSON.parse(event.ruleParameters);'
              - '    var configurationItem = checkDefined(invokingEvent.configurationItem, "invokingEvent.configurationItem");'
              - '    var compliance = ''NOT_APPLICABLE'';'
              - '    var putEvaluationsRequest = {};'
              - '    if (isApplicable(invokingEvent.configurationItem, event)) {'
              - '        // Invoke the compliance checking function.'
              - '        compliance = evaluateCompliance(invokingEvent.configurationItem, ruleParameters, context);'
              - '    }'
              - '    // Put together the request that reports the evaluation status'
              - '    // Note that we''re choosing to report this evaluation against the resource that was passed in.'
              - '    // You can choose to report this against any other resource type, as long as it is supported by Config rules'
              - '   '
              - '    putEvaluationsRequest.Evaluations = ['
              - '        {'
              - '            ComplianceResourceType: configurationItem.resourceType,'
              - '            ComplianceResourceId: configurationItem.resourceId,'
              - '            ComplianceType: compliance,'
              - '            OrderingTimestamp: configurationItem.configurationItemCaptureTime'
              - '        }'
              - '    ];'
              - '    putEvaluationsRequest.ResultToken = event.resultToken;'
              - '    // Invoke the Config API to report the result of the evaluation'
              - '    config.putEvaluations(putEvaluationsRequest, function (err, data) {'
              - '        if (err) {'
              - '            context.fail(err);'
              - '        } else {'
              - '            context.succeed(data);'
              - '        }'
              - '    });'
              - '};'
              - ''
      Timeout: 300
    DependsOn: LambdaIamRole
  LambdaIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: IAMRoleForinstance_desired_tenancy
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess'
        - '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

 
* Required field
Additional Attributes
Lambda Code (Nodejs)