Skip to content
/ tap Public

Patch Terraform Resource As Your Mind.

License

Notifications You must be signed in to change notification settings

seal-io/tap

Repository files navigation

Terraform Advanced Patcher (TAP)

Terraform Advanced Patcher, aka.TAP,is a tool to patchTerraformfile.

This tool is maintained bySeal.

Background

In some cases, consuming nativeTerraform Override can complete some additional expansion, like overriding a nested block or changing a predefined attribute, but the capabilities are limited. For example, it needs accurate block header to patch, and it's impossible to conditionally make changes to nested blocks or attributes.

TAPis designed to satisfy the above features.

Implementation

As we all know, the HCL used byTerraform supports JSON syntax.Therefore,TAPcan be implemented using JSON patching.

The patching mode ofTerraform Overridelooks likeJSON Merge Patch, RFC 7386,butTAPis working asJSON Patch, RFC 6902.

For a comparison of JSON patch and JSON merge patch, seeJSON Patch and JSON Merge Patch.

Note

AlthoughTAPandTerraform Overridepath in different ways, they have one thing in same, that is, top-level blocks cannot be deleted. The core reason is that top-level blocks can configureMeta-Argumentor participate in the configuration ofMeta-Argument.Directly deleting a top-level block will cause many problems.

Usage

TAPis not a complete JSON patch forTerraform JSON Configuration SyntaxThe original JSON path needs its operation to have exactly one "path" member, which values with aJSON Pointer,butTAPimplements limited operations:add,remove,andreplace,and also introduces a new operation:set.

#tap.hcl

tap{
path_syntax="json_pointer"
}

resource"kubernetes_deployment"{
type_alias=["kubernetes_deployment_v1"]

add{
path="/metadata/0/labels/new-label"
value="new-label-value"
}

remove{
path="/metadata/0/labels/old-label"
}

replace{
path="/spec/0/template/0/spec/0/replicas"
value="2"
}

set{
path="/spec/0/selector/0"
value {
match_labels=local.selectors
}
}
}

TAPrecognizes the path syntax according to thepath_syntaxattribute in thetapblock, in which the default value isjson_pointer.We are going to support more path syntax in the future.

TAP,at present, only supports patchingresourceanddatablocks, and filters out the target blocks bytype_aliasorname_matchattributes.

#tap.hcl

tap{
path_syntax="json_pointer"
}

resource"kubernetes_deployment"{
type_alias=["kubernetes_deployment_v1"]
name_match=["nginx"]

#... operations
}

data"kubernetes_config_map"{
type_alias=["kubernetes_config_map_v1"]
name_match=["nginx"]

#... operations
}

TAPalso allows ignoring error if patching fails, and it can be configured by thecontinue_on_errorattribute in thetapblock.

#tap.hcl

tap{
continue_on_error=true#global
path_syntax="json_pointer"
}

resource"kubernetes_deployment"{
continue_on_error=false#local
type_alias=["kubernetes_deployment_v1"]

#... operations
}

TAPis a wrapper toTerraformorOpenTofu,you can simplify aliasTAPastf,and use it as a drop-in replacement for Terraform or OpenTofu.

TAPis not a fork of Terraform or OpenTofu, so you still need to install the CLI ofTerraform orOpenTofu at first.

$ go install github.com/seal-io/tap/cmd/tap@latest
$ mv"${GOPATH}"/bin/tap"${GOPATH}"/bin/tf
$ tf --version

Put thetap.hclfile in the same directory as themain.tffile, and then executetf planortf applyto see the effect.

Example YouTube Overview

Requirements

License

Mozilla Public License v2.0