Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support data sources #35

Merged
merged 7 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
.envrc
moved.tf
moved_blocks.tf
.terraform
.terraform.lock.hcl
102 changes: 92 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,62 @@

[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/suzuki-shunsuke/tfmv/main/LICENSE) | [Install](docs/install.md)

CLI to rename Terraform resources and modules and generate moved blocks.
tfmv is a CLI to rename Terraform resources, data sources, and modules and generate moved blocks.

e.g. Replace `-` with `_`:

```sh
tfmv -r "-/_"
```

```diff
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:

```tf
moved {
from = github_repository.example-1
to = github_repository.example_1
}

moved {
from = module.example-3
to = module.example_3
}
```

## Getting Started

Expand All @@ -21,19 +76,28 @@ resource "github_repository" "example-1" {
name = "example-1"
}

resource "github_branch" "example" {
data "github_branch" "example-2" {
repository = github_repository.example-1.name
branch = "example"
depends_on = [
github_repository.example-1
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 need to specify either `-r` or `--jsonnet (-j)`.
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 Jsonnet. For details, please see here](#jsonnet).
If you need more flexible renaming, you can use [regular expression](#rename-resources-by-regular-expression) or [Jsonnet](#jsonnet).

Run `tfmv -r "-/_"`.
You don't need to run `terraform init`.
Expand All @@ -49,24 +113,37 @@ main.tf:

```diff
diff --git a/example/main.tf b/example/main.tf
index 48ce91d..e618ab1 100644
index 48ef3bd..9110880 100644
--- a/example/main.tf
+++ b/example/main.tf
@@ -1,11 +1,11 @@
@@ -1,20 +1,20 @@
-resource "github_repository" "example-1" {
+resource "github_repository" "example_1" {
name = "example-1"
}

resource "github_branch" "example" {
-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
+ github_repository.example_1
- 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:
Expand All @@ -76,6 +153,11 @@ moved {
from = github_repository.example-1
to = github_repository.example_1
}

moved {
from = module.example-3
to = module.example_3
}
```

### Pass *.tf via arguments
Expand Down
4 changes: 2 additions & 2 deletions example/foo/aws_s3_bucket.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
resource "aws_s3_bucket" "example_1" {
resource "aws_s3_bucket" "example-1" {
bucket = "test-1"
}

resource "aws_s3_bucket" "example_2" {
resource "aws_s3_bucket" "example-2" {
bucket = "test-2"
}
2 changes: 1 addition & 1 deletion example/foo/module_foo.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module "foo_prod" {
module "foo_production" {
source = "./module"
}
3 changes: 3 additions & 0 deletions example/foo/module_foo.tf.after
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module "foo_prod" {
source = "./module"
}
13 changes: 11 additions & 2 deletions example/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ resource "github_repository" "example-1" {
name = "example-1"
}

resource "github_branch" "example" {
data "github_branch" "example-2" {
repository = github_repository.example-1.name
branch = "example"
depends_on = [
github_repository.example-1
github_repository.example-1,
module.example-3
]
}

module "example-3" {
source = "./foo/module"
}

output "branch_sha" {
value = data.github_branch.example-2.sha
}
13 changes: 11 additions & 2 deletions example/main.tf.after
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ resource "github_repository" "example_1" {
name = "example-1"
}

resource "github_branch" "example" {
data "github_branch" "example_2" {
repository = github_repository.example_1.name
branch = "example"
depends_on = [
github_repository.example_1
github_repository.example_1,
module.example_3
]
}

module "example_3" {
source = "./foo/module"
}

output "branch_sha" {
value = data.github_branch.example_2.sha
}
2 changes: 1 addition & 1 deletion pkg/cli/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func parseFlags(f *Flag) {
f.Args = flag.Args()
}

const help = `tfmv - Rename Terraform resources and modules and generate moved blocks.
const help = `tfmv - Rename Terraform resources, data sources, and modules and generate moved blocks.
https://github.com/suzuki-shunsuke/tfmv

Usage:
Expand Down
39 changes: 31 additions & 8 deletions pkg/controller/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import (
"regexp"
)

const wordResource = "resource"
const (
wordResource = "resource"
wordData = "data"
wordModule = "module"
)

type Block struct {
File string `json:"file"`
Expand All @@ -21,30 +25,49 @@ type Block struct {
NewHCLAddress string `json:"-"`
}

func isResource(blockType string) bool {
return blockType == wordResource
}

func (b *Block) IsResource() bool {
return b.BlockType == wordResource
return isResource(b.BlockType)
}

func hclAddress(blockType, resourceType, name string) string {
if blockType == wordResource {
switch blockType {
case wordResource:
return fmt.Sprintf("resource.%s.%s", resourceType, name)
case wordData:
return fmt.Sprintf("data.%s.%s", resourceType, name)
case wordModule:
return "module." + name
}
return "module." + name
return ""
}

func tfAddress(blockType, resourceType, name string) string {
if blockType == wordResource {
switch blockType {
case wordResource:
return fmt.Sprintf("%s.%s", resourceType, name)
case wordData:
return fmt.Sprintf("data.%s.%s", resourceType, name)
case wordModule:
return "module." + name
}
return "module." + name
return ""
}

func (b *Block) Regstr() string {
// A name must start with a letter or underscore and may contain only letters, digits, underscores, and dashes.
if b.IsResource() {
switch b.BlockType {
case wordResource:
return fmt.Sprintf(`\b%s\.%s\b`, b.ResourceType, b.Name)
case wordData:
return fmt.Sprintf(`\bdata\.%s\.%s\b`, b.ResourceType, b.Name)
case wordModule:
return fmt.Sprintf(`\bmodule\.%s\b`, b.Name)
}
return fmt.Sprintf(`\bmodule\.%s\b`, b.Name)
return ""
}

func (b *Block) SetNewName(newName string) {
Expand Down
1 change: 0 additions & 1 deletion pkg/controller/jsonnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ func SetNativeFunctions(vm *jsonnet.VM) {
"strings.Repeat": strings.Repeat,
"strings.Replace": strings.Replace,
"strings.TrimPrefix": strings.TrimPrefix,
"strings.TrimSpace": strings.TrimSpace, //nolint:staticcheck
"url.Parse": url.Parse,
}
for k, v := range m {
Expand Down
3 changes: 3 additions & 0 deletions pkg/controller/moved_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
)

func (c *Controller) writeMovedBlock(block *Block, dest, movedFile string) error {
if block.BlockType == wordData {
return nil
}
file, err := c.fs.OpenFile(movedFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) //nolint:mnd
if err != nil {
return fmt.Errorf("open a file: %w", err)
Expand Down
9 changes: 7 additions & 2 deletions pkg/controller/parse_tf.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ func parse(src []byte, filePath string, include, exclude *regexp.Regexp) ([]*Blo
return blocks, nil
}

func parseBlock(filePath string, block *hclsyntax.Block, include, exclude *regexp.Regexp) (*Block, error) { //nolint:cyclop
if block.Type != wordResource && block.Type != "module" {
func parseBlock(filePath string, block *hclsyntax.Block, include, exclude *regexp.Regexp) (*Block, error) {
types := map[string]struct{}{
wordResource: {},
wordData: {},
wordModule: {},
}
if _, ok := types[block.Type]; !ok {
return nil, nil //nolint:nilnil
}
b := &Block{
Expand Down
14 changes: 8 additions & 6 deletions pkg/controller/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,14 @@ func (c *Controller) handleFile(logE *logrus.Entry, renamer Renamer, input *Inpu

func (c *Controller) handleBlock(logE *logrus.Entry, editor *Editor, input *Input, block *Block) error {
// generate moved blocks
if input.DryRun {
logE.WithField("moved_file", block.MovedFile).Info("[DRY RUN] generate a moved block")
} else {
logE.WithField("moved_file", block.MovedFile).Info("writing a moved block")
if err := c.writeMovedBlock(block, block.NewName, block.MovedFile); err != nil {
return fmt.Errorf("write a moved block: %w", err)
if block.BlockType != wordData {
if input.DryRun {
logE.WithField("moved_file", block.MovedFile).Info("[DRY RUN] generate a moved block")
} else {
logE.WithField("moved_file", block.MovedFile).Info("writing a moved block")
if err := c.writeMovedBlock(block, block.NewName, block.MovedFile); err != nil {
return fmt.Errorf("write a moved block: %w", err)
}
}
}

Expand Down
Loading