-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
docs: add a v1 to v2 migration guide #1884
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
Merged
+878
−423
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f41c990
docs: add a v1 to v2 migration guide
james00012 0da1ab4
docs: match house style in the v2 migration guide
james00012 9d59d6b
docs: fix errors found in review of the v2 migration guide
james00012 1a521fb
docs: address review on the v2 migration guide
james00012 8148993
docs: rewrap a line that exceeded the 75 column convention
james00012 431bbc5
docs: fix a ragged line left by an earlier edit
james00012 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| --- | ||
| layout: collection-browser-doc | ||
| title: Behavior changes | ||
| category: migrating-to-v2 | ||
| excerpt: >- | ||
| The two v2 changes the compiler will not find for you. Both are in the | ||
| k8s module. | ||
| tags: ["migration", "v2"] | ||
| order: 403 | ||
| nav_title: Documentation | ||
| nav_title_link: /docs/ | ||
| --- | ||
|
|
||
| Everything else in the v2 migration is a compile error. These two are not: | ||
| your code builds and behaves differently. Both are in `k8s`, so skip this | ||
| page if you do not use it, and see the [v2 | ||
| overview]({{site.baseurl}}/docs/migrating-to-v2/overview/) for the rest of | ||
| the migration. | ||
|
|
||
| ## Node addresses prefer `ExternalIP` | ||
|
|
||
| `k8s.FindNodeHostnameContextE`, and `GetServiceEndpointContextE` for a | ||
| NodePort service, now return the `ExternalIP` recorded on the Node object | ||
| when one is present. They fall back to the internal hostname exactly as | ||
| before when it is not. | ||
|
|
||
| Cloud controller managers record an instance's public IP as an | ||
| `ExternalIP`. Terratest previously ignored that field and, on AWS, called | ||
| `ec2:DescribeInstances` to find the public IP instead. Reading the Node | ||
| object is the same answer without the API call, so: | ||
|
|
||
| - `ec2:DescribeInstances` is no longer needed for this path | ||
| - `k8s` no longer depends on the `aws` module, which removes 22 AWS service | ||
| clients from its dependency graph | ||
|
|
||
| **What to check.** If your cluster advertises an `ExternalIP` and your test | ||
| previously received an internal hostname, it now receives the external | ||
| address. That is the documented behavior and almost certainly what you | ||
| wanted, but it is a different string. Tests that assert on the endpoint | ||
| value, or that rely on reaching the node over its internal address, are the | ||
| ones to look at. | ||
|
|
||
| Signatures are unchanged. The `ExternalIP` preference applies to every | ||
| provider. For AWS-backed nodes that advertise no `ExternalIP`, a new pair of | ||
| functions takes `*KubectlOptions` and consults | ||
| a lookup you provide: | ||
|
|
||
| ```go | ||
| options := k8s.NewKubectlOptions("", kubeconfig, "default") | ||
| options.NodePublicIPLookup = aws.GetPublicIpsOfEc2InstancesContextE | ||
|
|
||
| hostname, err := k8s.FindNodeHostnameWithOptionsContextE(t, ctx, options, node) | ||
| ``` | ||
|
|
||
| `NodePublicIPLookup` is only consulted after the Node's own `ExternalIP` | ||
| has been checked, so most callers can leave it nil. | ||
|
|
||
| ## `KubectlOptions` carrying a `RestConfig` cannot be saved | ||
|
|
||
| `json.Marshal` of a `KubectlOptions` built by | ||
| `NewKubectlOptionsWithRestConfig` now fails with an error wrapping | ||
| `k8s.ErrRestConfigNotSerializable`. Match it with `errors.Is`, not `==`: | ||
| `encoding/json` returns a `*json.MarshalerError` around it. This affects | ||
| `k8s.SaveKubectlOptions`, `teststructure.SaveTestData`, and any code of | ||
| your own that marshals options. | ||
|
|
||
| This already failed in v1, with an opaque `json: unsupported type: | ||
| transport.WrapperFunc`, because `rest.Config` holds func-typed fields that | ||
| `encoding/json` rejects. What changed is that the error now says what is | ||
| wrong and what to do instead. | ||
|
|
||
| It is deliberately an error rather than silently dropping the config. | ||
| Dropped, the reloaded options would carry no cluster identity at all, fall | ||
| back to the ambient kubeconfig, and run your test against a different | ||
| cluster. | ||
|
|
||
| **What to do.** For staged tests, build options from a kubeconfig path or | ||
| from in-cluster auth. Both round trip: | ||
|
|
||
| ```go | ||
| options := k8s.NewKubectlOptions(contextName, configPath, namespace) | ||
| // or | ||
| options := k8s.NewKubectlOptionsWithInClusterAuth() | ||
| ``` | ||
|
|
||
| If you need a `rest.Config` at runtime, keep building one, but rebuild it | ||
| in each stage rather than saving it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| --- | ||
| layout: collection-browser-doc | ||
| title: Import map | ||
| category: migrating-to-v2 | ||
| excerpt: >- | ||
| Every v1 import path and what it becomes in v2. | ||
| tags: ["migration", "v2"] | ||
| order: 402 | ||
| nav_title: Documentation | ||
| nav_title_link: /docs/ | ||
| --- | ||
|
|
||
| The complete v1 to v2 path mapping. See [rewriting | ||
| imports]({{site.baseurl}}/docs/migrating-to-v2/rewriting-imports/) for how | ||
| to apply it in bulk. | ||
|
|
||
| ## Collapsed into `core` | ||
|
|
||
| Six utility packages became subpackages of one module. The package | ||
| identifier at call sites is unchanged. | ||
|
|
||
| | v1 | v2 | | ||
| |---|---| | ||
| | `modules/random` | `modules/core/v2/random` | | ||
| | `modules/files` | `modules/core/v2/files` | | ||
| | `modules/logger` | `modules/core/v2/logger` | | ||
| | `modules/shell` | `modules/core/v2/shell` | | ||
| | `modules/retry` | `modules/core/v2/retry` | | ||
| | `modules/testing` | `modules/core/v2/testing` | | ||
|
|
||
| `modules/logger/parser` becomes `modules/core/v2/logger/parser`. | ||
|
|
||
| `modules/core/v2/formatting` is new in v2 and has no v1 equivalent to | ||
| migrate: it was `internal/lib/formatting`, which was never importable. | ||
|
|
||
| ## Renamed | ||
|
|
||
| Path *and* package identifier change. | ||
|
|
||
| | v1 | v2 | | ||
| |---|---| | ||
| | `modules/http-helper`, `http_helper.X` | `modules/httphelper/v2`, `httphelper.X` | | ||
| | `modules/dns-helper`, `dns_helper.X` | `modules/dnshelper/v2`, `dnshelper.X` | | ||
| | `modules/test-structure`, `test_structure.X` | `modules/teststructure/v2`, `teststructure.X` | | ||
|
|
||
| ## Suffix only | ||
|
|
||
| Path gains `/v2`; package identifier unchanged. | ||
|
|
||
| | v1 | v2 | | ||
| |---|---| | ||
| | `modules/aws` | `modules/aws/v2` | | ||
| | `modules/azure` | `modules/azure/v2` | | ||
| | `modules/gcp` | `modules/gcp/v2` | | ||
| | `modules/k8s` | `modules/k8s/v2` | | ||
| | `modules/helm` | `modules/helm/v2` | | ||
| | `modules/ssh` | `modules/ssh/v2` | | ||
| | `modules/docker` | `modules/docker/v2` | | ||
| | `modules/packer` | `modules/packer/v2` | | ||
| | `modules/database` | `modules/database/v2` | | ||
| | `modules/opa` | `modules/opa/v2` | | ||
| | `modules/terraform` | `modules/terraform/v2` | | ||
| | `modules/terragrunt` | `modules/terragrunt/v2` | | ||
|
|
||
| ## Removed | ||
|
|
||
| | v1 | Replacement | | ||
| |---|---| | ||
| | `modules/collections` | stdlib `slices` | | ||
| | `modules/environment` | stdlib `os.Getenv` | | ||
| | `modules/git` | stdlib `os/exec` | | ||
| | `modules/slack` | none; vendor from v1 if needed | | ||
| | `modules/version-checker` | none; shell out | | ||
| | `modules/oci` | none; Oracle Cloud is not carried forward to v2 | | ||
| | `cmd/pick-instance-type` | none | | ||
| | `cmd/terratest_log_parser` | none as a binary; the library survives at `modules/core/v2/logger/parser` | | ||
|
|
||
| These were deprecated in v1 first and deleted at the v2 cutover. If you | ||
| depend on `slack`, `version-checker` or `oci`, v1 stays available and is | ||
| the place to stay. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| --- | ||
| layout: collection-browser-doc | ||
| title: v2 overview | ||
| category: migrating-to-v2 | ||
| excerpt: >- | ||
| What changes when you move from Terratest v1 to v2, and the order to do | ||
| it in. | ||
| tags: ["migration", "v2"] | ||
| order: 400 | ||
| nav_title: Documentation | ||
| nav_title_link: /docs/ | ||
| --- | ||
|
|
||
| Terratest v2 splits the single `github.com/gruntwork-io/terratest` module | ||
| into 16 independent modules, so you depend only on the parts you use. A | ||
| test that imports `terraform` no longer pulls in the AWS SDK, client-go, | ||
| and every other provider's dependencies. | ||
|
|
||
| The cost is that every import path changes. This page tells you what the | ||
| changes are and the order to apply them; the per-topic pages hold the | ||
| details. | ||
|
|
||
| ## Should you migrate yet | ||
|
|
||
| v2 is in beta. v1 is in maintenance and receives security fixes only, until | ||
| 12 months after v2.0.0 reaches general availability. Migrate now if you want | ||
| the smaller dependency graph or are starting fresh; wait for v2.0.0 if you | ||
| would rather not track beta releases. | ||
|
|
||
| You can migrate incrementally. v1 and v2 import paths differ, so both can | ||
| coexist in one module while you convert package by package. The change | ||
| touches only `.go` files, `go.mod` and `go.sum`, so `git checkout` undoes | ||
| it. | ||
|
|
||
| The minimum Go version is unchanged. | ||
|
|
||
| ## The five changes | ||
|
|
||
| **1. Everything v1 deprecated is gone.** v1 kept deprecated aliases | ||
| alongside their replacements; v2 deletes them. This is the largest edit in | ||
| the migration, and it is not only the `Context` variants: | ||
|
|
||
| - non-`Context` wrappers: `terraform.Apply` is now only `ApplyContext` | ||
| - initialism renames: `random.UniqueId` is now `UniqueID`, | ||
| `aws.GetAccountIdE` is now `GetAccountIDContextE` | ||
| - reshaped helpers: `packer.BuildAmi` is now `BuildArtifactContextE` | ||
|
|
||
| The reliable way to find all of it is to run staticcheck against your | ||
| existing v1 code and clear every SA1019 (deprecated symbol) warning before | ||
| you touch imports. Once v1 is warning-free, the rest of this guide applies. | ||
|
|
||
| ```go | ||
| // v1 | ||
| out := terraform.Apply(t, options) | ||
| // v2 | ||
| out := terraform.ApplyContext(t, t.Context(), options) | ||
| ``` | ||
|
|
||
| The `Context` variants always take `(t, ctx, ...originalArgs)`. | ||
| `t.Context()` is the best default; `context.Background()` also works. The | ||
| [v1 guide]({{site.baseurl}}/docs/migrating-to-v1/overview/) covers this | ||
| migration in detail, and doing it on v1 first, where both forms still | ||
| compile, is easier than doing it at the same time as the import rewrite. | ||
|
|
||
| **2. Import paths gain a `/v2` suffix.** The `/v2` goes after the module | ||
| root, not at the end of the path: | ||
|
|
||
| ```go | ||
| // v1 | ||
| "github.com/gruntwork-io/terratest/modules/terraform" | ||
| // v2 | ||
| "github.com/gruntwork-io/terratest/modules/terraform/v2" | ||
| ``` | ||
|
|
||
| **3. Six utility packages collapse into `core`.** `random`, `files`, | ||
| `logger`, `shell`, `retry` and `testing` are no longer separate packages: | ||
|
|
||
| ```go | ||
| // v1 | ||
| "github.com/gruntwork-io/terratest/modules/random" | ||
| // v2 | ||
| "github.com/gruntwork-io/terratest/modules/core/v2/random" | ||
| ``` | ||
|
|
||
| **4. Three packages are renamed to drop the hyphen.** This changes the | ||
| package identifier at call sites, not just the import path: | ||
|
|
||
| `http-helper` becomes `httphelper`, `dns-helper` becomes `dnshelper`, and | ||
| `test-structure` becomes `teststructure`. The full table is in the [import | ||
| map]({{site.baseurl}}/docs/migrating-to-v2/import-map/#renamed). | ||
|
|
||
| **5. Each module needs its own `require`.** Where v1 was one line in | ||
| `go.mod`, v2 needs one per module you import. Add them with `go get` | ||
| rather than by hand: | ||
|
|
||
| ```bash | ||
| go get github.com/gruntwork-io/terratest/modules/terraform/v2@v2.0.0-beta.2 | ||
| go get github.com/gruntwork-io/terratest/modules/aws/v2@v2.0.0-beta.2 | ||
| ``` | ||
|
|
||
| Each module is tagged `modules/<name>/vX.Y.Z`, so the tag for the command | ||
| above is `modules/terraform/v2.0.0-beta.2`. The current version is on the | ||
| [releases page](https://github.com/gruntwork-io/terratest/releases). All 16 | ||
| modules are released together and their cross-module requires are pinned to | ||
| the release version, so keep them on the same version. | ||
|
|
||
| The full path mapping is in [the import | ||
| map]({{site.baseurl}}/docs/migrating-to-v2/import-map/). | ||
|
|
||
| ## Order to do it in | ||
|
|
||
| 1. Move to the `Context` variants, ideally while still on v1 so both forms | ||
| compile. | ||
| 2. Rewrite import paths and package identifiers. This is mechanical and the | ||
| compiler finds everything. | ||
| 3. Fix the symbol relocations. Also compile errors, also mechanical. They | ||
| are listed under [rewriting | ||
| imports]({{site.baseurl}}/docs/migrating-to-v2/rewriting-imports/). | ||
| 4. Add a `require` per module, then `go mod tidy`. | ||
| 5. Review the [behavior | ||
| changes]({{site.baseurl}}/docs/migrating-to-v2/behavior-changes/), which | ||
| the compiler will *not* find for you. There are two, both in `k8s`. | ||
|
|
||
| Steps 1 to 4 are compiler-detectable, so the build tells you when they are | ||
| complete. Step 5 is not: the code compiles either way, so it needs reading | ||
| before you call the migration done. | ||
|
|
||
| ## Removed packages | ||
|
|
||
| Six packages and two binaries are not carried forward. Three have a | ||
| standard library replacement: | ||
|
|
||
| | v1 | Replacement | | ||
| |---|---| | ||
| | `modules/collections` | stdlib `slices` | | ||
| | `modules/environment` | stdlib `os.Getenv` | | ||
| | `modules/git` | stdlib `os/exec` | | ||
| | `modules/slack` | none; vendor from v1 | | ||
| | `modules/version-checker` | none; shell out | | ||
| | `modules/oci` | none; Oracle Cloud is not carried forward, stay on v1 | | ||
|
|
||
| `cmd/pick-instance-type` and `cmd/terratest_log_parser` are gone as | ||
| binaries. The log parser's library survives at | ||
| `modules/core/v2/logger/parser`. | ||
|
|
||
| ## What did not change | ||
|
|
||
| The `Foo` / `FooE` convention is unchanged: `FooContext` fails the test, | ||
| `FooContextE` returns an error. Beyond dropping the non-`Context` wrappers | ||
| and the relocations above, function arguments and return types are the | ||
| same. Test data written by v1 loads in v2, since filenames and JSON layout | ||
| are unchanged. | ||
|
|
||
| ## Need help | ||
|
|
||
| Open an issue on the [Terratest | ||
| repo](https://github.com/gruntwork-io/terratest/issues) with the version | ||
| you are coming from and the error you hit. If you spot a gap in this | ||
| guide, send a PR against `docs/_docs/04_migrating-to-v2/`. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.