Feb 24, 2025
10 min read

Advantages of using GitFlow for Terraform

Advantages of using GitFlow for Terraform
How GitFlow enhances Terraform workflows (and where it gets complicated)

In Introduction to GitFlow for Terraform, we looked at why GitFlow can be a good fit for managing infrastructure changes and how teams can adapt it for Terraform and OpenTofu. Now, we’ll dig into the advantages GitFlow provides and why some teams prefer this structured approach over simpler workflows.

GitFlow can help infrastructure teams stay organized when managing multiple environments and cloud resources. Feature branches give engineers a safe way to test and validate changes without impacting shared environments. This is especially useful in larger organizations where different teams frequently modify interdependent resources like networking, databases, and compute clusters.

However, combining GitFlow with Terraform isn’t always straightforward. State file management, merge conflicts, and environment drift can introduce complexity that teams need to plan for. In this post, we’ll cover the advantages of GitFlow for infrastructure and the common challenges you’ll need to navigate.

Feature branch isolation

Feature branches let you test infrastructure changes without affecting your live environments. When you need to make significant changes, like updating an RDS database cluster, you can work in complete isolation:

You can use different .tfvars files to define environment-specific settings. This makes it easy to test with scaled-down resources before deploying to production:

This approach means you can thoroughly test your database changes with a smaller, cheaper instance type and minimal backup retention before switching to production-grade settings. The feature branch keeps these changes contained until they're ready for review and deployment.

Automation for change validation

Pull requests act as natural checkpoints for reviewing infrastructure changes. You can automate Terraform validation right in your PR workflow using GitHub Actions:

Parallel development

Parallel development becomes seamless with feature branches and isolated state files. Teams can configure backends to maintain separate state for each feature branch:

This automation ensures that every PR gets a Terraform plan run, letting reviewers see exactly what infrastructure changes will happen before they approve. The workflow runs automatically whenever someone opens or updates a pull request targeting the develop or main branches.

Security through branch protection

Branch protection rules provide a critical security layer for infrastructure deployments by enforcing strict controls on code changes. When implementing GitFlow with Terraform, you can codify these protections as infrastructure, ensuring consistent security policies across all infrastructure repositories:

This configuration enforces multiple security controls: requiring successful Terraform plans to prevent broken infrastructure changes, running automated security scans with tfsec to catch misconfigurations, and performing cost impact analysis through Infracost. The requirement for two approving reviews, including from designated code owners, adds human verification before any changes can reach production infrastructure.

While these automated guardrails help teams work confidently with infrastructure code, it's important to acknowledge that implementing GitFlow can introduce some non-trivial operational overhead. Managing state files across long-lived branches, handling merge complexity with infrastructure code, and coordinating releases across environments all require careful planning - challenges we'll examine in detail in the next section.

Common challenges with GitFlow in Terraform/OpenTofu

GitFlow's structured approach works well for application code, but brings some unique challenges when you're using it with Terraform or OpenTofu. Let's look at some of the key issues teams run into when implementing GitFlow for infrastructure code.

State file conflicts

One of the trickiest challenges comes from state file conflicts, especially when multiple teams are working on shared infrastructure. Unlike application code where Git handles most merge conflicts, Terraform state represents a single source of truth about your infrastructure. This can get complicated quickly when feature branches create different versions of the same infrastructure components.

Here's a real-world example. Imagine two teams are working on separate features that modify the same security group:

When these branches eventually merge, Terraform will raise an error during the plan phase:

There are several ways to handle these conflicts. You can use Terraform workspaces to keep feature branch states separate:

Or you might regularly sync your feature branches with the main branch's state:

In almost all cases, using a backend setup with proper locking is essential:

These challenges become more pronounced as your team grows and you have multiple infrastructure changes moving through your pipeline at once. The key is to keep your state files synchronized and maintain clear communication between teams working on related infrastructure components.

Environment-Specific Variables

Managing variables across different environments becomes especially challenging when using GitFlow, particularly when it comes to sensitive credentials and environment-specific configurations. Teams often discover missing or incorrect variables during environment promotions, leading to failed deployments:

Most teams organize their Terraform projects with separate variable files for each environment:

This structure works well for straightforward deployments, but GitFlow's branching strategy introduces additional overhead. Feature branches might require new variables that don't exist in staging or production yet. Similarly, when promoting changes through environments, teams need to ensure all required variables are properly set.

You’ve got at least a couple of choices in where to implement validation:

1) Implement strict variable validation in your CI/CD pipeline. For example, in GitHub Actions:

2) Use variable validation blocks to catch configuration errors early:

Using tools like terraform-docs makes it easier for team members to understand what inputs are needed for each module, and what resources are generated. For instance, you can automatically generate module documentation in your PRs:

This approach becomes particularly important as your infrastructure grows and you manage multiple feature branches simultaneously. By catching variable issues early in the development cycle, you can avoid surprises during environment promotions and keep your deployments reliable.

Secrets management in GitFlow

Managing secrets is different from managing regular environment variables. Hardcoding credentials in .tfvars files or committing them to Git is asking for trouble. Instead, use a secrets manager to pull in credentials securely when Terraform runs, whether that’s local or in CI/CD.

You don’t want secrets tied to long-lived GitFlow branches. Instead, they should be pulled in dynamically when needed. In CI/CD, that means retrieving them at runtime instead of baking them into pipeline configurations. It also helps to rotate credentials regularly, make sure only the right people and systems have access, and avoid exposing secrets in logs. Basically, don’t store secrets where they don’t belong, don’t let them leak, and make it easy to swap them out when needed.

Multi-region deployments

Multi-region or multi-account deployments add complexity that breaks GitFlow’s linear promotion model. Infrastructure often needs parallel updates across multiple regions or accounts. A multi-region deployment pipeline might look like this:

Terragrunt makes this kind of multi-region deployment a lot more manageable. Here's what that looks like in practice:

Pipeline complexity with GitFlow

As you implement GitFlow for infrastructure, your CI/CD pipelines need to handle different validation requirements for each branch type. Here's an example pipeline configuration that adapts its behavior based on the branch:

This setup helps your team maintain control as changes move through different environments. When changes target production, the pipeline runs additional checks like cost estimation and requires extra approvals. For development work, it stays more flexible to keep iteration quick. The pipeline also handles security by switching AWS roles based on which branch you're working with - development branches use different permissions than production ones. With security scans and validation running automatically, teams can work quickly while still following security and infrastructure standards.

Adopting GitFlow in infrastructure teams

Getting teams to adopt GitFlow means changing how they work, which is particularly challenging for infrastructure teams used to making quick changes. Engineers who regularly hotfix production issues often push back against the more structured workflow. This usually requires updates to access controls to enforce that infrastructure changes don’t happen outside the usual GitFlow loop, i.e. with “ClickOps”. An example IAM policy below restricts principals that aren’t a GitHub OIDC user from making changes to EC2

Conclusion

If you're thinking about using GitFlow for your infrastructure code, start small. Begin with basic features like branch protection and automated checks. These additions give you guard rails without disrupting how your team already works. As your team gets comfortable with these changes, you can gradually add more GitFlow practices. Make sure to help your team understand how these new workflows will make their lives easier when deploying infrastructure changes.

While GitFlow works great for many teams managing infrastructure code, it's not for everyone. It needs careful setup, lots of automation, and team training to work well. If you're a smaller team or your infrastructure isn't too complex, you might want to look at simpler branching strategies that can give you the security and stability you need without all of GitFlow’s moving parts. The key is to pick an approach that matches your team’s size and needs.

Open-source tools like Terrateam can make adopting GitFlow easier by automating Terraform plan operations, enforcing approval workflows, and handling Terraform state safely across branches. By integrating GitFlow with the right automation, teams can move fast without breaking infrastructure.

In the next part of this series, we’ll cover best practices for making GitFlow work with Terraform. We’ll dive into state management strategies, security scanning, compliance checks, and other areas that help teams avoid common pitfalls.