Policy as Code for the Cloud Development Kit (CDK)
APACHE-2.0 License
Cloud Patrol let's you define common policies with remediation strategies for your AWS CDK stacks and enforce them across your CDK stacks / applications.
NB: This is an alpha release - Everything might change.
Make sure your Cloud resources are:
yarn add cloudpatrol
Given this example:
import * as cdk from '@aws-cdk/core';
import { ExampleStack } from '../lib/example-stack';
import { AwsCdkPatrol } from 'cloudpatrol/lib'
import { awsDefaults } from 'cloudpatrol/policies/aws/packs/good-defaults'
const app = new cdk.App();
const stack = new ExampleStack(app, 'ExampleStack');
const cloudPatrol = new AwsCdkPatrol(awsDefaults)
cloudPatrol.check(stack)
We can do the following:
Check the full example.
Currently, there are two reporting mechanisms:
As part of your normal CDK commands (e.g. cdk synth --app bin/example.js
), will perform reporting on the Construct nodes itself and stop the synth process on errors.
For CI / CD workflows and local testing, just execute your CDK app directly with node
(e.g. node ./bin/example.js
). This is great for dedicated validation of policies without the synthesized output.
Hasn't been implemented, yet. But it's on the agenda, and probably possible right now with a bit of effort.
/**
* This Policy ensures that a bucket is properly versioned
*
* @cloudformationResource AWS::S3::Bucket
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-versioningconfig.html
*/
export class BucketVersioningPolicy extends Policy implements PolicyInterface {
public policyName = 'Bucket Versioning'
public description = 'This ensures that a bucket is properly versioned'
public link = 'https//docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-versioningconfig.html'
public scope = s3.CfnBucket
public validator(node: s3.CfnBucket, reporter: Reportable): void {
if (!node.versioningConfiguration ||
(!cdk.Tokenization.isResolvable(node.versioningConfiguration) && node.versioningConfiguration.status !== 'Enabled')) {
reporter.addWarning(node, this, 'Bucket versioning is not enabled');
}
}
}
Policies have to follow this schema
class YourCustomPolicy extends Policy implements PolicyInterface {
//...
}
There are two options to define the scope of a Policy:
Define an explicit scope:
class YourCustomPolicy extends Policy implements PolicyInterface {
//...
public scope = s3.CfnBucket
//...
}
Overwrite isApplicable
:
class YourCustomPolicy extends Policy implements PolicyInterface {
//...
public isApplicable(node: cdk.Resource): boolean {
// your custom logic here
}
//...
class YourCustomPolicy extends Policy implements PolicyInterface {
//...
public validator(node: s3.CfnBucket, reporter: Reportable, context: PolicyContext): void {
// your custom logic here.
}
//...
Found issues can be reported via the reporter
object. You can report multiple issues per Policy. There are three different issue severities:
context
is persistent across the entire Stack validation and can be passed in for dynamic information.
Cloud Patrol makes use of Aspects to visit all nodes in a given Construct (e.g. your stack). Aspects will be applied in the prepare stage, which will be called before synthesizing the stack. That's great if you're going to synthesize anyway. However, if you just wanna run the Cloud Patrol checks, we have to invoke the preparation by ourselves. Something along the lines of this:
stack.node.applyAspect(this);
cdk.ConstructNode.prepare(stack.node);
Reporter
to allow multiple ways of reporting.cloudpatrol
file?