A Workflow for Deploying IaC

Alt Text
The main steps in a workflow

Version Control

Splitting your Terraform version control repositories between application code and modules is a crucial best practice for efficient and effective infrastructure as code (IaC) management. Here are some general guidelines for achieving this separation:

Establish Separate Repositories: Maintain separate repositories for your application code and Terraform modules. The application repository should contain your application source code and the Terraform configuration files that define how your application is deployed.

Module Repository: This repository should contain reusable Terraform modules, each encapsulating a specific piece of infrastructure logic. Examples could include modules for creating a database, a virtual machine, a network, or any other repeatable infrastructure component. Each module should be self-contained, including all the necessary resources and variables to function independently.

Semantic Versioning: Apply semantic versioning to your Terraform modules. Each time you update a module, increment the version number. This way, your application configurations can specify exactly which versions of modules they want to use, preventing unintentional breaking of changes.

README and Documentation: For each module, provide a README file with a clear description of what the module does, its input variables, its outputs, and an example of how to use it. Good documentation makes your modules more maintainable and reusable.

Application Repositories: Within your application repositories, reference the modules from your module repository. These will be called with specific variable values relevant to the application.

Environment Separation: It’s good practice to separate your Terraform state files by environment (e.g., production, staging, development). This could be achieved by structuring your Terraform files in your application repo with different directories or workspaces for each environment. This separation can prevent accidental changes in production environments when you’re making adjustments in non-production environments.

Sandbox

Terraform code cannot be tested locally. You need a platform to test against. Testing Terraform code against a sandbox environment is considered a best practice because it allows you to validate the changes to your infrastructure in a safe and controlled environment before they are applied to production. This practice helps in catching any errors or unintended consequences that may arise due to new changes, thus preventing potential disruptions or damage in production. It’s essentially a form of “fail fast, fail safe” that gives developers confidence in their changes, and fosters a culture of experimentation and learning without risking critical infrastructure.

Make Changes

Using the sandbox and the checked out code, make the necessary changes and test and re-test until you are satisfied that the new version is good.

Submit for review

To submit new Infrastructure as Code (IaC) for review on GitHub, you typically use the Pull Request mechanism. First, create a new branch for your code changes and push this branch to GitHub. Then, on the GitHub web interface, navigate to your repository and select the ‘New pull request’ button. You’ll want to compare your new branch (the ‘compare’ branch) with the base branch you wish to merge the changes into. Fill out the details of your pull request, explaining what changes you’ve made and why, then submit it. Your team members can then review the proposed changes in the pull request, make comments, request changes, or approve the pull request. Once it is approved, it can be merged into the base branch.

Merge and release

Once your Pull Request has been reviewed and approved on GitHub, you can move on to the merge and release process.

Merge: Click on the ‘Merge pull request’ button to merge your changes into the base branch. This combines your branch with the target branch, integrating the new Infrastructure as Code (IaC) with the existing codebase. Depending on the project’s settings, you may have several merge options, such as creating a merge commit, squashing and merging (where all commits from the branch are squashed into one), or rebasing and merging (where your branch’s commits are re-applied onto the target).

Release: After merging, you should run any final tests or checks to ensure everything works as expected. When you’re ready, you can create a new release. Navigate to the ‘Releases’ section of your GitHub repository, then click ‘Draft a new release’. Here, you can tag the version (it’s good practice to follow semantic versioning), add release notes describing the changes, and publish the release. This can trigger any automated deployment pipelines you have set up and will make the new version of your IaC publicly available.

This release serves as a snapshot of your code at this point in time and can be used to deploy the infrastructure in your various environments. Moreover, it allows for better tracking of what code is running where, and makes rollbacks to previous versions easier if needed.

Last modified July 21, 2024: update (e2ae86c)