Write policy plugins
Plugins provide a way to extend Terraform policy with additional functions that you can use to customize your policy authoring experience. Write Terraform policy plugins in Golang using the terraform-policy-plugin-framework open source library.
Requirements
You must compile Terraform policy plugins and include them in your policy VCS repository before you can use them in your policies.
Author a plugin
To author your own plugins, create a new Go package, import the Terraform policy plugin framework library, and then author a main() function to register your plugin's functions and Go functions to implement each of them.
The following is an example of a plugin that defines two functions, echo, and trim:
plugins/src/example/main.go
package main
import (
"strings"
"github.com/hashicorp/terraform-policy-plugin-framework/policy-plugin/plugins"
)
func main() {
plugins.RegisterFunction("echo", echo)
plugins.RegisterFunction("trim", trim)
plugins.Serve()
}
func echo(value string) (string, error) {
return value, nil
}
func trim(value, prefix string) (string, error) {
return strings.TrimPrefix(value, prefix), nil
}
After you implement your plugin in Go, build it into a binary with the go build command, and store both the source and binary in the same VCS repository as your policy files.
Plugin directory structure
Set up the following recommended directory structure for your plugin in your VCS repository:
./
├── policies/
├── tests/
├── plugins/
│ ├── src/
│ │ └── example/
│ │ ├── main.go
│ │ ├── go.mod
│ │ └── go.sum
│ └── bin/
│ └── example
└── README.md
When you enforce your policies in HCP Terraform, your VCS repository must also contain the plugin binary.
Compile a plugin
Before you can use your plugin in your policies, you must compile it.
Change into the plugin source directory.
$ cd plugins/src/example
Initialize go modules.
$ go mod init example
Download and verify go modules.
$ go mod tidy
Build the plugin.
$ go build -o ../../bin/example main.go
Use plugins in policies
Specify plugins by using the plugins block within the policy block of your .policy.hcl files. Refer to policy for more information.
policies/example.policy.hcl
policy {
plugins {
example = {
source = "../plugins/bin/example"
}
second_example = {
source = "path/to/second-bin"
}
}
}
locals {
instance_type = plugin::example::trim("foo.t3.micro", "foo.")
}
The value of the source attribute must be a string that is the relative path to a binary in the same VCS repository as your policies. The binary must be a valid Terraform policy Go plugin server. Use the terraform-policy-plugin-framework open source library to ensure your plugin provides the correct interface.
In your policies, reference your plugin functions with the plugin::<plugin_label>::<function_name>(<arguments...>).