Steps
1. Check existing terraform version
1 | terraform -v |
2. Upgrade to Terraform 0.11 first (if applicable)
If the current version is not 0.11
then upgrade it to 0.11.14
first. If you are on 0.11.x, please make sure you are on 0.11.14.
3. Pre-upgrade Checklist
Terraform v0.11.14
introduced a temporary helper command terraform 0.12checklist
, which analyses the configuration to detect any required steps that will be easier to perform before upgrading.
4. Initialisation in 0.11
1 | terraform init |
5. Plan
and make sure no errors are shown
1 | terraform plan |
6. Apply
to ensure that your real infrastructure and Terraform state are consistent with the current configuration.
1 | terraform apply |
7. Do the checklist
check
to see if there are any pre-upgrade steps in the checklist
1 | terraform 0.12checklist |
8. Resolve suggestions from checklist
Depending upon the suggestions above, take the steps & change the tf scripts.
If you are using templates, then you need to update the template provider as well.
Run above command until there are no suggestions.
9. Switch to terraform 0.12
Switch to terraform 0.12 (choose one of the following methods, ranked in order of recommendation)
Using tfswitch (recommend) / tfenv to switch to 0.12
Using docker-terraform
Unpin the old 0.11 version (if applicable) and upgrade to Terraform 0.12:
brew upgrade terraform
10. Initialisation in 0.12
For those repos that ref terraform-modules, need to:
Make sure use git module to refer terraform-modules:
e.g.
1
source = "git@github.com:{user}/terraform-modules.git//{module_name}?ref={branch_name}"
replace branch name to refer testing branch in
terraform-modules
(if applicable)update
.gitmodules
first to use testing branch:e.g.
1
2
3
4
5
6
7
8
9cat .gitmodules
[submodule "common/modules"]
path = common/modules
url = git@github.com:{user}/terraform-modules.git
branch = {branch_name}
Then run command to update submodules:
1 | git submodule update --recursive --remote |
P.S.
Re-running init with modules already installed will install the sources for any modules that were added to configuration since the last init, but will not change any already-installed modules.
Use
-upgrade
to override this behavior, updating all modules to the latest available source code..So use this command when there’re changes from terraform-modules:
1 | terraform init -upgrade |
11. Check for errors
1 | terraform validate |
12. Auto update the code
with below command. Terraform v0.12 includes a new command terraform 0.12upgrade
that will read the configuration files for a module written for Terraform 0.11 and update them in-place to use the cleaner Terraform 0.12 syntax and also adjust for use of features that have changed behaviour in the 0.12 Terraform language.
1 | terraform 0.12upgrade |
12.1. Symlink
If there is a symlink under the directory, the directory of the actual file pointed by the symlink needs to be upgraded in the last, to avoid the situation where 0.11/0.12 codes coexist. This will terminate the execution of the 0.12upgrade
command.
And also need to delete symlink first, before running 0.12upgrade
, then restore the symlink files.
The logic for each directory would be something like this:
e.g.
1 |
|
12.2. Error on batch upgrade
According to the official doc, run the following command for batch upgrade:
1 | gfind . -name '*.tf' -printf "%h\n" | sort | uniq | xargs -n1 terraform init |
but got bunch of errors:
1 | Error: error resolving providers: |
Turned out the init command will overwrite the .terraform/plugins
dir each time:
e.g.
First init module ./A
:
1 | ls -rthl .terraform/plugins/darwin_amd64/ |
Then init module ./B
:
1 | ls -rthl .terraform/plugins/darwin_amd64/ |
So need to create script to process each directory one by one (first init
then upgrade
) instead of using xargs
for batch upgrade.
13. Fix syntax issues
Might need to manual fix syntax issues (that can not be auto-upgraded):
- Invalid expression value: number required
1 | Error: Incorrect value type |
Use a conditional expression to select the count based on the variable:
1 | count = var.enable_iam_db_auth ? 1 : 0 |
- Incorrect attribute value type
1 | Error: Incorrect attribute value type |
Referring to https://www.terraform.io/upgrade-guides/0-12.html#referring-to-list-variables
The solution is just remove the redundant list brackets
or add a flatten
function.
- Unsupported attribute for lifecycle/ignore_changes
1 | Error: Unsupported attribute |
Ref: https://www.terraform.io/docs/configuration/resources.html#lifecycle-lifecycle-customizations
ignore_changes
can only support list of attribute names, but image
is the sub-attribute name for container_definitions
- Deperacated condition for lb_listener_rule
1 | Warning: "condition.0.values": [DEPRECATED] use 'host_header' or 'path_pattern' attribute instead |
Just need to switch the format as follows:
From:
1 | condition { |
To:
1 | condition { |
From:
1 | condition { |
To:
1 | condition { |
This was a change introduced in terraform-providers/terraform-provider-aws#8268, which was released in AWS Provider 2.42.0.
Ref: https://github.com/brikis98/terraform-up-and-running-code/issues/43#issuecomment-569441777
Doc: https://www.terraform.io/docs/providers/aws/r/lb_listener_rule.html
- After fix
After fix syntax issues in terraform-modules, need to update modules and re-run init / upgrade when necessary:
1 | # git update submodules |
14. Plan
1 | terraform plan |
Be aware of using correct aws role to execute plan / apply for different directories.
And might also need to fix syntax errors manually for those files can not be upgraded automatically (e.g. templates)
15. Apply
1 | terraform apply |
16.Post Actions
IDE support (VSCode)
When using vscode extension for Terraform (v1.x
), it might show syntax error as follow:
1 | Unknown token: 2:26 IDENT var.cidr |
Need to add the following configs in VSCode settings.json
to enable support for terraform 0.12
1 | "terraform.languageServer": { |
Unfortunately after installing the latest VSCdoe extension (e.g. 2.0.1
- which officially support Terraform 0.12) it seems NOT working properly.
Found bunch of errors:
- Workspace not initialized
- Nothing works after update to 2.x
- “Server return 404” when trying to install an old version
The old version 1.40 used to work, so the workaround:
- Remove 2.0.1 extension from VS Code
Download 1.4.0 of the vsix from here - Manually install it:
code --install-extension mauve.terraform-v1.4.0.vsix
- Restart VS Code
- When prompted install language server, choose:
v.0.0.11-beta2
- If no prompt can install manually:
⇧⌘P
, then typeTerraform: Enable/Disable Language Server
and installv.0.0.11-beta2
Reference
- Upgrade Guilds
- Useful 0.12 code examples
- Terraform v0.12 - Syntax check broken: Unknown token IDENT
- Fix syntax issues
- syntax issue while upgrading from 11 to 12
- map var no longer merge when overriden
- refering to list var