Categorygithub.com/drlau/tfplanparse
modulepackage
0.0.14
Repository: https://github.com/drlau/tfplanparse.git
Documentation: pkg.go.dev

# README

tfplanparse

tfplanparse is a Go library for parsing terraform plan outputs. Supports terraform v0.12 CLI output currently. Does not fully support multiline diffs right now.

NOTE: This library does not parse the file produced by terraform plan -out=<file>. If you want to parse that file, you should use hashicorp/terraform-json.

This project is still WIP and the schemas are subject to change.

Why

By parsing the output from terraform plan into something more machine readable, you can perform some validation and workflows depending on what the output contains. Some example use cases include:

  • Filter out unexpected changes from routine terraform operations
  • Send a notification when a certain type of resource is being modified
  • Trigger additional workflows before terraform apply if a certain resource type is modified

tfplanparse vs terraform-json

You can parse the output from terraform plan using terraform-json by running terraform plan -out=<file> followed by terraform state show -json <file>. However, while the output file is encoded, it contains sensitive information, and terraform state show -json <file> will output this sensitive information in plain text.

With tfplanparse, you can parse the output from terraform plan directly, skipping writing a state file containing sensitive data to disk. Additionally, sensitive data is redacted in the terraform plan output, so the secrets will remain redacted when parsed.

Usage

import "github.com/drlau/tfplanparse"

func main() {
    result, err := tfplanparse.Parse(os.Stdin)
    if err != nil {
        panic(err)
    }

    // or, you can read directly from a file
    fromFile, err := tfplanparse.ParseFromFile("out.stdout")
    if err != nil {
        panic(err)
    }
}

The returned type from Parse and ParseFromFile is []*tfplanparse.ResourceChange. Each ResourceChange corresponds to a single resource in the terraform plan output and has the following fields:

  • Address: Absolute resource address
  • ModuleAddress: Module portion of the absolute address, if any
  • Type: The type of the resource (example: gcp_instance.foo -> "gcp_instance")
  • Name: The name of the resource (example: gcp_instance.foo -> "foo")
  • Index: The index key for resources created with count or for_each
  • UpdateType: The type of update (refer to updatetype.go for possible values)
  • Tainted: Indicates whether the resource is tainted or not
  • AttributeChanges: Planned attribute changes

Each ResourceChange also has the following helper functions:

  • GetBeforeResource: Returns the resource before the planned changes as a map[string]interface{}
  • GetAfterResource: Returns the resource after the planned changes as a map[string]interface{}

Additionally, these helper functions accept the following options:

  • IgnoreComputed
  • IgnoreSensitive
  • IgnoreNoOp
  • ComputedOnly

# Functions

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
IsArrayAttributeChangeLine returns true if the line is a valid attribute change This requires the line to start with "+", "-" or "~", not be followed with "resource" or "data", and ends with "[".
IsArrayAttributeTerminator returns true if the line is "]" or "] -> null".
IsAttributeChangeArrayItem returns true if the line is a valid attribute change in an array.
IsAttributeChangeLine returns true if the line is a valid attribute change This requires the line to start with "+", "-" or "~", and not be followed with "resource".
IsHeredocAttributeChangeLine returns true if the line is a valid attribute change This requires the line to start with "+", "-" or "~", delimited with a space, and the value to start with "<<".
IsHeredocAttributeTerminator returns true if the line is "EOT" EOT is the only possible terminator for the heredoc Ref: https://github.com/hashicorp/terraform/blob/6a126df0c601ab23689171506bfc1386fea4c96c/command/format/diff.go#L880.
IsJSONEncodeAttributeChangeLine returns true if the line is a valid attribute change This requires the line to start with "+", "-" or "~", delimited with a space, and the value to start with "jsonencode(".
IsJSONEncodeAttributeTerminator returns true if the line is ")" TODO: verify this.
IsMapAttributeChangeLine returns true if the line is a valid attribute change This requires the line to start with "+", "-" or "~", not be followed with "resource" or "data", and ends with "{".
IsMapAttributeTerminator returns true if the line is a "}" or "},".
IsOneLineEmptyArrayAttribute returns true if the line ends with a "[]".
IsOneLineEmptyMapAttribute returns true if the line ends with a "{}".
IsResourceChangeLine returns true if the line is a valid resource change line A valid line starts with the change type, then "resource" or "data", and then the type and name, followed by a { Example: + resource "type" "name" {.
IsResourceCommentLine returns true if the line is a valid resource comment line A valid line starts with a "#" and has a suffix describing the change Example: # module.type.item will be created.
IsResourceTerminator returns true if the line is a "}".
NewArrayAttributeChangeFromLine initializes an ArrayAttributeChange from a line containing an array attribute change It expects a line that passes the IsArrayAttributeChangeLine check.
NewAttributeChangeFromLine initializes an AttributeChange from a line within an Array attribute In an array resource, the attribute change does not have a name.
NewAttributeChangeFromLine initializes an AttributeChange from a line containing an attribute change It expects a line that passes the IsAttributeChangeLine check.
NewHeredocAttributeChangeFromLine initializes a HeredocAttributeChange from a line containing a heredoc change It expects a line that passes the IsHeredocAttributeChangeLine check.
NewJSONEncodeAttributeChangeFromLine initializes a JSONEncodeAttributeChange from a line containing a JSONEncode change It expects a line that passes the IsJSONEncodeAttributeChangeLine check.
NewMapAttributeChangeFromLine initializes an AttributeChange from a line containing an attribute change It expects a line that passes the IsAttributeChangeLine check.
NewResourceChangeFromComment creates a ResourceChange from a valid resource comment line.
No description provided by the author
No description provided by the author

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

TODO: array attributes can be any attribute change, an array of arrays, or array of maps Type of the attribute can vary, but they're all the same Should use an interface.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Type aliases

No description provided by the author
No description provided by the author