tfGuard

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2024 License: GPL-3.0 Imports: 9 Imported by: 0

README

latest build latest release Go Reference

tf-guard

A package for writing Terraform Resource evaluation rules in native Golang.

A problem I've encountered with other Terraform security tools is the lack of control caused (most often) by the abstractions imposed by Domain Specific Languages (DSLs) used to make writing the rules themselves easier.

This causes headaches when trying to write more complicated logic around resources that DSLs may not have support for, or may cause conflicts with other resources during evaluation. Additionally the overhead of having to learn an additional DSL to support these tools can be cumbersome and time consuming when you already know full coding languages.

This package serves as my solution to that problem, allowing the flexibility of the full Golang language to allow users to write their own custom logic and rules for their resources within a provided Terraform plan.

Usage

The package requires that a JSON formatted Terraform plan file be collected containing the resources that are to be evaluated. This can be accomplished with 2 Terraform commands:

terraform plan -out=plan.tfplan
terraform show -json plan.tfplan > myplanfile.json

This JSON formatted plan file is fed into the package via the Deployment struct to parse its contents.

d := Deployment{
    PlanFile: "./myplanfile.json",
    ...
}

Additionally, if utilizing modules, a ModulesFile can be provided as the path to the modules.json file for the deployment that is used to link the underlying resources being created from within a module, to its parent and children addresses. If not provided, a best effort is made to identify the file in the execution directory.

d := Deployment{
    PlanFile: "./myplanfile.json",
    ModulesFile: "./.terraform/modules.json",
    ...
}

Next, the functions to be executed against the resources must be provided. These functions must satisfy the Rule type and can be provided into the Rules parameter of the Deployment.

d := Deployment{
    PlanFile: "./myplanfile.json",
    ModulesFile: "./.terraform/modules.json",
    Rules: []Rule{
        ...
    },
    ...
}

By providing a simple function type, the package allows custom functions to be written with full access to each Terraform resource's configuration values.

type Rule func(tfresources.Resource) Result

An example Rule declaration to showing access to Terraform module attributes as well as resource values:

func main(){
    d := Deployment{
        PlanFile: "./myplanfile.json",
        ModulesFile: "./.terraform/modules.json",
        Rules: []Rule{
            MyCustomTRule
        },
    }
    ...
}

func MyCustomTFRule(r tfresources.Resource) tfGuard.Result {
    moduleReference := r.Module.Version           // Immutable versioning for the module linked to this resource
    attributeValues := r.Planned.AttributeValues  // map[string]interface{} Containing resource attribute values
    resourceType := r.Planned.Type                // A Terraform resource type - like aws_s3_bucket
    ...
    return tfGuard.Result {               // A Result struct must be returned for each Rule type
        Name: "This is my custom rule.",  // A simple name for this rule
        Valid: true,                      // A boolean Valid argument for rule validity
        ...                               // Other attributes can be defined if required - see Result struct
    }
}

Finally the Scan method can be executed to parse the resources, evaluate each rule against them, and return the results as StdOut string text, or in JSON formatting for programmatic parsing.

func main(){
    d := Deployment{
        ...
    }
    d.Scan()                    // Results are written to StdOut unless Disabled

    fmt.Println(d.ResultsJson)  // JSON output can be written to a file if desired, or parsed directly
}
TF Guard Rule Evaluation for Resources:

[ ✅ ]  Rule: S3 buckets must be tagged at all times.
	Valid: true
	Severity: Minor
	Resource: aws_s3_bucket.default
	Type: aws_s3_bucket

[ ❌ ]  Rule: All resources must include an Owner tag.
	Valid: false
	Severity: Major
	Resource: aws_s3_bucket.default
	Type: aws_s3_bucket

[ ✅ ]  Rule: S3 Bucket Objects must always be tagged.
	Valid: true
	Severity: Minor
	Resource: aws_s3_object.obj
	Type: aws_s3_object

[ ❌ ]  Rule: All resources must include an Owner tag.
	Valid: false
	Severity: Major
	Resource: aws_s3_object.obj
	Type: aws_s3_object

Overall Resource Score: 50%

Check out the examples on how you can integrate this package into your own codebase.

Author

This codebase is created and maintained by Dave Streng.

License

GNU General Public License v3.0 or later

See LICENSE to see the full text.

Documentation

Overview

A package that will parse a Terraform plan file and execute a set of functions against the underlying resources that can be used to gate or control how Terraform resources are being provisioned into your environment.

This package can be utilized to build your own infrastructure scanning rules with the ability to leverage the capabilities of a full language instead of being limited by Domain Specific Languages (DSLs).

Index

Constants

This section is empty.

Variables

View Source
var (
	Severity = struct {
		Minor    string
		Major    string
		Critical string
	}{
		Minor:    "Minor",
		Major:    "Major",
		Critical: "Critical",
	}
)

Some default values for Severities that can be easily leveraged if desired, if not, users can provide their own severity values/structures based on their own needs.

Functions

This section is empty.

Types

type Deployment

type Deployment struct {
	PlanFile      string
	ModulesFile   string
	Resources     []tfresources.Resource
	Rules         []Rule
	Results       []Result
	ResultsStdOut string
	ResultsJson   []byte
	DisableStdOut bool
	Debug         bool
	Logger        *logrus.Logger
}

A Deployment contains all the relevant attributes for a given Terraform plan execution. It contains references to Plan and Modules files, as well as the list of Rules to be evaluated against each resource, as lastly the results of the evaluation both in string-based StdOut format and JSON (to alloow for programmatic parsing).

func (*Deployment) Scan

func (d *Deployment) Scan()

The primary Scan function intakes the specified Plan and Modules file paths and utilizes the tfresources project to parse out the underlying Terraform resources and link them to any declared modules.

Once parsed, the resources are fed into the rule engine to begin the execution of each rule onto each resource and the results aggregated into StdOut and JSON formatting.

Debug logging can be enabled if desired to assist with writing Rules. Additionall the default StdOut text can be disabled if using the JSON output for programmatic control over the results.

type Result

type Result struct {
	Name          string
	Valid         bool
	Severity      string
	Resource      tfresources.Resource
	NotApplicable bool
}

Result is a data structure used to hold the evaluation results for a Rule (as defined above). A Rule type function must return a valid Result.

type Rule

type Rule func(tfresources.Resource) Result

A Rule function definition - this function type must be satisfied in order for it to be executed against the planned resources.

The input is a Resource type that extends the terraform-json project's StateResource struct by linking any resources created from modules back to their parent and children addresses. The output is a Result struct as defined below.

Check out the [terraform-json](https://github.com/hashicorp/terraform-json/blob/main/state.go#L124) project for more details on how you can access different resource values.

Directories

Path Synopsis
examples
complex command
simple command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL