The Terraform AWS Compliance module provides a comprehensive, opinionated solution for implementing enterprise-grade security and compliance controls across AWS Organizations. This module orchestrates multiple AWS security services to create a unified compliance framework that ensures consistent security posture, automated monitoring, and regulatory adherence across all organizational units and accounts.
Large organizations face significant challenges in maintaining security and compliance across their AWS infrastructure:
- Fragmented Security Posture: Multiple accounts and organizational units often have inconsistent security configurations
- Compliance Complexity: Meeting regulatory requirements (SOC 2, PCI DSS, HIPAA, etc.) across distributed infrastructure
- Manual Security Management: Time-consuming and error-prone manual configuration of security services
- Lack of Centralized Visibility: Difficulty in monitoring security posture across the entire organization
- Inconsistent Standards: Different teams implementing security controls differently
- Audit Preparation: Complex and time-consuming compliance reporting and evidence collection
This module provides a centralized, automated approach to security and compliance that:
- Centralizes Security Management: Implements Security Hub as the central security command center
- Automates Compliance Monitoring: Deploys AWS Config rules across organizational units via StackSets
- Enables Continuous Monitoring: Provides real-time security findings and compliance status
- Standardizes Security Controls: Applies consistent security policies across all accounts
- Facilitates Audit Preparation: Generates comprehensive compliance reports and evidence
- Reduces Operational Overhead: Automates security service configuration and management
- AWS Security Hub: Centralized security findings aggregation and management
- AWS Config: Configuration compliance monitoring and drift detection
- AWS Access Analyzer: Unused access identification and IAM policy analysis
- AWS Inspector: Vulnerability assessment for EC2, ECR, and Lambda workloads
- AWS Macie: Sensitive data discovery and protection
- AWS GuardDuty: Threat detection and security monitoring
- Multi-Standard Support: CIS, NIST, PCI DSS, AWS Foundational Security Best Practices
- Custom Security Policies: Configurable security controls with custom parameters
- Organizational Unit Targeting: Granular policy application across OUs and accounts
- Rule Group Management: Organized configuration rules for different environments
- Compliance Reporting: Automated compliance status reporting and evidence collection
- Multi-Channel Alerts: Slack, Microsoft Teams, and email notifications
- Severity-Based Filtering: Configurable alert thresholds (CRITICAL, HIGH, MEDIUM, LOW)
- Real-Time Monitoring: EventBridge-driven instant security finding notifications
- Customizable Templates: Tailored notification formats for different audiences
- Escalation Workflows: Automated escalation based on finding severity
- StackSet Distribution: Automated deployment across organizational units
- Regional Flexibility: Multi-region support with centralized management
- Account Exclusion: Granular control over which accounts receive specific policies
- Resource Tagging: Comprehensive tagging for governance and cost management
- Dependency Management: Proper resource dependencies and lifecycle management
- Least Privilege Access: Minimal IAM permissions for all operations
- Encryption Support: KMS integration for sensitive data protection
- Audit Trail: Comprehensive logging and monitoring capabilities
- Policy Customization: Fine-tuned security controls based on organizational needs
- Compliance Mapping: Direct mapping to regulatory frameworks and standards
- Terraform State Management: Full Terraform state management for all resources
- Resource Tagging: Consistent tagging across all created resources
- Output Management: Comprehensive outputs for integration with other modules
- Dependency Management: Proper resource dependencies and lifecycle management
- Rollback Capabilities: Safe rollback mechanisms for policy changes
graph TB
subgraph "Central Compliance Account"
A[Security Hub Aggregator]
B[Security Hub Organization Config]
C[Config Rules StackSets]
D[Access Analyzer]
E[Inspector Organization Config]
F[Macie StackSet]
G[Notification System]
end
subgraph "Security Hub Policies"
H[Foundational Best Practices]
I[CIS Benchmarks]
J[NIST 800-53]
K[PCI DSS]
L[Custom Policies]
end
subgraph "Organizational Units"
M[Production OU]
N[Development OU]
O[Security OU]
P[Compliance OU]
end
subgraph "Member Accounts"
Q[Account 1]
R[Account 2]
S[Account N]
end
A --> H
A --> I
A --> J
A --> K
A --> L
C --> M
C --> N
C --> O
C --> P
M --> Q
N --> R
O --> S
G --> A
D --> A
E --> A
F --> A
- Policy Definition: Security policies are defined in the central compliance account
- StackSet Distribution: Policies are distributed to organizational units via AWS StackSets
- Continuous Monitoring: AWS Config and Security Hub continuously monitor compliance
- Finding Generation: Security findings are generated and aggregated in Security Hub
- Notification Processing: Findings are processed and sent via configured notification channels
- Compliance Reporting: Automated reports are generated for audit and compliance purposes
- Security Hub: Central aggregation point for all security findings
- AWS Config: Configuration compliance monitoring and drift detection
- Access Analyzer: IAM policy analysis and unused access identification
- Inspector: Vulnerability assessment across compute workloads
- Macie: Sensitive data discovery and classification
- GuardDuty: Threat detection and security monitoring
module "compliance" {
source = "appvia/compliance/aws"
version = "0.1.0"
region = "us-east-1"
tags = {
Environment = "production"
ManagedBy = "terraform"
Purpose = "compliance"
}
securityhub = {
aggregator = {
create = true
linking_mode = "ALL_REGIONS"
specified_regions = ["us-east-1", "us-west-2"]
}
configuration = {
auto_enable = true
auto_enable_standards = "DEFAULT"
organization_configuration = {
configuration_type = "CENTRAL"
}
}
policies = {
"foundational-security" = {
enable = true
description = "AWS Foundational Security Best Practices for all accounts"
associations = [
{ organization_unit = "ou-1234567890" }
]
policy = {
standard_arns = ["aws_foundational_best_practices"]
controls = {
disabled = [
"Account.1", # Security contact details
"CloudTrail.1" # CloudTrail enabled (handled by org trail)
]
}
}
}
}
}
}module "compliance" {
source = "appvia/compliance/aws"
version = "0.1.0"
region = "us-east-1"
tags = {
Environment = "production"
ComplianceLevel = "high"
ManagedBy = "terraform"
}
# Access Analyzer Configuration
access_analyzer = {
enable_unused_analyzer = true
unused_analyzer_name = "enterprise-unused-access"
unused_access_age = 90
}
# Inspector Configuration
inspector = {
enable = true
account_id = "123456789012"
enable_ec2_scan = true
enable_ecr_scan = true
enable_lambda_scan = true
enable_lambda_code_scan = true
}
# Macie Configuration
macie = {
enable = true
frequency = "FIFTEEN_MINUTES"
organizational_units = ["ou-1234567890", "ou-0987654321"]
excluded_accounts = ["111111111111"] # Sandbox accounts
stackset_name = "enterprise-macie-config"
}
# Config Rules
config = {
stackset_name_prefix = "enterprise-config-"
rule_groups = {
"production-security" = {
description = "Production security rules for critical workloads"
associations = ["ou-prod-1234567890"]
enabled_regions = ["us-east-1", "us-west-2"]
rules = {
"required-tags" = {
description = "Validate required resource tags"
identifier = "REQUIRED_TAGS"
resource_types = [
"AWS::EC2::Instance",
"AWS::S3::Bucket",
"AWS::RDS::DBInstance"
]
inputParameters = {
tag1Key = "Environment"
tag2Key = "Owner"
tag3Key = "CostCenter"
}
max_execution_frequency = "TwentyFour_Hours"
}
"s3-bucket-encryption" = {
description = "Ensure S3 buckets have encryption enabled"
identifier = "S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED"
resource_types = ["AWS::S3::Bucket"]
max_execution_frequency = "TwentyFour_Hours"
}
}
}
}
}
# Security Hub Configuration
securityhub = {
aggregator = {
create = true
linking_mode = "SPECIFIED_REGIONS"
specified_regions = ["us-east-1", "us-west-2", "eu-west-1"]
}
configuration = {
auto_enable = true
auto_enable_standards = "DEFAULT"
organization_configuration = {
configuration_type = "CENTRAL"
}
}
notifications = {
enable = true
eventbridge_rule_name = "enterprise-security-findings"
severities = ["CRITICAL", "HIGH"]
sns_topic_queue_name = "enterprise-security-alerts"
}
policies = {
"cis-benchmark" = {
enable = true
description = "CIS AWS Foundations Benchmark v1.4.0"
associations = [
{ organization_unit = "ou-1234567890" }
]
policy = {
standard_arns = ["cis_v140"]
controls = {
disabled = [
"CIS.1.1", # Disable specific controls as needed
"CIS.1.2"
]
}
}
}
"nist-800-53" = {
enable = true
description = "NIST 800-53 Rev 5 compliance framework"
associations = [
{ organization_unit = "ou-compliance-0987654321" }
]
policy = {
standard_arns = ["nist_sp_800_53_rev5"]
controls = {
custom_parameter = [
{
security_control_id = "AC.1"
parameter = {
name = "maxAccessKeyAge"
value_type = "NUMBER"
enum = {
value = "90"
}
}
}
]
}
}
}
}
}
# Notification Configuration
notifications = {
slack = {
webhook_url = "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
}
teams = {
webhook_url = "https://outlook.office.com/webhook/YOUR/TEAMS/WEBHOOK"
}
email = {
addresses = [
"[email protected]",
"[email protected]"
]
}
}
}# For large enterprises with comprehensive security requirements
module "enterprise_compliance" {
source = "appvia/compliance/aws"
region = "us-east-1"
securityhub = {
aggregator = {
create = true
linking_mode = "ALL_REGIONS"
}
policies = {
"enterprise-foundational" = {
enable = true
description = "Enterprise-wide foundational security controls"
associations = [
{ organization_unit = "ou-all-accounts" }
]
policy = {
standard_arns = ["aws_foundational_best_practices"]
controls = {
disabled = [
# Customize based on enterprise requirements
]
}
}
}
}
}
config = {
rule_groups = {
"enterprise-tagging" = {
description = "Enterprise resource tagging standards"
associations = ["ou-all-accounts"]
rules = {
"required-tags" = {
description = "Validate enterprise tagging standards"
identifier = "REQUIRED_TAGS"
resource_types = ["AWS::EC2::Instance", "AWS::S3::Bucket"]
inputParameters = {
tag1Key = "Environment"
tag2Key = "Owner"
tag3Key = "CostCenter"
tag4Key = "DataClassification"
}
}
}
}
}
}
tags = {
Environment = "production"
BusinessUnit = "Security"
Compliance = "required"
}
}# For organizations with strict regulatory requirements
module "compliance_focused" {
source = "appvia/compliance/aws"
region = "us-east-1"
# Enable all security services
access_analyzer = {
enable_unused_analyzer = true
unused_access_age = 30 # Stricter than default
}
inspector = {
enable = true
enable_ec2_scan = true
enable_ecr_scan = true
enable_lambda_scan = true
}
macie = {
enable = true
frequency = "FIFTEEN_MINUTES"
organizational_units = ["ou-sensitive-data"]
}
securityhub = {
policies = {
"pci-dss-compliance" = {
enable = true
description = "PCI DSS v3.2.1 compliance controls"
associations = [
{ organization_unit = "ou-payment-systems" }
]
policy = {
standard_arns = ["pci_dss"]
}
}
}
}
notifications = {
email = {
addresses = [
"[email protected]",
"[email protected]",
"[email protected]"
]
}
}
tags = {
Environment = "production"
Compliance = "pci-dss"
DataClassification = "confidential"
}
}# For development and testing environments
module "dev_compliance" {
source = "appvia/compliance/aws"
region = "us-east-1"
securityhub = {
configuration = {
auto_enable = false # Manual enablement for dev
auto_enable_standards = "NONE"
}
policies = {
"dev-foundational" = {
enable = true
description = "Basic security controls for development"
associations = [
{ organization_unit = "ou-development" }
]
policy = {
standard_arns = ["aws_foundational_best_practices"]
controls = {
disabled = [
# Disable controls that are too restrictive for dev
"EC2.10", # VPC endpoints
"RDS.5", # Multi-AZ
"RDS.6" # Enhanced monitoring
]
}
}
}
}
}
config = {
rule_groups = {
"dev-tagging" = {
description = "Basic tagging requirements for dev"
associations = ["ou-development"]
rules = {
"required-tags" = {
description = "Validate basic resource tags"
identifier = "REQUIRED_TAGS"
resource_types = ["AWS::EC2::Instance", "AWS::S3::Bucket"]
inputParameters = {
tag1Key = "Environment"
tag2Key = "Owner"
}
}
}
}
}
}
tags = {
Environment = "development"
Purpose = "compliance"
}
}The module creates comprehensive monitoring capabilities:
# View Security Hub findings
aws securityhub get-findings --filters '{"ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}]}'
# Monitor Config compliance
aws config get-compliance-summary-by-config-rule
# Check Access Analyzer findings
aws accessanalyzer list-findings --analyzer-arn arn:aws:access-analyzer:region:account:analyzer/analyzer-name| Service | Metric | Description | Use Case |
|---|---|---|---|
| Security Hub | Findings |
Number of security findings | Monitor security posture |
| Config | ComplianceByConfigRule |
Compliance status by rule | Track configuration compliance |
| Access Analyzer | UnusedAccessFindings |
Unused access findings | Monitor IAM hygiene |
| Inspector | VulnerabilityFindings |
Vulnerability findings | Track security vulnerabilities |
Error: StackSet deployment failed for organizational unit
Solutions:
- Verify organizational unit ARNs are correct
- Check StackSet execution role permissions
- Ensure target accounts have proper permissions
- Review CloudFormation stack events for specific errors
Error: Security Hub policy association failed
Solutions:
- Verify policy ID and target ID are correct
- Check Security Hub organization configuration
- Ensure proper IAM permissions for policy association
- Verify target accounts are part of the organization
Error: Notifications not being delivered
Solutions:
- Verify webhook URLs are correct and accessible
- Check EventBridge rule configuration
- Ensure SNS topic permissions are correct
- Verify Lambda function execution permissions
- Regular Compliance Reviews: Schedule monthly compliance posture reviews
- Policy Updates: Keep security policies updated with latest standards
- Exception Management: Implement proper exception handling for disabled controls
- Training and Awareness: Provide training on compliance requirements
- Incident Response: Establish procedures for handling security findings
- AWS Organizations enabled
- Appropriate IAM permissions for Security Hub, Config, and StackSets
- Organizational units properly configured
- Notification channels (Slack, Teams, email) configured
- AWS Security Hub
- AWS Config
- AWS Access Analyzer
- AWS Inspector
- AWS Macie
- AWS GuardDuty (via separate module)
- AWS StackSets
- AWS EventBridge
- Amazon SNS
- Security Hub organization administrator
- Config organization administrator
- StackSets administrator
- IAM permissions for service configuration
- CloudFormation permissions for StackSet templates
The terraform-docs utility is used to generate this README. Follow the below steps to update:
- Make changes to the
.terraform-docs.ymlfile - Fetch the
terraform-docsbinary (https://terraform-docs.io/user-guide/installation/) - Run
terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .
| Name | Version |
|---|---|
| aws | >= 5.0.0 |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| region | The region to deploy the resources | string |
n/a | yes |
| tags | A map of tags to add to the resources | map(string) |
n/a | yes |
| access_analyzer | Configuration for the AWS Access Analyzer service | object({ |
null |
no |
| config | Configuration for the securityhub organization managed rules | object({ |
{ |
no |
| inspector | Organizational configuration for the AWS Inspector service | object({ |
{ |
no |
| macie | Configuration for the AWS Macie service | object({ |
null |
no |
| notifications | Configuration for the notifications | object({ |
{ |
no |
| securityhub | Configuration for the securityhub | object({ |
{ |
no |
| Name | Description |
|---|---|
| inspector_resource_types | A list of resources type to enable for inspector |
| securityhub_policy_associations | A map of policy associations by policy name |
| securityhub_policy_configurations | A map of all the policies to the central configuration arns |