Create a Policy and Block a Deployment
Write a security policy in OPA/Rego, attach it to an IaC project, and watch it block a non-compliant Terraform deployment before anything reaches your cloud.
Scenario
Your team is deploying S3 buckets but some are being created without server-side encryption. You want to:
- Write a policy that requires all S3 buckets to have encryption enabled
- Attach it to your IaC projects
- Have it automatically block any deployment that violates the rule
Prerequisites
can_policies IAM permission (admin role has this by default)Step 1: Create a Policy Group
Policy groups organize related policies and get attached to projects as a unit.
S3 Security PoliciesStep 2: Write the Policy
| Field | Value |
|---|---|
| Name | Require S3 Encryption |
| Description | All S3 buckets must have server-side encryption enabled |
| Category | Security |
| Severity | Critical |
Policy content (OPA/Rego):
package main
deny[msg] {
input.resource.type == "aws_s3_bucket"
not has_encryption(input.resource)
msg := sprintf(
"S3 bucket '%v' must have server-side encryption enabled. Add an aws_s3_bucket_server_side_encryption_configuration block.",
[input.resource.name]
)
}
has_encryption(resource) {
resource.values.server_side_encryption_configuration[_].rule[_].apply_server_side_encryption_by_default[_]
}
Click Save Policy.
Step 3: Add the Policy to the Group
Step 4: Attach the Group to an IaC Project
The policy group is now active on that project. Every future deployment will be checked against it.
Step 5: Trigger a Violation
To see the policy in action, try deploying an S3 bucket without encryption:
# This will be BLOCKED by the policy
resource "aws_s3_bucket" "insecure" {
bucket = "my-insecure-bucket"
}
Run a Plan on this code. When you try to apply, the policy engine evaluates the plan JSON and returns:
Policy Check: FAILED
✗ CRITICAL Require S3 Encryption
Resource: aws_s3_bucket.insecure
Message: S3 bucket 'insecure' must have server-side encryption enabled.
Add an aws_s3_bucket_server_side_encryption_configuration block.
Remediation: Add server_side_encryption_configuration block to resource
Deployment BLOCKED — critical violations must be resolved before applying.
The apply does not proceed. Nothing is created in AWS.
Step 6: Fix the Code and Redeploy
Add the encryption configuration:
resource "aws_s3_bucket" "secure" {
bucket = "my-secure-bucket"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "secure" {
bucket = aws_s3_bucket.secure.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
Run the plan again. This time the policy check passes and you can apply.
View Compliance Status
Go to Policies & Compliance → Compliance to see:
- Compliance score across your organization
- Policy groups and their attachment status
- Recent violations — which deployments were blocked and why
- Trend — violation rate over the past 30 days
Violation Severity Behavior
| Severity | Behavior |
|---|---|
| Critical | Deployment blocked — cannot proceed |
| High | Warning shown — engineer must acknowledge before applying |
| Medium | Info message logged — deployment continues |
| Low | Info message logged — deployment continues |
Next Steps
Troubleshooting
sprintf, or forgetting to import builtins. The error message points to the problematic line.play.openpolicyagent.org) before attaching it to projects. Check that your has_encryption helper correctly traverses the Terraform plan structure.