InfraSec / Terraform
Overview
Terraform is my tool of choice for automating my ‘cloud infrastructure’. In particular, I expect all but the earliest of prototype AWS resources to be created/deployed using terraform rather than by hand.
Contents
- Semantic Versioning
- Splitting a git repo
- Going public
- Publishing a release
- Updating a module for a new version of Terraform
- Terraform state mv
- How to layout/structure a Terraform Project
- How to test your Terraform code
Semantic Versioning
- When publishing a module for the first time, if you’re uncertain what version to use, use
v1.0.0 - Any changes to a module that don’t result in a resource being recreated, increment the patch version per semantic versioning guidelines.
- Any changes to a module that results in a resource being recreated, increment the minor version per semantic versioning guidelines.
- Any changes to support GovCloud that do not result in changes to resources, increment the minor version per semantic versioning guidelines.
- Any changes that results in a user having to update the module, increment the major version per semantic versioning guidelines.
- Upgrading a module from <0.12 to 0.12, increment the major version per semantic versioning guidelines.
Starting a module experiment
…
Splitting a git repo
I often start out with Terraform code embedded into the infrastructure for a specific project before I decide I want to publish a chunk of it as stand-alone module. When moving code from one git repository to another, it is useful to maintain the revision history. To split a git repository while preserving the history, see this page in the Standard Devz Processes.
Once the Terraform code has been split into a separate repo, you can add the usual trimmings for a Terraform module: README, pre-commit/CircleCI configuration, terratest(s), etc.
Before going public, consider sourcing the module from gitlab as described in the sources documentation to confirm that no changes are planned after the migration.
Going public
When you’re ready to turn the prototype module into a published one, there’s a few things you’ll need to do if you haven’t already:
- 🔒 Add your repo to the list of repos managed by my gitlab repo management module.
- 🔒 Add a subscription to your repo in my #infra-feed channel:
/gitlab subscribe Frontworks/your-repo-here/gitlab unsubscribe Frontworks/your-repo-here statuses commits deployments public releases
- Wire the repo up to the terraform module registry.
- First read through the Terraform docs on Publishing Modules and make appropriate changes to your repository
- Ensure that the module you wish to publish has a SemVer tag attached to it. If not use
v1.0.0. - Sign into the registry using your gitlab credentials
- In the upper right corner select “Publish” or go directly to the Publish URL
- Select the repository you wish to publish from the drop down list. If you don’t see it hit the refresh icon.
- Select the “Publish Module” button.
- Verify on the next screen that everything you expect to see is correct.
Publishing a release
To publish a release from a terraform module that’s already connected to the terraform module registry, all you need to do after your PR merges is:
- From the releases tab, click the “Draft a release” button.
- Add a meaningful description.
- Increment the package version per semantic versioning guidelines.
- Click the “Publish release” button.
You don’t need to add any binary files. gitlab will do this automatically for you.


Updating a module for a new version of Terraform
In order to preserve the ability to release updates for previous Terraform versions, when you update a module to support a new version, you should cut a separate branch I can use to publish updates for the old version. Follow this procedure:
- Compose your PR for the module updating it to the new version of Terraform and get it approved.
- Before you merge, create a branch off the current default branch named after the previous Terraform version (for instance, if the old version is 0.11, create a
terraform011branch) and push it to origin. - Add a note to the README in your PR that describes which major version of the module supports which version of Terraform and which branch to submit a PR to for each (e.g., “For Terraform 0.12, pin the module version to
~> 2.0. Submit pull requests to the default branch. For Terraform 0.11, pin the module version to~> 1.0. Submit pull requests to theterraform011branch.”) - Merge your changes in to the module’s default branch.
- Cut a new release as described above. Increment the major version of the module as you described in the README.
Terraform state mv
Refer to the I terraform state mv info sheet.
How to layout/structure a Terraform Project
Refer to the I Terraform Layout Example.
How to test your Terraform code
Refer to the I Terratest Guide.