Next up on Mock for clouds is Moto. Moto is primarily for running tests within the Python ecosystem.
Moto does offer a standalone server mode for a other langauges. General sense was that the standalone Moto server would offer the AWS services which will be accessible from the cli & non-Python SDKs. Gave Moto a shot with the same AWS services tried with Localstack.
(I) Set-up
While installing Moto ran into a couple of dependency conflicts across moto, boto3, botocore, requests, s3transfer & in turn with the installed awscli. With some effort reached a sort of dynamic equillibrium with (installed via pip):
- awscli 1.36.11
- boto3 1.35.63
- botocore 1.35.70
- moto 5.0.21
- requests 2.32.2
- s3transfer 0.10.4
(II) Start Moto Server
# Start Moto
moto_server -p3000
# Start Moto as Docker (Sticking to this option)
docker run --rm -p 5000:5000 --name moto motoserver/moto:latest
(III) Invoke services on Moto
(a) S3
# Create bucket
aws --endpoint-url=http://localhost:5000 s3 mb s3://test-buck
# Copy item to bucket
aws --endpoint-url=http://localhost:5000 s3 cp a1.txt s3://test-buck
# List bucket
aws --endpoint-url=http://localhost:5000 s3 ls s3://test-buck
--
(b) SQS
# Create queue
aws --endpoint-url=http://localhost:5000 sqs create-queue --queue-name test-q
# List queues
aws --endpoint-url=http://localhost:5000 sqs list-queues
# Get queue attribute
aws --endpoint-url=http://localhost:5000 sqs get-queue-attributes --queue-url http://localhost:5000/123456789012/test-q --attribute-names All
--
(c) IAM
## Issue: Moto does a basic check of user role & gives an AccessDeniedException when calling Lambda CreateFunction operation
## So have to create a specific IAM role (https://github.com/getmoto/moto/issues/3944#issuecomment-845144036) in Moto for the purpose.
aws iam --region=us-east-1 --endpoint-url=http://localhost:5000 create-role --role-name "lambda-test-role" --assume-role-policy-document "some policy" --path "/lambda-test/"
--
(d) Lambda
# Create Java function
aws --endpoint-url=http://localhost:5000 lambda create-function --function-name test-j-div --zip-file fileb://original-java-basic-1.0-SNAPSHOT.jar --handler example.HandlerDivide::handleRequest --runtime java8.al2 --role arn:aws:iam::123456789012:role/lambda-test/lambda-test-role
# List functions
aws --endpoint-url=http://localhost:5000 lambda list-functions
# Invoke function (Fails!)
aws --endpoint-url=http://localhost:5000 lambda invoke --function-name test-j-div --payload '[235241,17]' outputJ.txt
The invoke function fails with the message:
"WARNING - Unable to parse Docker API response. Defaulting to 'host.docker.internal'
<class 'json.decoder.JSONDecodeError'>::Expecting value: line 1 column 1 (char 0)
error running docker: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))".
Retried this from AWS Java-SDK & for other nodejs & python function but nothing worked. While this remains unsolved for now, check out Lambci docker option next.
(IV) Invoke services on Lambci Lambda Docker Images:
Moto Lambda docs also mention its dependent docker images from the lambci/lambda & mlupin/docker-lambda (for new ones). Started off with a slightly older java8.al2 docker image from lambci/lambda.
# Download lambci/lambda:java8.al2
docker pull lambci/lambda:java8.al2
# Run lambci/lambda:java8.al2.
## Ensure to run from the location which has the unzipped (unjarred) Java code
## Here it's run from a folder called data_dir_java which has the unzipped (unjarred) class file folders: com/, example/, META-INF/, net/
docker run -e DOCKER_LAMBDA_STAY_OPEN=1 -p 9001:9001 -v "$PWD":/var/task:ro,delegated --name lambcijava8al2 lambci/lambda:java8.al2 example.HandlerDivide::handleRequest
# Invoke Lambda
aws --endpoint-url=http://localhost:9001 lambda invoke --function-name test-j-div --payload '[235241,17]' outputJ.txt
This works!
No comments:
Post a Comment