WAF-OPS-020 – Infrastructure as Code Enforced
Description
All cloud infrastructure MUST be defined as code (Terraform, Pulumi, AWS CDK). Manual resource creation through the cloud console MUST be prohibited for production and staging. IaC definitions MUST be versioned, reviewed, and deployed through CI/CD.
Rationale
Manually created infrastructure cannot be reliably reproduced, cannot be reviewed, and cannot be audited. Snowflake servers are a primary risk for reliability and operational debt. IaC eliminates configuration drift, enables audit trails, and allows disaster recovery in minutes instead of weeks.
Threat Context
| Risk | Description |
|---|---|
Configuration Drift |
Manual console changes create invisible deviations between the IaC definition and reality. |
Snowflake Servers |
Manually configured systems cannot be reproduced after a failure. |
Missing Peer Review |
Without IaC and pull requests, there are no second eyes on infrastructure changes. |
DR Failure |
Disaster recovery tests fail because the actual infrastructure deviates from the documented IaC. |
Requirements
-
All production and staging infrastructure MUST be defined as IaC
-
Manual changes MUST be restricted by IAM policy or Service Control Policy (SCP)
-
Remote state backend with locking MUST be configured (no local state)
-
All IaC changes MUST go through pull request review
-
State bucket MUST have versioning enabled for rollback capability
Implementation Guidance
-
Configure remote state: S3+DynamoDB (AWS), Azure Storage Account, GCS Bucket – with locking
-
Secure state bucket: Enable versioning; encryption at rest; access logging
-
Restrict console access: SCP or IAM permission boundary for production accounts
-
Build module library: Reusable modules for networking, compute, security
-
Enable drift detection:
terraform plandaily via EventBridge schedule; alert on drift -
Brownfield import: Take over existing resources into state with
terraform import
Maturity Levels
| Level | Name | Criteria |
|---|---|---|
1 |
Manual |
No IaC; infrastructure created manually via console or CLI. |
2 |
Inconsistent IaC |
Parts of the infrastructure as IaC; manual resources coexist; no remote state. |
3 |
IaC Fully Enforced |
100% production infrastructure as IaC; remote state; manual changes restricted. |
4 |
Drift Detection & Policy Enforcement |
Drift detected and alerted daily; policy-as-code in CI; module library present. |
5 |
GitOps |
Git state = single source of truth; automatic drift remediation; IaC coverage 100%. |
Terraform Checks
waf-ops-020.tf.aws.s3-terraform-state-backend
Checks: Terraform remote state is configured in S3 backend (not local state).
| Compliant | Non-Compliant |
|---|---|
|
|
waf-ops-020.tf.aws.s3-state-bucket-versioning
Checks: S3 state bucket has versioning enabled.
# Compliant
resource "aws_s3_bucket_versioning" "state" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled" # Not Suspended
}
}
Remediation: Configure remote state backend with S3+DynamoDB locking. Enable state bucket versioning.
Evidence
| Type | Required | Description |
|---|---|---|
IaC |
✅ Required |
Terraform repository with remote state configuration (backend.tf with S3/Azure/GCS). |
Config |
✅ Required |
State backend configuration with versioning and locking enabled. |
Process |
Optional |
Drift detection report (last 30 days, drift events with resolution times). |
Governance |
Optional |
SCP or IAM policy preventing direct console changes in production accounts. |