Skip to content

OpenTofu

Config

Env vars:

Component Env var
Access Gitlab remote state

Usage

tofu apply -auto-approve

Debug:

OS_DEBUG=1 TF_LOG=DEBUG  apply

updating provider versions

find . -name versions.tf -exec sed -i 's/1.22.3/1.22.7/' {} \;

Import

Import a resource when a provider upgrade would force a resource recreation:

tf state show module.ricote.libvirt_pool.default  # note the `id`
tf state rm module.ricote.libvirt_pool.default
tofu import module.ricote.libvirt_pool.default 09f0dc94-5984-4330-b1fe-f150050643d1

Add provider versions to each submodule

git grep -l gitlabhq/gitlab | xargs -n 1 sed -i '/"gitlabhq\/gitlab"/a \      version = "16.3.0"'

Initialize all

Sequential:

find . -type d -name .terraform -exec tofu -chdir={}/.. init -upgrade \;

Parallel:

find . -type d -name .terraform -print0 | parallel -0 tofu -chdir={}/.. init -upgrade

or

for i in infrastructure infrastructure/* global environments/*/* kubernetes kubernetes/* ;\
  do echo $i; tofu init -upgrade $i; done

Remove all .terraform dirs

find . -type f -name .terraform.lock.hcl -exec rm {} \; && find . -type d -name .terraform -exec rm -rf {} \;

Tofu state

tf state list
tf state show 'google_compute_instance.legacy_vm["ofts105-3"]'

Remove provider definitions from modules

When you have provider configuration in modules and want to remove them you will get an error similar to this:

The module at module.folder_platform is a legacy module which contains its own local provider configurations, and so calls to it may not use the count, for_each, enabled or depends_on arguments. If you also control the module "./modules/folder", consider updating this module to instead expect provider configurations to be passed by its caller.

How to fix this with a remote state backend:

  • First of all create a backup of the current state:
tf state pull | jq > .terraform/terraform.tfstate.backup

Then change the provider definition in main.tf to point to a different, new state name (i.e. fix-providers) and copy the current state to the new state:

tf init -migrate-state  # Yes, copy the state

Change the obsolete module provider definitions:

cp .terraform/terraform.tfstate.backup /tmp/tf-state.json
grep provider /tmp/tf-state.json
sed -i 's/module.*provider/provider/' /tmp/tf-state.json
jq . < /tmp/tf-state.json  # check for valid json

Increment the serial in the state and upload the new state:

tf state push /tmp/tf-state.json
  • Ensure everything is working fine.
  • Change the remote state name to the old one
  • Remove the remote state (you made a backup earlier)
  • Push the new state to the old location:
tf state push /tmp/tf-state.json

Style

Vim integration

Gitblab CI & terraform