A rule contains an assertion to make against each individual resource in your CDK application.
A rule returns a NagRuleResult
which is either a NagRuleCompliance
status or a list of findings.
NagRuleCompliance.NON_COMPLIANT
- The resource that does not meet the requirements.NagRuleCompliance.COMPLIANT
- The resource that meets the requirements.NagRuleCompliance.NOT_APPLICABLE
- The rule does not apply to the given resource.- Ex. The current resource is a S3 Bucket but the rule is for validating DMS Replication Instances.
NagRuleFindings
A string array with a list of all findings.
import { CfnResource } from 'aws-cdk-lib';
import { NagRuleCompliance, NagRuleResult, NagRules } from 'cdk-nag';
import { CfnReplicationInstance } from 'aws-cdk-lib/aws-dms';
/**
* DMS replication instances are not public
* @param node the CfnResource to check
*/
export function myRule(node: CfnResource): NagRuleResult {
if (node instanceof CfnReplicationInstance) {
const publicAccess = NagRules.resolveIfPrimitive(
node,
node.publiclyAccessible
);
if (publicAccess !== false) {
return NagRuleCompliance.NON_COMPLIANT;
// or, if your rule returns multiple violations
// return ['publicAccess', ...]
}
return NagRuleCompliance.COMPLIANT;
} else {
return NagRuleCompliance.NOT_APPLICABLE;
}
}
In many cases you may find that you may have to deal with Tokenized values when creating a rule. cdk-nag
provides the NagRules
class to help resolve tokens when an the resolved value of a Token must be known to pass rule validation.
When using NagRules
helper function, if a Tokenized value can not be resolved to a specific value (ex. the token resolves to a CloudFormation Intrinsic function) you will see a CdkNagValidationFailure
in the cdk-nag
cli output for a given resource.
A list of NagRules
functions can be found in the API documentation.
A cdk-nag
rule validation error contains both the NagPack name and a rule name. You can set a default rule name and/or override the rule name when applying the rule in pack.
# An example cdk-nag message.
Error at /StackName/Resource] NagPackName-RuleName: Information.
You can use the Object.defineProperty() method to influence the name of the rule. Without this
import { CfnResource } from 'aws-cdk-lib';
import { NagRuleCompliance, NagRuleResult, NagRules } from 'cdk-nag';
import { CfnReplicationInstance } from 'aws-cdk-lib/aws-dms';
export function myRule(node: CfnResource): NagRuleResult {
if (node instanceof CfnReplicationInstance) {
const publicAccess = NagRules.resolveIfPrimitive(
node,
node.publiclyAccessible
);
if (publicAccess !== false) {
return NagRuleCompliance.NON_COMPLIANT;
}
return NagRuleCompliance.COMPLIANT;
} else {
return NagRuleCompliance.NOT_APPLICABLE;
}
}
Object.defineProperty(myRule, 'name', { value: 'MyDefaultName' });
You may optionally override the rule name when applying the rule in a NagPack by using a ruleSuffixOverride
. An overridden name takes priority over the defined function name.
import { CfnResource } from 'aws-cdk-lib';
import { IConstruct } from 'constructs';
import { NagMessageLevel, NagPack, NagPackProps } from 'cdk-nag';
import { myRule } from './MyRule';
export class ExampleChecks extends NagPack {
constructor(props?: NagPackProps) {
super(props);
this.packName = 'Example';
}
public visit(node: IConstruct): void {
if (node instanceof CfnResource) {
this.applyRule({
ruleSuffixOverride: 'OverriddenName',
info: 'My brief info.',
explanation: 'My detailed explanation.',
level: NagMessageLevel.ERROR,
rule: myRule,
node: node,
});
}
}
}