Using Gitlab to manage Multi Environment Terraform State
Gitlab allows you to store the state from your terraform files on the same repository of your project. This feature is quite useful because you can then use Gilab CICD pipelines to automatically deploy changes to your infrastructure. However, if you need to deploy your infrastructure to different environments, you might need to have a separate state for each environment. So, I will show you one way of achieving that.
What we want to do
For the sake of this example, let’s say we have two environments: dev and prod. And our infrastructure is simply an AWS Queue that has a different name and delay property based on the environment.
We start defining the backend:
Quite simple, we will configure the address for the backend later in our gitlab-ci.yml file.
Our main.tf defines our AWS SQS Queue. Notice that we have the var.env
and var.delay
properties that are based on the environment context:
Now, the most important part of our project: the gitlab-ci.yml
At the start, the workflow
section will define which environment we will build/deploy our changes based on the commit branch.
On the variables section, the TF_ADDRESS
variable defines the address to be used for our http backend in terraform. Some of environment variables in the TF_ADDRESS
are automatically defined by the gitlab runner, such as: CI_API_V4_URL and CI_PROJECT_ID. However, the ENV
variable that is used to define the state is the one previously defined in the workflow
On the plan
job from the build
stage, we will generate the plan
file and use the respective tfvars
file based on the current environment.
Results
Once you push your changes to the develop/main branch, your pipeline on gitlab should look like:
And if you navigate to Infrastructure
-> Terraform
, you should see two state files (assuming that you run the pipeline in both, develop and main, branches to completion):
On the AWS side, you should see the two AWS Queues:
The full code can be found here