Nền Tảng: IAM Service Role và S3 Artifact Bucket
Bài trước vẽ ra bức tranh: CodeBuild build, CodeDeploy deploy, CodePipeline điều phối. Nhưng các dịch vụ đó không tự nhiên có quyền đụng vào tài nguyên của bạn — CodeBuild không tự ghi được log hay đọc code, CodeDeploy không tự đẩy file lên EC2. Mỗi dịch vụ cần được cấp quyền, và cách AWS làm việc đó là service role. Bài này đặt hai viên gạch nền cho cả series: hiểu và tạo service role, và dựng một bucket S3 làm nơi chứa artifact. Tất cả bằng AWS CLI.
Mục tiêu
Hiểu service role và trust policy hoạt động ra sao (không chỉ "tạo cho có"), rồi tạo service role cho CodeBuild và một bucket artifact đúng chuẩn pipeline cần.
Service role: để dịch vụ làm việc thay bạn
Khi bạn gọi AWS, bạn dùng danh tính của mình (IAM user, access key). Nhưng khi CodeBuild chạy một build, nó hành động thay bạn — nó cần một danh tính riêng với đúng quyền cho việc build, không hơn. Đó là service role: một IAM role mà một dịch vụ AWS "mượn" để có quyền tạm thời.
Cơ chế nằm ở hai mảnh của một role:
Trust policy trả lời câu "ai được phép mượn role này?". Với service role cho CodeBuild, trust policy nói "dịch vụ codebuild.amazonaws.com được phép sts:AssumeRole". Không có dòng này, không dịch vụ nào dùng được role.
Permissions policy trả lời câu "role này làm được gì?". Đây là các quyền thật: ghi log, đọc/ghi S3, pull code...
Điểm cốt lõi, và là lý do AWS làm vậy: khi CodeBuild assume role, nó nhận về credential tạm thời (hết hạn sau vài giờ) thay vì một khóa cố định lưu đâu đó. Không có access key nào để rò rỉ, không phải xoay vòng khóa thủ công. Quyền được cấp đúng lúc cần và tự thu hồi.
CodeBuild (dịch vụ AWS)
│ "tôi cần làm việc" → sts:AssumeRole
▼
┌──────────────── awscicd-codebuild-role ─────────────────┐
│ trust policy : ai được assume? → codebuild.amazonaws.com
│ permissions : làm được gì? → ghi log, S3 artifact, GitPull
└──────────────────────────┬──────────────────────────────┘
│ cấp credential TẠM THỜI (vài giờ, tự hết hạn)
▼
CodeBuild dùng quyền đó để chạy build — không lưu khóa nào
Bucket S3 cho artifact
Pipeline cần một nơi để artifact đi qua: CodeBuild build xong cho ra một gói (mã đã build), cất ở S3; CodeDeploy lấy gói đó ra để deploy. Một bucket đứng giữa làm kho trung chuyển.
$ BUCKET="awscicd-artifacts-$(aws sts get-caller-identity --query Account --output text)-ap-southeast-1"
$ aws s3api create-bucket --bucket "$BUCKET" --region ap-southeast-1 \
--create-bucket-configuration LocationConstraint=ap-southeast-1
{
"Location": "http://awscicd-artifacts-111122223333-ap-southeast-1.s3.amazonaws.com/",
"BucketArn": "arn:aws:s3:::awscicd-artifacts-111122223333-ap-southeast-1"
}
Hai cấu hình bắt buộc cho bucket này. Thứ nhất, bật versioning — đây không phải tùy chọn: CodePipeline yêu cầu bucket artifact có versioning, vì nó tham chiếu artifact theo version object để biết chính xác đang chạy bản nào:
$ aws s3api put-bucket-versioning --bucket "$BUCKET" \
--versioning-configuration Status=Enabled
Thứ hai, chặn truy cập public — artifact là mã nguồn đã build, không bao giờ nên lộ ra Internet:
$ aws s3api put-public-access-block --bucket "$BUCKET" \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
Tạo service role cho CodeBuild
Bắt đầu với trust policy — file JSON nói ai được assume role. Lưu thành cb-trust.json:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "codebuild.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}
Tạo role với trust policy đó:
$ aws iam create-role --role-name awscicd-codebuild-role \
--assume-role-policy-document file://cb-trust.json \
--description "Service role for CodeBuild (awscicd series)" \
--query 'Role.[RoleName,Arn]' --output text
awscicd-codebuild-role arn:aws:iam::111122223333:role/awscicd-codebuild-role
Role vừa tạo chưa làm được gì — nó mới có trust policy (ai mượn được) chứ chưa có permissions (làm gì). Gắn permissions policy. Một build tối thiểu cần: ghi log lên CloudWatch, đọc/ghi artifact trên bucket vừa tạo, và pull code từ CodeCommit (nguồn của series). Lưu cb-perms.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Logs",
"Effect": "Allow",
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:log-group:/aws/codebuild/*"
},
{
"Sid": "ArtifactBucket",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:GetBucketLocation"],
"Resource": [
"arn:aws:s3:::awscicd-artifacts-111122223333-ap-southeast-1",
"arn:aws:s3:::awscicd-artifacts-111122223333-ap-southeast-1/*"
]
},
{
"Sid": "PullFromCodeCommit",
"Effect": "Allow",
"Action": ["codecommit:GitPull"],
"Resource": "*"
}
]
}
$ aws iam put-role-policy --role-name awscicd-codebuild-role \
--policy-name awscicd-codebuild-permissions \
--policy-document file://cb-perms.json
Để ý phong cách least privilege: quyền log chỉ giới hạn ở log group của CodeBuild (/aws/codebuild/*), quyền S3 chỉ trên đúng bucket artifact, không mở rộng ra toàn tài khoản. Mỗi dịch vụ một role, mỗi role chỉ đủ quyền cho việc của nó — khi có sự cố, phạm vi ảnh hưởng hẹp.
Kiểm chứng
Xem trust policy (ai được assume) và permissions đã gắn:
$ aws iam get-role --role-name awscicd-codebuild-role \
--query 'Role.AssumeRolePolicyDocument'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "codebuild.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
$ aws iam list-role-policies --role-name awscicd-codebuild-role --output text
POLICYNAMES awscicd-codebuild-permissions
$ aws s3api get-bucket-versioning --bucket "$BUCKET" --output text
Enabled
Trust policy đúng dịch vụ, permissions đã gắn, bucket đã bật versioning. Nền đã sẵn sàng. CodeDeploy và CodePipeline cũng cần service role riêng, nhưng ta sẽ tạo chúng ở đúng bài giới thiệu từng dịch vụ (bài 8 và bài 12), khi các quyền cụ thể có ngữ cảnh để hiểu — thay vì dồn hết vào đây.
🧹 Dọn dẹp
Bucket artifact và role CodeBuild là nền dùng chung cho cả series, nên giữ lại tới khi học xong. Khi muốn xóa (cuối series), chạy:
$ aws iam delete-role-policy --role-name awscicd-codebuild-role --policy-name awscicd-codebuild-permissions
$ aws iam delete-role --role-name awscicd-codebuild-role
$ aws s3 rm "s3://$BUCKET" --recursive # xóa object trước
$ aws s3api delete-bucket --bucket "$BUCKET"
IAM role và bucket S3 rỗng gần như không tốn phí, nên giữ qua các bài không sao; chỉ cần nhớ dọn ở cuối.
Tổng kết
Service role là cách AWS cấp quyền cho một dịch vụ hành động thay bạn: trust policy quyết ai được assume (vd codebuild.amazonaws.com), permissions policy quyết làm được gì, và khi assume dịch vụ nhận credential tạm thời thay vì khóa cố định. Ta đã tạo role cho CodeBuild theo least-privilege (log + S3 artifact + GitPull) và một bucket S3 artifact bật versioning (CodePipeline bắt buộc) cùng chặn public. Đây là nền mọi bài sau dựa vào.
Bài tới dựng nguồn code: tạo một repo CodeCommit, cấp Git credential để push, đẩy một ứng dụng mẫu lên, rồi làm quen branch và pull request — tất cả bằng AWS CLI và Git.