IaC: version-controlled config for infra. Auditable, reviewable, repeatable. Also codifies misconfigs.
Common misconfigs
Public S3:
# VULNERABLE
acl = "public-read"
# SECURE
resource "aws_s3_bucket_public_access_block" "data" {
block_public_acls = true
block_public_policy = true
}
Permissive security groups:
# VULNERABLE
cidr_blocks = ["0.0.0.0/0"]
# SECURE
cidr_blocks = ["10.0.0.0/8"]
IAM wildcards:
# VULNERABLE
{"Action": "*", "Resource": "*"}
# SECURE
{"Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::my-bucket/*"}
Scanning
checkov -d .
tfsec .
Policy as code: Custom rules with OPA/Sentinel.
State file
Contains resource IDs, outputs (may include secrets). Never commit. Remote backend with encryption. Restrict access.
Drift
Manual console changes = drift. terraform plan shows differences. Automate detection.
Modules
Encapsulate best practices:
module "secure_bucket" {
source = "./modules/secure-s3-bucket"
}
The takeaway
Scan in CI. Protect state files. Detect drift. Encapsulate patterns in modules.
