Building and Pushing Tesseracts with Github Actions and Deploying them on Amazon ECS

Purpose

This writeup describes how to

  1. build Tesseracts with Github Actions
  2. push them to Amazon Elastic Container Registry
  3. and deploy them to Amazon Elastic Container Service

This document assumes you have some knowledge of Github Actions and how to use it to build and push Docker images to a container registry e.g. DockerHub, Azure, GCP, AWS

AWS Architecture Diagram

We will be building and deploying a Tesseract to the following AWS architecture

Creating and storing your Tesseract Image

Create a repo for your Tesseract in Amazon ECR

Use Github Actions to build and push the tesseract to Amazon ECR

# This is a basic workflow to help you get started with Actions
name: deploy
# Controls when the action will run.
on:
  # Triggers the workflow on push or pull request events but only for the master branch
  push:
    branches:
      - main
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  deploy-tsadar-tesseract:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1
      - name: Build and tag app image to Amazon ECR
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: continuum
          IMAGE_TAG: <INSERT_YOUR_TAG_HERE>
          TESSERACT_NAME: <INSERT_TESSERACT_NAME_HERE>
        run: |
          pip install tesseract-core
          tesseract --loglevel debug build tesseract/ --tag $IMAGE_TAG
          docker tag $TESSERACT_NAME:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
      - name: Push all images to Amazon ECR
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: continuum
        run: |
          docker push --all-tags $ECR_REGISTRY/$ECR_REPOSITORY

There should now be an image in your ECR repo

Deploying the Tesseract to Amazon Elastic Container Service

Create a VPC (if you haven’t already)

If you don’t have a Virtual Private Cloud (VPC) set up already (effectively a local secure network on the cloud), you should do so . There are many tutorials for this if you need.

Create an ECS Fargate Service and Container

Once you have a VPC, we can deploy a server that hosts the Tesseract using Amazon ECS. We use the following CDK code to operationalize building and deployment of the Tesseracts. Note that we use Fargate here but similar ideas apply to ContainerInstances as well.

tess_task_def = ecs.FargateTaskDefinition(stack, "thomson-tesseract-task-def", cpu=512, memory_limit_mib=2048)
tess_container = tess_task_def.add_container(
    "tess-container",
    image=ecs.ContainerImage.from_ecr_repository(repository=stack.ecr_repo, tag=$IMAGE_TAG),
    logging=ecs.LogDriver.aws_logs(stream_prefix="tesseract_log"),
    environment={"ENV_VAR": "env_var"},
    entry_point=["tesseract-runtime"],
    command=["serve"],
)
tess_container.add_port_mappings(ecs.PortMapping(protocol=ecs.Protocol.TCP, container_port=8000))
tess_service = ecs.FargateService(
    stack,
    "thomson-tess-service",
    cluster=stack.cluster,
    vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS),
    assign_public_ip=False,
    task_definition=tess_task_def,
    desired_count=1,
)

Add a cloudmap namespace so dynamic routing can be performed

tess_service.enable_cloud_map(
    cloud_map_namespace="namespace", dns_record_type=serv_disc.DnsRecordType.A, name="tesseract1"
)

This line makes your ECS service visible to other entities in the VPC. You can establish a cloud map which functions as a local domain that is accessible within the VPC. The name=tess_prefix sets the address at which you can find the Tesseract to http://tesseract1.namespace:8000

Update Security Group

Any object that interacts with the Tesseract need to be in the appropriate security group. Make sure you let the security group that is interacting with the Tesseract access port 8000 of the Tesseract security group

Using the Tesseract

This code snippet can be used on a server that has access to the Tesseract server (making sure the security group is set correctly, the cloud map is performed correctly, etc.)

from tesseract_core import Tesseract

tesseract = Tesseract(url="http://tesseract1.namespace:8000")
apply_args = {} # Create apply args here
apply_result = tesseract.apply(apply_args)

More full-fledged example - Interacting with a Tesseract through a Streamlit App

e.g. tsadar-app/tsadar_gui/tesseract_ui.py at 79bccd4bd917a119e1d046a6b080540e1adcb536 · ergodicio/tsadar-app · GitHub

1 Like