AWS ECS bật tính năng Execute-Command đúng chuẩn – Kinh nghiệm thực chiến Chuyên mục Devops 2025-06-26 0 Lượt xem 0 Lượt thích 0 Bình luận
Tổng quan
Tính năng execute-command của ECS cho phép truy cập trực tiếp vào container đang chạy mà không cần SSH hay mở port, rất an toàn và tiện cho việc debug, kiểm tra container.
Tuy nhiên, muốn bật tính năng này trên ECS Fargate hoặc EC2, cần tuân thủ một số yêu cầu bắt buộc về Task Role, quyền hạn IAM và cấu hình chính xác Task Definition. Dưới đây là checklist và hướng xử lý thực tế mà mình đã triển khai.
1. Các yêu cầu bắt buộc
✅ Task Definition cần có trường taskRoleArn hợp lệ
-
Đây là role IAM mà Task assume để được phép sử dụng execute-command.
-
Không có trường này hoặc để trống, khi update ECS service kèm --enable-execute-command sẽ báo lỗi:
The service couldn't be updated because a valid taskRoleArn is not being used.
✅ Role được gán (taskRoleArn) cần có quyền tối thiểu sau:
-
AmazonSSMManagedInstanceCore
→ Cho phép task sử dụng SSM để truyền dữ liệu khi execute-command. -
CloudWatchLogsFullAccess hoặc quyền tối thiểu để ghi log ra CloudWatch.
→ Giúp theo dõi lệnh thực thi hoặc output khi vào container.
2. Quy trình triển khai chi tiết
Bước 1: Tạo Task Role cho ECS
-
Vào IAM → Roles → Create Role
-
Trusted entity: Elastic Container Service Task
-
Gán các policy sau:
AmazonSSMManagedInstanceCore
AmazonECSTaskExecutionRolePolicy
CloudWatchLogsFullAccess
-
Đặt tên ví dụ: ecsTaskRoleForYour_Project_Name
Bước 2: Cập nhật Task Definition gán Task Role
Nếu update Task Definition tự động qua Jenkins pipeline, cần bổ sung đoạn sau:
stage ('Update Task Definition') {
steps {
withAWS(credentials: 'awscreds', region: AWS_REGION) {
script {
try {
echo "🔍 Fetching current Task Definition..."
sh "aws ecs describe-task-definition --task-definition ${TASK_DEF_NAME} --query taskDefinition --output json --region ${AWS_REGION} > task-def.json"
def imageTag = "${API_IMAGE}:${BUILD_NUMBER}"
def containerName = "${TASK_CONTAINER_NAME}"
def taskRoleArn = "${TASK_ROLE_ARN}"
echo "🖼 Image to update: ${imageTag}"
echo "🎯 Container Name: ${containerName}"
echo "🛠 Filtering and updating Task Definition..."
sh """
cat task-def.json | jq --arg IMAGE '${imageTag}' --arg NAME '${containerName}' '
del(.taskDefinitionArn, .revision, .status, .registeredAt, .registeredBy, .requiresAttributes, .compatibilities)
| (.containerDefinitions[] | select(.name == \$NAME) .image) = \$IMAGE
| .taskRoleArn = '${taskRoleArn}'
' > updated-task-def.json
"""
echo "✅ Validating JSON before registering..."
sh "cat updated-task-def.json | jq empty || (echo '❌ JSON is invalid!' && exit 1)"
echo "📜 Task Definition after update:"
sh "cat updated-task-def.json"
echo "🚀 Registering new Task Definition..."
sh "aws ecs register-task-definition --cli-input-json file://updated-task-def.json --region ${AWS_REGION}"
// Get latest revision of task definition
def newTaskDef = sh(
script: "aws ecs describe-task-definition --task-definition ${TASK_DEF_NAME} --query taskDefinition.revision --output text --region ${AWS_REGION}",
returnStdout: true
).trim()
echo "✅ New Task Definition Revision: ${newTaskDef}"
// Save new task definition to use in next stage
env.NEW_TASK_DEF = newTaskDef
} catch (Exception e) {
error "❌ Failed to update Task Definition: ${e.message}"
}
}
}
}
}
stage ('Deploy to ECS') {
steps {
withAWS(credentials: 'awscreds', region: AWS_REGION) {
echo "🚀 Updating ECS service to use new Task Definition: ${TASK_DEF_NAME}:${env.NEW_TASK_DEF}"
sh """
aws ecs update-service \
--cluster ${ECS_CLUSTER} \
--service ${ECS_SERVICE} \
--task-definition ${TASK_DEF_NAME}:${env.NEW_TASK_DEF} \
--enable-execute-command \
--region ${AWS_REGION}
"""
}
}
}
Lưu ý escape biến trong Groovy pipeline để tránh lỗi.
Bước 3: Deploy ECS Service kèm bật execute-command
aws ecs update-service \
--cluster <cluster-name> \
--service <service-name> \
--task-definition <task-definition-name>:<revision-number> \
--enable-execute-command \
--region <aws-region>
3. Kiểm tra và truy cập vào container
Tìm task-id của Service
aws ecs list-tasks \
--cluster <cluster-name> \
--service-name <service-name> \
--region ap-northeast-1
Hoặc lấy nhanh task-id:
TASK_ARN=$(aws ecs list-tasks --cluster <cluster-name> --service-name <service-name> --region ap-northeast-1 --query 'taskArns[0]' --output text)
TASK_ID=$(echo $TASK_ARN | awk -F'/' '{print $NF}')
Kiểm tra đã bật execute-command chưa
aws ecs describe-tasks \
--cluster <cluster-name> \
--tasks $TASK_ID \
--region ap-northeast-1 \
--query "tasks[0].enableExecuteCommand"
Nếu trả về true là đã bật thành công.
Truy cập vào container
aws ecs execute-command \
--cluster <cluster-name> \
--task $TASK_ID \
--container <container-name> \
--interactive \
--command "/bin/sh" \
--region ap-northeast-1
4. Một số lưu ý khác
✅ Nếu là Fargate, không cần cài SSM Agent, AWS tự xử lý.
✅ Nếu dùng EC2, cần đảm bảo instance thuộc ECS Cluster đã bật SSM Agent.
✅ Nếu thiếu quyền hoặc cấu hình sai, execute-command sẽ báo lỗi kết nối.
✅ Sau khi update Task Definition hoặc Service, nên kiểm tra lại trên Console phần Task Role để chắc chắn đúng.
5. Tổng kết
Việc bật execute-command trên ECS rất hữu ích nhưng cũng cần hiểu đúng yêu cầu của AWS để tránh sai sót. Quy trình trên là kinh nghiệm thực tế, đã triển khai thành công trên hệ thống sản xuất, bạn hoàn toàn có thể áp dụng tương tự.
Hy vọng bài note giúp bạn hoặc team tiết kiệm thời gian và tránh lỗi vặt khi cần bật tính năng execute-command trên ECS.
6. Tài liệu tham khảo chính thức
AWS hướng dẫn về enable-execute-command:
https://docs.aws.amazon.com/cli/latest/reference/ecs/update-service.html
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html
Bình luận (0)