Đến nội dung chính
Phạm Nam

Tìm kiếm

Nhập từ khoá để tìm trong các bài viết.

Quay lại
vi

AWS Emulator: test code chạm AWS ngay trên máy

AWS Emulator là trình giả lập AWS chính thức: chạy S3, DynamoDB, SQS ngay trên máy qua HTTPS 127.0.0.1:9297, không cần tài khoản, không phí, cho dev và CI.

10 phút đọc—

AWS Emulator chạy thử code AWS ngay trên máy local

AWS Emulator: test code chạm AWS ngay trên máy

Mở đầu: mock thì sai, deploy thật thì chậm

Bạn viết code đọc file từ S3, ghi metadata vào DynamoDB, đẩy message sang SQS. Test local thì phải mock cả ba service — mock chỉ trả về những gì bạn code sẵn, nên test xanh không chứng minh được hành vi thật. Deploy lên môi trường dev trên AWS thật thì phải chờ pipeline, chờ tài nguyên tạo xong, và lỡ xóa nhầm bảng DynamoDB dùng chung thì cả team cùng dừng lại — chưa kể mỗi lần test là tiền thật.

Coding agent càng làm bài toán này nặng hơn: một vòng lặp viết code, chạy thử, sửa, chạy lại có thể cần hàng chục lần gọi AWS. AWS vừa phát hành AWS Emulator ngày 11/11/2026 để giải đúng chỗ này: trình giả lập AWS chạy ngay trên máy bạn, nhận đúng API AWS thật qua HTTPS local, không cần tài khoản, không phí.

AWS Emulator là gì?

AWS Emulator là trình giả lập cục bộ các API của AWS, do chính AWS phát hành. Repo aws/aws-emulator trên GitHub, viết bằng Rust, giấy phép CC0 1.0 (riêng vendor/ dùng Apache 2.0). Bản ngày ra mắt là v1.0.322 (11/11/2026); tới lúc kiểm chứng (13/11/2026) repo đã lên v1.0.342, khoảng 6.100 sao và 228 fork — release nhiều bản mỗi ngày, phần lớn sửa fidelity.

Cách dùng gọn: cài emulator, chạy nó, rồi trỏ CLI, SDK hoặc coding agent về endpoint local — code không đổi. Một unit test tạo bảng DynamoDB, ghi item rồi đọc lại chạy y hệt như trước, chỉ khác là nó chạy trên máy bạn. Agent cũng vậy: tạo resource, kiểm tra kết quả, lặp lại mà không chờ deploy.

Emulator hỗ trợ các API của những service có API model trong kho API models công khai của AWS — cùng model mà AWS SDK dùng — nên request và lỗi trả về có cùng hình dạng như trên AWS thật. Trong workspace của repo, mỗi service là một crate riêng, driven bởi Smithy model.

Kiến trúc: một endpoint, mỗi service một crate

flowchart LR
    A[AWS CLI / SDK / Coding agent] -->|HTTPS + SigV4| B[AWS Emulator\n127.0.0.1:9297]
    B --> C[Router]
    C --> D[S3]
    C --> E[DynamoDB]
    C --> F[SQS]
    D --> G[In-memory state]
    E --> G
    F --> G

Luồng chạy: client gửi request AWS chuẩn, ký SigV4, tới https://127.0.0.1:9297. Router gắn mọi service lên cùng một endpoint, điều phối request tới crate của từng service, mỗi crate giữ state trong bộ nhớ theo Smithy model của nó. Emulator không có giao diện đồ họa — nó chạy nền, log ra JSON lines.

Khi khởi động, emulator tự sinh credentials, config và chứng chỉ, ghi vào ~/.aws/emulator/9297/. Access key ID bắt đầu bằng EMULATOR nên không nhầm với key thật, và emulator từ chối request ký bằng key khác. Mỗi emulator đóng vai một account duy nhất 000000000000, không có hành vi cross-account hay cross-Region. Endpoint /__admin/health trên cùng cổng để script hoặc CI chờ emulator sẵn sàng.

Cài đặt và chạy lần đầu

Trên Linux, cài bằng gói RPM hoặc Debian:

PKG=https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest
sudo dnf install -y $PKG/aws-emulator-x86_64.rpm

Trên macOS và Windows, chạy emulator trong Docker bằng cách build image từ Dockerfile ngắn trong tài liệu — AWS không phát hành image sẵn.

Chạy emulator:

aws-emulator

Mặc định nó phục vụ HTTPS tại 127.0.0.1:9297, chỉ máy bạn mới chạm tới được. Sau đó, trỏ AWS CLI về endpoint local bằng biến môi trường, đồng thời bỏ mọi biến có thể đưa credential thật vào:

export AWS_ENDPOINT_URL=https://127.0.0.1:9297
export AWS_SHARED_CREDENTIALS_FILE=~/.aws/emulator/9297/emulator_credentials
export AWS_CONFIG_FILE=~/.aws/emulator/9297/config
export AWS_EC2_METADATA_DISABLED=true
export AWS_DISABLE_HOST_PREFIX_INJECTION=true
export AWS_REGION=us-east-1
export AWS_DEFAULT_REGION=us-east-1
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE

Emulator sinh key mới mỗi lần khởi động. Kiểm tra shell đang nói chuyện với emulator:

curl --cacert ~/.aws/emulator/9297/ca.pem https://127.0.0.1:9297/__admin/health
aws sts get-caller-identity

Lệnh AWS CLI quen thuộc chạy y nguyên:

aws s3 mb s3://local-getting-started
echo "hello from the emulator" > hello.txt
aws s3 cp hello.txt s3://local-getting-started/
aws s3 ls s3://local-getting-started/

Với coding agent, có thêm đường tắt: cài skill aws-emulator rồi nhờ agent tự setup emulator (cần AWS CLI 2.35.0 trở lên):

aws agent-toolkit add-skill --skill-name aws-emulator --region us-east-1

Theo mình, điểm đáng tiền nhất nằm ở vòng lặp agent: agent tạo bảng, put item, get item, kiểm tra kết quả rồi sửa code — tất cả local, không deploy, không chờ. Nhớ rằng agent đang test với emulator, không phải AWS thật; bước kiểm chứng cuối vẫn phải làm trên AWS thật (xem phần giới hạn). Nếu muốn agent chạy trên cloud thay vì local, tham khảo chạy Claude Code từ xa trên AWS Bedrock AgentCore.

Embedded mode: nhúng emulator vào test Rust

Ngoài chế độ server, AWS Emulator có chế độ embedded cho test Rust: khởi tạo emulator trong tiến trình test và nối HTTP client của nó vào SDK, thay vì nói chuyện qua mạng với một server riêng. Mỗi instance embedded giữ state riêng, nên các test không chia sẻ bucket, bảng hay queue, và chạy song song được. Chế độ này hiện chỉ cho AWS SDK for Rust, qua crate aws-emulator-embedded trong [dev-dependencies] của Cargo.toml.

Ví dụ tạo bảng, ghi item rồi đọc lại trong tiến trình test:

use aws_emulator_embedded::{AwsEmulatorEmbedded, EmbeddedOptions};
use aws_sdk_dynamodb::types::{AttributeDefinition, AttributeValue, BillingMode, KeySchemaElement, KeyType, ScalarAttributeType};

#[tokio::test]
async fn put_then_get_returns_the_item() {
    let emulator = AwsEmulatorEmbedded::new(EmbeddedOptions::default());
    let config = aws_config::defaults(aws_config::BehaviorVersion::latest())
        .http_client(emulator.http_client())
        .region(aws_config::Region::new("us-east-1"))
        .credentials_provider(emulator.aws_credentials_provider())
        .load()
        .await;

    let ddb = aws_sdk_dynamodb::Client::new(&config);
    ddb.create_table().table_name("emulator-demo-table")
        .attribute_definitions(AttributeDefinition::builder().attribute_name("id").attribute_type(ScalarAttributeType::S).build().unwrap())
        .key_schema(KeySchemaElement::builder().attribute_name("id").key_type(KeyType::Hash).build().unwrap())
        .billing_mode(BillingMode::PayPerRequest).send().await.unwrap();
    ddb.put_item().table_name("emulator-demo-table")
        .item("id", AttributeValue::S("item-1".into()))
        .item("msg", AttributeValue::S("hi".into())).send().await.unwrap();
    let got = ddb.get_item()
        .table_name("emulator-demo-table")
        .key("id", AttributeValue::S("item-1".into()))
        .send().await.unwrap();
    assert_eq!(got.item().unwrap().get("msg").unwrap().as_s().unwrap(), "hi");
}

Lưu ý: embedded mode biên dịch emulator vào binary test, nên lần cargo test đầu tiên nặng như build từ source. Nên dùng chung một CARGO_TARGET_DIR, cache target/ trong CI, và pin emulator theo một commit release.

Fidelity: đo bằng test, công bố theo từng release

Một emulator chỉ hữu ích khi test pass trên nó cũng pass trên AWS thật. AWS đo điều này bằng fidelity test: một chương trình ngắn dùng SDK chạy một workflow — ví dụ lưu object rồi đọc và xóa — và khẳng định hành vi của AWS. Mỗi test được kiểm chứng với AWS thật, và chỉ pass khi emulator khớp AWS trên mọi lời gọi: status code, body, mã lỗi và message chính xác, cùng resource và dữ liệu workflow tạo ra.

Với mỗi release, AWS công bố số test pass của từng service dưới dạng k trên n — ví dụ 40 trên 50 nghĩa là 40 trong 50 test của service đó pass. Bộ test công khai trong repo aws-emulator-evaluation-suite, gồm cả những test chưa pass. Đọc điểm fidelity như ảnh chụp nhanh của một sản phẩm đang cải thiện: thêm test mới có thể làm điểm giảm dù emulator tốt lên.

Nếu emulator chưa implement một operation, nó trả HTTP 501 để test fail ngay lập tức thay vì fail âm thầm. Các khoảng trống được theo dõi trong thư mục issues/ của repo: API và hành vi chưa chạy được nằm ở issues/things-that-do-not-work/, đã sửa xong chuyển sang issues/things-that-now-work/. Repo không nhận PR; báo lỗi qua GitHub Issues, nêu rõ service, operation, SDK và phiên bản, request đã gửi và response khác AWS thật ra sao.

Dùng trong CI

Trong CI: start emulator, set cùng biến môi trường trong script chạy test, chờ /__admin/health rồi chạy test suite. Vì không cần tài khoản AWS, mỗi pull request chạy test tích hợp mà không cần xin credential, lo quota hay dọn resource. Giữ credential thật ngoài môi trường của job test — unset AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN và AWS_PROFILE như ví dụ ở trên.

Build từ source chỉ cần khi bạn sửa emulator, chạy từ checkout, hoặc dùng embedded mode: cần Rust toolchain với Cargo, một C compiler, ít nhất 100 GB đĩa trống cho target/, và máy nhiều nhân; chỉ hỗ trợ Linux x86_64 và aarch64, Windows và macOS dùng đường Docker.

Giới hạn phải biết trước khi dùng

AWS Emulator chỉ dùng để build và test — đừng dùng cho production workload, và đừng dùng để test xem ứng dụng của bạn có an toàn không. Emulator không đánh giá IAM policy và resource-based policy như AWS làm, nên một request mà AWS thật sẽ từ chối vẫn có thể chạy được local. Đây là giới hạn quan trọng nhất: test xanh trên emulator không có nghĩa là phân quyền của bạn đúng. Kiểm tra bảo mật và toàn bộ ứng dụng trên AWS trước khi production.

Các giới hạn khác: mỗi emulator đóng vai một account duy nhất, không có hành vi cross-account hay cross-Region. Mức độ khớp với AWS khác nhau theo từng service — trước khi dựa vào nó, kiểm tra điểm fidelity của đúng service mình dùng trong release notes. Operation chưa hỗ trợ trả 501, nghĩa là test fail rõ ràng thay vì lặng lẽ sai — theo mình đó là hành vi đúng, nhưng bạn cần biết để khỏi ngạc nhiên khi một operation ít dùng chưa chạy được.

Telemetry mặc định bật: emulator gửi dữ liệu sử dụng và lỗi ẩn danh về AWS, tối thiểu hóa nghiêm ngặt — không gồm nội dung request/response, code, credential hay dữ liệu cá nhân, không chia sẻ với bên thứ ba. Tắt bằng aws-emulator --telemetry off (chỉ phiên đó), export EMULATOR_TELEMETRY=off, hoặc ghi [telemetry] enabled = false vào ~/.aws/emulator/config.toml; embedded mode tắt qua EmbeddedOptions::default().telemetry(Telemetry::Off).

Một chi tiết đáng nói: toàn bộ code của emulator do AI agent viết, từ API model của AWS, chạy trên Bedrock AgentCore Runtime Instances, CodePipeline và CodeCommit. Một nhóm agent tìm khoảng trống bằng cách so response của emulator với AWS thật và so code với Smithy model; nhóm khác nhận issue, viết test, implement và review. Một security agent độc lập review các thay đổi theo hướng đối kháng, cả trong lúc sửa lẫn trong pipeline release. Theo mình, đây là trường hợp hiếm hoi một vendor lớn công khai toàn bộ pipeline phát triển bằng agent — và cũng là lý do nên đọc kỹ giới hạn fidelity thay vì tin mù vào logo AWS.

AWS Emulator và Floci: chọn cái nào?

Trên blog này đã có Floci giả lập AWS local miễn phí — trình giả lập AWS mã nguồn mở viết bằng Java, giấy phép MIT, tương thích LocalStack, chạy mọi client qua một endpoint duy nhất http://localhost:4566. Hai tool giải cùng một bài toán nhưng khác gốc gác.

Floci là dự án cộng đồng, thay thế trực tiếp LocalStack Community: cùng cổng 4566, cùng cách cấu hình SDK và credential, init script và endpoint health vẫn chạy. AWS Emulator là sản phẩm chính thức của AWS: driven bởi Smithy model — cùng model mà SDK dùng — chạy HTTPS tại 127.0.0.1:9297, bắt buộc SigV4, key riêng bắt đầu bằng EMULATOR, một account duy nhất, và công bố điểm fidelity theo từng release.

Theo mình, chọn như sau: nếu team bạn đang chạy LocalStack Community và muốn bản thay thế nhẹ, miễn phí, tương thích drop-in qua Docker Compose, Floci hợp lý hơn. Nếu bạn làm việc sâu với AWS SDK, cần hình dạng request/response và mã lỗi khớp AWS thật, muốn điểm fidelity công khai theo từng service, hoặc muốn agent test vòng lặp nhanh — AWS Emulator phù hợp hơn, với điều kiện chấp nhận các giới hạn ở trên và kiểm tra fidelity của đúng service mình dùng. Hai tool không loại trừ nhau: dùng emulator cho vòng lặp dev/test nhanh, và kiểm chứng cuối cùng trên AWS thật trước production.

Lưu ý: AWS không nhắc tới LocalStack trong tài liệu chính thức của emulator, nên bài này không so sánh trực tiếp với LocalStack như một khẳng định đã kiểm chứng. Phần so sánh trên chỉ đối chiếu AWS Emulator với Floci — bài đã đăng trên chính blog này — theo tài liệu của cả hai dự án.

Ưu và nhược điểm

Tiêu chíƯu điểmNhược điểm
Chi phíKhông cần tài khoản, không phí dịch vụ thêmVẫn trả tiền khi deploy lên AWS thật
Vòng lặpTest local, không chờ deployBuild source lần đầu rất nặng
Độ khớpSmithy model, khớp hình dạng request/lỗi; fidelity theo releaseKhông đánh giá IAM; khác nhau theo service; operation thiếu trả 501
Cài đặtLinux gói RPM/Debian; macOS/Windows DockerKhông có image Docker sẵn; embedded chỉ cho Rust SDK
Vận hànhKey riêng; health endpoint cho CIMột account; không cross-account/Region
Bảo mậtChỉ lắng nghe trên máy mìnhTelemetry mặc định bật; code do agent viết

Bài học rút ra

  1. Mock test xanh không chứng minh hành vi thật — emulator khớp hình dạng API mới là cầu nối giữa mock và deploy thật.
  2. Test pass trên emulator không có nghĩa là phân quyền đúng: emulator không đánh giá IAM, nên kiểm chứng bảo mật luôn làm trên AWS thật.
  3. Đọc điểm fidelity của đúng service mình dùng trước khi dựa vào emulator; điểm là ảnh chụp theo release, có thể giảm khi AWS thêm test mới.
  4. Operation chưa hỗ trợ trả 501 là tính năng, không phải lỗi — fail rõ ràng còn hơn fail âm thầm.
  5. Tắt telemetry ngay khi setup nếu team có chính sách dữ liệu, luôn unset credential thật trong job test, và nhớ emulator do agent viết toàn bộ — đọc giới hạn đã công bố thay vì tin mù.

Phạm vi kiểm chứng

Kiểm tra ngày 13/11/2026 với blog chính thức của AWS (“Test your applications against AWS locally with AWS Emulator”, cập nhật 12/11/2026), README và releases của repo aws/aws-emulator: ngày GA 11/11/2026 (v1.0.322), bản mới nhất v1.0.342, khoảng 6.100 sao và 228 fork, giấy phép CC0 1.0 (vendor/ Apache 2.0), endpoint HTTPS 127.0.0.1:9297, biến môi trường, lệnh cài đặt, chế độ embedded, cách đo fidelity, giới hạn IAM/account/501, cách tắt telemetry, pipeline phát triển bằng agent. Các con số 400+ model, 200+ service không có trong nguồn chính thức đã đọc nên bài không dùng; fidelity tổng 56,6% và 6.545 file gap chỉ có ở nguồn thứ cấp nên cũng không dùng. Bài chưa chạy thử emulator bằng tay — lệnh và ví dụ lấy từ tài liệu chính thức của AWS, chưa chạy thực tế; build từ source và hành vi trên macOS/Windows qua Docker chưa kiểm chứng trực tiếp.


Bài viết liên quan

Bình luận

Bình luận được duyệt trước khi hiển thị.

Đang tải bình luận…

Để lại bình luận