AWS AppMesh for Intelligent ECS Deployments

Jonah Jones
7 min readAug 14, 2019

--

Introduction

  1. Introduction
  2. Deployment Types
  3. AppMesh Basics
  4. Launching the Demo
  5. Verifying Deployment Works
  6. Verifying AppMesh Works
  7. Wrapping Up

If you made it through my last story about python factory method, then awesome! We will be tying that back in during the 3rd post, but for now we need to get our App up and running.

This article will be about getting our Application working, and deployable with AppMesh Service Discovery, and Tracing. If you don’t know what AppMesh is already let’s take a look at the AWS definition.

AWS App Mesh is a service mesh that provides application-level networking to make it easy for your services to communicate with each other across multiple types of compute infrastructure. App Mesh standardizes how your services communicate, giving you end-to-end visibility and ensuring high-availability for your applications.

Deployment Types

What are the different types of Deployments?

Canary Deployment is a deployment type where you deploy the new version of your application onto a % of your cluster, and test it out before declaring it successful, and moving the new version to all your servers.

The major drawback here is the reduced capacity of total compute power from updating/testing and potentially rolling back active servers.

Blue/Green Deployment is a deployment type in which you spin up an identical copy of you application, but running the new version of code. You then cutover your load balancer to the new version, resulting in no reduced server capacity or downtime.

The major drawback here is that we can test functionally test our “green” environment, but not with production level traffic.

Canary Blue/Green Deployment is a deployment type that starts like a blue/green deployment, but once our green services are online we can test utilizing canary traffic shifting to test our new application with a small % of real traffic.

The major drawback is that this is not out of the box supported by AWS ECS and Codedeploy at the moment. Which is why we are going to achieve this with AppMesh

Our final article will be combining two deployment methods. This article’s demo today will end you with a working Blue/Green Deployment.

AppMesh Basics

There are a few key components of AppMesh to cover before we go through the example. I am going to summarize each portion in my own simple terms, if you really want a more in depth understanding check out the AWS docs on AppMesh.

Mesh

This is logical boundary for all of our mesh components

Virtual Service

These are the services within the mesh that will be where we route requests to. In other works our Backend.

Virtual Router

Which port protocol to listen to traffic on, and where to route those requests we receive. (Very similar to an ALB)

Virtual Routes

Once the Router receives a request, routes define which nodes to send traffic to, and at what weighted percentage. (Very similar to an ALB Listener Rule)

Virtual Nodes

Envoy image configured with AppMesh settings in the task definition providing a proxy for our tasks.

A typical request looks like such

Launching the Demo

To launch our infrastructure we are going to use our git repo

github.com/jonahjones777/canary-mesh

Check the README.md for the list of required packages we need, and the corresponding commands to install them on OSX with Brew.

Once we are ready we can launch with

make launch

This will do 3 things

  1. launch our AWS stack using terraform. This includes
  • VPC and required pieces for public/private subnets
  • ECS Service, ECR Repo, and ECS Cluster
  • ALB, and On-Demand EC2 Cluster configured to join ECS Cluster
  • Codepipeline, CodeBuild, Codedeploy to Handle BlueGreen Deployments.
  • Service discovery namespace, and AWS Cloudmap app
  • AWS AppMesh Mesh, Service, Router and Routes tied to Cloudmap
  • Xray Tracing for AppMesh

2. Create Buildspec and Task Definition for BlueGreen Deploys

  • Uses Jinja to Template buildspec.yml and task_def.json with created values
  • Uploads created files to CodePipeline artifact bucket

3. Build and Push Image

  • Build our demo app with Xray tracing written in app
  • Uploads our image to ECR repo, which triggers pipeline!

One this is finished we should be able go see our new service by clicking on the URL from the tf.env, or from the Load Balancer console DNS name.

Awesome it looks like our app works, let’s check the URL/service-status path too.

Verifying Deployment Works

We should be able to push new software deployments now by executing a make command.

Let’s give it a try by incrementing the version number in app/app/version.txt to 1.1, saving and running

make build

Next we need to go our Codepipeline, and find the CodeDeploy Blue/Green step which is currently the 3rd step. We need to guide it through the process of approving our new app version.

Once we are here, and the new green tasks come online and pass their Application Load Balancer Health Checks, we will be allowed to click the button to route traffic to our new version.

To confirm our CICD pipeline is working we go back to our service-status endpoint and we should be able to see the version got incremented by hitting the URL/service-status

Verify AppMesh Works

Now we know that our app works, and our deployment pipeline is functioning as intended we are going to verify that AppMesh, and our service discovery are working correctly. There are a few things we need to check here.

  1. Service Discovery

We have configured our AppMesh Virtual nodes to use AWS CloudMap to automatically publish and register themselves via CloudMap for other apps to route to.

We can confirm this by going to AWS CloudMap and checking the service namespace, and confirming we have healthy registered nodes.

We see it registered, but let’s confirm that it’s actually working correctly by hitting our service discovery URL. We write a quick curl loop hitting test1.service/service-status

We have just confirmed we are able to route to our service discovery namespace. We are doing internal routing with these requests via our service mesh, which has some great benefits such as:

  • Reduces cost since inter app traffic isn’t going through our LoadBalancers
  • Reduces latency since inter app traffic isn’t going through our LoadBalancers

2. Xray Tracing

Let’s go to the Xray service page, and check to make sure our internal tracing, and AppMesh tracing are working. It should look something like this.

For Internal App tracing a typical use case would be to turn tracing on when we have an application function we suspect is having issues. We then add tracing at the start of that function, and send a user.id or customer.id to Xray via the trace metadata function. We can then observe and correlate failures to particular users we detect might be having issues, and look for patterns in these issues.

AppMesh tracing can also be really useful once when we have multiple Microservices within the same AppMesh talking to each other. It can help solve and detect issues such dropped and throttled requests, api latencies, and TLS errors.

Wrapping Up

To Cleanup the application run this command from the project root.

make destroy

Thanks for reading, and stay tuned for last article in our series where add the canary portion to our Blue/Green Deployment using the Factory Method discussed in the first article.

“Opinions expressed are solely my own and do not express the views or opinions of Amazon”

--

--

Jonah Jones

Hi I work at AWS as a DevOps Consultant. Stay tuned for some wacky DevOps, bad python , and even worse golang.