Skip to content

Latest commit

 

History

History
159 lines (136 loc) · 4.65 KB

NagPack.md

File metadata and controls

159 lines (136 loc) · 4.65 KB

NagPack

A NagPack is a named collection of rules that can be used to validate your stacks and applications. All of the pre-built packs are NagPacks.

Creating a NagPack

cdk-nag exposes libraries that allow you to create your own NagPack.

Setup

Below is the minimal set-up for creating your own NagPack. At it's core a NagPack is an extension of CDK Aspects and inherits all the properties of Aspects.

import { CfnResource } from 'aws-cdk-lib';
import { IConstruct } from 'constructs';
import { NagPack, NagPackProps } from 'cdk-nag';

export class ExampleChecks extends NagPack {
  constructor(props?: NagPackProps) {
    super(props);
    this.packName = 'Example';
  }
  public visit(node: IConstruct): void {
    if (node instanceof CfnResource) {
      // Add your rules here.
    }
  }
}

Adding Rules

You may add both premade and custom rules to your NagPack. The documentation on rules walks through the process of creating a rule.

import { CfnResource } from 'aws-cdk-lib';
import { IConstruct } from 'constructs';
import {
  NagMessageLevel,
  NagPack,
  NagPackProps,
  NagRuleCompliance,
  NagRuleResult,
  NagRules,
  rules,
} from 'cdk-nag';
import { CfnReplicationInstance } from 'aws-cdk-lib/aws-dms';

export class ExampleChecks extends NagPack {
  constructor(props?: NagPackProps) {
    super(props);
    this.packName = 'Example';
  }
  public visit(node: IConstruct): void {
    if (node instanceof CfnResource) {
      // premade rule
      this.applyRule({
        info: 'My brief info.',
        explanation: 'My detailed explanation.',
        level: NagMessageLevel.ERROR,
        rule: rules.s3.S3BucketSSLRequestsOnly,
        node: node,
      });
      // custom rule
      this.applyRule({
        ruleSuffixOverride: 'NoPublicDMS',
        info: 'This rule triggers on public DMS replication instances.',
        explanation:
          'This rule does not prevent deployment unless level is set to NagMessageLevel.ERROR.',
        level: NagMessageLevel.WARN,
        rule: function (node2: CfnResource): NagRuleResult {
          if (node2 instanceof CfnReplicationInstance) {
            const publicAccess = NagRules.resolveIfPrimitive(
              node2,
              node2.publiclyAccessible
            );
            if (publicAccess !== false) {
              return NagRuleCompliance.NON_COMPLIANT;
            }
            return NagRuleCompliance.COMPLIANT;
          } else {
            return NagRuleCompliance.NOT_APPLICABLE;
          }
        },
        node: node,
      });
    }
  }
}

Ignoring Suppressions

You can optionally add a prebuilt or custom condition that prevents a rule from being suppressed. Below is an example of a condition that always prevents suppressions. The documentation on rules walks through the process of creating your own conditions.

import { CfnResource } from 'aws-cdk-lib';
import { IConstruct } from 'constructs';
import {
  NagMessageLevel,
  NagPack,
  NagPackProps,
  NagRuleCompliance,
  NagRuleResult,
  NagRules,
  SuppressionIgnoreAlways,
  rules,
} from 'cdk-nag';

const ALWAYS_IGNORE = new SuppressionIgnoreAlways(
  'Here is a reason for ignoring the suppression.'
);

export class ExampleChecks extends NagPack {
  constructor(props?: NagPackProps) {
    super(props);
    this.packName = 'Example';
  }
  public visit(node: IConstruct): void {
    if (node instanceof CfnResource) {
      this.applyRule({
        info: 'My brief info.',
        explanation: 'My detailed explanation.',
        level: NagMessageLevel.ERROR,
        rule: rules.s3.S3BucketSSLRequestsOnly,
        ignoreSuppressionCondition: ALWAYS_IGNORE,
        node: node,
      });
    }
  }
}

Custom Logging

NagLoggers give NagPack authors and users the ability to create their own custom reporting mechanisms. Read the NagLogger documentation for more details

Using a NagPack

You can apply as many NagPacks to a CDK Stack or Application via Aspects

import { App, Aspects } from 'aws-cdk-lib';
import { CdkTestStack } from '../lib/cdk-test-stack';
import { AwsSolutionsChecks } from 'cdk-nag';
import { ExampleChecks } from './ExampleClass';

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
// Simple rule informational messages
Aspects.of(app).add(new AwsSolutionsChecks());
Aspects.of(app).add(new ExampleChecks());