npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

eslint-plugin-awscdk

v0.0.65

Published

<!--BEGIN STABILITY BANNER-->

Downloads

1,855

Readme

ESLint Plugin for AWS CDK


cdk: Experimental

This module is experimental and under active development. Features are subject to non-backward compatible changes or removal in any future version. These are not subject to the Semantic Versioning model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.


How to use

Install

npm install --save-dev eslint-plugin-awscdk

Configure

Using ESLint configs

Using projen

import { AwsCdkTypeScriptApp } from 'projen';
const project = new AwsCdkTypeScriptApp({
  ...

  devDeps: [
    'eslint-plugin-awscdk',
  ],

  ...
});
project.eslint?.config.plugins.push('awscdk');
project.eslint?.config.extends.push('plugin:awscdk/all'); // or 'awscdk/aws-foundational' etc

without projen update eslintrc.json

{
	"plugins": [
		"awscdk"
	],
	"extends": [
		"plugin:awscdk/all"
	]
}

Using ESLint rules

using projen

import { AwsCdkTypeScriptApp } from 'projen';
const project = new AwsCdkTypeScriptApp({
  ...

  devDeps: [
    'eslint-plugin-awscdk',
  ],

  ...
});
project.eslint?.config.plugins.push('awscdk');

// add individual rules
project.eslint?.addRules({
  'awscdk/require-bucket-encryption': [
    2, // can set severity (0 = info, 1 = warning, 2 = error)
  ],
});

without projen update eslintrc.json

{
	"plugins": [
		"awscdk"
	],
	"rules": {
		"awscdk/require-bucket-encryption": [
			2
		]
	}
}

Rules

AWS Foundational Security Best Practices

How to enable

new apigateway.Stage(this, 'Stage', {
  loggingLevel: apigateway.MethodLoggingLevel.ERROR, // or INFO
  ...
});

// or

new apigateway.RestApi(this, 'API', {
  deployOptions: {
    loggingLevel: apigateway.MethodLoggingLevel.ERROR, // or INFO
  },
  ...
})

How to enable

// if autoScalingGroupName is provided then it should use ELB health checks
new autoscaling.AutoScalingGroup(this, 'ASG', {
  autoScalingGroupName: 'my-asg',
  healthCheck: autoscaling.HealthCheck.elb(),
});

How to enable

new Distribution(this, 'Distribution', {
  defaultBehavior: {
    ...
  },
  defaultRootObject: 'index.html',
})

How to enable

new Distribution(this, 'Distribution', {
  defaultBehavior: {
    viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
    ...
  },
})

// or

new Distribution(this, 'Distribution', {
  defaultBehavior: {
    viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.HTTPS_ONLY,
    ...
  },
})

How to enable

new Distribution(this, 'Distribution', {
  defaultBehavior: {
    origin: new origins.OriginGroup(...),
  }
})

Currently no L2 construct

How to enable

// either set billingMode to PAY_PER_REQUEST

new Table(this, 'Table', {
  billingMode: BillingMode.PAY_PER_REQUEST,
});

new Table(this, 'Table', {
  replicationRegions: ['us-east-1', 'us-east-2'], // if replication regions is specified then billingMode is set to PAY_PER_REQUEST
})

// or if billingMode is PROVISIONED, then enable autoscaling

const table = new Table(this, 'Table', {
  billingMode: BillingMode.PROVISIONED, // this is also the default
});

table.autoScaleReadCapacity();
table.autoScaleWriteCapacity();

How to enable

new Table(this, 'Table', {
  pointInTimeRecovery: true,
})

Currently no L2 construct

How to enable

new ec2.Volume(this, 'Volume', {
  encrypted: true,
});
new efs.FileSystem(this, 'FileSystem', {
  encrypted: true,
});

How to enable

const alb = new ApplicationLoadBalancer(this, 'ALB', {
  ...
})

alb.setAttribute('routing.http.drop_invalid_header_fields.enabled', true);

How to enable

const alb = new ApplicationLoadBalancer(this, 'ALB', {
  ...
})

alb.logAccessLogs(bucket);

How to enable

new ApplicationLoadBalancer(this, 'ALB', {
  deletionProtection: true,
  ...
})

How to enable

const alb = new elbv2.ApplicationLoadBalancer(this, 'ALB');

alb.addListener('1', {
  protocol: elbv2.ApplicationProtocol.HTTP, // applies to listeners with HTTP protocol
  port: 80, //  if protocol is not provided then will default to http if port is 80 | 8080 | 8000 | 8008
  defaultAction: elbv2.ListenerAction.redirect({
    protocol: elbv2.ApplicationProtocol.HTTPS,
    ...
  }),
});

// or

new elbv2.ApplicationListener(this, 'Listener', {
  protocol: elbv2.ApplicationProtocol.HTTP, // applies to listeners with HTTP protocol
  port: 80, //  if protocol is not provided then will default to http if port is 80 | 8080 | 8000 | 8008
  defaultAction: elbv2.ListenerAction.redirect({
    protocol: elbv2.ApplicationProtocol.HTTPS,
    ...
  }),
})

Currently no L2 construct

How to enable

new elasticsearch.Domain(this, 'Domain', {
  encryptionAtRest: {
    enabled: true,
  }
});

How to enable

new elasticsearch.Domain(this, 'Domain', {
  vpc,
});

How to enable

new elasticsearch.Domain(this, 'Domain', {
  nodeToNodeEncryption: true,
});
new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  resources: ['*'],
  actions: ['*'],
});

Will fail rule

const user = new iam.User(this, 'User', {
  managedPolicies: [...] // will fail if this is provided.
});

user.addManagedPolicy();
user.addToPolicy();
user.addToPrincipalPolicy();
user.attachInlinePolicy();

Will fail rule

import * as iam from '@aws-cdk/aws-iam';
new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  resources: ['*'],
  actions: ['kms:Decrypt', 'kms:ReEncryptFrom'],
});

Will fail rule

import * as iam from '@aws-cdk/aws-iam';
new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  resources: ['*'],
  actions: ['kms:Decrypt', 'kms:ReEncryptFrom'],
});

Will fail rule

new kms.Key(this, 'Key', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
});
// any policy with `iam.AnyPrincipal() can't be attached to a Lambda function
const policy = new iam.PolicyStatment({
  principals: [ 
    new iam.AnyPrincipal() // equals {"AWS": "*"}
  ],
  ...
});

// Lots of ways to attach this permission to a lambda function...

// used in `initialPolicy`
const handler = new lambda.Function(this, 'Handler', {
  initialPolicy: [policy],
  ...
});

// or
handler.grantPrincipal.addToPrincipalPolicy(policy);

//or
handler.role?.addToPrincipalPolicy(policy);

//or
handler.role?.attachInlinePolicy(policy);

//or
handler.role?.grant(new iam.AnyPrincipal(), [...]);

//or
handler.role?.grantPassRole(new iam.AnyPrincipal());

//or
handler.role?.grantPrincipal.addToPrincipalPolicy(policy);

//or
handler.addPermission('permission', {
  principal: new iam.AnyPrincipal(),
  ...
});

//or
handler.addToRolePolicy(policy);

//or
handler.grantInvoke(new iam.AnyPrincipal());

How to enable

new lambda.Function(this, 'Handler', {
  runtime: Runtime.PYTHON_3_8, 
});

Will check for these runtimes:

new rds.DatabaseInstance(this, 'Instance', {
  ...
  publiclyAccessible: true,
});

default value of 'publiclyAccessible' is determined by the subnet type

new rds.DatabaseInstance(this, 'Instance', {
  ...
  vpcSubnets: {
    subnetType: ec2.SubnetType.PUBLIC,
  }
});
new rds.DatabaseInstance(this, 'Instance', {
  ...
  storageEncrypted: false,
})

How to enable

new rds.DatabaseInstance(this, 'DB', {
  multiAz: true,
  ...
});

How to enable

new rds.DatabaseInstance(this, 'Instance', {
  ...
  enablePerformanceInsights: true,
});

// or
new rds.DatabaseInstance(this, 'Instance', {
  ...
  enablePerformanceInsights: true,
});

or

new rds.DatabaseInstance(this, 'Instance', {
  ...
  performanceInsightsEncryptionKey: key,
})

or

new rds.DatabaseInstance(this, 'Instance', {
  ...
  performanceInsightsRetention: rds.PerformanceInsightsRetention.DEFAULT,
})
new rds.DatabaseCluster(this, 'Instance', {
  ...
  deletionProtection: false,
})

How to enable

new rds.DatabaseCluster(this, 'Instance', {
  ...
  deletionProtection: true,
})

or

new rds.DatabaseCluster(this, 'Instance', {
  ...
  removalPolicy: cdk.RemovalPolicy.RETAIN,
})
new rds.DatabaseInstance(this, 'Instance', {
  ...
  deletionProtection: false,
})

How to enable

new rds.DatabaseInstance(this, 'Instance', {
  ...
  deletionProtection: true,
})

or

new rds.DatabaseInstance(this, 'Instance', {
  ...
  removalPolicy: cdk.RemovalPolicy.RETAIN,
})

How to enable also applies to XXFromSnapshot & XXReadReplica

// log exports depend on the engine used
new rds.DatabaseCluster(this, 'Cluster', {
  cloudwatchLogsExports: []
  ...
});

// for AURORA_POSTGRESQL
new rds.DatabaseCluster(this, 'Cluster', {
  engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,
  cloudwatchLogsExports: ['Postgresql', 'Upgrade'],
  ...
});

// for AURORA_MYSQL & AURORA
new rds.DatabaseCluster(this, 'Cluster', {
  engine: rds.DatabaseClusterEngine.AURORA_MYSQL,
  cloudwatchLogsExports: ['Audit', 'Error', 'General', 'SlowQuery'],
  ...
});

// for MySQL
new rds.DatabaseInstance(this, 'RDS', {
  engine: rds.DatabaseInstanceEngine.MYSQL,
  cloudwatchLogsExports: ['Audit', 'Error', 'General', 'SlowQuery'],
});

// for POSTGRES
new rds.DatabaseInstance(this, 'RDS', {
  engine: rds.DatabaseInstanceEngine.POSTGRESQL,
  cloudwatchLogsExports: ['Postgresql', 'Upgrade'],
  ...
});

// for ORACLE_EE, ORACLE_SE, ORACLE_SE1, ORACLE_SE2
new rds.DatabaseInstance(this, 'RDS', {
  engine: rds.DatabaseInstanceEngine.ORACLE_XX,
  cloudwatchLogsExports: ['Alert', 'Audit', 'Trace', 'Listener'],
  ...
});

// for SQL_SERVER_EE, SQL_SERVER_EX, SQL_SERVER_SE, SQL_SERVER_SE, SQL_SERVER_WEB
new rds.DatabaseInstance(this, 'RDS', {
  engine: rds.DatabaseInstanceEngine.SQL_SERVER_XX,
  cloudwatchLogsExports: ['Error', 'Agent'],
  ...
});

// for MARIADB
new rds.DatabaseInstance(this, 'RDS', {
  engine: rds.DatabaseInstanceEngine.MARIADB,
  cloudwatchLogsExports: ['Audit', 'Error', 'General', 'SlowQuery'],
  ...
});

How to enable

new rds.DatabaseInstance(this, 'RDS', {
  iamAuthentication: true,
  ...
});

// or
new rds.DatabaseInstanceFromSnapshot(this, 'RDS', {
  iamAuthentication: true,
  ...
});

// or
new rds.DatabaseInstanceReadReplica(this, 'RDS', {
  iamAuthentication: true,
  ...
});

Will fail rule

new redshift.Cluster(this, 'Cluster', {
  publiclyAccessible:  true,
});

How to enable

const parameterGroup = new redshift.ClusterParameterGroup(this, 'ParamGroup', {
  parameters: {
    require_SSL: '1',
  },
});

new redshift.Cluster(this, 'Cluster', {
  parameterGroup,
});

Currently default to 1 without the ability to change. issue link

This is automatically enabled when using the Redshift Cluster L2 Construct

How to enable

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});

// or

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: new s3.BlockPublicAccess({
    blockPublicAcls: true,
    blockPublicPolicy: true,
    ignorePublicAcls: true,
    restrictPublicBuckets: true,
  }),
});

Through Block Public Access settings How to enable

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});

// or

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: new s3.BlockPublicAccess({
    blockPublicAcls: true,
    blockPublicPolicy: true,
    ignorePublicAcls: true,
    restrictPublicBuckets: true,
  }),
});

Through Bucket ACL Will fail rule

new s3.Bucket(this, 'Bucket', {
  accessControl: s3.BucketAccessControl.PUBLIC_READ,
});

// or

new s3.Bucket(this, 'Bucket', {
  accessControl: s3.BucketAccessControl.PUBLIC_READ_WRITE,
});

// or

const bucket = new s3.Bucket(this, 'Bucket', {
  accessControl: s3.BucketAccessControl.AUTHENTICATED_READ,
});

b.grantReadAccess()
bucket.grantReadAccess();

// or

new s3.Bucket(this, 'Bucket', {
  publicReadAccess: true,
});

Through Bucket policy

const bucket = new s3.Bucket(this, 'Bucket');

bucket.grantPublicAccess();

// or
bucket.addToResourcePolicy(new iam.PolicyStatement({
  ...,
  principals: ['*'],
}));

// or
const bucketPolicy = new s3.BucketPolicy(this, 'BucketPolicy', {
  bucket,
});

bucketPolicy.document.addStatements([
  new iam.PolicyStatement({
    ...,
    principals: ['*'],
  }),
]);

Through Block Public Access settings How to enable

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});

// or

new s3.Bucket(this, 'Bucket', {
  blockPublicAccess: new s3.BlockPublicAccess({
    blockPublicAcls: true,
    blockPublicPolicy: true,
    ignorePublicAcls: true,
    restrictPublicBuckets: true,
  }),
});

Through Bucket ACL Will fail rule

new s3.Bucket(this, 'Bucket', {
  accessControl: s3.BucketAccessControl.PUBLIC_READ_WRITE,
});

Through Bucket policy Will fail rule

const bucket = new s3.Bucket(this, 'Bucket');

bucket.grantPublicAccess();

// or
bucket.addToResourcePolicy(new iam.PolicyStatement({
  ...,
  principals: ['*'],
}));

// or
const bucketPolicy = new s3.BucketPolicy(this, 'BucketPolicy', {
  bucket,
});

bucketPolicy.document.addStatements([
  new iam.PolicyStatement({
    ...,
    principals: ['*'],
  }),
]);

How to enable

new s3.Bucket(this, 'Bucket', {
  encryption: s3.BucketEncryption.XXX // any value
});

// or

new s3.Bucket(this, 'Bucket', {
  encryptionKey,
});

How to enable

new s3.Bucket(this, 'Bucket', {
  enforceSSL: true,
})

Will fail rule

const policy = new iam.PolicyStatement({
  actions: [ // these actions are not allowed
    's3:DeleteBucketPolicy',
    's3:PutBucketAcl',
    's3:PutBucketPolicy',
    's3:PutEncryptionConfiguration',
    's3:PutObjectAcl',
  ],
  principals: [
    new iam.AccountPrincipal('11111111111'), // If granting access to current account should use iam.AccountRootPrincipal()
    new iam.AnyPrincipal(), // allows access from any AWS account, i.e. { "AWS": "*" }
  ],
  ...
})

Currently no L2

How to enable

const secret = new secretsmanager.Secret(this, 'Secret');
secret.addRotationSchedule();

// or

const secret = new secretsmanager.Secret(this, 'Secret');
new secretsmanager.RotationSchedule(this, 'Rotation', {
  secret,
})

How to enable

new sns.Topic(this, 'Topic', {
  masterKey,
  ...
})