Implementing OSRM Map Backend on AWS Elastic Container Service (ECS)
Tags: aws, cloud, ecs, docker
Published: 2023-07-06 16:31:26


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/li3jwaxmvxceucyeq5so.png)

## 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
```
2- Create a demo folder and navigate to it:
```
mkdir demo && cd demo
```
3- Pull the OSRM Docker image from DockerHub:
```
docker pull osrm/osrm-backend
```
4- Create a Dockerfile:
```
vi Dockerfile
```
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" ]
```


## 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
```


## 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"
        }
    ]
}
```


**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvu4uc8eahvfsnogbdsw.png)

**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oocrmdz6et1s9a7z09c6.png)


## 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
```

**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!