How to Access S3 Bucket from Another AWS Account

  • January 14, 2025
  • 40

Có 2 tài khoản aws khác nhau, làm sao để từ EC2 trong tài khoản A có thể access vào S3 của tài khoản B. Chúng ta hoàn toàn có thể làm được điều này khi cấu hình cross-account access giữa hai tài khoản aws.

Bước 1: Tạo IAM Role trong Account B

  1. Đăng nhập vào Account B và vào IAM console.
  2. Chọn Roles và nhấn Create role.
  3. Trong Select trusted entity, chọn Another AWS account.
  4. Nhập Account ID của Account A vào mục Account ID. (Nếu cần bảo mật cao hơn, bạn có thể dùng thêm External ID.)
  5. Nhấn Next để gán quyền.

Bước 2: Gán Quyền S3 cho IAM Role trong Account B

  1. Trong phần Permissions policies, thêm quyền s3:PutObject cho bucket trong Account B để cho phép Elastic Beanstalk của Account A tải file lên bucket. Tạo một chính sách tùy chỉnh với nội dung sau:


// Thêm quyền cho role để có thể truy cập đến toàn bộ bucket s3 của tài khoản B

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "s3:ListAllMyBuckets",
               "s3:GetObject",
               "s3:PutObject",
               "s3:DeleteObject"
           ],
           "Resource": "arn:aws:s3:::*"
       }
   ]
}

// Chỉ cho phép access đến 1 số bucket
{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": "s3:*",
           "Resource": [
                "arn:aws:s3:::your-bucket-name",
                "arn:aws:s3:::your-bucket-name/*"
            ]
       }
   ]
}

Thay your-bucket-name bằng tên bucket của bạn trong Account B.
Đặt tên cho IAM Role, ví dụ: AccountA-Upload-To-S3-AccountB, và nhấn Create role để hoàn tất.

Bước 3: Cấu hình IAM Role trong Account A để Assume Role của Account B

Trong Account A, vào IAM console, tạo một IAM Role dành cho EC2. Gán cho role này quyền sts:AssumeRole để assume role vừa tạo trong Account B. Bạn có thể tạo một chính sách tùy chỉnh như sau:


{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam:::role/AccountA-Upload-To-S3-AccountB"
    }
  ]
}

Thay bằng Account ID của Account B và AccountA-Upload-To-S3-AccountB là tên IAM Role đã tạo trong Account B.
Gán IAM Role này cho EC2 trong Account A.

Bước 4: Check assume role

Kiểm tra xem từ EC2 của Account A có access được vào S3 của account B không?

ROLE_ARN="arn:aws:iam::{AccountIdAccountB}:role/{RoleCreateFromAccountB}"
CREDS=$(aws sts assume-role --role-arn $ROLE_ARN --role-session-name "EC2ToS3Session")

export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r '.Credentials.SessionToken')
Các lệnh trên sẽ assume role và thiết lập thông tin xác thực tạm thời. Sau đó đùng awl cli để kiểm tra xem có access được đến các bucket của account B không?

aws s3 ls

aws s3 ls s3://your-bucket-name
Nếu liệt kê được các bucket của account B thì config đã thành công.

PHP Assume Role and upload File to S3

Thêm code php để có thể upload được file lên s3 của account B

<?php
require 'vendor/autoload.php'; use Aws\Sts\StsClient; use Aws\S3\S3Client; use Aws\Exception\AwsException; function uploadFileToS3($filePath, $bucketName, $key) { // 1. Assume Role $stsClient = new StsClient([ 'version' => 'latest', 'region' => 'ap-northeast-1', // Thay đổi nếu cần ]); try { $result = $stsClient->assumeRole([ 'RoleArn' => 'arn:aws:iam::{accountIdAccountB}:role/EC2UploaderRoleAccountB', // Role ARN của Account B 'RoleSessionName' => 'PHPAppS3UploadSession', ]); $credentials = $result->get('Credentials'); // 2. Tạo S3 client với thông tin xác thực tạm thời từ Assume Role $s3Client = new S3Client([ 'version' => 'latest', 'region' => 'ap-northeast-1', 'credentials' => [ 'key' => $credentials['AccessKeyId'], 'secret' => $credentials['SecretAccessKey'], 'token' => $credentials['SessionToken'], ], ]); // 3. Upload file lên S3 bucket trong Account B $s3Client->putObject([ 'Bucket' => $bucketName, 'Key' => $key, 'SourceFile' => $filePath, ]); echo "File uploaded successfully to {$bucketName}/{$key}"; } catch (AwsException $e) { // Hiển thị lỗi nếu quá trình assume role hoặc tải lên gặp lỗi echo "Error: " . $e->getMessage(); } } // Gọi hàm để tải file $filePath = '/path/to/local-file.png'; // Đường dẫn tới file cục bộ $bucketName = 'bucket-cua-ban'; // Thay bằng tên S3 bucket trong Account B $key = 'duong-dan-luu-file.png'; // Đường dẫn mong muốn lưu file trên S3 uploadFileToS3($filePath, $bucketName, $key);

Tài liệu tham khảo

https://repost.aws/knowledge-center/cross-account-access-s3
https://www.geeksforgeeks.org/how-to-access-s3-bucket-from-another-aws-account