From b9c7ec383c8a1ad9d30b3141f16f2edcfd1566a6 Mon Sep 17 00:00:00 2001 From: kbalk <7536198+kbalk@users.noreply.github.com> Date: Sat, 21 Aug 2021 00:45:52 -0400 Subject: [PATCH] Add AWS ConfigService put_config_rule, delete_config_rule, describe_config_rule (#4171) Co-authored-by: Karri Balk --- IMPLEMENTATION_COVERAGE.md | 6 +- MANIFEST.in | 1 + moto/config/exceptions.py | 64 +- moto/config/models.py | 676 +++++- moto/config/resources/aws_managed_rules.json | 2141 ++++++++++++++++++ moto/config/responses.py | 20 +- scripts/pull_down_aws_managed_rules.py | 141 ++ tests/test_config/test_config_rules.py | 728 ++++++ tests/test_config/test_config_tags.py | 46 +- 9 files changed, 3748 insertions(+), 75 deletions(-) create mode 100644 moto/config/resources/aws_managed_rules.json create mode 100755 scripts/pull_down_aws_managed_rules.py create mode 100644 tests/test_config/test_config_rules.py diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index e693c0e6b..3caaf7f73 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -2450,7 +2450,7 @@ - [X] batch_get_aggregate_resource_config - [X] batch_get_resource_config - [X] delete_aggregation_authorization -- [ ] delete_config_rule +- [X] delete_config_rule - [X] delete_configuration_aggregator - [X] delete_configuration_recorder - [ ] delete_conformance_pack @@ -2471,7 +2471,7 @@ - [ ] describe_compliance_by_config_rule - [ ] describe_compliance_by_resource - [ ] describe_config_rule_evaluation_status -- [ ] describe_config_rules +- [X] describe_config_rules - [ ] describe_configuration_aggregator_sources_status - [X] describe_configuration_aggregators - [X] describe_configuration_recorder_status @@ -2511,7 +2511,7 @@ - [ ] list_stored_queries - [X] list_tags_for_resource - [X] put_aggregation_authorization -- [ ] put_config_rule +- [X] put_config_rule - [X] put_configuration_aggregator - [X] put_configuration_recorder - [ ] put_conformance_pack diff --git a/MANIFEST.in b/MANIFEST.in index 9dc2a1590..567be3ce6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ include README.md LICENSE AUTHORS.md include requirements.txt requirements-dev.txt tox.ini +include moto/config/resources/aws_managed_rules.json include moto/ec2/resources/instance_types.json include moto/ec2/resources/instance_type_offerings/*/*.json include moto/ec2/resources/amis.json diff --git a/moto/config/exceptions.py b/moto/config/exceptions.py index d30881221..18c1f8b76 100644 --- a/moto/config/exceptions.py +++ b/moto/config/exceptions.py @@ -1,16 +1,14 @@ -from __future__ import unicode_literals from moto.core.exceptions import JsonRESTError class NameTooLongException(JsonRESTError): code = 400 - def __init__(self, name, location): + def __init__(self, name, location, max_limit=256): message = ( - "1 validation error detected: Value '{name}' at '{location}' failed to satisfy" - " constraint: Member must have length less than or equal to 256".format( - name=name, location=location - ) + f"1 validation error detected: Value '{name}' at '{location}' " + f"failed to satisfy constraint: Member must have length less " + f"than or equal to {max_limit}" ) super().__init__("ValidationException", message) @@ -234,11 +232,13 @@ class TagKeyTooBig(JsonRESTError): class TagValueTooBig(JsonRESTError): code = 400 - def __init__(self, tag): + def __init__(self, tag, param="tags.X.member.value"): super().__init__( "ValidationException", - "1 validation error detected: Value '{}' at 'tags.X.member.value' failed to satisfy " - "constraint: Member must have length less than or equal to 256".format(tag), + "1 validation error detected: Value '{}' at '{}' failed to satisfy " + "constraint: Member must have length less than or equal to 256".format( + tag, param + ), ) @@ -340,9 +340,6 @@ class TooManyResourceKeys(JsonRESTError): bad_list=bad_list ) ) - # For PY2: - message = str(message) - super().__init__("ValidationException", message) @@ -366,3 +363,46 @@ class NoSuchOrganizationConformancePackException(JsonRESTError): def __init__(self, message): super().__init__("NoSuchOrganizationConformancePackException", message) + + +class MaxNumberOfConfigRulesExceededException(JsonRESTError): + code = 400 + + def __init__(self, name, max_limit): + message = ( + f"Failed to put config rule '{name}' because the maximum number " + f"of config rules: {max_limit} is reached." + ) + super().__init__("MaxNumberOfConfigRulesExceededException", message) + + +class ResourceInUseException(JsonRESTError): + code = 400 + + def __init__(self, message): + super().__init__("ResourceInUseException", message) + + +class InsufficientPermissionsException(JsonRESTError): + code = 400 + + def __init__(self, message): + super().__init__("InsufficientPermissionsException", message) + + +class NoSuchConfigRuleException(JsonRESTError): + code = 400 + + def __init__(self, rule_name): + message = ( + f"The ConfigRule '{rule_name}' provided in the request is " + f"invalid. Please check the configRule name" + ) + super().__init__("NoSuchConfigRuleException", message) + + +class MissingRequiredConfigRuleParameterException(JsonRESTError): + code = 400 + + def __init__(self, message): + super().__init__("ParamValidationError", message) diff --git a/moto/config/models.py b/moto/config/models.py index 04499d8a3..571dcf14f 100644 --- a/moto/config/models.py +++ b/moto/config/models.py @@ -1,3 +1,5 @@ +"""Implementation of the AWS Config Service APIs.""" +import json import re import time import random @@ -42,14 +44,20 @@ from moto.config.exceptions import ( InvalidResultTokenException, ValidationException, NoSuchOrganizationConformancePackException, + MaxNumberOfConfigRulesExceededException, + InsufficientPermissionsException, + NoSuchConfigRuleException, + ResourceInUseException, + MissingRequiredConfigRuleParameterException, ) from moto.core import BaseBackend, BaseModel -from moto.s3.config import s3_account_public_access_block_query, s3_config_query from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID from moto.core.responses import AWSServiceSpec - from moto.iam.config import role_config_query, policy_config_query +from moto.s3.config import s3_account_public_access_block_query, s3_config_query +from moto.utilities.utils import load_resource + POP_STRINGS = [ "capitalizeStart", @@ -60,6 +68,7 @@ POP_STRINGS = [ "CapitalizeARN", ] DEFAULT_PAGE_SIZE = 100 +CONFIG_RULE_PAGE_SIZE = 25 # Map the Config resource type to a backend: RESOURCE_MAP = { @@ -69,8 +78,13 @@ RESOURCE_MAP = { "AWS::IAM::Policy": policy_config_query, } +CAMEL_TO_SNAKE_REGEX = re.compile(r"(? 128: + raise TagKeyTooBig(tag_key, "ConfigRule.Scope.TagKey") + if tag_value and len(tag_value) > 256: + raise TagValueTooBig(tag_value, "ConfigRule.Scope.TagValue") + self.tags = {tag_key: tag_value} + + # Can't use more than one combo to specify scope - either tags, + # resource types, or resource id and resource type. + if self.tags and (compliance_resource_types or compliance_resource_id): + raise InvalidParameterValueException( + "Scope cannot be applied to both resource and tag" + ) + + if compliance_resource_id and len(compliance_resource_types) != 1: + raise InvalidParameterValueException( + "A single resourceType should be provided when resourceId " + "is provided in scope" + ) + self.compliance_resource_types = compliance_resource_types + self.compliance_resource_id = compliance_resource_id + + +class SourceDetail(ConfigEmptyDictable): + + """Source and type of event triggering AWS Config resource evaluation. + + Applies only to customer rules. + """ + + MESSAGE_TYPES = { + "ConfigurationItemChangeNotification", + "ConfigurationSnapshotDeliveryCompleted", + "OversizedConfigurationItemChangeNotification", + "ScheduledNotification", + } + DEFAULT_FREQUENCY = "TwentyFour_Hours" + FREQUENCY_TYPES = { + "One_Hour", + "Six_Hours", + "Three_Hours", + "Twelve_Hours", + "TwentyFour_Hours", + } + EVENT_SOURCES = ["aws.config"] + + def __init__( + self, event_source=None, message_type=None, maximum_execution_frequency=None + ): + super().__init__(capitalize_start=True, capitalize_arn=False) + + # If the event_source or message_type fields are not provided, + # boto3 reports: "SourceDetails should be null/empty if the owner is + # AWS. SourceDetails should be provided if the owner is CUSTOM_LAMBDA." + # A more specific message will be used here instead. + if not event_source: + raise MissingRequiredConfigRuleParameterException( + "Missing required parameter in ConfigRule.SourceDetails: " + "'EventSource'" + ) + if event_source not in SourceDetail.EVENT_SOURCES: + raise ValidationException( + f"Value '{event_source}' at " + f"'configRule.source.sourceDetails.eventSource' failed " + f"to satisfy constraint: Member must satisfy enum value set: {{" + + ", ".join((SourceDetail.EVENT_SOURCES)) + + "}" + ) + + if not message_type: + # boto3 doesn't have a specific error if this field is missing. + raise MissingRequiredConfigRuleParameterException( + "Missing required parameter in ConfigRule.SourceDetails: 'MessageType'" + ) + if message_type not in SourceDetail.MESSAGE_TYPES: + raise ValidationException( + f"Value '{message_type}' at " + f"'configRule.source.sourceDetails.message_type' failed " + f"to satisfy constraint: Member must satisfy enum value set: {{" + + ", ".join(sorted(SourceDetail.MESSAGE_TYPES)) + + "}" + ) + + if maximum_execution_frequency: + if maximum_execution_frequency not in SourceDetail.FREQUENCY_TYPES: + raise ValidationException( + f"Value '{maximum_execution_frequency}' at " + f"'configRule.source.sourceDetails.maximumExecutionFrequency' " + f"failed to satisfy constraint: " + f"Member must satisfy enum value set: {{" + + ", ".join(sorted(SourceDetail.FREQUENCY_TYPES)) + + "}" + ) + if message_type in [ + "ConfigurationItemChangeNotification", + "OversizedConfigurationItemChangeNotification", + ]: + raise InvalidParameterValueException( + "A maximum execution frequency is not allowed if " + "MessageType is ConfigurationItemChangeNotification or " + "OversizedConfigurationItemChangeNotification" + ) + else: + # If no value is specified, use a default value for + # maximum_execution_frequency for message types representing a + # periodic trigger. + if message_type in [ + "ScheduledNotification", + "ConfigurationSnapshotDeliveryCompleted", + ]: + maximum_execution_frequency = SourceDetail.DEFAULT_FREQUENCY + + self.event_source = event_source + self.message_type = message_type + self.maximum_execution_frequency = maximum_execution_frequency + + +class Source(ConfigEmptyDictable): + + """Defines rule owner, id and notification for triggering evaluation.""" + + OWNERS = {"AWS", "CUSTOM_LAMBDA"} + + def __init__(self, region, owner, source_identifier, source_details=None): + super().__init__(capitalize_start=True, capitalize_arn=False) + if owner not in Source.OWNERS: + raise ValidationException( + f"Value '{owner}' at 'configRule.source.owner' failed to " + f"satisfy constraint: Member must satisfy enum value set: {{" + + ", ".join(sorted(Source.OWNERS)) + + "}" + ) + + if owner == "AWS": + # Can the Source ID be found in the dict of managed rule IDs? + if source_identifier not in MANAGED_RULES_CONSTRAINTS: + raise InvalidParameterValueException( + f"The sourceIdentifier {source_identifier} is invalid. " + f"Please refer to the documentation for a list of valid " + f"sourceIdentifiers that can be used when AWS is the Owner" + ) + if source_details: + raise InvalidParameterValueException( + "SourceDetails should be null/empty if the owner is AWS. " + "SourceDetails should be provided if the owner is " + "CUSTOM_LAMBDA" + ) + + self.owner = owner + self.source_identifier = source_identifier + self.source_details = None + return + + # Otherwise, owner == "CUSTOM_LAMBDA" + if not source_details: + raise InvalidParameterValueException( + "SourceDetails should be null/empty if the owner is AWS. " + "SourceDetails should be provided if the owner is CUSTOM_LAMBDA" + ) + + # Import is slow and as it's not needed for all config service + # operations, only load it if needed. + from moto.awslambda import lambda_backends + + lambda_func = lambda_backends[region].get_function(source_identifier) + if not lambda_func: + raise InsufficientPermissionsException( + f"The AWS Lambda function {source_identifier} cannot be " + f"invoked. Check the specified function ARN, and check the " + f"function's permissions" + ) + + details = [] + for detail in source_details: + detail_dict = convert_to_class_args(detail) + details.append(SourceDetail(**detail_dict)) + + self.source_details = details + self.owner = owner + self.source_identifier = source_identifier + + def to_dict(self): + """Format the SourceDetails properly.""" + result = super().to_dict() + if self.source_details: + result["SourceDetails"] = [x.to_dict() for x in self.source_details] + return result + + +class ConfigRule(ConfigEmptyDictable): + + """AWS Config Rule to evaluate compliance of resources to configuration. + + Can be a managed or custom config rule. Contains the instantiations of + the Source and SourceDetail classes, and optionally the Scope class. + """ + + MAX_RULES = 150 + RULE_STATES = {"ACTIVE", "DELETING", "DELETING_RESULTS", "EVALUATING"} + + def __init__(self, region, config_rule, tags): + super().__init__(capitalize_start=True, capitalize_arn=False) + self.config_rule_name = config_rule.get("ConfigRuleName") + if config_rule.get("ConfigRuleArn") or config_rule.get("ConfigRuleId"): + raise InvalidParameterValueException( + "ConfigRule Arn and Id can not be specified when creating a " + "new ConfigRule. ConfigRule Arn and Id are generated by the " + "service. Please try the request again without specifying " + "ConfigRule Arn or Id" + ) + + self.maximum_execution_frequency = None # keeps pylint happy + self.modify_fields(region, config_rule, tags) + self.config_rule_id = f"config-rule-{random_string():.6}" + self.config_rule_arn = f"arn:aws:config:{region}:{DEFAULT_ACCOUNT_ID}:config-rule/{self.config_rule_id}" + + def modify_fields(self, region, config_rule, tags): + """Initialize or update ConfigRule fields.""" + self.config_rule_state = config_rule.get("ConfigRuleState", "ACTIVE") + if self.config_rule_state not in ConfigRule.RULE_STATES: + raise ValidationException( + f"Value '{self.config_rule_state}' at " + f"'configRule.configRuleState' failed to satisfy constraint: " + f"Member must satisfy enum value set: {{" + + ", ".join(sorted(ConfigRule.RULE_STATES)) + + "}" + ) + if self.config_rule_state != "ACTIVE": + raise InvalidParameterValueException( + f"The ConfigRuleState {self.config_rule_state} is invalid. " + f"Only the following values are permitted: ACTIVE" + ) + + self.description = config_rule.get("Description") + + self.scope = None + if "Scope" in config_rule: + scope_dict = convert_to_class_args(config_rule["Scope"]) + self.scope = Scope(**scope_dict) + + source_dict = convert_to_class_args(config_rule["Source"]) + self.source = Source(region, **source_dict) + + self.input_parameters = config_rule.get("InputParameters") + self.input_parameters_dict = {} + if self.input_parameters: + try: + # A dictionary will be more useful when these parameters + # are actually needed. + self.input_parameters_dict = json.loads(self.input_parameters) + except ValueError: + raise InvalidParameterValueException( # pylint: disable=raise-missing-from + f"Invalid json {self.input_parameters} passed in the " + f"InputParameters field" + ) + + self.maximum_execution_frequency = config_rule.get("MaximumExecutionFrequency") + if self.maximum_execution_frequency: + if self.maximum_execution_frequency not in SourceDetail.FREQUENCY_TYPES: + raise ValidationException( + f"Value '{self.maximum_execution_frequency}' at " + f"'configRule.maximumExecutionFrequency' failed to " + f"satisfy constraint: Member must satisfy enum value set: {{" + + ", ".join(sorted(SourceDetail.FREQUENCY_TYPES)) + + "}" + ) + + # For an AWS managed rule, validate the parameters and trigger type. + # Verify the MaximumExecutionFrequency makes sense as well. + if self.source.owner == "AWS": + self.validate_managed_rule() + else: + # Per the AWS documentation for a custom rule, ConfigRule's + # MaximumExecutionFrequency can only be set if the message type + # is ConfigSnapshotDeliveryProperties. However, if + # ConfigSnapshotDeliveryProperties is used, the AWS console + # leaves the Trigger Type blank and doesn't show the frequency. + # If you edit the rule, it doesn't show the frequency either. + # + # If you provide two custom rules, one with a message type of + # ConfigurationSnapshotDeliveryCompleted, one with + # ScheduleNotification and specify a MaximumExecutionFrequency + # for each, the first one is shown on the AWS console and the + # second frequency is shown on the edit page. + # + # If you provide a custom rule for + # OversizedConfigurationItemChangeNotification (not a periodic + # trigger) with a MaximumExecutionFrequency for ConfigRule itself, + # boto3 doesn't complain and describe_config_rule() shows the + # frequency, but the AWS console and the edit page do not. + # + # So I'm not sure how to validate this situation or when to + # set this value to a default value. + pass + + self.created_by = config_rule.get("CreatedBy") + if self.created_by: + raise InvalidParameterValueException( + "AWS Config populates the CreatedBy field for " + "ServiceLinkedConfigRule. Try again without populating the " + "CreatedBy field" + ) + + self.last_updated_time = datetime2int(datetime.utcnow()) + self.tags = tags + + def validate_managed_rule(self): + """Validate parameters specific to managed rules.""" + rule_info = MANAGED_RULES_CONSTRAINTS[self.source.source_identifier] + param_names = self.input_parameters_dict.keys() + + # Verify input parameter names are actual parameters for the rule ID. + if param_names: + allowed_names = {x["Name"] for x in rule_info["Parameters"]} + if allowed_names.difference(set(param_names)): + raise InvalidParameterValueException( + "Unknown parameters provided in the inputParameters: " + + self.input_parameters.replace('"', '\\"') + ) + + # Verify all the required parameters are specified. + required_names = { + x["Name"] for x in rule_info["Parameters"] if not x["Optional"] + } + diffs = required_names.difference(set(param_names)) + if diffs: + raise InvalidParameterValueException( + "The required parameter [" + + ", ".join(sorted(diffs)) + + "] is not present in the inputParameters" + ) + + # boto3 doesn't appear to be checking for valid types in the + # InputParameters. It did give an error if a unquoted number was + # used: "Blank spaces are not acceptable for input parameter: + # MinimumPasswordLength. InputParameters': + # '{"RequireNumbers":"true","MinimumPasswordLength":10}' + # but I'm not going to attempt to detect that error. I could + # check for ints, floats, strings and stringmaps, but boto3 doesn't + # check. + + # WARNING: The AWS documentation indicates MaximumExecutionFrequency + # can be specified for managed rules triggered at a periodic frequency. + # However, boto3 allows a MaximumExecutionFrequency to be specified + # for a AWS managed rule regardless of the frequency type. Also of + # interest: triggers of "Configuration Changes and Periodic", + # i.e., both trigger types. But again, the trigger type is ignored. + # if rule_info["Trigger type"] == "Configuration changes": + # if self.maximum_execution_frequency: + # raise InvalidParameterValueException( + # "A maximum execution frequency is not allowed for " + # "rules triggered by configuration changes" + # ) + # + # WARNING: boto3's describe_config_rule is not showing the + # MaximumExecutionFrequency value as being updated, but the AWS + # console shows the default value on the console. The default value + # is used even if the rule is non-periodic + # if "Periodic" in rule_info["Trigger type"]: + # if not self.maximum_execution_frequency: + # self.maximum_execution_frequency = SourceDetail.DEFAULT_FREQUENCY + # if not self.maximum_execution_frequency: + # self.maximum_execution_frequency = SourceDetail.DEFAULT_FREQUENCY + + # Verify the rule is allowed for this region -- not yet implemented. + + class ConfigBackend(BaseBackend): def __init__(self): self.recorders = {} @@ -418,6 +851,7 @@ class ConfigBackend(BaseBackend): self.config_aggregators = {} self.aggregation_authorizations = {} self.organization_conformance_packs = {} + self.config_rules = {} self.config_schema = None def _validate_resource_types(self, resource_list): @@ -429,11 +863,8 @@ class ConfigBackend(BaseBackend): # Verify that each entry exists in the supported list: bad_list = [] for resource in resource_list: - # For PY2: - r_str = str(resource) - - if r_str not in self.config_schema.shapes["ResourceType"]["enum"]: - bad_list.append(r_str) + if resource not in self.config_schema.shapes["ResourceType"]["enum"]: + bad_list.append(resource) if bad_list: raise InvalidResourceTypeException( @@ -470,14 +901,16 @@ class ConfigBackend(BaseBackend): # Tag validation: tags = validate_tags(config_aggregator.get("Tags", [])) - # Exception if both AccountAggregationSources and OrganizationAggregationSource are supplied: + # Exception if both AccountAggregationSources and + # OrganizationAggregationSource are supplied: if config_aggregator.get("AccountAggregationSources") and config_aggregator.get( "OrganizationAggregationSource" ): raise InvalidParameterValueException( - "The configuration aggregator cannot be created because your request contains both the" - " AccountAggregationSource and the OrganizationAggregationSource. Include only " - "one aggregation source and try again." + "The configuration aggregator cannot be created because your " + "request contains both the AccountAggregationSource and the " + "OrganizationAggregationSource. Include only one aggregation " + "source and try again." ) # If neither are supplied: @@ -485,8 +918,9 @@ class ConfigBackend(BaseBackend): "AccountAggregationSources" ) and not config_aggregator.get("OrganizationAggregationSource"): raise InvalidParameterValueException( - "The configuration aggregator cannot be created because your request is missing either " - "the AccountAggregationSource or the OrganizationAggregationSource. Include the " + "The configuration aggregator cannot be created because your " + "request is missing either the AccountAggregationSource or " + "the OrganizationAggregationSource. Include the " "appropriate aggregation source and try again." ) @@ -760,16 +1194,19 @@ class ConfigBackend(BaseBackend): delivery_channel.get("name"), "deliveryChannel.name" ) - # We are going to assume that the bucket exists -- but will verify if the bucket provided is blank: + # We are going to assume that the bucket exists -- but will verify if + # the bucket provided is blank: if not delivery_channel.get("s3BucketName"): raise NoSuchBucketException() - # We are going to assume that the bucket has the correct policy attached to it. We are only going to verify + # We are going to assume that the bucket has the correct policy + # attached to it. We are only going to verify # if the prefix provided is not an empty string: if delivery_channel.get("s3KeyPrefix", None) == "": raise InvalidS3KeyPrefixException() - # Ditto for SNS -- Only going to assume that the ARN provided is not an empty string: + # Ditto for SNS -- Only going to assume that the ARN provided is not + # an empty string: if delivery_channel.get("snsTopicARN", None) == "": raise InvalidSNSTopicARNException() @@ -863,7 +1300,9 @@ class ConfigBackend(BaseBackend): limit, next_token, ): - """This will query against the mocked AWS Config (non-aggregated) listing function that must exist for the resource backend. + """Queries against AWS Config (non-aggregated) listing function. + + The listing function must exist for the resource backend. :param resource_type: :param backend_region: @@ -887,8 +1326,9 @@ class ConfigBackend(BaseBackend): if resource_ids and len(resource_ids) > 20: raise TooManyResourceIds() - # If the resource type exists and the backend region is implemented in moto, then - # call upon the resource type's Config Query class to retrieve the list of resources that match the criteria: + # If resource type exists and the backend region is implemented in + # moto, then call upon the resource type's Config Query class to + # retrieve the list of resources that match the criteria: if RESOURCE_MAP.get(resource_type, {}): # Is this a global resource type? -- if so, re-write the region to 'global': backend_query_region = ( @@ -897,7 +1337,8 @@ class ConfigBackend(BaseBackend): if RESOURCE_MAP[resource_type].backends.get("global"): backend_region = "global" - # For non-aggregated queries, the we only care about the backend_region. Need to verify that moto has implemented + # For non-aggregated queries, the we only care about the + # backend_region. Need to verify that moto has implemented # the region for the given backend: if RESOURCE_MAP[resource_type].backends.get(backend_region): # Fetch the resources for the backend's region: @@ -931,10 +1372,12 @@ class ConfigBackend(BaseBackend): def list_aggregate_discovered_resources( self, aggregator_name, resource_type, filters, limit, next_token ): - """This will query against the mocked AWS Config listing function that must exist for the resource backend. + """Queries AWS Config listing function that must exist for resource backend. - As far a moto goes -- the only real difference between this function and the `list_discovered_resources` function is that - this will require a Config Aggregator be set up a priori and can search based on resource regions. + As far a moto goes -- the only real difference between this function + and the `list_discovered_resources` function is that this will require + a Config Aggregator be set up a priori and can search based on resource + regions. :param aggregator_name: :param resource_type: @@ -954,8 +1397,9 @@ class ConfigBackend(BaseBackend): if limit > DEFAULT_PAGE_SIZE: raise InvalidLimitException(limit) - # If the resource type exists and the backend region is implemented in moto, then - # call upon the resource type's Config Query class to retrieve the list of resources that match the criteria: + # If the resource type exists and the backend region is implemented + # in moto, then call upon the resource type's Config Query class to + # retrieve the list of resources that match the criteria: if RESOURCE_MAP.get(resource_type, {}): # We only care about a filter's Region, Resource Name, and Resource ID: resource_region = filters.get("Region") @@ -994,11 +1438,16 @@ class ConfigBackend(BaseBackend): return result def get_resource_config_history(self, resource_type, resource_id, backend_region): - """Returns the configuration of an item in the AWS Config format of the resource for the current regional backend. + """Returns configuration of resource for the current regional backend. - NOTE: This is --NOT-- returning history as it is not supported in moto at this time. (PR's welcome!) - As such, the later_time, earlier_time, limit, and next_token are ignored as this will only - return 1 item. (If no items, it raises an exception) + Item returned in AWS Config format. + + NOTE: This is --NOT-- returning history as it is not supported in + moto at this time. (PR's welcome!) + + As such, the later_time, earlier_time, limit, and next_token are + ignored as this will only return 1 item. (If no items, it raises an + exception). """ # If the type isn't implemented then we won't find the item: if resource_type not in RESOURCE_MAP: @@ -1027,7 +1476,9 @@ class ConfigBackend(BaseBackend): return {"configurationItems": [item]} def batch_get_resource_config(self, resource_keys, backend_region): - """Returns the configuration of an item in the AWS Config format of the resource for the current regional backend. + """Returns configuration of resource for the current regional backend. + + Item is returned in AWS Config format. :param resource_keys: :param backend_region: @@ -1078,10 +1529,14 @@ class ConfigBackend(BaseBackend): def batch_get_aggregate_resource_config( self, aggregator_name, resource_identifiers ): - """Returns the configuration of an item in the AWS Config format of the resource for the current regional backend. + """Returns configuration of resource for current regional backend. - As far a moto goes -- the only real difference between this function and the `batch_get_resource_config` function is that - this will require a Config Aggregator be set up a priori and can search based on resource regions. + Item is returned in AWS Config format. + + As far a moto goes -- the only real difference between this function + and the `batch_get_resource_config` function is that this will require + a Config Aggregator be set up a priori and can search based on resource + regions. Note: moto will IGNORE the resource account ID in the search query. """ @@ -1140,7 +1595,8 @@ class ConfigBackend(BaseBackend): if not result_token: raise InvalidResultTokenException() - # Moto only supports PutEvaluations with test mode currently (missing rule and token support) + # Moto only supports PutEvaluations with test mode currently + # (missing rule and token support). if not test_mode: raise NotImplementedError( "PutEvaluations without TestMode is not yet implemented" @@ -1206,8 +1662,9 @@ class ConfigBackend(BaseBackend): if not pack: raise NoSuchOrganizationConformancePackException( - "One or more organization conformance packs with specified names are not present. " - "Ensure your names are correct and try your request again later." + "One or more organization conformance packs with " + "specified names are not present. Ensure your names are " + "correct and try your request again later." ) packs.append(pack.to_dict()) @@ -1224,8 +1681,9 @@ class ConfigBackend(BaseBackend): if not pack: raise NoSuchOrganizationConformancePackException( - "One or more organization conformance packs with specified names are not present. " - "Ensure your names are correct and try your request again later." + "One or more organization conformance packs with " + "specified names are not present. Ensure your names " + "are correct and try your request again later." ) packs.append(pack) @@ -1271,9 +1729,8 @@ class ConfigBackend(BaseBackend): if not pack: raise NoSuchOrganizationConformancePackException( - "Could not find an OrganizationConformancePack for given request with resourceName {}".format( - name - ) + "Could not find an OrganizationConformancePack for given " + "request with resourceName {}".format(name) ) self.organization_conformance_packs.pop(name) @@ -1281,8 +1738,7 @@ class ConfigBackend(BaseBackend): def _match_arn(self, resource_arn): """Return config instance that has a matching ARN.""" # The allowed resources are ConfigRule, ConfigurationAggregator, - # and AggregatorAuthorization. ConfigRule isn't currently - # supported. + # and AggregatorAuthorization. allowed_resources = [ { "configs": self.config_aggregators, @@ -1292,6 +1748,7 @@ class ConfigBackend(BaseBackend): "configs": self.aggregation_authorizations, "arn_attribute": "aggregation_authorization_arn", }, + {"configs": self.config_rules, "arn_attribute": "config_rule_arn"}, ] # Find matching config for given resource_arn among all the @@ -1333,7 +1790,9 @@ class ConfigBackend(BaseBackend): for tag_key in tag_keys: matched_config.tags.pop(tag_key, None) - def list_tags_for_resource(self, resource_arn, limit, next_token): + def list_tags_for_resource( + self, resource_arn, limit, next_token + ): # pylint: disable=unused-argument """Return list of tags for AWS Config resource.""" # The limit argument is essentially ignored as a config instance # can only have 50 tags, but we'll check the argument anyway. @@ -1345,9 +1804,118 @@ class ConfigBackend(BaseBackend): matched_config = self._match_arn(resource_arn) return { - "Tags": [{"Key": k, "Value": v} for k, v in matched_config.tags.items()] + "Tags": [ + {"Key": k, "Value": v} for k, v in sorted(matched_config.tags.items()) + ] } + def put_config_rule(self, region, config_rule, tags=None): + """Add/Update config rule for evaluating resource compliance. + + TBD - Only the "accounting" of config rules are handled at the + moment. No events are created or triggered. There is no + interaction with the config recorder. + """ + # If there is no rule_name, use the ARN or ID to get the + # rule_name. + rule_name = config_rule.get("ConfigRuleName") + if rule_name: + if len(rule_name) > 128: + raise NameTooLongException(rule_name, "configRule.configRuleName", 128) + else: + # Can we find the rule using the ARN or ID? + rule_arn = config_rule.get("ConfigRuleArn") + rule_id = config_rule.get("ConfigRuleId") + if not rule_arn and not rule_id: + raise InvalidParameterValueException( + "One or more identifiers needs to be provided. Provide " + "Name or Id or Arn" + ) + for config_rule_obj in self.config_rules.values(): + if rule_id and config_rule_obj.config_rule_id == rule_id: + rule_name = config_rule_obj.config_rule_name + break + if rule_arn and config_rule_obj.config_rule_arn == rule_arn: + rule_name = config_rule_obj.config_rule_name + break + else: + raise InvalidParameterValueException( + "One or more identifiers needs to be provided. Provide " + "Name or Id or Arn" + ) + + tags = validate_tags(tags or []) + + # With the rule_name, determine whether it's for an existing rule + # or whether a new rule should be created. + rule = self.config_rules.get(rule_name) + if rule: + # Rule exists. Make sure it isn't in use for another activity. + rule_state = rule.config_rule_state + if rule_state != "ACTIVE": + activity = "deleted" if rule_state.startswith("DELET") else "evaluated" + raise ResourceInUseException( + f"The rule {rule_name} is currently being {activity}. " + f"Please retry after some time" + ) + + # Update the current rule. + rule.modify_fields(region, config_rule, tags) + else: + # Create a new ConfigRule if the limit hasn't been reached. + if len(self.config_rules) == ConfigRule.MAX_RULES: + raise MaxNumberOfConfigRulesExceededException( + rule_name, ConfigRule.MAX_RULES + ) + rule = ConfigRule(region, config_rule, tags) + self.config_rules[rule_name] = rule + return "" + + def describe_config_rules(self, config_rule_names, next_token): + """Return details for the given ConfigRule names or for all rules.""" + result = {"ConfigRules": []} + if not self.config_rules: + return result + + rule_list = [] + if config_rule_names: + for name in config_rule_names: + if not self.config_rules.get(name): + raise NoSuchConfigRuleException(name) + rule_list.append(name) + else: + rule_list = list(self.config_rules.keys()) + + # The rules are not sorted alphanumerically. + sorted_rules = sorted(rule_list) + start = 0 + if next_token: + if not self.config_rules.get(next_token): + raise InvalidNextTokenException() + start = sorted_rules.index(next_token) + + rule_list = sorted_rules[start : start + CONFIG_RULE_PAGE_SIZE] + result["ConfigRules"] = [self.config_rules[x].to_dict() for x in rule_list] + + if len(sorted_rules) > (start + CONFIG_RULE_PAGE_SIZE): + result["NextToken"] = sorted_rules[start + CONFIG_RULE_PAGE_SIZE] + return result + + def delete_config_rule(self, rule_name): + """Delete config rule used for evaluating resource compliance.""" + rule = self.config_rules.get(rule_name) + if not rule: + raise NoSuchConfigRuleException(rule_name) + + # The following logic is not applicable for moto as far as I can tell. + # if rule.config_rule_state == "DELETING": + # raise ResourceInUseException( + # f"The rule {rule_name} is currently being deleted. Please " + # f"retry after some time" + # ) + rule.config_rule_state = "DELETING" + self.config_rules.pop(rule_name) + config_backends = {} for available_region in Session().get_available_regions("config"): diff --git a/moto/config/resources/aws_managed_rules.json b/moto/config/resources/aws_managed_rules.json new file mode 100644 index 000000000..5d5a36f60 --- /dev/null +++ b/moto/config/resources/aws_managed_rules.json @@ -0,0 +1,2141 @@ +{ + "ManagedRules": { + "ACCESS_KEYS_ROTATED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "90", + "Name": "maxAccessKeyAge", + "Optional": false, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "ACCOUNT_PART_OF_ORGANIZATIONS": { + "AWS Region": "All supported AWS regions except China (Beijing), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "MasterAccountId", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "ACM_CERTIFICATE_EXPIRATION_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), Asia Pacific (Osaka), Europe (Milan) Region", + "Parameters": [ + { + "Default": "14", + "Name": "daysToExpiration", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "ALB_HTTP_DROP_INVALID_HEADER_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "ALB_HTTP_TO_HTTPS_REDIRECTION_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "ALB_WAF_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "wafWebAclIds", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "API_GW_ASSOCIATED_WITH_WAF": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "WebAclArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "API_GW_CACHE_ENABLED_AND_ENCRYPTED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "API_GW_ENDPOINT_TYPE_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "endpointConfigurationTypes", + "Optional": false, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "API_GW_EXECUTION_LOGGING_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Default": "ERROR,INFO", + "Name": "loggingLevel", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "API_GW_SSL_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "CertificateIDs", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "API_GW_XRAY_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "APPROVED_AMIS_BY_ID": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "amiIds", + "Optional": false, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "APPROVED_AMIS_BY_TAG": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "tag-key", + "Name": "amisByTagKeyAndValue", + "Optional": false, + "Type": "StringMap" + } + ], + "Trigger type": "Configuration changes" + }, + "AURORA_MYSQL_BACKTRACKING_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Europe (Milan), Europe (Stockholm), Middle East (Bahrain), Africa (Cape Town), South America (Sao Paulo) Region", + "Parameters": [ + { + "Name": "BacktrackWindowInHours", + "Optional": true, + "Type": "double" + } + ], + "Trigger type": "Configuration changes" + }, + "AUTOSCALING_GROUP_ELB_HEALTHCHECK_REQUIRED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "AUTOSCALING_LAUNCH_CONFIG_PUBLIC_IP_DISABLED": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "BEANSTALK_ENHANCED_HEALTH_REPORTING_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CLOUDFORMATION_STACK_DRIFT_DETECTION_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Europe (Milan), Europe (Paris), Europe (Stockholm), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "cloudformationRoleArn", + "Optional": false, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "CLOUDFORMATION_STACK_NOTIFICATION_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Europe (Milan), Europe (Paris), Europe (Stockholm), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "snsTopic1", + "Optional": true, + "Type": "String" + }, + { + "Name": "snsTopic2", + "Optional": true, + "Type": "String" + }, + { + "Name": "snsTopic3", + "Optional": true, + "Type": "String" + }, + { + "Name": "snsTopic4", + "Optional": true, + "Type": "String" + }, + { + "Name": "snsTopic5", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_ACCESSLOGS_ENABLED": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [ + { + "Name": "S3BucketName", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_ASSOCIATED_WITH_WAF": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [ + { + "Name": "wafWebAclIds", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_CUSTOM_SSL_CERTIFICATE": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_DEFAULT_ROOT_OBJECT_CONFIGURED": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_ORIGIN_ACCESS_IDENTITY_ENABLED": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_ORIGIN_FAILOVER_ENABLED": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_SNI_ENABLED": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CLOUDFRONT_VIEWER_POLICY_HTTPS": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CLOUDTRAIL_S3_DATAEVENTS_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "S3BucketNames", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "CLOUDTRAIL_SECURITY_TRAIL_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "CLOUDWATCH_ALARM_ACTION_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "true", + "Name": "alarmActionRequired", + "Optional": false, + "Type": "String" + }, + { + "Default": "true", + "Name": "insufficientDataActionRequired", + "Optional": false, + "Type": "String" + }, + { + "Default": "false", + "Name": "okActionRequired", + "Optional": false, + "Type": "String" + }, + { + "Name": "action1", + "Optional": true, + "Type": "String" + }, + { + "Name": "action2", + "Optional": true, + "Type": "String" + }, + { + "Name": "action3", + "Optional": true, + "Type": "String" + }, + { + "Name": "action4", + "Optional": true, + "Type": "String" + }, + { + "Name": "action5", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "CLOUDWATCH_ALARM_RESOURCE_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "resourceType", + "Optional": false, + "Type": "String" + }, + { + "Name": "metricName", + "Optional": false, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "CLOUDWATCH_ALARM_SETTINGS_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "metricName", + "Optional": false, + "Type": "String" + }, + { + "Name": "threshold", + "Optional": true, + "Type": "int" + }, + { + "Name": "evaluationPeriods", + "Optional": true, + "Type": "int" + }, + { + "Default": "300", + "Name": "period", + "Optional": true, + "Type": "int" + }, + { + "Name": "comparisonOperator", + "Optional": true, + "Type": "String" + }, + { + "Name": "statistic", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "CLOUDWATCH_LOG_GROUP_ENCRYPTED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "KmsKeyId", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "CLOUD_TRAIL_CLOUD_WATCH_LOGS_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "expectedDeliveryWindowAge", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "CLOUD_TRAIL_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "s3BucketName", + "Optional": true, + "Type": "String" + }, + { + "Name": "snsTopicArn", + "Optional": true, + "Type": "String" + }, + { + "Name": "cloudWatchLogsLogGroupArn", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "CLOUD_TRAIL_ENCRYPTION_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Periodic" + }, + "CLOUD_TRAIL_LOG_FILE_VALIDATION_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Periodic" + }, + "CMK_BACKING_KEY_ROTATION_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Periodic" + }, + "CODEBUILD_PROJECT_ENVVAR_AWSCRED_CHECK": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CODEBUILD_PROJECT_SOURCE_REPO_URL_CHECK": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "CODEPIPELINE_DEPLOYMENT_COUNT_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Europe (Milan), Europe (Stockholm), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "deploymentLimit", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "CODEPIPELINE_REGION_FANOUT_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Europe (Milan), Europe (Stockholm), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [ + { + "Default": "3", + "Name": "regionFanoutFactor", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "CW_LOGGROUP_RETENTION_PERIOD_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "LogGroupNames", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "MinRetentionTime", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "DAX_ENCRYPTION_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Asia Pacific (Seoul), Canada (Central), Europe (Milan), Europe (Stockholm), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "DB_INSTANCE_BACKUP_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "backupRetentionPeriod", + "Optional": true, + "Type": "int" + }, + { + "Name": "backupRetentionMinimum", + "Optional": true, + "Type": "int" + }, + { + "Name": "preferredBackupWindow", + "Optional": true, + "Type": "String" + }, + { + "Name": "checkReadReplicas", + "Optional": true, + "Type": "boolean" + } + ], + "Trigger type": "Configuration changes" + }, + "DESIRED_INSTANCE_TENANCY": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "tenancy", + "Optional": false, + "Type": "String" + }, + { + "Name": "imageId", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "hostId", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "DESIRED_INSTANCE_TYPE": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "instanceType", + "Optional": false, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "DMS_REPLICATION_NOT_PUBLIC": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "DYNAMODB_AUTOSCALING_ENABLED": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West) Region", + "Parameters": [ + { + "Name": "minProvisionedReadCapacity", + "Optional": true, + "Type": "int" + }, + { + "Name": "maxProvisionedReadCapacity", + "Optional": true, + "Type": "int" + }, + { + "Name": "targetReadUtilization", + "Optional": true, + "Type": "double" + }, + { + "Name": "minProvisionedWriteCapacity", + "Optional": true, + "Type": "int" + }, + { + "Name": "maxProvisionedWriteCapacity", + "Optional": true, + "Type": "int" + }, + { + "Name": "targetWriteUtilization", + "Optional": true, + "Type": "double" + } + ], + "Trigger type": "Periodic" + }, + "DYNAMODB_IN_BACKUP_PLAN": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "DYNAMODB_PITR_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "DYNAMODB_TABLE_ENCRYPTED_KMS": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "kmsKeyArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "DYNAMODB_TABLE_ENCRYPTION_ENABLED": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Europe (Milan), Europe (Stockholm), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "DYNAMODB_THROUGHPUT_LIMIT_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Default": "80", + "Name": "accountRCUThresholdPercentage", + "Optional": true, + "Type": "int" + }, + { + "Default": "80", + "Name": "accountWCUThresholdPercentage", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "EBS_IN_BACKUP_PLAN": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "EBS_OPTIMIZED_INSTANCE": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EBS_SNAPSHOT_PUBLIC_RESTORABLE_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "EC2_EBS_ENCRYPTION_BY_DEFAULT": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "EC2_IMDSV2_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EC2_INSTANCE_DETAILED_MONITORING_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EC2_INSTANCE_MANAGED_BY_SSM": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EC2_INSTANCE_MULTIPLE_ENI_CHECK": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "NetworkInterfaceIds", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "EC2_INSTANCE_NO_PUBLIC_IP": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EC2_INSTANCE_PROFILE_ATTACHED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "IamInstanceProfileArnList", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "EC2_MANAGEDINSTANCE_APPLICATIONS_BLACKLISTED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "applicationNames", + "Optional": false, + "Type": "CSV" + }, + { + "Name": "platformType", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "EC2_MANAGEDINSTANCE_APPLICATIONS_REQUIRED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "applicationNames", + "Optional": false, + "Type": "CSV" + }, + { + "Name": "platformType", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "EC2_MANAGEDINSTANCE_ASSOCIATION_COMPLIANCE_STATUS_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EC2_MANAGEDINSTANCE_INVENTORY_BLACKLISTED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "inventoryNames", + "Optional": false, + "Type": "CSV" + }, + { + "Name": "platformType", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "EC2_MANAGEDINSTANCE_PATCH_COMPLIANCE_STATUS_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EC2_MANAGEDINSTANCE_PLATFORM_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "platformType", + "Optional": false, + "Type": "String" + }, + { + "Name": "platformVersion", + "Optional": true, + "Type": "String" + }, + { + "Name": "agentVersion", + "Optional": true, + "Type": "String" + }, + { + "Name": "platformName", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "EC2_SECURITY_GROUP_ATTACHED_TO_ENI": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EC2_STOPPED_INSTANCE": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Default": "30", + "Name": "AllowedDays", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "EC2_VOLUME_INUSE_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "deleteOnTermination", + "Optional": true, + "Type": "boolean" + } + ], + "Trigger type": "Configuration changes" + }, + "ECS_TASK_DEFINITION_USER_FOR_HOST_MODE_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "SkipInactiveTaskDefinitions", + "Optional": true, + "Type": "boolean" + } + ], + "Trigger type": "Configuration changes" + }, + "EFS_ENCRYPTED_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "KmsKeyId", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "EFS_IN_BACKUP_PLAN": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "EIP_ATTACHED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EKS_ENDPOINT_NO_PUBLIC_ACCESS": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Europe (Milan), US West (N. California), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "EKS_SECRETS_ENCRYPTED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), US West (N. California), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "kmsKeyArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Periodic" + }, + "ELASTICACHE_REDIS_CLUSTER_AUTOMATIC_BACKUP_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Default": "15", + "Name": "snapshotRetentionPeriod", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "ELASTICSEARCH_ENCRYPTED_AT_REST": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "ELASTICSEARCH_IN_VPC_ONLY": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "ELASTICSEARCH_LOGS_TO_CLOUDWATCH": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West) Region", + "Parameters": [ + { + "Name": "logTypes", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "ELASTICSEARCH_NODE_TO_NODE_ENCRYPTION_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "ELASTIC_BEANSTALK_MANAGED_UPDATES_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "UpdateLevel", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "ELBV2_ACM_CERTIFICATE_REQUIRED": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "AcmCertificatesAllowed", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Periodic" + }, + "ELB_ACM_CERTIFICATE_REQUIRED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "ELB_CROSS_ZONE_LOAD_BALANCING_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "ELB_CUSTOM_SECURITY_POLICY_SSL_CHECK": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "sslProtocolsAndCiphers", + "Optional": false, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "ELB_DELETION_PROTECTION_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "ELB_LOGGING_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "s3BucketNames", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "ELB_PREDEFINED_SECURITY_POLICY_SSL_CHECK": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "predefinedPolicyName", + "Optional": false, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "ELB_TLS_HTTPS_LISTENERS_ONLY": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "EMR_KERBEROS_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "TicketLifetimeInHours", + "Optional": true, + "Type": "int" + }, + { + "Name": "Realm", + "Optional": true, + "Type": "String" + }, + { + "Name": "Domain", + "Optional": true, + "Type": "String" + }, + { + "Name": "AdminServer", + "Optional": true, + "Type": "String" + }, + { + "Name": "KdcServer", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "EMR_MASTER_NO_PUBLIC_IP": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "ENCRYPTED_VOLUMES": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "kmsId", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "FMS_SHIELD_RESOURCE_POLICY_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia) Region", + "Parameters": [ + { + "Name": "webACLId", + "Optional": false, + "Type": "String" + }, + { + "Name": "resourceTypes", + "Optional": false, + "Type": "String" + }, + { + "Name": "resourceTags", + "Optional": true, + "Type": "String" + }, + { + "Name": "excludeResourceTags", + "Optional": true, + "Type": "boolean" + }, + { + "Name": "fmsManagedToken", + "Optional": true, + "Type": "String" + }, + { + "Name": "fmsRemediationEnabled", + "Optional": true, + "Type": "boolean" + } + ], + "Trigger type": "Configuration changes" + }, + "FMS_WEBACL_RESOURCE_POLICY_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia) Region", + "Parameters": [ + { + "Name": "webACLId", + "Optional": false, + "Type": "String" + }, + { + "Name": "resourceTags", + "Optional": true, + "Type": "String" + }, + { + "Name": "excludeResourceTags", + "Optional": true, + "Type": "boolean" + }, + { + "Name": "fmsManagedToken", + "Optional": true, + "Type": "String" + }, + { + "Name": "fmsRemediationEnabled", + "Optional": true, + "Type": "boolean" + } + ], + "Trigger type": "Configuration changes" + }, + "FMS_WEBACL_RULEGROUP_ASSOCIATION_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia) Region", + "Parameters": [ + { + "Name": "ruleGroups", + "Optional": false, + "Type": "String" + }, + { + "Name": "fmsManagedToken", + "Optional": true, + "Type": "String" + }, + { + "Name": "fmsRemediationEnabled", + "Optional": true, + "Type": "boolean" + } + ], + "Trigger type": "Configuration changes" + }, + "GUARDDUTY_ENABLED_CENTRALIZED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "CentralMonitoringAccount", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "GUARDDUTY_NON_ARCHIVED_FINDINGS": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Middle East (Bahrain), Africa (Cape Town) Region", + "Parameters": [ + { + "Default": "30", + "Name": "daysLowSev", + "Optional": true, + "Type": "int" + }, + { + "Default": "7", + "Name": "daysMediumSev", + "Optional": true, + "Type": "int" + }, + { + "Default": "1", + "Name": "daysHighSev", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "IAM_CUSTOMER_POLICY_BLOCKED_KMS_ACTIONS": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "blockedActionsPatterns", + "Optional": false, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "IAM_GROUP_HAS_USERS_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "IAM_INLINE_POLICY_BLOCKED_KMS_ACTIONS": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "blockedActionsPatterns", + "Optional": false, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "IAM_NO_INLINE_POLICY_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "IAM_PASSWORD_POLICY": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "true", + "Name": "RequireUppercaseCharacters", + "Optional": true, + "Type": "boolean" + }, + { + "Default": "true", + "Name": "RequireLowercaseCharacters", + "Optional": true, + "Type": "boolean" + }, + { + "Default": "true", + "Name": "RequireSymbols", + "Optional": true, + "Type": "boolean" + }, + { + "Default": "true", + "Name": "RequireNumbers", + "Optional": true, + "Type": "boolean" + }, + { + "Default": "14", + "Name": "MinimumPasswordLength", + "Optional": true, + "Type": "int" + }, + { + "Default": "24", + "Name": "PasswordReusePrevention", + "Optional": true, + "Type": "int" + }, + { + "Default": "90", + "Name": "MaxPasswordAge", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "IAM_POLICY_BLACKLISTED_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "arn", + "Name": "policyArns", + "Optional": false, + "Type": "CSV" + }, + { + "Name": "exceptionList", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "IAM_POLICY_IN_USE": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "policyARN", + "Optional": false, + "Type": "String" + }, + { + "Name": "policyUsageType", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "IAM_POLICY_NO_STATEMENTS_WITH_FULL_ACCESS": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "IAM_ROLE_MANAGED_POLICY_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "managedPolicyArns", + "Optional": false, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "IAM_ROOT_ACCESS_KEY_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "IAM_USER_GROUP_MEMBERSHIP_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "groupNames", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "IAM_USER_MFA_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Periodic" + }, + "IAM_USER_NO_POLICIES_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "IAM_USER_UNUSED_CREDENTIALS_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "90", + "Name": "maxCredentialUsageAge", + "Optional": false, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "INCOMING_SSH_DISABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "INSTANCES_IN_VPC": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "vpcId", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "INTERNET_GATEWAY_AUTHORIZED_VPC_ONLY": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "AuthorizedVpcIds", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "KMS_CMK_NOT_SCHEDULED_FOR_DELETION": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan) Region", + "Parameters": [ + { + "Name": "kmsKeyIds", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "LAMBDA_CONCURRENCY_CHECK": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "ConcurrencyLimitLow", + "Optional": true, + "Type": "String" + }, + { + "Name": "ConcurrencyLimitHigh", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "LAMBDA_DLQ_CHECK": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "dlqArns", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "LAMBDA_FUNCTION_SETTINGS_CHECK": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "runtime", + "Optional": false, + "Type": "CSV" + }, + { + "Name": "role", + "Optional": true, + "Type": "String" + }, + { + "Default": "3", + "Name": "timeout", + "Optional": true, + "Type": "int" + }, + { + "Default": "128", + "Name": "memorySize", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "LAMBDA_INSIDE_VPC": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "subnetIds", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "MFA_ENABLED_FOR_IAM_CONSOLE_ACCESS": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Periodic" + }, + "MULTI_REGION_CLOUD_TRAIL_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "s3BucketName", + "Optional": true, + "Type": "String" + }, + { + "Name": "snsTopicArn", + "Optional": true, + "Type": "String" + }, + { + "Name": "cloudWatchLogsLogGroupArn", + "Optional": true, + "Type": "String" + }, + { + "Name": "includeManagementEvents", + "Optional": true, + "Type": "boolean" + }, + { + "Name": "readWriteType", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "NO_UNRESTRICTED_ROUTE_TO_IGW": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "routeTableIds", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_CLUSTER_DELETION_PROTECTION_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), Asia Pacific (Osaka), Middle East (Bahrain), South America (Sao Paulo) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_CLUSTER_IAM_AUTHENTICATION_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Middle East (Bahrain), South America (Sao Paulo) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_CLUSTER_MULTI_AZ_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Middle East (Bahrain), South America (Sao Paulo) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_ENHANCED_MONITORING_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "monitoringInterval", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "RDS_INSTANCE_DELETION_PROTECTION_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "databaseEngines", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "RDS_INSTANCE_IAM_AUTHENTICATION_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), Asia Pacific (Hong Kong), Asia Pacific (Osaka), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_INSTANCE_PUBLIC_ACCESS_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_IN_BACKUP_PLAN": { + "AWS Region": "All supported AWS regions except AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "RDS_LOGGING_ENABLED": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "additionalLogs", + "Optional": true, + "Type": "StringMap" + } + ], + "Trigger type": "Configuration changes" + }, + "RDS_MULTI_AZ_SUPPORT": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_SNAPSHOTS_PUBLIC_PROHIBITED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_SNAPSHOT_ENCRYPTED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "RDS_STORAGE_ENCRYPTED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "kmsKeyId", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "REDSHIFT_BACKUP_ENABLED": { + "AWS Region": "All supported AWS regions except China (Ningxia), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "MinRetentionPeriod", + "Optional": true, + "Type": "int" + }, + { + "Name": "MaxRetentionPeriod", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "REDSHIFT_CLUSTER_CONFIGURATION_CHECK": { + "AWS Region": "All supported AWS regions except Middle East (Bahrain) Region", + "Parameters": [ + { + "Default": "true", + "Name": "clusterDbEncrypted", + "Optional": false, + "Type": "boolean" + }, + { + "Default": "true", + "Name": "loggingEnabled", + "Optional": false, + "Type": "boolean" + }, + { + "Default": "dc1.large", + "Name": "nodeTypes", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "REDSHIFT_CLUSTER_KMS_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "kmsKeyArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK": { + "AWS Region": "All supported AWS regions except Middle East (Bahrain) Region", + "Parameters": [ + { + "Default": "true", + "Name": "allowVersionUpgrade", + "Optional": false, + "Type": "boolean" + }, + { + "Name": "preferredMaintenanceWindow", + "Optional": true, + "Type": "String" + }, + { + "Default": "1", + "Name": "automatedSnapshotRetentionPeriod", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "REDSHIFT_ENHANCED_VPC_ROUTING_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "REDSHIFT_REQUIRE_TLS_SSL": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "REQUIRED_TAGS": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "CostCenter", + "Name": "tag1Key", + "Optional": false, + "Type": "String" + }, + { + "Name": "tag1Value", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "tag2Key", + "Optional": true, + "Type": "String" + }, + { + "Name": "tag2Value", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "tag3Key", + "Optional": true, + "Type": "String" + }, + { + "Name": "tag3Value", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "tag4Key", + "Optional": true, + "Type": "String" + }, + { + "Name": "tag4Value", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "tag5Key", + "Optional": true, + "Type": "String" + }, + { + "Name": "tag5Value", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "tag6Key", + "Optional": true, + "Type": "String" + }, + { + "Name": "tag6Value", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "RESTRICTED_INCOMING_TRAFFIC": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Default": "20", + "Name": "blockedPort1", + "Optional": true, + "Type": "int" + }, + { + "Default": "21", + "Name": "blockedPort2", + "Optional": true, + "Type": "int" + }, + { + "Default": "3389", + "Name": "blockedPort3", + "Optional": true, + "Type": "int" + }, + { + "Default": "3306", + "Name": "blockedPort4", + "Optional": true, + "Type": "int" + }, + { + "Default": "4333", + "Name": "blockedPort5", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "ROOT_ACCOUNT_HARDWARE_MFA_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "ROOT_ACCOUNT_MFA_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "S3_ACCOUNT_LEVEL_PUBLIC_ACCESS_BLOCKS": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka), Europe (Milan), Middle East (Bahrain) Region", + "Parameters": [ + { + "Default": "True", + "Name": "IgnorePublicAcls", + "Optional": true, + "Type": "String" + }, + { + "Default": "True", + "Name": "BlockPublicPolicy", + "Optional": true, + "Type": "String" + }, + { + "Default": "True", + "Name": "BlockPublicAcls", + "Optional": true, + "Type": "String" + }, + { + "Default": "True", + "Name": "RestrictPublicBuckets", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes (current status not checked, only evaluted when changes generate new events)" + }, + "S3_ACCOUNT_LEVEL_PUBLIC_ACCESS_BLOCKS_PERIODIC": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West) Region", + "Parameters": [ + { + "Name": "IgnorePublicAcls", + "Optional": true, + "Type": "String" + }, + { + "Name": "BlockPublicPolicy", + "Optional": true, + "Type": "String" + }, + { + "Name": "BlockPublicAcls", + "Optional": true, + "Type": "String" + }, + { + "Name": "RestrictPublicBuckets", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "S3_BUCKET_BLACKLISTED_ACTIONS_PROHIBITED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "blacklistedActionPattern", + "Optional": false, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_DEFAULT_LOCK_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "mode", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "excludedPublicBuckets", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_LOGGING_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "targetBucket", + "Optional": true, + "Type": "String" + }, + { + "Name": "targetPrefix", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_POLICY_GRANTEE_CHECK": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "awsPrincipals", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "servicePrincipals", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "federatedUsers", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "ipAddresses", + "Optional": true, + "Type": "CSV" + }, + { + "Name": "vpcIds", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_POLICY_NOT_MORE_PERMISSIVE": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "controlPolicy", + "Optional": false, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_PUBLIC_READ_PROHIBITED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes and Periodic" + }, + "S3_BUCKET_PUBLIC_WRITE_PROHIBITED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes and Periodic" + }, + "S3_BUCKET_REPLICATION_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_SSL_REQUESTS_ONLY": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "S3_BUCKET_VERSIONING_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "isMfaDeleteEnabled", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "S3_DEFAULT_ENCRYPTION_KMS": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "kmsKeyArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "SAGEMAKER_ENDPOINT_CONFIGURATION_KMS_KEY_CONFIGURED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "kmsKeyArns", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "SAGEMAKER_NOTEBOOK_INSTANCE_KMS_KEY_CONFIGURED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "kmsKeyArns", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "SAGEMAKER_NOTEBOOK_NO_DIRECT_INTERNET_ACCESS": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "SECRETSMANAGER_ROTATION_ENABLED_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "maximumAllowedRotationFrequency", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Configuration changes" + }, + "SECRETSMANAGER_SCHEDULED_ROTATION_SUCCESS_CHECK": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "SECRETSMANAGER_SECRET_PERIODIC_ROTATION": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "maxDaysSinceRotation", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "SECRETSMANAGER_SECRET_UNUSED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "unusedForDays", + "Optional": true, + "Type": "int" + } + ], + "Trigger type": "Periodic" + }, + "SECRETSMANAGER_USING_CMK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "kmsKeyArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "SECURITYHUB_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "SERVICE_VPC_ENDPOINT_ENABLED": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "serviceName", + "Optional": false, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "SHIELD_ADVANCED_ENABLED_AUTORENEW": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "SHIELD_DRT_ACCESS": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "SNS_ENCRYPTED_KMS": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "kmsKeyIds", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Configuration changes" + }, + "SSM_DOCUMENT_NOT_PUBLIC": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West) Region", + "Parameters": [], + "Trigger type": "Periodic" + }, + "SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "VPC_DEFAULT_SECURITY_GROUP_CLOSED": { + "AWS Region": "All supported AWS regions", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "VPC_FLOW_LOGS_ENABLED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Name": "trafficType", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Periodic" + }, + "VPC_NETWORK_ACL_UNUSED_CHECK": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "VPC_SG_OPEN_ONLY_TO_AUTHORIZED_PORTS": { + "AWS Region": "All supported AWS regions except Asia Pacific (Osaka) Region", + "Parameters": [ + { + "Name": "authorizedTcpPorts", + "Optional": true, + "Type": "String" + }, + { + "Name": "authorizedUdpPorts", + "Optional": true, + "Type": "String" + } + ], + "Trigger type": "Configuration changes" + }, + "VPC_VPN_2_TUNNELS_UP": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), Asia Pacific (Osaka), Middle East (Bahrain) Region", + "Parameters": [], + "Trigger type": "Configuration changes" + }, + "WAFV2_LOGGING_ENABLED": { + "AWS Region": "All supported AWS regions except China (Beijing), China (Ningxia), AWS GovCloud (US-East), AWS GovCloud (US-West), Asia Pacific (Osaka), Europe (Milan), Africa (Cape Town) Region", + "Parameters": [ + { + "Name": "KinesisFirehoseDeliveryStreamArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Periodic" + }, + "WAF_CLASSIC_LOGGING_ENABLED": { + "AWS Region": "Only available in US East (N. Virginia) Region", + "Parameters": [ + { + "Name": "KinesisFirehoseDeliveryStreamArns", + "Optional": true, + "Type": "CSV" + } + ], + "Trigger type": "Periodic" + } + } +} \ No newline at end of file diff --git a/moto/config/responses.py b/moto/config/responses.py index 749e564d6..19baa85ba 100644 --- a/moto/config/responses.py +++ b/moto/config/responses.py @@ -186,14 +186,12 @@ class ConfigResponse(BaseResponse): conformance_packs = self.config_backend.describe_organization_conformance_packs( self._get_param("OrganizationConformancePackNames") ) - return json.dumps(conformance_packs) def describe_organization_conformance_pack_statuses(self): statuses = self.config_backend.describe_organization_conformance_pack_statuses( self._get_param("OrganizationConformancePackNames") ) - return json.dumps(statuses) def get_organization_conformance_pack_detailed_status(self): @@ -201,14 +199,12 @@ class ConfigResponse(BaseResponse): statuses = self.config_backend.get_organization_conformance_pack_detailed_status( self._get_param("OrganizationConformancePackName") ) - return json.dumps(statuses) def delete_organization_conformance_pack(self): self.config_backend.delete_organization_conformance_pack( self._get_param("OrganizationConformancePackName") ) - return "" def tag_resource(self): @@ -222,3 +218,19 @@ class ConfigResponse(BaseResponse): self._get_param("ResourceArn"), self._get_param("TagKeys"), ) return "" + + def put_config_rule(self): + self.config_backend.put_config_rule( + self.region, self._get_param("ConfigRule"), self._get_param("Tags"), + ) + return "" + + def describe_config_rules(self): + rules = self.config_backend.describe_config_rules( + self._get_param("ConfigRuleNames"), self._get_param("NextToken"), + ) + return json.dumps(rules) + + def delete_config_rule(self): + self.config_backend.delete_config_rule(self._get_param("ConfigRuleName")) + return "" diff --git a/scripts/pull_down_aws_managed_rules.py b/scripts/pull_down_aws_managed_rules.py new file mode 100755 index 000000000..d0d8f2858 --- /dev/null +++ b/scripts/pull_down_aws_managed_rules.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +"""Download markdown files with AWS managed ConfigRule info and convert to JSON. + +The first markdown file is read to obtain the names of markdown files for +all the AWS managed config rules. Then each of those markdown files are read +and info is extracted with the final results written to a JSON file. + +The JSON output will look as follows: + +{ + "ManagedRules": [ + { + "ACCESS_KEYS_ROTATED": { + "AWS Region": "All supported AWS regions", + "Parameters": [ + { + "Default": "90", + "Name": "maxAccessKeyAgeType", + "Optional": false, + "Type": "intDefault" + } + ], + "Trigger type": "Periodic" + }, + }, + ... + ] +} +""" +import json +import re +import sys + +import requests + +MANAGED_RULES_OUTPUT_FILENAME = "../moto/config/resources/aws_managed_rules.json" + +AWS_MARKDOWN_URL_START = "https://raw.githubusercontent.com/awsdocs/aws-config-developer-guide/main/doc_source/" + +LIST_OF_MARKDOWNS_URL = "managed-rules-by-aws-config.md" + + +def managed_rule_info(lines): + """Return dict of qualifiers/rules extracted from a markdown file.""" + rule_info = {} + label_pattern = re.compile(r"(?:\*\*)(?P