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

Generate imports using multiple resource addresses #18

Merged
merged 3 commits into from
May 7, 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: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
run: make build

- name: Lint
uses: golangci/golangci-lint-action@v4
uses: golangci/golangci-lint-action@v6
with:
version: latest

Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ import {
}
```

### Generating import statements by multiple resource

```bash
$ terraform show -json | tf-import-gen aws_instance.example module.example

import {
to = aws_instance.example
id = "i-123456789012"
}

import {
to = module.example.aws_glue_catalog_database.example_db
id = "123456789012:example_db"
}

import {
to = module.example.aws_iam_instance_profile.example_instance_profile
id = "example_instance_profile"
}
```

### Generating import statements for all resources

```bash
Expand Down Expand Up @@ -108,7 +129,7 @@ addresses, such as:
module.example.aws_instance.example

Usage:
tf-import-gen [flags] address
tf-import-gen [flags] address...

Examples:

Expand All @@ -118,6 +139,9 @@ terraform show -json | tf-import-gen module.example
## Generating import statements by resource
terraform show -json | tf-import-gen aws_instance.example

## Generating import statements by multiple resources
terraform show -json | tf-import-gen aws_instance.example module.example

## Generating import statements for all resources
terraform show -json | tf-import-gen

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/zclconf/go-cty v1.14.4 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/text v0.15.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8=
github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
5 changes: 4 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var Version = "dev"

func main() {
var rootCmd = &cobra.Command{
Use: "tf-import-gen [flags] address",
Use: "tf-import-gen [flags] address...",
Short: "Generate terraform import statements",
Long: strings.TrimSpace(`
Generate terraform import statements to simplify state migrations from one terraform code base to another.
Expand All @@ -35,6 +35,9 @@ terraform show -json | tf-import-gen module.example
## Generating import statements by resource
terraform show -json | tf-import-gen aws_instance.example

## Generating import statements by multiple resources
terraform show -json | tf-import-gen aws_instance.example module.example

## Generating import statements for all resources
terraform show -json | tf-import-gen
`,
Expand Down
8 changes: 5 additions & 3 deletions pkg/internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ type TerraformResource struct {

type TerraformResources []TerraformResource

func (resources TerraformResources) FilterByAddress(address string) TerraformResources {
func (resources TerraformResources) FilterByAddresses(addresses ...string) TerraformResources {
var filteredResources TerraformResources
for _, resource := range resources {
if strings.HasPrefix(resource.Address, address) {
filteredResources = append(filteredResources, resource)
for _, address := range addresses {
if strings.HasPrefix(resource.Address, address) {
filteredResources = append(filteredResources, resource)
}
}
}
return filteredResources
Expand Down
4 changes: 2 additions & 2 deletions pkg/tfimportgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"io"
)

func GenerateImports(stateJsonReader io.Reader, address string) (TerraformImports, error) {
func GenerateImports(stateJsonReader io.Reader, address ...string) (TerraformImports, error) {
resources, err := parser.NewTerraformStateJsonParser(stateJsonReader).Parse()
if err != nil {
return nil, err
}

resources = resources.FilterByAddress(address)
resources = resources.FilterByAddresses(address...)

var imports TerraformImports
for _, resource := range resources {
Expand Down
45 changes: 45 additions & 0 deletions pkg/tfimportgen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,48 @@ func Test_GenerateImports_ShouldGenerateHelpfulCommentForResourceThatCannotBeImp
}
require.Equal(t, expectedImports, actual)
}

func Test_GenerateImports_ShouldGenerateImportsForResourcesForGivenAddresses(t *testing.T) {
tests := []struct {
name string
address []string
expected tfimportgen.TerraformImports
}{
{
name: "filtering by module",
address: []string{"module.test_mwaa", "aws_glue_catalog_database.test_db"},
expected: tfimportgen.TerraformImports{
{
ResourceAddress: "aws_glue_catalog_database.test_db",
ResourceID: "id_test_db",
SupportsImport: true,
},
{
ResourceAddress: "module.test_mwaa.aws_iam_policy.test_mwaa_permissions",
ResourceID: "id_test_mwaa_permissions",
SupportsImport: true,
},
{
ResourceAddress: "module.test_mwaa.aws_mwaa_environment.test_airflow_env",
ResourceID: "id_test_airflow_env",
SupportsImport: true,
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
stateJsonFile, err := os.Open(filepath.FromSlash("testdata/resources_in_root_and_child_modules.json"))
require.NoError(t, err)
t.Cleanup(func() {
_ = stateJsonFile.Close()
})

actual, err := tfimportgen.GenerateImports(stateJsonFile, tt.address...)

require.NoError(t, err)
require.Equal(t, tt.expected, actual)
})
}
}