Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flag previous generation instance types #2267

Merged
merged 11 commits into from
May 26, 2022
45 changes: 45 additions & 0 deletions src/cfnlint/rules/resources/PreviousGenerationInstanceType.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
import re
from cfnlint.rules import CloudFormationLintRule
from cfnlint.rules import RuleMatch


class PreviousGenerationInstanceType(CloudFormationLintRule):
id = 'I3100'
shortdesc = 'Checks for legacy instance type generations'
description = 'New instance type generations increase performance and decrease cost'
source_url = 'https://aws.amazon.com/ec2/previous-generation/'
tags = ['resources', 'ec2', 'rds', 'elasticcache', 'elasticsearch']

def match(self, cfn):
matches = []
for resource_type, property_type in [
('AWS::AutoScaling::LaunchConfiguration', 'InstanceType'),
('AWS::EC2::CapacityReservation', 'InstanceType'),
('AWS::EC2::Host', 'InstanceType'),
('AWS::EC2::Instance', 'InstanceType'),
('AWS::RDS::DBInstance', 'DBInstanceClass'),
('AWS::ElastiCache::CacheCluster', 'CacheNodeType'),
('AWS::ElastiCache::GlobalReplicationGroup', 'CacheNodeType'),
('AWS::ElastiCache::ReplicationGroup', 'CacheNodeType'),
]:
for resource_name, resource in cfn.get_resources([resource_type]).items():
if isinstance(resource.get('Properties', {}).get(property_type, ''), str):
if re.search(r'([cmr][1-3]|cc2|cg1|cr1|g2|hi1|hs1|i2|t1)\.', resource.get('Properties', {}).get(property_type, '')):
matches.append(RuleMatch(['Resources', resource_name, property_type], 'Upgrade previous generation instance type: ' + resource.get('Properties').get(property_type)))

for resource_type, top_level_property_type, property_type in [
('AWS::EC2::EC2Fleet', 'FleetLaunchTemplateOverridesRequest', 'InstanceType'),
('AWS::EC2::LaunchTemplate', 'LaunchTemplateData', 'InstanceType'),
('AWS::EC2::SpotFleet', 'SpotFleetLaunchSpecification', 'InstanceType'),
('AWS::OpenSearchService::Domain', 'ClusterConfig', 'InstanceType'),
('AWS::Elasticsearch::Domain', 'ElasticsearchClusterConfig', 'InstanceType'),
]:
for resource_name, resource in cfn.get_resources([resource_type]).items():
if isinstance(resource.get('Properties', {}).get(top_level_property_type, {}).get(property_type, ''), str):
if re.search(r'([cmr][1-3]|cc2|cg1|cr1|g2|hi1|hs1|i2|t1)\.', resource.get('Properties', {}).get(top_level_property_type, {}).get(property_type, '')):
matches.append(RuleMatch(['Resources', resource_name, top_level_property_type, property_type], 'Upgrade previous generation instance type: ' + resource.get('Properties').get(top_level_property_type).get(property_type)))
return matches
23 changes: 23 additions & 0 deletions test/fixtures/templates/bad/previous_generation_instances.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Resources:
Domain:
Type: AWS::Elasticsearch::Domain
Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: m1.small
ImageId: ami-abc
DBInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: db.t1.micro
CacheCluster:
Type: AWS::ElastiCache::CacheCluster
Properties:
CacheNodeType: cache.r3.large
Engine: memcached
NumCacheNodes: 1
Domain2:
Type: AWS::Elasticsearch::Domain
Properties:
ElasticsearchClusterConfig:
InstanceType: m3.medium.elasticsearch
4 changes: 2 additions & 2 deletions test/fixtures/templates/good/generic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Resources:
Type: "AWS::EC2::Instance"
Properties:
ImageId: "ami-2f726546"
InstanceType: t1.micro
InstanceType: t3.micro
KeyName: testkey
IamInstanceProfile: !Ref RootInstanceProfile
BlockDeviceMappings:
Expand All @@ -93,7 +93,7 @@ Resources:
Type: "AWS::EC2::Instance"
Properties:
ImageId: "ami-2f726546"
InstanceType: t1.micro
InstanceType: t3.micro
KeyName: testkey
BlockDeviceMappings:
- DeviceName: /dev/sdm
Expand Down
2 changes: 1 addition & 1 deletion test/unit/module/test_rules_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def test_fail_run(self):
filename = 'test/fixtures/templates/bad/generic.yaml'
template = cfnlint.decode.cfn_yaml.load(filename)
cfn = Template(filename, template, ['us-east-1'])
expected_err_count = 30
expected_err_count = 32
matches = []
matches.extend(self.rules.run(filename, cfn))
assert len(matches) == expected_err_count, 'Expected {} failures, got {}'.format(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
from cfnlint.rules.resources.PreviousGenerationInstanceType import PreviousGenerationInstanceType # pylint: disable=E0401
from .. import BaseRuleTestCase


class TestPreviousGenerationInstanceType(BaseRuleTestCase):
def setUp(self):
super(TestPreviousGenerationInstanceType, self).setUp()
self.collection.register(PreviousGenerationInstanceType())

def test_file_positive(self):
self.helper_file_positive()

def test_file_negative(self):
self.helper_file_negative('test/fixtures/templates/bad/previous_generation_instances.yaml', 4)