yorbox
is a command-line interface (CLI) tool that helps manage tags consistently across infrastructure as code (IaC) frameworks. It is specifically designed to work with BridgeCrew Yor, an open-source tool that enables auto-tagging in IaC, making it possible to trace any resource from code to cloud.
However, when writing a reusable Terraform module, Yor's tags are hard-coded and cannot be turned off by a variable.
resource azurerm_kubernetes_cluster "k8s_cluster" {
dns_prefix = "terragoat-${var.environment}"
location = var.location
name = "terragoat-aks-${var.environment}"
resource_group_name = azurerm_resource_group.example.name
identity {
type = "SystemAssigned"
}
default_node_pool {
name = "default"
vm_size = "Standard_D2_v2"
node_count = 2
}
addon_profile {
oms_agent {
enabled = false
}
kube_dashboard {
enabled = true
}
}
role_based_access_control {
enabled = false
}
tags = {
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}
}
This is where YorBox comes in. It scans the tags created by Yor and puts them into a "box" with a variable toggle that allows users to turn it on and off as needed. This makes it easier to manage tags and ensures consistency across your infrastructure. With YorBox, you can take control of your tags and streamline your IaC workflow.
It reads all Terraform files in a directory, adds toggle blocks to all tags of resources and modules that generated by yor, and writes the updated files back to disk.
resource azurerm_kubernetes_cluster "k8s_cluster" {
dns_prefix = "terragoat-${var.environment}"
location = var.location
name = "terragoat-aks-${var.environment}"
resource_group_name = azurerm_resource_group.example.name
identity {
type = "SystemAssigned"
}
default_node_pool {
name = "default"
vm_size = "Standard_D2_v2"
node_count = 2
}
addon_profile {
oms_agent {
enabled = false
}
kube_dashboard {
enabled = true
}
}
role_based_access_control {
enabled = false
}
tags = (/*<box>*/(var.yor_toggle ? /*</box>*/{
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}/*<box>*/ : {})/*</box>*/)
}
Assume we've boxed the tags as follows:
tags = (var.yor_toggle ? {
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
} : {})
What if we'd like to use a different box template, e.g:
tags = (var.yor_toggle ? { for k,v in {
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
} : "my_prefix_${k}"=> v }: {})
How can we remove the previous box and add a new one? Here comes the box denotation. The box denotation is a special comment that tells YorBox where the box starts and ends. It's a special comment that starts with /*<box>*/
and ends with /*</box>*/
. YorBox will remove the box denotation and the box itself, and then add a new box with the new template:
tags = (/*<box>*/(var.yor_toggle ? /*</box>*/{
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}/*<box>*/ : {})/*</box>*/)
The tokens between box denotation would be removed:
tags = ({
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
})
Then YorBox will add a new box with the new template:
tags = (/*<box>*/(var.yor_toggle ? { for k,v in /*</box>*/{
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}/*<box>*/:"my_prefix_${k}"=>v } : {})/*</box>*/)
A pair of paren would be added to tags
attribute if it doesn't have one:
tags = {
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}
Would be boxed as:
tags = (/*<box>*/(var.yor_toggle ? /*</box>*/{
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}/*<box>*/ : {})/*</box>*/)
That's because of hclwrite
's limitation. If we call the following go code:
tags := block.Body().GetAttribute("tags")
if tags == nil {
return
}
tokens := tags.Expr().BuildTokens(hclwrite.Tokens{})
If tags
's expression is:
tags = /*<box>*/ (var.yor_toggle ? /*</box>*/{ yor_trace = 123 } /*<box>*/ : {})</box>
Then tokens
wouldn't contain the first /*<box>*/
comment token as it would be interpreted as a lead comment token for the whole expression. To make YorBox work we have to ensure that the expression is wrapped with a pair of paren. That's why we add a pair of paren to the expression if it doesn't have one.
You can install Yor Box using go install command:
go install github.com/lonegunmanb/yorbox@latest
$ yor tag -d ./
...
$ yorbox -dir <directory path> [-toggleName <toggle name>] [-help]
Flags
-boxTemplate string
Box template to use when adding boxes (default "/*<box>*/(var.{{ .toggleName }} ? /*</box>*/ { yor_trace = 123 } /*<box>*/ : {})/*</box>*/")
-dir string
path to the directory containing .tf files
-help
Print help information
-tagsPrefix string
Prefix for tags applied to resources
-toggleName string
Name of the toggle to add (default "yor_toggle")
# Add "my_toggle" block to all tags in the "terraform" directory
yorbox -dir terraform -toggleName my_toggle
The box template is a go template that is used to generate the box. e.g.:
$ yorbox -dir <directory path> -boxTemplate '/*<box>*/(var.{{ .toggleName }} ? { for k,v in /*</box>*/ { yor_trace = 123 } /*<box>*/ : "my_prefix_${k}"=> v} : {})/*</box>*/'
The left side of the box would be /*<box>*/(var.{{ .toggleName }} ? { for k,v in /*</box>*/
, the right side of the box would be /*<box>*/ : "my_prefix_${k}"=> v} : {})/*</box>*/
, so the boxed tags could be:
tags = (/*<box>*/(var.yor_toggle ? { for k,v in /*</box>*/{
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}/*<box>*/:"my_prefix_${k}"=>v } : {})/*</box>*/)
The BoxTemplate would be rendered with user-provided variables. e.g., the default box template /*<box>*/(var.{{ .toggleName }} ? /*</box>*/ { yor_trace = 123 } /*<box>*/ : {})/*</box>*/
with the following command:
$ yorbox -dir <directory> -toggleName "my_toggle"
The generated code could be:
tags = (/*<box>*/(var.my_toggle ? /*</box>*/{
git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
git_file = "terraform/azure/aks.tf"
git_last_modified_at = "2020-06-17 12:59:55"
git_last_modified_by = "[email protected]"
git_modifiers = "nimrodkor"
git_org = "bridgecrewio"
git_repo = "terragoat"
yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}/*<box>*/ : {})/*</box>*/)
The available variables are:
dirPath
:-dir
,toggleName
:-toggleName
,tagsPrefix
:-tagsPrefix
,
In case you're using yor with specifix prefix:
# Apply tags with a specifix prefix
$ yor tag -d . --tag-prefix "my_prefix_"
The generated tags could be:
tags = {
my_prefix_git_commit = "898d5beaec7ffdef6df0d7abecff407362e2a74e"
my_prefix_git_file = "terraform/azure/aks.tf"
my_prefix_git_last_modified_at = "2020-06-17 12:59:55"
my_prefix_git_last_modified_by = "[email protected]"
my_prefix_git_modifiers = "nimrodkor"
my_prefix_git_org = "bridgecrewio"
my_prefix_git_repo = "terragoat"
my_prefix_yor_trace = "6103d111-864e-42e5-899c-1864de281fd1"
}
YorBox relies on the tag's key to locate the tags generated by yor
(git_commit
and yor_trace
). So if you're using a prefix, you have to specify it using -tagsPrefix
flag:
$ yorbox -dir <directory path> -tagsPrefix "my_prefix_"
Yor Boxer is licensed under the MIT License. See LICENSE for more information.