Last active
February 11, 2024 01:04
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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