Gem Versions Locking
Gem version locking is handled with bundler, Gemfile
and Gemfile.lock
. The concept is similar to package.json
and package-lock.json
or yarn.lock
in the nodejs world and sort of like requirements.txt
and pyenv
in the python world.
The generated Terraspace project with terraspace new project provides a starter Gemfile
. It looks something like this:
source "https://rubygems.org"
gem "terraspace", '~> 2.2.6'
gem "rspec-terraspace"
gem "terraspace_plugin_aws"
In this example, terraspace itself is pinned by using a version specifier ~>
. This means that when bundle
runs it will use at least version 2.2.6
. Other patch versions above within the minor version are also ok.
- Bundler Docs: Gemfile
You can add and specify additional gem version dependencies if you wish or need to lock down specific versions of gems further. For example, if you want to add tilt
.
source "https://rubygems.org"
gem "terraspace", '~> 2.2.6'
gem "rspec-terraspace"
gem "terraspace_plugin_aws"
# added for more control over the dependencies
gem "tilt", "~> 2.1.0"
And run bundle
again to regenerate the Gemfile.lock
file.
bundle
Check that the gem is pinned to the desired version.
bundle info tilt
You should commit Gemifle.lock,
so others or the pipeline use the exact same dependencies.
Thoughts
Considering adding additional version specifiers in the generated Gemfile
, but there are some trade-offs.
An analogy:
Consider how Terraform itself handles version locking of providers and modules. You can always specify pinned versions of providers like aws, azurerm, or google in your provider.tf
. Where you use the module
keyword to source in a module, you can also specify specific versions to lock the module down. This practice has been repeated often enough that it often goes unquestioned without considering the trade-offs.
Locking versions can provide stability, especially since the speed at which terraform move is quick. At the same time, because terraform moves rapidly, locking versions means you won’t get the latest updates and fixes. In practice, this can also break things and cause the very thing you were trying to prevent: instability.
Because pinned versions are too old, they are not really being tested by the community. So you end up unlocking the versions and updating everything in one big go to fix things. It becomes a mouse-and-cat game of updating versions in hopes of fixing the breakage. To compound matters, this often happens at a non-ideal time. The updates would have of happened more incrementally had the versions been more “free”.
So is it better to leave versions free?
Of course not. As often the answer, it depends. It’s often pragmatic to consider each dependency closely on a case-by-case basis. Currently, the generated Gemfile contains a small list. Additional gem versions may be added as cases are considered.
Update
Terraspace 1.0.0 should resolve gem dependency graph issues. The improvements included:
- Improved the terraspace wrapper generated by the standalone installers. Details and docs here: Standalone Terraspace Wrapper and
Shim. You won’t have to remember to type
bundle exec
. - Removed
terraspace_plugins_*
out of terraspace core. This mitigates gem dependency graph resolution issues. PR Lighter terraspace core - Added a friendly usage message with instructions on how to resolve if the error occurs. PR Shim Message
Terrapace Shim Wrapper
On certain system setups, you may want or need to add a terraspace shim to ensure that bundle exec
gets called early enough. It’s really system-dependent. Details are covered here: Shim Wrapper.