Hướng dẫn Deploy
Hướng dẫn chi tiết từng bước để deploy môi trường stage
Yêu cầu trước khi chạy
Phần mềm trên máy local
- Terraform ≥ 1.5
- AWS CLI v2 (đã có lệnh
aws,aws sso loginhoạt động) - PowerShell 5.1+ (Windows mặc định OK)
Quyền AWS
- Tài khoản phải có quyền tạo: VPC, EC2, ELB (ALB/NLB), ECR, ACM, Route53, CloudWatch, IAM, S3, CloudFront
- IAM role
MILU2-AWS-ALLOWđã tồn tại (hoặc đặtexisting_iam = falsetrong shared để tự tạo) - Có quyền vào DNS zone
*.milu.jp(để validate ACM certificate)
Đăng nhập AWS
Đăng nhập AWS
aws sso login # mở browser, login lần đầu trong ngày
aws sts get-caller-identity # kiểm tra credential còn hạnThông tin
Nếu credential hết hạn giữa chừng (1h), deploy.ps1 sẽ tự gọi lại login.
Kiểm tra trước khi chạy (preflight)
Preflight Check
cd d:\terraform_svn\terraform-resource\terraform
.\preflight-check.ps1Script tự kiểm 10 thứ: credential, S3 bucket, IAM, CloudFront, ECR, AMI, ACM, VPC peering, CIDR conflict, region. Tự sửa cờ existing_* và stage_index trong terraform.tfvars nếu cần.
Deploy nhanh nhất (1 lệnh)
Script tự chạy 7 bước theo thứ tự, dừng lại hỏi xác nhận ở các điểm cần thiết:
Quick Deploy
cd d:\terraform_svn\terraform-resource\terraform
.\deploy.ps1| Step | Việc | Cần thao tác? |
|---|---|---|
| 0 | AWS login (mở browser nếu hết hạn) | Confirm trên web |
| 1 | Confirm aws_region, az_*, ec2_ami_id, stage_index | Enter để giữ, gõ giá trị mới để đổi |
| 2 | Sync shared region | Tự động |
| 3 | Preflight check | Enter để tiếp tục |
| 4 | Deploy Shared (chỉ chạy nếu có existing = false) | Tự động |
| 5 | Deploy Stage: auto import → terraform plan → review → Enter → terraform apply | Review plan rồi Enter |
| 6 | Verify outputs | Tự động |
Deploy thủ công (khi cần kiểm soát hơn)
Deploy thủ công (khi cần kiểm soát hơn)
cd d:\terraform_svn\terraform-resource\terraform
# (1) Preflight
.\preflight-check.ps1
# (2) Shared — chạy 1 lần cho cả account, không lặp lại trừ khi shared có thay đổi
cd shared
terraform init
terraform plan # Mong đợi: No changes (nếu existing = true)
terraform apply # Chỉ chạy nếu plan có thay đổi
cd ..
# (3) Stage
terraform init
terraform plan # Review xem tạo những gì
terraform apply # Gõ 'yes' để xác nhậnDeploy/Update RIÊNG một module (target apply)
Dùng khi chỉ muốn áp 1 thay đổi nhỏ (vd: chỉ đổi user_data của EC2, không động vào VPC/ALB).
Target Apply
cd d:\terraform_svn\terraform-resource\terraform
# Chỉ apply module 17-ec2-instances
terraform plan -target='module.ec2_instances'
terraform apply -target='module.ec2_instances'
# Chỉ apply module 09-autoscaling (Launch Template + ASG API)
terraform plan -target='module.autoscaling'
terraform apply -target='module.autoscaling'
# Chỉ apply module 06-alb
terraform plan -target='module.alb'
terraform apply -target='module.alb'
# Apply nhiều module cùng lúc
terraform apply -target='module.target_groups_listeners' -target='module.alb'Apply chỉ 1 instance trong module 17
Khi instance_counts.mysql = 1 thì state key sẽ là mysql-1:
Replace Instance
# Replace EC2 mysql-1 (giữ nguyên các EC2 khác)
terraform apply -replace='module.ec2_instances.aws_instance.this["mysql-1"]'
# Replace cả mysql-1 và mysql_mirror-1
terraform apply `
-replace='module.ec2_instances.aws_instance.this["mysql-1"]' `
-replace='module.ec2_instances.aws_instance.this["mysql_mirror-1"]'
# Force refresh ASG (ép launch lại lập tức)
terraform apply -replace='module.autoscaling.aws_launch_template.api'Thông tin
-replace ép terraform destroy + create lại đúng resource đó, không động đến hàng xóm.
Tên các module để target
| Module | Target string |
|---|---|
| 01-vpc | module.vpc |
| 02-subnets | module.subnets |
| 03-internet-gateway | module.internet_gateway |
| 04-route-tables-peering | module.route_tables_peering |
| 05-security-groups | module.security_groups |
| 06-alb | module.alb |
| 07-nlb | module.nlb |
| 08-target-groups-listeners | module.target_groups_listeners |
| 09-autoscaling | module.autoscaling |
| 11-ecr | module.ecr |
| 12-acm | module.acm |
| 13-route53 | module.route53 |
| 15-iam | module.iam |
| 16-cloudwatch | module.cloudwatch |
| 17-ec2-instances | module.ec2_instances |
Khi resource trên AWS đã tồn tại sẵn (import)
deploy.ps1 tự dò và import 31 loại resource (ECR, ALB, NLB, TG, ASG, Launch Template, CloudWatch alarms…). Nếu cần import tay:
Import Resources
# ECR
terraform import 'module.ecr.aws_ecr_repository.this["milu2/milu2-stage-api"]' milu2/milu2-stage-api
# ALB internal
terraform import 'module.alb.aws_lb.internal' arn:aws:elasticloadbalancing:...
# Xem state hiện tại
terraform state listMulti-region / Multi-stage
Không cần copy folder. Cùng 1 thư mục terraform/:
- Đổi aws_region, az_1, az_2, ec2_ami_id trong terraform.tfvars
- Chạy preflight-check.ps1 → script đọc route table của Build VPC, đề xuất stage_index không xung đột
- Chạy deploy.ps1 như bình thường
Mẹo
Mỗi region có file state riêng (terraform.tfstate trong working directory hiện tại).
Destroy (xoá môi trường)
Nguy hiểm
Cảnh báo: destroy stage sẽ xoá hết VPC, EC2, ALB, NLB của môi trường này. Dữ liệu trên /home2 (mysql) sẽ mất theo. Backup mysqldump --all-databases lên S3 trước.
Destroy
# Xoá stage, GIỮ shared
.\deploy.ps1 -DestroyOnly
# Khi hỏi 'Destroy shared resources too?' → bấm Enter (không gõ yes)
# Xoá luôn shared
.\deploy.ps1 -DestroyOnly
# Khi hỏi → gõ yes + Enter
# Hoặc thủ công
terraform destroy
cd shared
terraform destroy
cd ..Lưu ý quan trọng — đọc trước khi đổi user_data EC2
Cảnh báo
Module 17 có user_data_replace_on_change = true, nghĩa là mọi thay đổi trong file scripts/*.sh sẽ destroy + create lại EC2.
Hậu quả:
- EBS root mất → mất dữ liệu trên /home/ec2-user, /var/log, …
- EBS /home2 (mysql) cũng mất → MySQL phải import lại từ schema_only.sql + mysql_users.sql trên S3
- ASG (module 09) tự rolling refresh, không bị destroy đột ngột
Trước khi apply một thay đổi user_data lên DB:
Backup trước khi apply
# 1. Backup MySQL
mysqldump --all-databases > schema_only.sql
aws s3 cp schema_only.sql s3://<bucket>/docker/milu2-mysql/
# 2. Apply riêng từng instance để giảm rủi ro
terraform apply -replace='module.ec2_instances.aws_instance.this["mysql-1"]'Mẹo
Hot-fix không cần redeploy: SSH vào EC2 rồi sửa trực tiếp /etc/systemd/system/mount-s3.service hoặc /home/ec2-user/milu2/<role>/docker/run.sh rồi systemctl restart.