Tại Sao CDK Deploy Bị Lỗi Sau Khi Thêm Quy Tắc SCP Nghiêm Ngặt?
Gần đây, tôi đã gặp một vấn đề khó khăn trong quá trình triển khai một CDK stack. Mọi thứ trước đây đều hoạt động bình thường, nhưng sau khi tổ chức của tôi giới thiệu các quy tắc SCP nghiêm ngặt dựa trên thẻ, lệnh cdk deploy của tôi bắt đầu thất bại với thông báo lỗi:
AccessDenied: action cloudformation:CreateChangeSet is not authorized
Ban đầu, điều này không có ý nghĩa với tôi. Tôi đã gán thẻ cho mọi thứ trong mã CDK của mình. Tôi thậm chí còn có một vòng lặp lấy thẻ từ props.Tags và đính kèm chúng bằng cdk.Tags.of(this).add(...). Những thẻ này đã được áp dụng cho tất cả các tài nguyên — bao gồm cả stack CloudFormation.
Vậy tại sao nó lại ngừng hoạt động đột ngột? 🤔
Những Thay Đổi Đã Xảy Ra? SCP và Thực Thi Tại Thời Điểm Yêu Cầu
Chìa khóa nằm ở nơi mà các quy tắc SCP được đánh giá.
Một SCP có thể không chỉ hạn chế các tài nguyên tồn tại, mà còn những cuộc gọi API nào được cho phép. Trong trường hợp của tôi, tổ chức đã có một chính sách như thế này: (ví dụ giả định)
{
"Effect": "Deny",
"Action": "cloudformation:CreateChangeSet",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestTag/Org": "ABC"
}
}
}
Điều này có nghĩa là: nếu yêu cầu CreateChangeSet không bao gồm thẻ yêu cầu, cuộc gọi sẽ bị chặn ngay lập tức.
Gán Thẻ CDK: Hai Thế Giới Khác Nhau
Đây là nơi mà hành vi của CDK trở nên quan trọng:
-
StackProps.tags
Khi bạn truyền các thẻ vào hàm khởi tạosuper(scope, id, props), CDK sẽ bao gồm những thẻ đó trong cuộc gọi APICreateChangeSet. Những thẻ này sẽ xuất hiện dưới dạngRequestTags. Đây là điều mà SCP kiểm tra. -
cdk.Tags.of(resource).add(...)
Phương thức này gán thẻ cho các tài nguyên trong mẫu CloudFormation. Chúng được áp dụng sau khi stack đã được tạo.
Vì vậy, cách tiếp cận cũ của tôi là lặp qua props.Tags và gọi cdk.Tags.of(this).add(...) đã hoạt động tốt trong quá khứ, nhưng giờ đây thất bại vì SCP không cho phép stack được tạo ngay từ đầu. Những thẻ cần thiết đơn giản là không có mặt tại thời điểm yêu cầu.
Giải Pháp: Truyền Thẻ Qua StackProps
Giải pháp rất đơn giản khi tôi hiểu được sự khác biệt này. Trước đây, thuộc tính thẻ của tôi trong props đã được thay thế bằng thẻ mà props:cdk.StackProps mong đợi và sử dụng để khởi tạo cây cấu trúc trong bộ nhớ của CDK (đối tượng Stack bên trong ứng dụng của bạn).
Khi bạn chạy lệnh cdk deploy, CLI sử dụng SDK CloudFormation để gọi:
CreateChangeSet (hoặc UpdateChangeSet) → đây là cuộc gọi API đầu tiên đến AWS.
Tại đây, các thẻ cấp stack (props.tags) được tiêm vào payload yêu cầu
typescript
export class MyStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
for (const [k, v] of Object.entries(props.tags)) {
cdk.Tags.of(this).add(k, v);
}
}
}
new MyStack(app, "MyTaggedStack", {
tags: {
Org: "ABC",
Owner: "TeamA"
}
});
Bây giờ:
- StackProps.tags → sẽ được truyền thẳng vào yêu cầu
CreateChangeSet(SCP chấp nhận ✅). - cdk.Tags.of(this).add(...) → vẫn đảm bảo tất cả các tài nguyên nhận được cùng một thẻ sau khi được tạo.
Kết Luận
Nếu tổ chức của bạn thực thi các quy tắc SCP nghiêm ngặt trên cloudformation:CreateChangeSet, bạn không thể chỉ dựa vào cdk.Tags.of(...). Những thẻ đó đến quá muộn. Bạn cần sử dụng StackProps.tags để các thẻ có mặt trong chính yêu cầu.
Đây là một sự khác biệt tinh tế nhưng quan trọng — và khi tôi hiểu điều đó, lỗi “AccessDenied” cuối cùng cũng có ý nghĩa.
Các Thực Hành Tốt Nhất
- Kiểm tra trước khi triển khai: Luôn kiểm tra các quy tắc SCP hiện tại trong tổ chức của bạn trước khi triển khai.
- Ghi chú thẻ rõ ràng: Đảm bảo rằng các thẻ bạn sử dụng có ý nghĩa và dễ hiểu cho mọi người trong nhóm.
Những Cạm Bẫy Thường Gặp
- Quên xác định thẻ: Một trong những cạm bẫy lớn nhất là quên xác định thẻ cần thiết trong yêu cầu.
- Sử dụng sai phương thức gán thẻ: Như đã nêu, hiểu rõ sự khác biệt giữa các phương thức gán thẻ có thể giúp bạn tránh được nhiều rắc rối.
Mẹo Hiệu Suất
- Tối ưu hóa cấu trúc CDK: Hãy chắc chắn rằng cấu trúc CDK của bạn được tối ưu hóa để giảm thiểu các yêu cầu không cần thiết.
Phần Hỏi Đáp
H: Tại sao tôi không thấy thẻ trong yêu cầu API?
Đ: Bạn cần đảm bảo rằng bạn đã sử dụng StackProps.tags để các thẻ có mặt trong yêu cầu.
H: Có cách nào khác để gán thẻ không?
Đ: Bạn có thể sử dụng các phương thức khác, nhưng hãy đảm bảo hiểu rõ cách chúng hoạt động với SCP.
H: Tôi có thể làm gì nếu gặp lỗi khác trong CDK?
Đ: Luôn kiểm tra log của CDK để tìm hiểu nguyên nhân gốc rễ của vấn đề.
Với những thông tin trên, hy vọng bạn sẽ tránh được những rắc rối khi làm việc với CDK và các quy tắc SCP nghiêm ngặt. Hãy áp dụng những mẹo và thực hành tốt nhất để cải thiện quy trình phát triển của bạn!