Skip to content

Commit

Permalink
refactor: move list of stateful resource types to data file (#1897)
Browse files Browse the repository at this point in the history
The CDK would like to use the same data that cfn-lint is using to
help our code generation.

This change moves the list of stateful resource types to a JSON file,
which is easier to parse for the CDK build process than a Python source
file. This will help keep the source of truth in sync between the
two projects.

This is not supposed to be the be-all-and-end-all solution of
integration between the two projects. I'm aware it's quite ad-hoc;
but let's try something low-friction and see how it goes?
  • Loading branch information
rix0rrr committed Feb 10, 2021
1 parent b32851e commit e12a293
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 26 deletions.
29 changes: 29 additions & 0 deletions src/cfnlint/data/AdditionalSpecs/StatefulResources.json
@@ -0,0 +1,29 @@
{
"ResourceTypes": {
"AWS::CloudFormation::Stack" : {},
"AWS::Backup::BackupVault" : {},
"AWS::Cognito::UserPool" : {},
"AWS::DocDB::DBCluster" : {},
"AWS::DocDB::DBInstance" : {},
"AWS::DynamoDB::Table" : {},
"AWS::EC2::Volume" : {},
"AWS::EFS::FileSystem" : {},
"AWS::EMR::Cluster" : {},
"AWS::ElastiCache::CacheCluster" : {},
"AWS::ElastiCache::ReplicationGroup" : {},
"AWS::Elasticsearch::Domain" : {},
"AWS::FSx::FileSystem" : {},
"AWS::Logs::LogGroup" : {},
"AWS::Neptune::DBCluster" : {},
"AWS::Neptune::DBInstance" : {},
"AWS::QLDB::Ledger" : {},
"AWS::RDS::DBCluster" : {},
"AWS::RDS::DBInstance" : {},
"AWS::Redshift::Cluster" : {},
"AWS::SDB::Domain" : {},
"AWS::SQS::Queue" : {},
"AWS::S3::Bucket" : {
"DeleteRequiresEmptyResource": true
}
}
}
Expand Up @@ -4,6 +4,8 @@
"""
from cfnlint.rules import CloudFormationLintRule
from cfnlint.rules import RuleMatch
import cfnlint.helpers
from cfnlint.data import AdditionalSpecs


class UpdateReplacePolicyDeletionPolicyOnStatefulResourceTypes(CloudFormationLintRule):
Expand All @@ -15,38 +17,27 @@ class UpdateReplacePolicyDeletionPolicyOnStatefulResourceTypes(CloudFormationLin
source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html'
tags = ['resources', 'updatereplacepolicy', 'deletionpolicy']

def __init__(self):
"""Init"""
super(UpdateReplacePolicyDeletionPolicyOnStatefulResourceTypes, self).__init__()

spec = cfnlint.helpers.load_resource(AdditionalSpecs, 'StatefulResources.json')

self.likely_stateful_resource_types = [
resource_type
for resource_type, descr in spec['ResourceTypes'].items()

# Resources that won't be deleted if they're not empty (ex: S3)
# don't need to be checked for policies, as chance of mistakes are low.
if not descr.get('DeleteRequiresEmptyResource', False)]

def match(self, cfn):
"""Check for UpdateReplacePolicy / DeletionPolicy"""
matches = []

likely_stateful_resource_types = ['AWS::CloudFormation::Stack',
'AWS::Backup::BackupVault',
'AWS::Cognito::UserPool',
'AWS::DocDB::DBCluster',
'AWS::DocDB::DBInstance',
'AWS::DynamoDB::Table',
'AWS::EC2::Volume',
'AWS::EFS::FileSystem',
'AWS::EMR::Cluster',
'AWS::ElastiCache::CacheCluster',
'AWS::ElastiCache::ReplicationGroup',
'AWS::Elasticsearch::Domain',
'AWS::FSx::FileSystem',
'AWS::Logs::LogGroup',
'AWS::Neptune::DBCluster',
'AWS::Neptune::DBInstance',
'AWS::QLDB::Ledger',
'AWS::RDS::DBCluster',
'AWS::RDS::DBInstance',
'AWS::Redshift::Cluster',
'AWS::SDB::Domain',
'AWS::SQS::Queue',
# 'AWS::S3::Bucket', (CloudFormation won't delete anyways)
]

resources = cfn.get_resources()
for r_name, r_values in resources.items():
if r_values.get('Type') in likely_stateful_resource_types:
if r_values.get('Type') in self.likely_stateful_resource_types:
if not r_values.get('DeletionPolicy') or not r_values.get('UpdateReplacePolicy'):
path = ['Resources', r_name]
message = 'The default action when replacing/removing a resource is to delete it. Set explicit values for UpdateReplacePolicy / DeletionPolicy on potentially stateful resource: %s' \
Expand Down

0 comments on commit e12a293

Please sign in to comment.