Awesome
tfmv
| Install
tfmv is a CLI to rename Terraform resources, data sources, and modules and generate moved blocks.
e.g. Replace -
with _
:
tfmv -r "-/_"
diff --git a/example/main.tf b/example/main.tf
index 48ef3bd..9110880 100644
--- a/example/main.tf
+++ b/example/main.tf
@@ -1,20 +1,20 @@
-resource "github_repository" "example-1" {
+resource "github_repository" "example_1" {
name = "example-1"
}
-data "github_branch" "example-2" {
- repository = github_repository.example-1.name
+data "github_branch" "example_2" {
+ repository = github_repository.example_1.name
branch = "example"
depends_on = [
- github_repository.example-1,
- module.example-3
+ github_repository.example_1,
+ module.example_3
]
}
-module "example-3" {
+module "example_3" {
source = "./foo/module"
}
output "branch_sha" {
- value = data.github_branch.example-2.sha
+ value = data.github_branch.example_2.sha
}
moved.tf is created:
moved {
from = github_repository.example-1
to = github_repository.example_1
}
moved {
from = module.example-3
to = module.example_3
}
Getting Started
- Install tfmv
- Checkout this repository
git clone https://github.com/suzuki-shunsuke/tfmv
cd tfmv/example
main.tf:
resource "github_repository" "example-1" {
name = "example-1"
}
data "github_branch" "example-2" {
repository = github_repository.example-1.name
branch = "example"
depends_on = [
github_repository.example-1,
module.example-3
]
}
module "example-3" {
source = "./foo/module"
}
output "branch_sha" {
value = data.github_branch.example-2.sha
}
Let's replace -
with _
.
You must specify one of --replace (-r)
, --regexp
, or --jsonnet (-j)
.
In this case, let's use -r
.
If you need more flexible renaming, you can use regular expression or Jsonnet.
Run tfmv -r "-/_"
.
You don't need to run terraform init
.
tfmv -r "-/_"
Then a resource name is changed and moved.tf
is created.
By default, tfmv finds *.tf on the current directory.
main.tf:
diff --git a/example/main.tf b/example/main.tf
index 48ef3bd..9110880 100644
--- a/example/main.tf
+++ b/example/main.tf
@@ -1,20 +1,20 @@
-resource "github_repository" "example-1" {
+resource "github_repository" "example_1" {
name = "example-1"
}
-data "github_branch" "example-2" {
- repository = github_repository.example-1.name
+data "github_branch" "example_2" {
+ repository = github_repository.example_1.name
branch = "example"
depends_on = [
- github_repository.example-1,
- module.example-3
+ github_repository.example_1,
+ module.example_3
]
}
-module "example-3" {
+module "example_3" {
source = "./foo/module"
}
output "branch_sha" {
- value = data.github_branch.example-2.sha
+ value = data.github_branch.example_2.sha
}
moved.tf:
moved {
from = github_repository.example-1
to = github_repository.example_1
}
moved {
from = module.example-3
to = module.example_3
}
Pass *.tf via arguments
You can also pass *.tf via arguments:
tfmv -r "-/_" foo/aws_s3_bucket.tf foo/aws_instance.tf
tfmv supports modules too.
tfmv -r "production/prod" foo/module_foo.tf
Dry Run: --dry-run
With --dry-run
, tfmv outputs logs but doesn't rename blocks.
tfmv -r "-/_" --dry-run bar/main.tf
Rename resources by regular expression
With --regexp
, tfmv renames resources by regular expression.
tfmv --regexp '^example-(\d+)/test-$1' regexp/main.tf
About regular expression, please see the following document:
Filter resources by regular expression
With --include <regular expression>
, only resources matching the regular expression are renamed.
tfmv -r "-/_" --include "^aws_" bar/main.tf
With --exclude <regular expression>
, only resources not matching the regular expression are renamed.
tfmv -r "-/_" --exclude "^null_resource" bar/main.tf
Change the filename for moved blocks
By default tfmv writes moved blocks to moved.tf
.
You can change the file name via -m
option.
tfmv -r "-/_" -m moved_blocks.tf bar/main.tf
You can also write moved blocks to the same file with renamed resources and modules.
tfmv -r "-/_" -m same bar/foo.tf
--recursive (-R)
Recursive option
By default, tfmv finds *.tf on the current directory.
You can find files recursively using -R
option.
tfmv -Rr "-/_"
The following directories are ignored:
- .git
- .terraform
- node_modules
Jsonnet
-r
is simple and useful, but sometimes you need more flexible renaming.
In that case, you can use --jsonnet (-j)
.
Jsonnet is a powerful data configuration language.
tfmv.jsonnet (You can change the filename freely):
std.native("strings.Replace")(std.extVar('input').name, "-", "_", -1)[0]
tfmv -j tfmv.jsonnet
You need to define Jsonnet whose input is each resource and output is a new resource name.
tfmv passes an input via External Variables.
You can access an input by std.extVar('input')
.
local input = std.extVar('input');
The type of an external variable input
is as following:
{
"file": "A relative file path from the current directory to the Terraform configuration file",
"block_type": "Either module or resource",
"resource_type": "A resource type. e.g. null_resource. If block_type is module, resource_type is empty",
"name": "A resource name. For example, the resource address is null_resource.foo, the name is foo."
}
e.g.
{
"file": "foo/main.tf",
"block_type": "resource",
"resource_type": "null_resource",
"name": "foo"
}
The Jsonnet must returns a new resource name. If the returned value is an empty string or not changed, the resource isn't renamed.
Native Functions
tfmv supports the following native functions.
You can executed these functions by std.native("{native function name}")
.
e.g.
std.native("strings.Replace")(input.name, "-", "_", -1)[0]
For details, please see Native functions.