Managing multiple AWS environments (sandbox/dev/uat/stage/prod) is challenging, as it is hard to keep track of the current status of each environment. For example, user A deploys his feature branch into dev to test his code, then later user B deploys his hotfix branch into dev to test his code. This can cause many issues:
- User B’s code can overwrite User A’s code without proper notification
- There are no single source for truth
- Every is only focus on his own branch, and not aware of other people’s changes.
The problems become worse especially when the codes have dependencies between each other. E.g One CloudFormation template’s output (export) is another CloudFormation template’s input (Import). Or one CloudFormation template’s parameters are used by Ansibles playbooks.
I think the best solution to tackle such issue is to adopt Git Workflow. Please keep in mind that Git Workflow is guidelines instead of rules. IMHO, the principle of Git Workflow is to utilise branches to enhance the team’s effectiveness and communications. There are many styles of Git Workflow, we just need to figure out the one the fits best. E.g Software release workflow is different from infrastructure maintenance workflow.
Here is the one that I designed to effectively manage multiple AWS environments’ infrastructures:
Some key points:
- Every change requires a branch that is associated with a Jira ticket.
- Master branch is the single source of truth for the official production codes for AWS prod environment. And it requires PR (Pull Request) to merge any new changes.
- Release/(sandbox/dev/stg) branches are the single source of truth for each associated AWS non-prod environments. e.g release/sandbox is for AWS sandbox environment. And those release branches are automatically managed which improves the collaborations and communications.
Code-Releaser is the implementation of the design. Here are the detailed steps of the whole work flow:
1. User creates a branch JIRA-XXX based on master branch.
2. User releases the branch JIRA-XXX into env (sandbox/dev/stg/prod) via Code-Releaser.
3. Code-Releaser clones the repository. (START)
4. Code-Releaser checks which environment that the user wants to release code to.
a. If it is for prod, just releases master branch into AWS prod. (END)
b. If it is for non-prod env, checks out associated release branch release/env, then merge user’s branch JIRA-XXX
5. Code-Releaser checks the merge results.
a. If the merge is successful, pushes the merged codes back to the release/env branch, and release it to the AWS env. (END)
b. If the merge is failed, fail the build and output the conflicts which user needs to solve. (END)
6. If user is happy with change, then raises a PR for team to review before it can be merged into master branch.