--- AWSTemplateFormatVersion: 2010-09-09 Description: Sets up AWS Config Rules (qs-1nb14cqcq) Metadata: Stack: Value: 0 VersionDate: Value: 4012016 Identifier: Value: template-config-rules Input: Description: optional tag key Output: Description: Outputs ID of all deployed resources RegionSupport: Value: NOTGOVCLOUD Parameters: pRequiredTagKey: Description: Tag key to check for with EC2/EBS REQUIRED_TAGS rule (optional, leave blank to ignore) Type: String Conditions: cRequiredTagsRule: !Not - !Equals - '' - !Ref pRequiredTagKey cApprovedAMIsRule: !Not - !Equals - '' - '' Resources: rConfigRuleForSSH: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: check-for-unrestricted-ssh-access Description: Checks whether security groups that are in use disallow unrestricted incoming SSH traffic. Scope: ComplianceResourceTypes: - AWS::EC2::SecurityGroup Source: Owner: AWS SourceIdentifier: INCOMING_SSH_DISABLED rConfigRuleForRequiredTags: Type: AWS::Config::ConfigRule Condition: cRequiredTagsRule Properties: ConfigRuleName: check-ec2-for-required-tag Description: Checks whether EC2 instances and volumes use the required tag. InputParameters: tag1Key: !Ref pRequiredTagKey Scope: ComplianceResourceTypes: - AWS::EC2::Volume - AWS::EC2::Instance Source: Owner: AWS SourceIdentifier: REQUIRED_TAGS rConfigRuleForUnrestrictedPorts: Type: AWS::Config::ConfigRule Condition: cRequiredTagsRule Properties: ConfigRuleName: check-for-unrestricted-ports Description: Checks whether security groups that are in use disallow unrestricted incoming TCP traffic to the specified ports. InputParameters: blockedPort1: 3389 Scope: ComplianceResourceTypes: - AWS::EC2::SecurityGroup Source: Owner: AWS SourceIdentifier: RESTRICTED_INCOMING_TRAFFIC rConfigRulesLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / rConfigRulesLambdaPolicy: Type: AWS::IAM::Policy Properties: PolicyName: configrules PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: '*' Resource: '*' Roles: - !Ref rConfigRulesLambdaRole rConfigRulesLambdaProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref rConfigRulesLambdaRole rAMIComplianceFunction: Type: AWS::Lambda::Function DependsOn: rConfigRulesLambdaRole Condition: cApprovedAMIsRule Properties: Code: ZipFile: | var aws = require('aws-sdk'); var config = new aws.ConfigService(); // Custom rule for evaluating pre-approved AMI use function evaluateCompliance(configurationItem, ruleParameters, context) { if(configurationItem.resourceType !== 'AWS::EC2::Instance') return 'NOT_APPLICABLE'; var amiIDs = ruleParameters.amiList.split(','); if (amiIDs.indexOf(configurationItem.configuration.imageId) > -1) { return 'COMPLIANT'; } else return 'NON_COMPLIANT'; } function isApplicable(configurationItem, event) { var status = configurationItem.configurationItemStatus; var eventLeftScope = event.eventLeftScope; return (status === 'OK' || status === 'ResourceDiscovered') && eventLeftScope === false; } exports.handler = function(event, context) { var invokingEvent = JSON.parse(event.invokingEvent); var ruleParameters = JSON.parse(event.ruleParameters); var compliance = 'NOT_APPLICABLE'; if (isApplicable(invokingEvent.configurationItem, event)) compliance = evaluateCompliance(invokingEvent.configurationItem, ruleParameters, context); // Invoke the compliance checking function. var putEvaluationsRequest = { Evaluations: [ { ComplianceResourceType: invokingEvent.configurationItem.resourceType, ComplianceResourceId: invokingEvent.configurationItem.resourceId, ComplianceType: compliance, OrderingTimestamp: invokingEvent.configurationItem.configurationItemCaptureTime } ], ResultToken: event.resultToken }; config.putEvaluations(putEvaluationsRequest, function (err, data) { if (err) { context.fail(err); } else { context.succeed(data); } }); }; Handler: index.handler Runtime: nodejs8.10 Timeout: 30 Role: !GetAtt - rConfigRulesLambdaRole - Arn rConfigRuleForAMICompliance: Type: AWS::Config::ConfigRule Condition: cApprovedAMIsRule Properties: ConfigRuleName: check-for-ami-compliance Description: Checks whether approved AMIs are used. Scope: ComplianceResourceTypes: - AWS::EC2::Instance InputParameters: amiList: '' Source: Owner: CUSTOM_LAMBDA SourceDetails: - EventSource: aws.config MessageType: ConfigurationItemChangeNotification SourceIdentifier: !GetAtt - rAMIComplianceFunction - Arn DependsOn: rConfigPermissionToCallLambdaAMICompliance rConfigPermissionToCallLambdaAMICompliance: Type: AWS::Lambda::Permission Condition: cApprovedAMIsRule Properties: FunctionName: !GetAtt - rAMIComplianceFunction - Arn Action: lambda:InvokeFunction Principal: config.amazonaws.com rCloudTrailValidationFunction: Type: AWS::Lambda::Function DependsOn: rConfigRulesLambdaRole Properties: Code: ZipFile: | var aws = require('aws-sdk'); var config = new aws.ConfigService(); // Custom rule for evaluating CloudTrail configuration compliance // 3 config parameters for Trail must be true: Multi-Region, Global Services Events, and Log File Validation function evaluateCompliance(configurationItem, ruleParameters, context) { if(configurationItem.resourceType !== 'AWS::CloudTrail::Trail') return 'NOT_APPLICABLE'; if((configurationItem.configuration.logFileValidationEnabled) && (configurationItem.configuration.includeGlobalServiceEvents) && (configurationItem.configuration.isMultiRegionTrail)) { return 'COMPLIANT'; } else return 'NON_COMPLIANT'; } function isApplicable(configurationItem, event) { var status = configurationItem.configurationItemStatus; var eventLeftScope = event.eventLeftScope; return (status === 'OK' || status === 'ResourceDiscovered') && eventLeftScope === false; } exports.handler = function(event, context) { var invokingEvent = JSON.parse(event.invokingEvent); var ruleParameters = JSON.parse(event.ruleParameters); var compliance = 'NOT_APPLICABLE'; if (isApplicable(invokingEvent.configurationItem, event)) compliance = evaluateCompliance(invokingEvent.configurationItem, ruleParameters, context); // Invoke the compliance checking function. var putEvaluationsRequest = { Evaluations: [ { ComplianceResourceType: invokingEvent.configurationItem.resourceType, ComplianceResourceId: invokingEvent.configurationItem.resourceId, ComplianceType: compliance, OrderingTimestamp: invokingEvent.configurationItem.configurationItemCaptureTime } ], ResultToken: event.resultToken }; config.putEvaluations(putEvaluationsRequest, function (err, data) { if (err) { context.fail(err); } else { context.succeed(data); } }); }; Handler: index.handler Runtime: nodejs8.10 Timeout: 30 Role: !GetAtt - rConfigRulesLambdaRole - Arn rConfigRuleForCloudTrail: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: check-whether-cloudtrail-is-enabled Description: Checks whether CloudTrail is enabled in this region. Scope: ComplianceResourceTypes: - AWS::EC2::Instance Source: Owner: CUSTOM_LAMBDA SourceDetails: - EventSource: aws.config MessageType: ConfigurationItemChangeNotification SourceIdentifier: !GetAtt - rCloudTrailValidationFunction - Arn DependsOn: rConfigPermissionToCallLambdaCloudTrail rConfigPermissionToCallLambdaCloudTrail: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt - rCloudTrailValidationFunction - Arn Action: lambda:InvokeFunction Principal: config.amazonaws.com ...