This repository provides tools and scripts to dynamically generate Rego policies for TFLint that enforce label requirements on Google Cloud Platform (GCP) resources defined in Terraform configurations. The scripts categorize GCP resources based on their support for labels and generate corresponding Rego policies to validate label adherence.
Below is an overview of the folder structure:
.
├── .tflint.d
│ └── policies
│ ├── resources.rego
│ └── tags.rego
├── .tflint.hcl
├── main.tf
├── outputs.tf
├── providers.tf
├── scripts
│ ├── generate.py
│ ├── resources_with_labels.json
│ └── resources_without_labels.json
└── variables.tf
.tflint.d/policies/
: Directory where TFLint policy files are stored.resources.rego
: Contains dynamically generated Rego policies based on the Terraform configuration.tags.rego
: Defines policies for mandatory labels and handling unlabeled resources.
scripts/
: Directory containing the Python script (generate.py
) used to generate theresources.rego
file..tflint.hcl
: Configuration file for TFLint.
TFLint is a powerful linting tool designed for Terraform configurations. It checks Terraform code for potential issues, enforces best practices, and ensures that configurations are optimized for the cloud provider in use.
- Error Prevention: Catches errors early, such as deprecated syntax, missing required fields, or improper resource configurations.
- Best Practices: Enforces best practices for each cloud provider to avoid misconfigurations and unnecessary complexity.
- Policy Enforcement: With its plugin architecture, TFLint allows custom policies using OPA Rego, enabling users to enforce specific organizational policies.
AWS and Azure have built-in TFLint rulesets that check for missing tags and enforce tagging policies by default. However, GCP lacks built-in rules for enforcing label requirements in Terraform configurations, leaving GCP resources often unlabelled, which complicates billing, tracking, and compliance.
To address this gap, this repository provides custom policies using OPA Rego to ensure:
- Custom Validation: Mandatory labels such as
Environment
andOwner
are enforced on all GCP resources that support labels. - Flexibility: Dynamically generated policies can be adjusted based on your specific Terraform configurations and requirements.
TFLint OPA Ruleset is a plugin that allows integration of Open Policy Agent (OPA) Rego policies into TFLint. With this plugin, users can write custom validation rules using Rego, and TFLint will apply them during the Terraform code analysis.
- Rego Policy Integration: Allows writing custom rules for resource validation using Rego language.
- Flexibility: Supports enforcement of custom policies, such as security best practices, label validation, and resource-specific requirements.
- Compatibility: Can be used for any Terraform provider, including AWS, Azure, and GCP, by writing rules specific to that provider.
The OPA plugin extends the default capabilities of TFLint, making it possible to add granular control over Terraform configurations based on user-defined rules.
The tags.rego
file includes Rego policies that enforce label requirements on GCP resources. The policies are:
-
Mandatory Labels 🏷️
- Enforces the presence of the following labels:
Environment
🌍Owner
👤
- Enforces the presence of the following labels:
-
Supported Resource Types ✅
- Applies to resource types that support labels, as defined in the dynamically generated
resources.rego
file.
- Applies to resource types that support labels, as defined in the dynamically generated
-
Rules
- Missing or Empty Labels ❌
- Rule: Resources must have at least one label.
- Issue: Reports if the
labels
field is missing or empty.
- Missing Mandatory Labels ❌
- Rule: Resources must include all mandatory labels (
Environment
,Owner
). - Issue: Reports if any mandatory labels are missing.
- Rule: Resources must include all mandatory labels (
- Unknown Labels ❓
- Rule: Dynamic or unknown values are not allowed in labels.
- Issue: Reports if a label contains dynamic or unknown values.
- Missing or Empty Labels ❌
This file is dynamically generated by the script and contains resource types that support labels. It is critical for defining the resource types that TFLint will enforce label rules on.
-
Policy Files 📜
- Place the
tags.rego
and dynamically generatedresources.rego
files in the.tflint.d/policies
directory.
- Place the
-
Configuration ⚙️
- Ensure that the
resources.rego
file correctly reflects the supported resource types, as this defines where the label policies will apply.
- Ensure that the
-
TFLint Configuration ⚙️
-
The
.tflint.hcl
file should include the following configuration to enable the OPA plugin:plugin "opa" { enabled = true version = "0.7.0" source = "github.com/terraform-linters/tflint-ruleset-opa" }
-
-
Running TFLint
▶️ -
Validate Terraform configurations with TFLint and the Rego policies:
tflint --config .tflint.hcl --recursive
-
TFLint will read the policies from the
.tflint.d/policies
directory and apply them to your Terraform configurations.
-
-
Example 🌟
- The policy will ensure GCP resources in Terraform configurations have mandatory labels and do not have unknown or empty labels. Issues will be reported with details.
This script automates the generation of a dynamic resources.rego
file based on the current Terraform configuration for GCP resources.
- Terraform (version 0.13 or later)
- Python 3.x
- Required Python modules:
json
,subprocess
,os
,shutil
,argparse
-
Basic Usage 🚀
-
Ensure Terraform is installed and in your system's PATH.
-
Navigate to the
scripts
directory:cd scripts
-
Run the script to generate the Rego policy and perform other operations:
python3 generate.py
-
This will:
- Clean up existing Terraform files and directories.
- Create a
provider.tf
file. - Initialize Terraform.
- Fetch the GCP provider schema.
- Categorize resources based on label support.
- Generate the
resources.rego
file in the.tflint.d/policies/
directory.
-
-
Generating JSON Files 📊
-
To generate JSON files for resources with and without labels, use the
--generate-json
flag:python3 generate.py --generate-json
-
This will create:
resources_with_labels.json
: List of GCP resources that support labels.resources_without_labels.json
: List of GCP resources that do not support labels.
-
cleanup()
: Removes the.terraform
directory,provider.tf
file, and any.terraform.lock.hcl
files.write_provider_tf()
: Creates aprovider.tf
file with GCP provider configuration.terraform_init()
: Initializes the Terraform working directory.get_gcp_provider_schema()
: Fetches the GCP provider schema in JSON format.categorize_resources_by_labels(schema)
: Categorizes GCP resources based on label support.write_json_file(filename, data)
: Writes data to JSON files.write_rego_file(resource_types)
: Generates theresources.rego
file with a list of resource types that support labels.main()
: Coordinates script execution based on command-line arguments.
If you would like to contribute to this project, please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Make your changes and commit them.
- Push your changes to your forked repository.
- Submit a pull request to the main repository.