Add migration instructions from Terraform v0.11 to v0.12

* Provide Terraform v0.11 to v0.12 migration guide. Show an
in-place strategy and a move resources strategy
* Describe in-place modifying an existing cluster and providers,
using the Terraform helper to edit syntax, and checking the
plan produces a zero diff
* Describe replacing existing clusters by creating a new config
directory for use with Terraform v0.12 only and moving resources
one by one
* Provide some limited advise on migrating non-Typhoon resources
This commit is contained in:
Dalton Hubble 2019-05-31 00:27:25 -07:00
parent db36959178
commit 3276bf5878
2 changed files with 160 additions and 1 deletions

View File

@ -5,7 +5,8 @@ Notable changes between versions.
## Latest
* Migrate from Terraform v0.11 to v0.12.x (**action required!**)
* Require `terraform-provider-ct` v0.3.2+ to support Terraform v0.12 (action required)
* [Migration](https://typhoon.psdn.io/topics/maintenance/#terraform-v012x) instructions for Terraform v0.12
* Require `terraform-provider-ct` v0.3.2+ to support Terraform v0.12 (action required)
#### AWS

View File

@ -271,3 +271,161 @@ Expect downtime.
Google Cloud creates a new worker template and edits the worker instance group instantly. Manually terminate workers and replacement workers will use the user-data.
## Terraform v0.12.x
Terraform [v0.12](https://www.hashicorp.com/blog/announcing-terraform-0-12) introduces major changes to the provider plugin protocol and HCL language (first-class expressions, formal list and map types, nullable variables, variable constraints, and short-circuting ternary operators).
Typhoon modules have been adapted for Terraform v0.12. Provider plugins requirements now enforce v0.12 compatibility. However, some HCL language changes were breaking. List [type hint](https://www.terraform.io/upgrade-guides/0-12.html#referring-to-list-variables) workarounds in v0.11 now have new meaning. We cannot offer both v0.11 and v0.12 compatibility at the same time. Upgrading Terraform to v0.12 is neccessary.
| Typhoon Release | Terraform version |
|-------------------|---------------------|
| v1.14.4 - ? | v0.12.x |
| v1.10.3 - v1.14.3 | v0.11.x |
| v1.9.2 - v1.10.2 | v0.10.4+ or v0.11.x |
| v1.7.3 - v1.9.1 | v0.10.x |
| v1.6.4 - v1.7.2 | v0.9.x |
### New users
New users can start with Terraform v0.12.x and follow the docs for Typhoon v1.14.4+ without issue.
### Existing users
Migrate from Terraform v0.11 to v0.12 either **in-place** (easier, riskier) or by **moving resources** (safer, tedious).
Install [Terraform](https://www.terraform.io/downloads.html) v0.12.x on your system alongside Terraform v0.11.x.
```shell
sudo ln -sf ~/Downloads/terraform-0.12.0/terraform /usr/local/bin/terraform12
```
!!! note
For example, `terraform` may refer Terraform v0.11.14, while `terraform12` is symlinked to Terraform v0.12.0. Once migration is complete, Terraform v0.11.x can be deleted and `terraform12` renamed.
#### In-place
For existing Typhoon v1.14.2 or v1.14.3 clusters, edit the Typhoon `ref` to the first SHA that introduced Terraform v0.12 support (aim is to minimize the diff). For example:
```tf
module "bare-metal-mercury" {
- source = "git::https://github.com/poseidon/typhoon//bare-metal/container-linux/kubernetes?ref=v1.14.3"
+ source = "git::https://github.com/poseidon/typhoon//bare-metal/container-linux/kubernetes?ref=v1.14.4"
...
```
Typhoon clusters no longer require the `providers` block (unless you actually need to pass an [aliased provider](https://www.terraform.io/docs/configuration/providers.html#alias-multiple-provider-instances)). A regression in Terraform v0.11 made it neccessary to explicitly pass aliased providers in order for Typhoon to continue to enforce constraints (see [terraform#16824](https://github.com/hashicorp/terraform/issues/16824)). Terraform v0.12 resolves this issue.
```tf
module "bare-metal-mercury" {
source = "git::https://github.com/poseidon/typhoon//bare-metal/container-linux/kubernetes?ref=v1.14.4"
- providers = {
- local = "local.default"
- null = "null.default"
- template = "template.default"
- tls = "tls.default"
- }
```
Provider constrains ensure suitable plugin versions are used. Install new versions of `terraform-provider-ct` and `terraform-provider-matchbox` (bare-metal only) according to tutorial docs. Remove the now uneccessary `local`, `null`, `template`, and `tls` blocks in `providers.tf`.
```tf
provider "matchbox" {
- version = "0.2.3"
+ version = "0.3.0"
endpoint = "matchbox.example.com:8081"
client_cert = "${file("~/.config/matchbox/client.crt")}"
client_key = "${file("~/.config/matchbox/client.key")}"
}
provider "ct" {
- version = "0.3.2"
+ version = "0.3.3"
}
-
-provider "local" {
- version = "~> 1.0"
- alias = "default"
-}
-
-provider "null" {
- version = "~> 1.0"
- alias = "default"
-}
-
-provider "template" {
- version = "~> 1.0"
- alias = "default"
-}
-
-provider "tls" {
- version = "~> 1.0"
- alias = "default"
-}
```
Within the Terraform config directory (i.e. working directory), initialize to fetch suitable provider plugins.
```shell
terraform12 init # using Terraform v0.12 binary, not v0.11
```
Use the Terraform v0.12 upgrade subcommand to convert v0.11 syntax to v0.12. This _will_ edit resource definitions in `*.tf` files in the working directory. Start from a clean version control state. Inspect the changes. Resolve any "TODO" items.
```shell
terraform12 0.12upgrade
git diff
```
Finally, plan.
```shell
terraform12 plan
```
Verify no changes are proposed and commit changes to version control. You've migrated to Terraform v0.12! Use the Terraform v0.12 binary going forward.
!!! note
It is known that plan may propose re-creating `template_dir` resources. This is harmless.
!!! error
If plan produced errors, seek to address them (they may be in non-Typhoon resources). If plan proposed a diff, you'll need to evaluate whether that's expected and safe to apply. In-place edits between Typhoon releases aren't supported (favoring blue/green replacement). The larger the version skew, the greater the risk. Use good judgement. If in doubt, abandon the generated changes, delete `.terraform` as [suggested](https://www.terraform.io/upgrade-guides/0-12.html#upgrading-to-terraform-0-12), and try the move resources approach.
#### Moving Resources
Alternately, continue maintaining existing clusters using Terraform v0.11.x and existing Terraform configuration directory(ies). Create new Terraform directory(ies) and move resources there to be managed with Terraform v0.12. This approach allows resources to be migrated incrementally and ensures existing resources can always be managed (e.g. emergency patches).
Create a new Terraform [config directory](/architecture/concepts#organize) for *new* resources.
```shell
mkdir infra2
tree .
├── infraA <- existing Terraform v0.11.x configs
└── infraB <- new Terraform v0.12.x configs
```
Define Typhoon clusters in the new config directory using Terraform v0.12 syntax. Follow the Typhoon v1.14.4+ docs (e.g. use `terraform12` in the `infraB` dir). See [AWS](/cl/aws), [Azure](/cl/azure), [Bare-Metal](/cl/bare-metal), [Digital Ocean](/cl/digital-ocean), or [Google-Cloud](/cl/google-cloud)) to create new clusters. Follow the usual [upgrade](/topics/maintenance/#upgrades) process to apply workloads and shift traffic. Later, switch back to the old config directory and deprovision clusters with Terraform v0.11.
```shell
terraform12 init
terraform12 plan
terraform12 apply
```
Your Terraform configuration directory likely defines resources other than just Typhoon modules (e.g. application DNS records, firewall rules, etc.). While such migrations are outside Typhoon's scope, you'll probably want to move existing resource definitions into your new Terraform configuration directory. Use Terraform v0.12 to import the resource into the state associated with the new config directory (to avoid trying to recreate a resource that exists). Then with Terraform v0.11 in the old directory, remove the resource from the state (to avoid trying to delete the resource). Verify neither `plan` produces a diff.
```sh
# move google_dns_record_set.some-app from infraA to infraB
cd infraA
terraform state list
terraform state show google_dns_record_set.some-app
cd ../infraB
terraform12 import google_dns_record_set.some-app SOMEID
terraform12 plan
cd ../infraA
terraform state rm google_dns_record_set.some-app
terraform plan
```