Terraform Upgrade to 0.13 in Production

Hey folks! I recently made the time to upgrade all of my make Terraform code to work with version 0.13, exhausted a few months back. The endeavor compelled was much less than expected, largely thanks to using DRY, modular system that is applied apply continuous integration within GitLab. However, there is indeed numerous” ah ha !” minutes encountered. I’m always learning how to write better infrastructure as code but am far from perfect!

In this affix, I handle the key milestones and takeaways encountered during the upgrade process to Terraform version 0.13. Keep in recollection that this is just my experience and opinions on the matter. I start with remote mood, the 0.13 refurbish bid, tool copies, and addiction planning. From there, I conclude with stopping the code stateless, the migration of production, and a few bonus components. Let’s get to it!

Quick Reminder: I livestream on technological topics every week on Twitch– be joining the undertaking! Drop a follow and enable notifications to stay current.

Addressing Remote State

The first( and biggest) clod of exertion came from altogether remaking the backend remote government configuration across all projects. I was initially storing state remotely within the GitLab project itself, along with a few campaigns exploiting Amazon S3 with DynamoDB. This productions fine? But it comes with a load of caveats and” additional things you have to know” “thats been” a fus to cope with across a team.

Below is the old-time technique I was using to handle state. Not fun.

terraform init -reconfigure -backend-config= “address =$ GITLA_BTF_ADDRESS ” -backend-config= “lock_address =$ GITLA_BTF_ADDRESS / lock” -backend-config= “unlock_address =$ GITLA_BTF_ADDRESS / lock” -backend-config= “username =$ GITLA_BUSER_LOGIN ” -backend-config= “password =$ GITLA_BTF_PASSWORD ” -backend-config= “lock_method =P OST” -backend-config= “unlock_method =D ELETE” -backend-config= “retry_wait_min= 5”

In an effort to keep things simple, I moved all territory files to Terraform Cloud. I talk about setting up each workspace in the Using Terraform to Manage Git Repositories blog post. Instead of guiding along a plethora of backend-config appraises during CI functionings, I precisely plopped this chip of code into each project 😛 TAGEND

Terraform Cloud is great for remote country!

In an nutshell, each Terraform project was given a unique workspace and then state is moved over. I then dedicated the remote position changes to the project.

Merge, my friend, consolidate!

This vastly improved my consumer ordeal while dealing with state documents. This is ultra important- formerly a country document is upgraded to version 0.13, that’s it! The only ” cleanse ” way to go back is to revert the version, which may cause all sorts of other headaches. If you’re brand-new to Terraform state, here is a quick 10 time video I made to cover the basics.

Using the Terraform 0.13 Upgrade Command

Terraform comes with a 0.13 upgrade bidding to help with upgrading code. This assistance in avoiding deprecations and caveats while contributing to brand-new the characteristics and requirements. I make it a habit to use this command in a clean working git branch to easily spot any differences. Make sure to read the upgrade usher!

For example, providers received a fairly significant change in version 0.13. The required_providers code block now requires a path to the source code whereas before it was assumed that all providers came from the Terraform registry or a regional beginning. Using git diff HEAD on the fork( or any other diff tool) exposes the schema alteration after performing an upgrade.

git diff Thought

diff –git a/ code/ tf-cluster-asg/ provider.tf b/ system/ tf-cluster-asg/ provider.tf indicator 22 f1520 .. 00624 db 100644 — a/ system/ tf-cluster-asg/ provider.tf +++ b/ code/ tf-cluster-asg/ provider.tf @@ -1, 6 +1,9 @@


required_providers – aws= “> 2.66 “+ aws=+ generator= “hashicorp/ aws”+ form= “> 2.66 “+

Additionally, the upgrade bidding establishes a versions.tf record to specify the Terraform CLI version required if none exists previously. I contemplated this was handy because I had been controlling the required account within GitLab CI.


required_version= ” >= 0.13 ”

Having an definite call out promotions originate the system more portable across CI implements and increases clarity on my wanted version to the team.

Terraform CLI Upgrade and Explanations

For my own workstation tooling purposes, I stop copies of Terraform 0.12 and 0.13 liberates inside of% APPDATA %\ bucket. This is my ” toolbox” of kinds and allows me to reference a single entering in the Windows environmental PATH system variable previously for variou tools. I store Terraform, Helm, Kubectl, and other goodies in there.

>$ env 😛 ath.Split( ‘; ‘) | findstr “Roaming \ bin”

C :\ Users \ chris \ AppData \ Roaming \ bucket \

Any time Terraform CLI is downloaded it emerges as “terraform.exe”. I rename each forgery with the version multitude, e.g. “terraform1229.exe” for edition 0.12.29. Here’s a look at what’s stored on my dev carton right now 😛 TAGEND

I’m a hoarder

This starts it easy to swap between versions to prototype on version 0.13 while still being able to manage code on explanation 0.12. I detected this helpful when combing through several campaigns as the migration progressed. To improve my user know, profile aliases are used to expose wanted Terraform versions.

New-Alias -Name “tf” -Value “terraform1 304. exe”

New-Alias -Name “tf1 2” -Value “terraform1 229. exe”

I’ve do it a dres to refer to the latest editions as simply tf and tf12 to save on keystrokes.

Fixing Addiction

This felt like a good time to review all of my provider and module addictions and “clean up” any bad wonts. The first place I settled eyeballs on was the provider requirements is presented in both mother and child modules. Considering that I host my own private module repository, it didn’t make a whole lot of appreciation to express provider accounts in both the module storehouse and parent( announcing) code.

Instead, I moved all provider account requirements into the parent code to gain tighter control over the copy consumed. Couple this with sprig pinning to find specific iterations of the child module code and I have a fairly simple method for ensuring the right version of system is used in the right places and clouds.

I also reviewed precisely which downstream providers I was eating and how they were being pinned. For example, much of my older AWS code was configured with bleak conditional hustlers is under an obligation to 2.66, a reasonably aged edition 😛 TAGEND




root= “hashicorp/ aws”

copy= ” ~> 2.66 ”

This seemed like a great time to try out new major copies and to start tracking which providers are being used for which code bases. I’ve commence exerting a staggered liberate meter in which dev abuses something a bit more akin to bleeding edge are responsible for ensuring that push will not self-destruct during the next exercise. This was again aided by using specific private modules with branch pinning configured together with a” blue/ lettuce” mode deployment for pretty much everything that goes into AWS, Azure, and GCP.

Stateless Avoids Headaches

In a small number of cases, I found that a. terraform folder was hiding apart in the source git repositories. This is no good! In the pattern below, the modules.json file had snuck in and was being updated from my neighbourhood workstation.


I try hard to avoid carrying the ” belonging” of anything persisting in the. terraform folder. Instead, I prefer to let GitLab CI load all of the needed providers, modules, and backend items at runtime upon a clean slate.

The culprit was a misconfigured. gitignore register. I think this is something I wrote a very long time ago, before I genuinely understand what happens in the. terraform folder with CI, and was carried forward via emulate/ adhesive enterprises. Oops!

Changing the filter from **/. terraform/ plugins /** to **/. terraform /** did the trick.

Set filters to maximum power

With a proper filter in place, I only needed to go back and hunt down any stragglers and being withdrawn from the clean-living working git branch.

Migration of Production

Once I had addressed country, dependencies,. gitignore filters, and so forth, it was time to start testing the fruits of my strive. I prefer to select a region in each shadow and do a planned deployment of everything defined in code.

Because GitLab CI is doing the effort, the process is repeatable: from standing up identity/ roles and infrastructure to pushing out applications and system business, the part spring is automated. The only difference is the region, which has a few caveats( such as accessible facets ).

For example, my AWS infrastructure code, lovingly identified “site-deploy”, was first tested in us-west-1 as an evacuate region that I only use for testing. I begins with the old-time edition 0.12 system and then modernized it to the newer version 0.13 code. Once the pipeline was fully dark-green, I was able to discern that the process manipulated and could be repeated in other regions with a high level of confidence.

My commit messages are lame

Pushing to production is always a little scary when performing an upgrade. To slake this fear, I constituted sure to accomplish a few cases” terraform schedule” dry run locally to ensure that there were no hidden surprises. Each creation campaign was updated in about 15 hours without anything memorable happening.

The Bonus Round

I nearly forgot! Terraform version 0.13 has a few nice bonus pieces that I snagged for a few cases campaigns. Chiefly, the ability to use iterators such as count on child modules immediately from the mother module. This is handy for propagandizing multiple two copies of an speciman, such as the illustration employment below, with a single order of code.

Count is super handy

In addition to count, there is also support for depends_on and for_each. Snazzy!

Overall, I tackled the amend of 27 campaigns from Terraform version 0.12 to 0.13 in the cavity of about 8 hours. It felt good to address a knot of nagging incompatibilities and newbie motif decisions that I had attained in the past.

I hope your upgrade leads super smoothly and you get to enjoy all that the new copy has in store!

Next Steps

Please accept a crispy high five for reaching this point in the upright!

If you’d like to learn more about Infrastructure as Code, or other modern technology comings, thought over to the Guided Learning page.

If there’s anything I missed, please reach out to me on Twitter or catch my next Twitch live series. Cheers!

Read more: feedproxy.google.com