Skip to content

Instantly share code, notes, and snippets.

@aaronfranco
Created December 4, 2019 02:18
Show Gist options
  • Save aaronfranco/eedbfbaba433b7218122961f859de4d1 to your computer and use it in GitHub Desktop.
Save aaronfranco/eedbfbaba433b7218122961f859de4d1 to your computer and use it in GitHub Desktop.
var aws = require('aws-sdk');
var config = new aws.ConfigService();
var ec2 = new aws.EC2();
// 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.
// 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 = async function(event) {
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 = await evaluateCompliance(invokingEvent.configurationItem, ruleParameters);
checkDefined(configurationItem, "configurationItem");
checkDefined(configurationItem.configuration, "configurationItem.configuration");
checkDefined(configurationItem.resourceId, "configurationItem.resourceIds");
let instanceDetails = await ec2.describeInstances({"InstanceIds":[configurationItem.resourceId]}).promise();
if ('AWS::EC2::Instance' !== configurationItem.resourceType) {
compliance = 'NOT_APPLICABLE';
}
if(!instanceDetails.Reservations[0].Instances[0].hasOwnProperty("IamInstanceProfile")){
compliance = "NON_COMPLIANT"
}else{
let instanceProfileArn = instanceDetails.Reservations[0].Instances[0].IamInstanceProfile.Arn;
if (instanceProfileArn === "arn:aws:iam::<<ACCOUNT_ID>>:instance-profile/InstanceProfileRemediationRole") {
compliance = 'COMPLIANT';
} else {
compliance = 'NON_COMPLIANT';
}
}
}
// 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
await config.putEvaluations(putEvaluationsRequest).promise();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment