Lỗi Gặp Phải
The stack is in an UPDATE_ROLLBACK_FAILED state and can not be updated.
Bạn đẩy một bản cập nhật CloudFormation lên. Nó thất bại giữa chừng. CloudFormation cố gắng rollback — và bản rollback đó cũng thất bại. Bây giờ stack bị đóng băng. Bạn không thể cập nhật, không thể xóa sạch, và mỗi lần deploy lại đều ném ra cùng một lỗi. Production đang ở trạng thái hoạt động một nửa, hoặc bạn đang nhìn chằm chằm vào một stack cập nhật dở dang lúc 2 giờ sáng và không biết phải làm gì tiếp theo.
Nguyên Nhân
Khi một bản cập nhật stack thất bại, CloudFormation tự động thực hiện rollback. Bản rollback đó có thể thất bại khi:
- Một resource bị chỉnh sửa thủ công bên ngoài CloudFormation — stack muốn khôi phục lại nhưng trạng thái hiện tại không còn khớp nữa
- Một resource bị xóa bên ngoài stack trước khi rollback cố gắng khôi phục nó
- Một quyền IAM bị thu hồi trong quá trình thực hiện, khiến CloudFormation không thể hoàn tác resource đó
- Một resource phụ thuộc ở dịch vụ khác đang ở trạng thái chuyển tiếp (ví dụ: một RDS instance vẫn đang ở trạng thái
modifying)
Nguyên nhân cốt lõi luôn giống nhau: CloudFormation không thể tự mình khôi phục stack về trạng thái trước đó mà không có sự can thiệp của bạn.
Cách Khắc Phục Từng Bước
Bước 1 — Xác Định Resource Đang Bị Lỗi
Bắt đầu bằng cách xác định chính xác resource nào đã khiến rollback thất bại. Mở AWS Console → CloudFormation → chọn stack của bạn → tab Events. Tìm sự kiện UPDATE_ROLLBACK_FAILED hoặc UPDATE_FAILED gần nhất và ghi lại Logical ID của resource đó.
Thích dùng CLI hơn? Chạy lệnh sau:
aws cloudformation describe-stack-events \
--stack-name YOUR_STACK_NAME \
--query 'StackEvents[?ResourceStatus==`UPDATE_ROLLBACK_FAILED`].[LogicalResourceId,ResourceStatusReason]' \
--output table
Lệnh này cho bạn biết chính xác resource nào bị lỗi và lý do tại sao. Kết quả thường trông như sau:
MyBucket | Resource does not exist
MyFunction | IAM role not found
Bước 2 — Dùng ContinueUpdateRollback Kết Hợp Skip Resources
ContinueUpdateRollback tiếp tục rollback đang bị dừng. Mấu chốt là flag --resources-to-skip — nó yêu cầu CloudFormation bỏ qua resource bị lỗi và để mọi thứ còn lại rollback bình thường.
aws cloudformation continue-update-rollback \
--stack-name YOUR_STACK_NAME \
--resources-to-skip LogicalResourceId1 LogicalResourceId2
Dùng logical ID từ Bước 1. Nhiều resource được phân cách bằng dấu cách.
Ví dụ thực tế:
aws cloudformation continue-update-rollback \
--stack-name my-prod-stack \
--resources-to-skip MyS3Bucket MyLambdaFunction
Không chắc cần skip resource nào? Thử chạy không có flag trước:
aws cloudformation continue-update-rollback \
--stack-name YOUR_STACK_NAME
Lệnh này thử lại toàn bộ rollback từ đầu. Chỉ hoạt động nếu bạn đã khắc phục vấn đề gốc rễ — ví dụ như đã khôi phục lại một resource bị xóa thủ công trước khi chạy lệnh.
Bước 3 — Sửa Thủ Công Các Resource Đã Bị Skip
Skip một resource không có nghĩa là khôi phục nó. CloudFormation chỉ đánh dấu nó là đã rollback rồi tiếp tục. Trạng thái thực tế của resource trong AWS có thể hoàn toàn không đồng bộ với template của bạn — đó là vấn đề bạn phải tự giải quyết.
Cách xử lý tùy thuộc vào tình huống:
- Resource bị xóa bên ngoài stack: Tạo lại thủ công trong AWS, sau đó dùng stack import hoặc drift detection để đồng bộ lại.
- Resource bị chỉnh sửa bên ngoài stack: Hoặc hoàn tác thay đổi thủ công đó, hoặc cập nhật template CloudFormation để phản ánh trạng thái thực tế hiện tại rồi đẩy một bản cập nhật stack mới.
- Resource không còn cần thiết nữa: Xóa nó khỏi template trong lần cập nhật tiếp theo.
Bước 4 — Kiểm Tra Drift Sau Khi Khôi Phục
Sau khi rollback hoàn tất, hãy chạy drift detection trước khi làm bất cứ điều gì khác:
aws cloudformation detect-stack-drift \
--stack-name YOUR_STACK_NAME
Sau đó kiểm tra kết quả (quá trình phát hiện thường mất 30–60 giây):
aws cloudformation describe-stack-drift-detection-status \
--stack-drift-detection-id DETECTION_ID
Hãy đồng bộ lại các resource bị drift trước lần deploy tiếp theo. Bỏ qua bước này là cách bạn sẽ lại rơi vào vòng lặp thất bại tương tự một tuần sau.
Nếu ContinueUpdateRollback Tiếp Tục Thất Bại
Một số stack bị hỏng quá nhiều để có thể khôi phục từng bước. Lúc đó, hãy xóa và deploy lại. Nếu stack chứa các resource bạn muốn giữ lại — như S3 bucket hay RDS instance — hãy bảo vệ chúng trước:
# Tách riêng các resource cụ thể thay vì xóa chúng
aws cloudformation delete-stack \
--stack-name YOUR_STACK_NAME \
--retain-resources MyS3Bucket MyRDSInstance
Các resource được liệt kê trong --retain-resources sẽ tồn tại sau khi xóa stack. Chúng chỉ bị tách khỏi stack mà thôi. Deploy lại từ một template sạch, sau đó import các resource đã giữ lại vào stack mới.
Xác Nhận Đã Khắc Phục
Sau khi ContinueUpdateRollback chạy xong, kiểm tra trạng thái stack:
aws cloudformation describe-stacks \
--stack-name YOUR_STACK_NAME \
--query 'Stacks[0].StackStatus'
UPDATE_ROLLBACK_COMPLETE nghĩa là thành công — stack đã trở về trạng thái ổn định trước khi cập nhật và sẵn sàng cho lần deploy mới.
Vẫn hiển thị UPDATE_ROLLBACK_FAILED? Quay lại Bước 1. Có thể có một resource thứ hai trong event log cũng cần được skip.
Mẹo Phòng Tránh
- Đừng chỉnh sửa trực tiếp các resource được quản lý bởi CloudFormation trên Console. Thay đổi thủ công là nguyên nhân hàng đầu gây ra lỗi này. Nếu cần kiểm thử gì đó, hãy thực hiện qua stack.
- Bật termination protection cho các stack production:
aws cloudformation update-termination-protection --stack-name YOUR_STACK --enable-termination-protection - Dùng change set trước mỗi lần cập nhật.
aws cloudformation create-change-setcho bạn thấy chính xác những gì sẽ thay đổi — thay thế, xóa, chỉnh sửa — trước khi bất cứ điều gì thực sự xảy ra. - Thêm stack policy để ngăn việc vô tình thay thế các resource có trạng thái quan trọng như RDS instance và S3 bucket.
- Chạy
detect-stack-drifttrong CI/CD trước mỗi lần deploy. Phát hiện resource bị drift trong quá trình kiểm tra pipeline chỉ mất vài phút. Phát hiện nó trong lúc rollback thất bại lúc 2 giờ sáng có thể mất hàng giờ đồng hồ.

