Does atlantis support GitHub multi-branching strategy?
What we need is to use separated git branches which consists of different terraform configuration for different evironments (like dev,staging,production) and need to use atlantis to do terraform plan whenever a pull request opened to the specific branch. This means there is no common branch like master which carry all the configurations. I couldn't find any specific branching strategy for atlantis and would be great if you can let me know whether it is possible or not? Thanks!!
Iād want to follow-up on the original idea with a similar issue, and I possible solution proposal (whose viability I didnāt have time to test š). I recently finished configuring CircleCI for a new project with a workflow that works something like this:
develop branch, run terraform fmt -check, terraform validate and tflint, and once all three succeed, calculate Terraform plan against the development environment (using Terraform workspace, and different -var-file), save the plan for future applying, and notify the changes by commenting on the PR, as well as sending a message on Slack; on merge, apply the changes to the development environment only;staging branch, perform all actions against the staging environment; master then affects the production environment; up to this point, I think my setup is somewhat similar to what @hossein-rasi is describing;develop through staging to production, and the only difference should be input variables and of course, state file.After I spent two days fighting with CircleCIās quirks, I never want to do that again š (What kind of CI system allows you to set the project to only build on a commit which has a PR associated to it, but then doesnāt trigger a build once the PR is merged and closed? š¤Æ)
And thatās when I found Atlantis and realized that perhaps, I couldāve spent the past two days in a much better way. One thing that Iām not seeing in the documentation, however, is how I could achieve the āGit flowā setup that I described above⦠but what I see are a few pieces of the puzzle that when put together, they could perhaps help?
What Iām asking is⦠Iām sorry for the long introduction, but would the following setup have a chance to work for me or would I run into some other traps that it would be difficult to get out of?
atlantis.yaml, define a single workflow for all three branches/environments.The first step in the plan action would look something like this:
- env:
name: CUSTOM_WORKSPACE
command: |
if [ "${BASE_BRANCH_NAME}" == "master" ]; then
echo "production"
elif [ "${BASE_BRANCH_NAME}" == "staging" ]; then
echo "staging"
elif [ "${BASE_BRANCH_NAME}" == "develop" ]; then
echo "development
else
# echo "Where are you merging into?"
exit 1
fi
init, the third step would switch the workspace to the value generated in the first step, and all of this would be followed by a rather simple adjustment of the standard plan step:
<ul>
<li>init</li>
<li>run: terraform workspace select $CUSTOM_WORKSPACE</li>
<li>plan:<br />
extra_args: ["-var-file", "${CUSTOM_WORKSPACE}.tfvars"]<br />
apply phase.Iām sorry for asking for a consultation like this, but Iād be incredibly grateful to hear opinions/improvements/traps, and especially any warnings if I am proposing something impossible (perhaps variable interpolation in extra_args is not possible?)
@hossein-rasi Atlantis actually doesn't care about the branches. It will operate on a PR opened to any branch and will actually read the atlantis.yaml from the pull request branch itself rather than the base branch. Have you tried it out? I think it should work for your use-case but if you have specific issues let me know.
@Cellane that approach looks good to me (caveat, I haven't tested it). FYI extra_args interpolation does work.
Thanks @Cellane for the detailed explanation. I will try out your approach and see whether it works or not. @lkysow Thanks for your response. The thing is each branch consists of different config for each env and so TF should at least know the base branch. This is mainly because of the reusable modules/resources and when we want to only plan one env and not the others even if we have changed in the other directories.
So I just want to share my current progress. Iām not sure if Iām finished yet as I havenāt tested all possible scenarios, but I am at a stage where correct plans are being calculated. I think I encountered three gotchas:
Problem number one: various issues about escaping my multi-line env stepās `command.
Solution: remove all the lines š¤£
Problem number two: the default plan step switches Terraform workspace.
Solution: use another run step instead of the plan step, like so: - run: terraform plan -input=false -refresh -no-color -out $PLANFILE
Problem number three: Atlantis doesnāt update PATH to point to the projectās Terraform binary, so when you use the solution from the previous step, you will essentially disable Atlantisā Terraform version switching.
Solution: Iām just going to share my entire config file at this point I think š
version: 3
projects:
- dir: .
terraform_version: v0.12.24
workflow: custom
workflows:
custom:
plan:
steps:
- env: &define-custom-workspace
name: CUSTOM_WORKSPACE
command: 'if [ "${BASE_BRANCH_NAME}" == "master" ]; then echo "production"; elif [ "${BASE_BRANCH_NAME}" == "staging" ]; then echo "staging"; elif [ "${BASE_BRANCH_NAME}" == "develop" ]; then echo "development"; else exit 1; fi;'
- env: &define-terraform-binary
name: TERRAFORM_BINARY
command: 'echo "/home/atlantis/.atlantis/bin/terraform${ATLANTIS_TERRAFORM_VERSION}"'
- init
- run: $TERRAFORM_BINARY workspace select $CUSTOM_WORKSPACE
- run: $TERRAFORM_BINARY plan -input=false -refresh -no-color -out $PLANFILE
apply:
steps:
- env: *define-custom-workspace
- env: *define-terraform-binary
- run: $TERRAFORM_BINARY workspace select $CUSTOM_WORKSPACE
- run: $TERRAFORM_BINARY apply -no-color $PLANFILE
I havenāt yet properly tested the apply phase ā from the documentation, Iām getting a hint that the workspace select step is not necessary, but Iām not sure about itā¦
And I kind of worry if I run into some problems regarding locks later on, because Atlantis for sure thinks that itās working in the default workspace.
I also have a similar question.
Where I work, if code is in develop branch it is in development environment. if code is in master/main it is in production environment.
We also use Terraform Workspaces, we define two; test & prod, and do not use default.
We'd like to use a custom workflow to do plan/apply against the correct workspace ONLY. Let me elaborate.
When develop is the base branch, the branch that's getting merged into, we want atlantis to plan/apply against the test terraform workspace. When master is the base branch, the branch that's getting merged into, we want atlantis to plan/apply against the prod terraform workspace.
One of the main motivations around using these different branch/workspace workflows is because a) we'd like to remove approval restrictions for plan/apply in development but keep them in production. The other reason is b) we do not want atlantis to plan for both workspaces/environments at the same time because, often, neither are ready at the same time IE. we iron out the kinks in development environment before it's ready for prod; a great usecase for terraform workspaces.
I understand atlantis does not care about which git branch but we do based on the workflow described above.
Worth noting, did come across the BASE_BRANCH_NAME environment variable. Just have not quite wrapped my brain around how to use it effectively. Any input would be appreciated. Cheers!
based on what read in @Cellane post above is seems like I could do the following
if (wksp eq test) && (base branch eq develop)
run plan
else if (wksp eq prod) && ((base branch eq master) || (base branch eq main))
run plan
else if (wksp eq default)
run plan
else
exit
the last else if is because we do have some terraform runs that do not leverage workspaces
So I just want to share my current progress. Iām not sure if Iām finished yet as I havenāt tested all possible scenarios, but I am at a stage where correct plans are being calculated. I think I encountered three gotchas:
Problem number one: various issues about escaping my multi-line
envstepās `command.
Solution: remove all the lines š¤£Problem number two: the default
planstep switches Terraform workspace.
Solution: use anotherrunstep instead of theplanstep, like so:- run: terraform plan -input=false -refresh -no-color -out $PLANFILEProblem number three: Atlantis doesnāt update
PATHto point to the projectās Terraform binary, so when you use the solution from the previous step, you will essentially disable Atlantisā Terraform version switching.
Solution: Iām just going to share my entire config file at this point I think šversion: 3 projects: - dir: . terraform_version: v0.12.24 workflow: custom workflows: custom: plan: steps: - env: &define-custom-workspace name: CUSTOM_WORKSPACE command: 'if [ "${BASE_BRANCH_NAME}" == "master" ]; then echo "production"; elif [ "${BASE_BRANCH_NAME}" == "staging" ]; then echo "staging"; elif [ "${BASE_BRANCH_NAME}" == "develop" ]; then echo "development"; else exit 1; fi;' - env: &define-terraform-binary name: TERRAFORM_BINARY command: 'echo "/home/atlantis/.atlantis/bin/terraform${ATLANTIS_TERRAFORM_VERSION}"' - init - run: $TERRAFORM_BINARY workspace select $CUSTOM_WORKSPACE - run: $TERRAFORM_BINARY plan -input=false -refresh -no-color -out $PLANFILE apply: steps: - env: *define-custom-workspace - env: *define-terraform-binary - run: $TERRAFORM_BINARY workspace select $CUSTOM_WORKSPACE - run: $TERRAFORM_BINARY apply -no-color $PLANFILEI havenāt yet properly tested the
applyphase ā from the documentation, Iām getting a hint that theworkspace selectstep is not necessary, but Iām not sure about itā¦And I kind of worry if I run into some problems regarding locks later on, because Atlantis for sure thinks that itās working in the
defaultworkspace.
now I understand, why you did what you did š ... thanks for the detailed example
Most helpful comment
Iād want to follow-up on the original idea with a similar issue, and I possible solution proposal (whose viability I didnāt have time to test š). I recently finished configuring CircleCI for a new project with a workflow that works something like this:
developbranch, runterraform fmt -check,terraform validateandtflint, and once all three succeed, calculate Terraform plan against the development environment (using Terraform workspace, and different-var-file), save the plan for future applying, and notify the changes by commenting on the PR, as well as sending a message on Slack; on merge, apply the changes to the development environment only;stagingbranch, perform all actions against the staging environment;masterthen affects the production environment; up to this point, I think my setup is somewhat similar to what @hossein-rasi is describing;developthroughstagingtoproduction, and the only difference should be input variables and of course, state file.After I spent two days fighting with CircleCIās quirks, I never want to do that again š (What kind of CI system allows you to set the project to only build on a commit which has a PR associated to it, but then doesnāt trigger a build once the PR is merged and closed? š¤Æ)
And thatās when I found Atlantis and realized that perhaps, I couldāve spent the past two days in a much better way. One thing that Iām not seeing in the documentation, however, is how I could achieve the āGit flowā setup that I described above⦠but what I see are a few pieces of the puzzle that when put together, they could perhaps help?
What Iām asking is⦠Iām sorry for the long introduction, but would the following setup have a chance to work for me or would I run into some other traps that it would be difficult to get out of?
atlantis.yaml, define a single workflow for all three branches/environments.The first step in the
planaction would look something like this:init, the third step would switch the workspace to the value generated in the first step, and all of this would be followed by a rather simple adjustment of the standardplanstep:<ul> <li>init</li> <li>run: terraform workspace select $CUSTOM_WORKSPACE</li> <li>plan:<br /> extra_args: ["-var-file", "${CUSTOM_WORKSPACE}.tfvars"]<br />applyphase.Iām sorry for asking for a consultation like this, but Iād be incredibly grateful to hear opinions/improvements/traps, and especially any warnings if I am proposing something impossible (perhaps variable interpolation in
extra_argsis not possible?)