compliance.tf

Getting Started with Operational Rules

Operational Rules apply your organization's operational standards — lifecycle blocks like prevent_destroy, tag ignore_changes, provisioner removal, instance type restrictions — to modules at download time, without forks or wrapper modules. They are independent from compliance controls: controls enforce regulatory requirements and run first, rules enforce operational standards and run second. See the Operational Rules overview for the full concept.

This guide takes you from viewing available rules to verifying they are applied. Typically under 5 minutes.

Prerequisites

Before you begin, make sure you have:

  • A compliance.tf account. Start a free trial or sign in.
  • Terraform >= 1.0 or OpenTofu >= 1.6 installed.
  • A module source pointing at a compliance.tf registry endpoint (e.g., soc2.compliance.tf/...). See Get Started if you have not set this up yet.
  • An access token configured via terraform login or .terraformrc. See Get Started for details.

Step 1: Browse available rules

Browse the full catalog of available rules at Rule Catalog. Each rule page shows what the rule does, which resources it affects, and example before/after HCL.

The 7 built-in rules are:

RuleWhat it does
pofix/prevent_destroy_dataAdds prevent_destroy = true to data-bearing resources (S3, RDS, DynamoDB, EFS)
pofix/ignore_tag_changesAdds ignore_changes = [tags, tags_all] to all resources
pofix/ignore_autoscaling_changesAdds ignore_changes = [read_capacity, write_capacity] to DynamoDB tables
pofix/ignore_ami_changesAdds ignore_changes = [ami] to EC2 instances
pofix/prevent_destroy_encryptionAdds prevent_destroy = true to KMS keys and Secrets Manager secrets
pofix/no_provisionersRemoves all provisioner blocks from resources
pofix/restrict_instance_typesDenies GPU and specialty instance types (p3, p4, x1, x2, u-*)

Step 2: Add rules to your module source

The simplest way to apply rules is to add the ?rules= query parameter to your HTTPS module source URL. No API calls needed. Just add the rules you want directly in your Terraform configuration:

module "s3_bucket" {
  source = "https://soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws?version=5.0.0&rules=pofix/prevent_destroy_data,pofix/ignore_tag_changes,pofix/no_provisioners"
}

This works on all tiers and gives you per-module control over which rules are applied. Always include the namespace in rule ids (pofix/prevent_destroy_data, not prevent_destroy_data) — a name without its namespace matches nothing and is silently ignored. When org defaults exist (paid tier, below), prefix a rule with + to add it on top of the defaults or - to remove it for that download: ?rules=-pofix/prevent_destroy_data.

Paid tier: org-level defaults. On paid tiers, org admins configure default rules for the entire organization from the org dashboard at app.compliance.tf (backed by PUT /api/org/rules). This requires a signed-in dashboard session with the org admin role on a paid tier — it is separate from the ctf_ registry access token, which authenticates module downloads only. When org defaults are configured, rules are applied automatically to every module download without needing ?rules= in the URL. Individual developers can still override org defaults per-request using ?rules=.


Step 3: Verify rules are applied

Run terraform init -upgrade on any module sourced from the compliance.tf registry (-upgrade forces a fresh download past the local module cache):

terraform init -upgrade

Expected output:

Initializing modules...
Downloading soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws 5.0.0 for s3_bucket...
- s3_bucket in .terraform/modules/s3_bucket

Initializing provider plugins...

Terraform has been successfully initialized!

After init completes, inspect the downloaded module to confirm rules were applied. For example, if you enabled Prevent Destroy Data, check the S3 bucket resource:

grep -B1 -A2 "prevent_destroy" .terraform/modules/s3_bucket/main.tf

Expected output:

  lifecycle {
    prevent_destroy = true
  }

The lifecycle block is now in the module source code. It was not there in the upstream terraform-aws-modules version.


Rules manifest (coming soon)

Coming Soon

A .ctf-rules-manifest.json file will be included in every downloaded module, recording which rules were applied, which resources were affected, and a SHA-256 ruleset hash. This feature is planned but not yet available.


Troubleshooting

Check that your module source URL includes the ?rules= parameter with the rules you want, or that your org has rules configured via the compliance.tf API (app.compliance.tf/api/org/rules).

If neither is set, no rules will be applied. This issue can also occur when the module was cached from a previous download. Run terraform init -upgrade to force a fresh download.

Controls run first, rules run second. If both affect the same attribute, changes are merged additively (e.g., both adding entries to ignore_changes). Explicit conflict detection, where a rule contradicts a control, is planned for a future release. If you see unexpected behavior, adjust your rule configuration to avoid overlap with the control.

Use the per-request override in the module source URL:

module "s3_bucket" {
  source = "https://soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws?version=5.0.0&rules=-pofix/prevent_destroy_data"
}

The - prefix removes a rule for this specific download. The + prefix adds a rule that is not in your org defaults.

The org rules API uses your signed-in dashboard session, not the registry access token. Sign in at app.compliance.tf and retry; a 403 means your account lacks the org admin role or your organization is not on a paid tier. (The ctf_ access token from the Access Tokens page authenticates module downloads, not this API.)


Next steps

On this page

Ask AI about this

Help improve this page