Launching Virtual Channels on AWS with Consuo
Tags: aws, videostreaming, docker, ecs
Published: 2020-05-27 20:37:33

[Consuo](www.consuo.tv) is a cloud-agnostic software component to generate virtual linear TV channels, and in this blog post we will describe how you can deploy this component to AWS and not having to manage any server instances.

# Elastic Container Service and Fargate

[Amazon ECS (Elastic Container Service)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) is a container management and orchestrator of Docker containers running on a cluster. With the Fargate launch type you run your cluster on a serverless infrastructure, and this is what we will use in the example.

## Task Definitions

Before we create the ECS cluster we will start by defining two task definitions. One task definition for the Consuo Schedule container, and another for the Consuo Engine container.

Let us begin with the task definition for the Consuo Schedule task. Some parts are left out to highlight the Consuo specifics.

```json
{
  ...
  "containerDefinitions": [
    {
      ...
      "entryPoint": null,
      "portMappings": [
        {
          "hostPort": 8001,
          "protocol": "tcp",
          "containerPort": 8001
        }
      ],
      ...
      "environment": [
        {
          "name": "CORS_WHITELIST",
          "value": "https://example.com,https://www.example.com"
        },
        {
          "name": "KEY",
          "value": <LICENSEKEY>
        }
      ],
      ...
      "image": "eyevinntechnology/consuo-schedule:v1.1.0",
      "name": "consuo-schedule",
      ...
    }
  ],
  "requiresCompatibilities": [
    "FARGATE"
  ],
  ...
}
```

We define the port mappings for the default port that is 8001 for Consuo Schedule and provide the environment variables `CORS_WHITELIST` and the license key. For a full list of available environment variables and their purpose read the [Consuo documentation](docs.consuo.tv).

We then define a similar task definition for the Consuo Engine.

```json
{
  ...
  "containerDefinitions": [
    {
      ...
      "entryPoint": null,
      "portMappings": [
        {
          "hostPort": 8000,
          "protocol": "tcp",
          "containerPort": 8000
        }
      ],
      ...
      "environment": [
        {
          "name": "CHANNELMGRAPI",
          "value": "http://<CONSUO_SCHEDULE_IP>:8001"
        },
        {
          "name": "KEY",
          "value": <LICENSEKEY>
        }
      ],
      ...
      "image": "eyevinntechnology/consuo-engine:v1.1.0",
      "name": "consuo-schedule",
      ...
    }
  ],
  "requiresCompatibilities": [
    "FARGATE"
  ],
  ...
}
```

At the moment we have a placeholder for the `CHANNELMGRAPI` variable and we will later replace it with the URI that the Consuo Schedule API will be accessible on. In both task definitions we define that we want to use Fargate as the launch type for these tasks.

## Cluster and Services

Then we will create the cluster for Consuo services in ECS. Once the cluster is created we will then create two services. One for the Consuo Schedule service and another for the Consuo Engine service.

When creating the services we will use each of the task definitions defined above and service type `REPLICA` and launch type `FARGATE`. For the Schedule service you need to ensure that the security group allows TCP traffic on port 8001 and for the Engine service open up port 8000, as this is what we specified in the task definitions. Number of replicas we set initially to 1.

## Load Balancing

To be able to access these services we need to setup a load balancer. We will use the AWS Application Load Balancer so we can reuse the same instance for both services. We will have one target group for each of the services. The ALB we configure with two listeners: HTTP 8000 and HTTP 8001 where port 8000 forwards to the Consuo engine target group and port 8001 forwards traffic to the Consuo schedule target group.

Once everything is setup you will then be able to access the Consuo schedule service on for example: `http://alb-consuo-486438318.eu-north-1.elb.amazonaws.com:8001/api/docs/`

And now you can update the `CHANNELMGRAPI` variable to point to for example `http://alb-consuo-486438318.eu-north-1.elb.amazonaws.com:8001`.

If you don't intend to have the schedule accessible outside of the cluster we could use the service discovery functionality and have the Consuo schedule container only accessible by the Consuo engine container. That is left as an exercise for the reader.

## CDN

To off-load the traffic to the Consuo engine service it is recommended to place a CDN in front of it. With AWS we can use their CDN service Cloudfront to do this. This also gives a possibility to have SSL termination which is today needed to be able to play the stream in a browser. You create a distribution where you specify the ALB as the origin and origin port 8000. Important to configure the distribution to `Use Origin Cache Headers` and query string whitelist `channel`. You might also want to override the caching TTLs for error codes such as 404 and 500, to avoid getting 404s stuck in the caches.

When everything is up and running you will now have a system setup that looks similar to this drawing.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i2drh1xe20pek7o57mmr.png)