EnglishPolski
Moto server - AWS API mocking
AWS Cloud

Moto server - AWS API mocking

In this post, I want to show a tool that I find very useful during the development of scripts relying on AWS cloud API.

Since I deal with it quite often (especially recently), and I don’t necessarily want to pay for testing my scripts, MotoServer fits perfectly into this need.

I used localstack not so long ago for this purpose, but due to its recent license change, I lost confidence in recommending it to anyone (even in the free version). In my opinion, the creators of localstack behaved badly.

Disclaimer

Remember that Moto Server and LocalStack are not exactly the same kind of tool.

Moto Server is for mocking, while LocalStack can to some extent simulate real cloud infrastructure, but its API is also limited, and a large part of “working” services require licensing.

Certainly, it’s possible to simulate certain services with other tools instead of localstack, but it’s not as simple, requiring the running of different containers, and rather precise configuration to make everything work together. This is often not necessary for me, so I chose Moto Server for this reason.

Installation

In general, MotoServer is just one of the functionalities of the Moto library for Python. So, to use it you can simply install the library itself:

python3 -m pip install moto

Or if you prefer versions in a container (like me):

docker pull motoserver/moto:latest

From this moment on, I assume that Moto will be running in a container, so I intend to describe this scenario here.

Running

We launch the container, opening port 5000, which is the default port for Moto Server:

docker run -d --rm -p 5000:5000 --name moto motoserver/moto:latest

If you want to see server logs immediately after startup, it’s worth running the container in attached mode by removing the -d flag.

Configuration

Since Moto Server is not a real AWS server, proper configuration profile is required for CLI to work.

Since I like to make things easier for myself in the future, I created such a configuration profile in the file ~/.aws/config:

[profile moto]
region = us-east-1
output = json
aws_access_key_id = test
aws_secret_access_key = test
endpoint_url = http://localhost:5000

The most important thing here is setting the endpoint_url variable to the address of our local Moto server.

From this moment on, setting the moto profile for AWS CLI, it will operate on it:

export AWS_PROFILE=moto
aws sts get-caller-identity

This returns:

{
    "UserId": "AKIAIOSFODNN7EXAMPLE",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:user/moto"
}

Terraform

To configure Terraform/OpenTofu, we also need to set the appropriate endpoint in the provider configuration.

provider "aws" {
  region = "us-east-1"
  endpoints {
    ec2 = "http://localhost:5000"
  }
}

After setting the endpoint, Terraform can easily connect to Moto Server and manage its state just like it was connected to a real cloud.

Don’t forget to set the endpoints for each service you plan to use (only ec2 is show in the example above).

A few additional points at the end

I highlt encourgae to look through the documentation of moto, as you may discover something even more useful for your special needs. Link provided at the bottom of this post.

Non-standard port

If you don’t want to rely on Moto Server’s default port, it can be changed by setting the MOTO_PORT environment variable:

docker run -d --rm -p 3000:3000 --name moto -e MOTO_PORT=3000 motoserver/moto:latest

Dashboard

Try opening following link in your browser:

http://localhost:5000/moto-api

You will see a simple dashboard allowing viewing all resources created on the server.

Quick state reset

If you want to quickly reset the server state, it’s enough to send a POST request to the endpoint /moto-api/reset:

Remember to set proper port, if you haven’t used the default one.

curl -X POST http://localhost:5000/moto-api/reset
Back to Top