Skip to content

Instantly share code, notes, and snippets.

@atheiman
Last active February 11, 2024 01:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save atheiman/f345ea4aa059bf2d2c5dec490547a86f to your computer and use it in GitHub Desktop.
Save atheiman/f345ea4aa059bf2d2c5dec490547a86f to your computer and use it in GitHub Desktop.
Evaluate an AWS Config Conformance Pack CloudFormation template for regional support. This script lists unsupported SourceIdentifiers in a conformance pack CloudFormation template for the current configured region using AWS Config api.
#!/usr/bin/env python
# Usage example:
# CONFIG_CONFORMANCE_PACK_TEMPLATE=Operational-Best-Practices-for-NIST-800-171.yaml ./config_conformance_pack_region_validator.py
import boto3
import botocore
import json
import os
import time
import yaml
import re
config_conformance_pack_template = os.environ["CONFIG_CONFORMANCE_PACK_TEMPLATE"]
identity = boto3.client("sts").get_caller_identity()
region = boto3.session.Session().region_name
config = boto3.client("config")
print("Testing for regional support of AWS Config managed rules")
print(f"Region: '{region}'")
print(f"Identity: '{identity['Arn']}'")
print(f"YAML CloudFormation template: '{config_conformance_pack_template}'")
print(f"Unsupported CloudFormation resource ids / ConfigRuleNames / SourceIdentifiers will be listed below:")
print("-----")
def delete_rule(rule_name):
try:
config.delete_config_rule(ConfigRuleName=rule_name)
except botocore.exceptions.ClientError as e:
if e.response["Error"]["Code"] == "ResourceInUseException":
time.sleep(5)
delete_rule(rule_name)
elif e.response["Error"]["Code"] != "NoSuchConfigRuleException":
print(f"ERROR - Failed to delete Config rule '{rule_name}' due to unexpected error:")
raise e
with open(config_conformance_pack_template) as template_file:
cfn_template = yaml.safe_load(template_file)
rules = {k:v for k, v in cfn_template["Resources"].items() if v["Type"] == "AWS::Config::ConfigRule" and v["Properties"]["Source"]["Owner"] == "AWS"}
unsupported_rules = {}
for resource_name, rule in rules.items():
rule_name = f"region-check-{rule['Properties']['ConfigRuleName']}"
delete_rule(rule_name)
filtered_rule_definition = {
"ConfigRuleName": rule_name,
"Source": rule["Properties"]["Source"],
}
try:
config.put_config_rule(ConfigRule=filtered_rule_definition)
except botocore.exceptions.ClientError as e:
if e.response["Error"]["Code"] == "InvalidParameterValueException":
if re.search("the sourceidentifier [\w_]+ is invalid", e.response["Error"]["Message"].lower()):
print(f"{resource_name} / {rule['Properties']['ConfigRuleName']} / {rule['Properties']['Source']['SourceIdentifier']}")
unsupported_rules[resource_name] = rule
elif re.search("the required parameter .* is not present in the inputparameters", e.response["Error"]["Message"].lower()) is None:
print(repr(e))
else:
print(f"ERROR - Failed to create Config rule '{rule_name}' due to unexpected error:")
raise e
delete_rule(rule_name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment