DEV Community

Samir
Samir

Posted on

Implementing OSRM Map Backend on AWS Elastic Container Service (ECS)

Image description

Introduction:

The Open Source Routing Machine (OSRM) is a powerful routing engine designed for calculating shortest paths in road networks.

In this blog, we will explore the process of deploying OSRM on AWS Elastic Container Service (ECS), allowing you to leverage the scalability and flexibility of containerized environments.
We will cover the steps to install Docker, create an OSRM Docker image, push the image to AWS Elastic Container Registry (ECR), and create an ECS cluster, task definition, and service, then publish OSRM service through AWS Application loadBalancer.

Step1: Installing Docker and Creating an OSRM Docker Image:

Install Docker on Linux:
1- Run the following commands in your Admin Server:

sudo yum install -y docker
systemctl enable docker
systemctl start docker
Enter fullscreen mode Exit fullscreen mode

2- Create a demo folder and navigate to it:

mkdir demo && cd demo
Enter fullscreen mode Exit fullscreen mode

3- Pull the OSRM Docker image from DockerHub:

docker pull osrm/osrm-backend
Enter fullscreen mode Exit fullscreen mode

4- Create a Dockerfile:

vi Dockerfile
Enter fullscreen mode Exit fullscreen mode

5- Add the following content to the Dockerfile:

FROM osrm/osrm-backend:latest

RUN mkdir /data
WORKDIR /data
ADD https://download.geofabrik.de/asia/gcc-states-latest.osm.pbf /data
RUN /usr/local/bin/osrm-extract -p /opt/car.lua /data/gcc-states-latest.osm.pbf && \
    /usr/local/bin/osrm-partition /data/gcc-states-latest.osrm && \
    /usr/local/bin/osrm-customize /data/gcc-states-latest.osrm

CMD [ "/usr/local/bin/osrm-routed", "--max-table-size", "100000", "--algorithm", "mld", "/data/gcc-states-latest.osrm" ]
Enter fullscreen mode Exit fullscreen mode

Step2- Create an AWS ECR Repository and Push the OSRM Docker Image:

1- Go to AWS ECR and click on "Repositories."
2- Create a new repository with the name "osrm" and set the visibility to "Private."

Push the Docker image to AWS ECR:
Execute the following commands in your Admin Server:

aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 612843029448.dkr.ecr.us-east-1.amazonaws.com
docker build -t osrm .
docker tag osrm:latest 612843029448.dkr.ecr.us-east-1.amazonaws.com/osrm:latest
docker push 612843029448.dkr.ecr.us-east-1.amazonaws.com/osrm:latest
Enter fullscreen mode Exit fullscreen mode

Step3- Creating an ECS Cluster, Task Definition, and Service:

Create an ECS Cluster:
Provide a name for the cluster (e.g., "osrm-demo").
Choose the desired VPC and private subnets.
Select "Amazon EC2 instances" as the infrastructure type.
Create a new Auto Scaling group (ASG) with the following settings:
Operating system/Architecture: Amazon Linux 2
EC2 instance type: t3.large
Desired capacity: Minimum (1), Maximum (1)
Enable optional monitoring using Container Insights.

Create a Task Definition in JSON format:
Use the provided JSON template to define the OSRM task with the necessary configurations.

{
    "taskDefinitionArn": "arn:aws:ecs:ap-south-1:012345678901:task-definition/osrm:1",
    "containerDefinitions": [
        {
            "name": "osrm",
            "image": "012345678901.dkr.ecr.ap-south-1.amazonaws.com/osrm:latest",
            "cpu": 2048,
            "memory": 4096,
            "portMappings": [
                {
                    "name": "osrm-5000-tcp",
                    "containerPort": 5000,
                    "hostPort": 0,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "environment": [],
            "mountPoints": [],
            "volumesFrom": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-create-group": "true",
                    "awslogs-group": "/ecs/osrm",
                    "awslogs-region": "us-east-1",
                    "awslogs-stream-prefix": "ecs"
                }
            }
        }
    ],
    "family": "osrm",
    "taskRoleArn": "arn:aws:iam::012345678901:role/ecsTaskRole",
    "executionRoleArn": "arn:aws:iam::012345678901:role/ecsTaskExecutionRole",
    "networkMode": "bridge",
    "revision": 1,
    "volumes": [],
    "status": "ACTIVE",
    "requiresAttributes": [
        {
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "name": "com.amazonaws.ecs.capability.ecr-auth"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        },
        {
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "name": "ecs.capability.execution-role-ecr-pull"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
        }
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2"
    ],
    "requiresCompatibilities": [
        "EC2"
    ],
    "cpu": "2048",
    "memory": "4096",
    "runtimePlatform": {
        "cpuArchitecture": "X86_64",
        "operatingSystemFamily": "LINUX"
    },
    "registeredAt": "2023-01-01T16:18:09.874Z",
    "registeredBy": "arn:aws:iam::012345678901:user/myuser",
    "tags": [
        {
            "key": "Name",
            "value": "osrm"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Create an ECS Service:
1- In either the Task Definition or Cluster console, click on "Create Service."
2- Select the existing ECS cluster "osrm-demo".
3- Choose "Capacity provider strategy" under "Compute options."
3- Set the task definition to "osrm" with revision 1 (or the latest revision).
3- Specify the desired number of tasks (e.g., 1).
4- Configure the deployment options and failure detection as per your requirements.
5- Set up an Application Load Balancer (ALB) for load balancing.
6- Create the service.

Image description

Creating an AWS Application Load Balancer (ALB):
1- Provide a name for the ALB (e.g., "osrm-demo-ALB").
2- Set the scheme to "Internet-facing" and IP address type to "IPv4".
3- Choose your VPC and configure mappings for two Availability Zones with one public subnet per zone.
4- Associate the ALB with an existing security group (e.g., "Demo-SG").
5- Configure the ALB listener for port 5000 and protocol HTTP.
6- Create a new target group (e.g., "osrm-tg") and set the health check path to "/nearest/v1/driving/13.388860%2C52.517037?number=3&bearings=0%2C20" (URL-encoded format).
7- Save the ALB configuration.

Image description

Step4- Testing the OSRM Deployment:

You can test your OSRM deployment by accessing the URL generated by your ALB, for example:

http://osrm-demo-alb-012345678901.us-east-1.elb.amazonaws.com:5000/nearest/v1/driving/13.388860%2C52.517037?number=3&bearings=0%2C20
Enter fullscreen mode Exit fullscreen mode

Links:
OSRM: https://map.project-osrm.org/
osrm-backend in GitHub: https://github.com/Project-OSRM/osrm-backend/tree/master
osrm-backend image in Dockerhub: https://hub.docker.com/r/osrm/osrm-backend/
URL Encoding Reference: https://www.w3schools.com/tags/ref_urlencode.ASP

Conclusion:
By following the steps outlined in this blog, you can successfully deploy OSRM on AWS Elastic Container Service (ECS). Leveraging the power of containers and AWS services like ECR and ECS, you can easily scale and manage your OSRM routing engine to handle routing requests efficiently. Enjoy exploring the possibilities of OSRM and building applications that leverage its robust routing capabilities!

Top comments (2)

Collapse
 
osamagamal profile image
Osama Gamal

Great , keep puplishing these good articles.

Collapse
 
eoasis profile image
Blaine • Edited

Well written and to the point. When encountering "is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken action", the IAM > Roles > AmazonSSMRoleForInstancesQuickSetup needs have the added permission of AmazonEC2ContainerRegistryFullAccess.