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 login hoạ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 đặt existing_iam = false trong 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ạn

Thô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.ps1

Script 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
StepViệcCần thao tác?
0AWS login (mở browser nếu hết hạn)Confirm trên web
1Confirm aws_region, az_*, ec2_ami_id, stage_indexEnter để giữ, gõ giá trị mới để đổi
2Sync shared regionTự động
3Preflight checkEnter để tiếp tục
4Deploy Shared (chỉ chạy nếu có existing = false)Tự động
5Deploy Stage: auto import → terraform plan → review → Enter → terraform applyReview plan rồi Enter
6Verify outputsTự độ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ận

Deploy/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

ModuleTarget string
01-vpcmodule.vpc
02-subnetsmodule.subnets
03-internet-gatewaymodule.internet_gateway
04-route-tables-peeringmodule.route_tables_peering
05-security-groupsmodule.security_groups
06-albmodule.alb
07-nlbmodule.nlb
08-target-groups-listenersmodule.target_groups_listeners
09-autoscalingmodule.autoscaling
11-ecrmodule.ecr
12-acmmodule.acm
13-route53module.route53
15-iammodule.iam
16-cloudwatchmodule.cloudwatch
17-ec2-instancesmodule.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 list

Multi-region / Multi-stage

Không cần copy folder. Cùng 1 thư mục terraform/:

  1. Đổi aws_region, az_1, az_2, ec2_ami_id trong terraform.tfvars
  2. Chạy preflight-check.ps1 → script đọc route table của Build VPC, đề xuất stage_index không xung đột
  3. 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.