7. multi-region
Separate regions (apne2 & use1) by cluster
- serve clients in S. Korea & USA
multi-stage
Separate environments (dev & prod) by cluster
- each cluster has different specs
=> Terraform, save us…
System Backend
VPC & Cluster
use1
apne2
dev
prod
VPC VPC
VPC VPC
8. Infra Provisioning
Hello Terraform!
efficiency
More application => need for automation
- repetitive steps in multi-stage & -region
- console / ad-hoc scripts are not enough
service A
service B
service C
service D
9. efficiency
More application => need for automation
- repetitive steps in multi-stage & -region
- console / ad-hoc scripts are not enough
Infra Provisioning
Hello Terraform!
Let’s add to our backend.
But first...
service A
X4
10. Let’s add to our backend.
But first...
service A
efficiency
More application => need for automation
- repetitive steps in multi-stage & -region
- console / ad-hoc scripts are not enough
standardization
Define and share reusable components
- increases consistency b/w applications
Infra Provisioning
Hello Terraform!
Let’s add to our backend.
We need for our backend.
service B
service C
How about in our backend?
service D
X4
12. Don’t reinvent the wheel
Fork and customize AWS registry modules.
Initial Layout
Initiatives
fork
13. Don’t reinvent the wheel
Fork and customize AWS registry modules.
Build once, deploy many
Build custom module with reference modules.
Set vars for multi-stage & -region deployment.
Initial Layout
Initiatives
service A
module
fork
variable "fargate_desired_count" {
type = number
}
variable "fargate_deployment_maximum_percent" {
type = number
}
variable "fargate_deployment_minimum_healthy_percent" {
type = number
}
…
apne2-dev
apne2-prod
use1-dev
use1-prod
14. Don’t reinvent the wheel
Fork and customize AWS registry modules.
Build once, deploy many
Build custom module with reference modules.
Set vars for multi-stage & -region deployment.
Fast development cycle
No CI/CD pipeline. No branch protection.
One repository for each module / deployment.
Initial Layout
Initiatives
service A
module
A: apne2-dev
A: apne2-prod
A: use1-dev
A: use1-prod
fork
15. complexity
ex) one additional service
= (1 module repo + 4 deployment repos)
x (number of modules)
Problems
Unwanted Result
service A
static
A: apne2-dev
A: apne2-prod
A: use1-dev
A: use1-prod
service A
dynamic
A: apne2-dev
A: apne2-prod
A: use1-dev
A: use1-prod
16. Problems
Unwanted Result
complexity
ex) one additional service
= (1 module repo + 4 deployment repos)
x (number of modules)
inefficiency
More repositories => consistency gradually lost
Scattered documents => high barrier to entry
18. Multi Repo
Good
- submodule versioning
- independent testing
- separate access control
Bad
- multiple source of truth
(= more PRs which leads to inefficiency)
- inconsistency across projects
The Great Debate
https://www.hashicorp.com/blog/terraform-mono-repo-vs-multi-repo-the-great-debate
Mono Repo
Good
- single source of truth
(= lower barrier to entry)
- consistency across projects
Bad
- submodule versioning is hard
- separate CI pipelines is hard
- separate access control is hard
19. Multi Repo
Good
- submodule versioning
- independent testing
- separate access control
Bad
- multiple source of truth
(= more PRs which leads to inefficiency)
- inconsistency across projects
Mono Repo
Good
- single source of truth
(= lower barrier to entry)
- consistency across projects
Bad
- submodule versioning is hard
- separate CI pipelines is hard
- separate access control is hard
The Great Debate
https://www.hashicorp.com/blog/terraform-mono-repo-vs-multi-repo-the-great-debate
20. Multi Repo
Good
- submodule versioning
- independent testing
- separate access control
Bad
- multiple source of truth
(= more PRs which leads to inefficiency)
- inconsistency across projects
Mono Repo
Good
- single source of truth
(= lower barrier to entry)
- consistency across projects
Bad
- submodule versioning is hard
- separate CI pipelines is hard
- separate access control is hard
The Great Debate
https://www.hashicorp.com/blog/terraform-mono-repo-vs-multi-repo-the-great-debate
<-> initial goals
hard but doable
21. 3 mono repos
- Reference Modules
- Service Modules
- Live Deployments
Q. why not just 1 big mono repo?
- Separate modules from deployments
- Prevent self-reference
New Layout
Improvement
Reference Modules
Source Tree [GITHUB]
> terraform-aws-alb
> terraform-aws-bastion
> terraform-aws-code-deploy
> terraform-aws-dynamodb
> terraform-aws-ecr
> terraform-aws-ecs
…
Service Modules
Source Tree [GITHUB]
> module-service-A
> module-service-B
> module-service-C
> module-service-D
…
Live Repository
Source Tree [GITHUB]
> suite-service-A
> dev
> apne2
> use1
> prod
> apne2
> use1
…
22. CODE EDITOR
Continuous
Integration
1. check formatting
2. fetch dependencies
3. validate project
# Set up terraform
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
# Checks canonical formatting
- name: Terraform Format
run: terraform fmt -check -recursive
# Initialize and validate sub-directories
- name: Terraform Validate
run: |
find "$(pwd -P)" -type d -links 2
| while read subdir
do
cd $subdir
terraform init
terraform validate
done
24. collaboration
What if multiple applys happen at the same time?
=> state locking solves everything?
In reality, things can get messy…
- someone may force-unlock
- partial apply (ex. apply target)
=> CI/CD (ex. bind commands to github actions)
Can we do better?
Remaining Issues
https://quileswest.medium.com/how-to-lock-terraform-state-with-s3-bucket-in-dynamodb-3ba7c4e637
terraform plan
terraform apply
25. maintenance
What if modules become stale?
=> Use git tags for versioning
How to prevent potential misconfigurations?
=> Use static analysis tools
Can we do better?
Remaining Issues
A/1.1.1 B/1.0.1 C/0.4.2
A/1.1.2
A B A C
tfsec checkov