Last active
February 22, 2024 18:21
-
-
Save austinsonger/51d7c087b1fa41f7cb5cfd4594189c2b to your computer and use it in GitHub Desktop.
Grade Terraform Code Based on AWS Conformance Pack Criteria
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
import os | |
import yaml | |
import hcl2 | |
# Constants | |
YAML_FILE_PATH = '<Path to YAML File>' | |
TERRAFORM_DIRECTORY_PATH = '<Path to Terraform Code>' | |
def parse_yaml(yaml_file_path): | |
"""Parse the YAML file containing the AWS Conformance Pack criteria.""" | |
with open(yaml_file_path, 'r') as file: | |
return yaml.safe_load(file) | |
def read_terraform_files(directory_path): | |
"""Read and parse Terraform files in the specified directory using python-hcl2.""" | |
terraform_configs = {} | |
for root, dirs, files in os.walk(directory_path): | |
for file in files: | |
if file.endswith('.tf'): | |
file_path = os.path.join(root, file) | |
with open(file_path, 'r') as tf_file: | |
terraform_configs[file] = hcl2.load(tf_file) | |
return terraform_configs | |
def evaluate_compliance(terraform_configs, yaml_criteria): | |
"""Evaluate the compliance of Terraform configurations against YAML criteria.""" | |
compliance_report = {} | |
for tf_file, config in terraform_configs.items(): | |
for resource_type, resources in config.get('resource', {}).items(): | |
for resource_name, resource_config in resources.items(): | |
resource_id = f"{resource_type}.{resource_name}" | |
if resource_type in yaml_criteria['Resources']: | |
compliance_report[resource_id] = 'Compliant' | |
properties_to_check = yaml_criteria['Resources'][resource_type].get('Properties', {}) | |
for property_name, expected_value in properties_to_check.items(): | |
actual_value = resource_config.get(property_name) | |
if actual_value != expected_value: | |
compliance_report[resource_id] = 'Non-Compliant' | |
break # Exit the loop early if any non-compliance is found | |
return compliance_report | |
def grade_compliance(compliance_report): | |
"""Assign a grade based on compliance percentage.""" | |
total_resources = len(compliance_report) | |
compliant_resources = sum(status == 'Compliant' for status in compliance_report.values()) | |
if total_resources == 0: | |
return "Grade: N/A (No resources found)" | |
compliance_percentage = (compliant_resources / total_resources) * 100 | |
# Define grade thresholds | |
if compliance_percentage == 100: | |
grade = "A" | |
elif 90 <= compliance_percentage < 100: | |
grade = "B" | |
elif 80 <= compliance_percentage < 90: | |
grade = "C" | |
elif 70 <= compliance_percentage < 80: | |
grade = "D" | |
else: | |
grade = "F" | |
# Return a detailed grade statement | |
return f"Grade: {grade} ({compliance_percentage:.2f}% compliant - {compliant_resources}/{total_resources} resources)" | |
def main(): | |
yaml_criteria = parse_yaml(YAML_FILE_PATH) | |
terraform_configs = read_terraform_files(TERRAFORM_DIRECTORY_PATH) | |
compliance_report = evaluate_compliance(terraform_configs, yaml_criteria) | |
grade = grade_compliance(compliance_report) | |
print(grade) | |
# Optionally, print detailed compliance report | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment