Using App Mesh To Secure Inter-service Communication - Setup App Mesh, Cloud Map

I will be writing series three articles to discuss a step by step approach to set up AWS App Mesh for services also enabling secure communication between them. In this first article, we will set up AWS Cloud Map and App Mesh for our services.
Before diving into the setup let's understand the scenario. 

Scenario

 
We have two web services, namely API1 and API2. UI component will call API1 and API1 will call API2 to get the required data. We have to use service mesh for services to make them more observable, reliable and secure without any updates at application/service level. Services will scale up/down based on load so services must use service discovery mechanism.
 
We will make use of following AWS services to setup demo infrastructure.
 
  • AWS Cloud Map
  • Elastic Container Service
  • Route53
  • AWS App Mesh
  • Elastic Container Registry
  • AWS Certificate Manager
  • IAM
  • Network Load Balancer
 
 
Design of the diagram for demo application,
 
 
Let's start discussing and setting up each service.
 

AWS Cloud Map

 
AWS Cloud Map is a cloud resource discovery service. It allows us to specify service and register instances with that service. That service will keep track of dynamically updating resources. In demo applications for service discovery requirement we will use AWS Cloud Map. We have two web services, so first decide service discovery names for services which will be used to locate service resource. e. g. for API1 – api1.demo.local and for API2 – api2.demo.local.
 
setup 
 
We will create namespce for these services. Go to AWS console and search for AWS Cloud Map service. Click on Create namespace button. Provide name for namespace as “demo.local”. This namespace will be used by service for service discovery. We will create services under namespace in step 3.
 
You can create namespace using AWS CLI as well, as follow.
  1. aws servicediscovery create-private-dns-namespace --name demo.local --vpc vpc-*****c86

AWS App Mesh

 
AWS App Mesh is a service mesh. It provides application-level networking, end-to-end visibility and high-availability for applications. To meet service mesh requirement we will use AWS App Mesh. UI will call services via NLB. NLB will talk to Gateway service in App Mesh, which will redirect traffic to API1 virtual service through virtual gateway. API1 will in turn call API2 if required via virtual service.
 
setup
 
To create App Mesh, search for AWS App Mesh in AWS console. Click on create mesh button. Provide name for App Mesh and select deny external traffic as we are going to use any service which will be out of our App Mesh. Click Save.
  1. input:  
  2. aws appmesh create-mesh --mesh-name demoappmesh --spec '{"egressFilter": {"type": "DROP_ALL"}}'  
  3.   
  4. output:  
  5. {  
  6.     "mesh": {  
  7.         "meshName""demoappmesh",  
  8.         "metadata": {  
  9.             "arn""arn:aws:appmesh:us-east-1:*********:mesh/demoappmesh",  
  10.             "createdAt": "***", "lastUpdatedAt": "***", "meshOwner": "***", "resourceOwner": "***", "uid": "***", "version": 1  
  11.         },  
  12.         "spec": {  
  13.             "egressFilter": {  
  14.                 "type""DROP_ALL"  
  15.             }  
  16.         },  
  17.         "status": {  
  18.             "status""ACTIVE"  
  19.         }  
  20.     }  
  21. }  

Virtual node

 
We will create virtual node for each web service. Select App Mesh and go to Virtual nodes in left side pane. Click on Create virtual node. Provide name for node. Select AWS Cloud Map as service discovery method. Provide Namespace as name of cloud map namespace, we have created above i.e. demo.local. Provide service name as name of service which we create in step 3 i.e. api1. Select protocol and port which your service exposes. Create virtual node for API2 as well.
 
 
AWS CLI command to create virtual node,
  1. input:    
  2. aws appmesh create-virtual-node   
  3. --mesh-name demoappmesh   
  4. --spec '{"listeners": [{"portMapping": {"port": 5000,"protocol""http"}}], "serviceDiscovery": {    
  5.     "awsCloudMap": { "namespaceName""demo.local""serviceName""api2"    
  6.     }}}' --virtual-node-name api2    
  7.     
  8. output:    
  9. {    
  10.     "virtualNode": {    
  11.         "meshName""demoappmesh",    
  12.         "metadata": {    
  13.             "arn""arn:aws:appmesh:us-east-1:***:mesh/demoappmesh/virtualNode/api2",    
  14.             "createdAt""***""lastUpdatedAt""***""meshOwner""***""resourceOwner""***""uid""***""version": 1    
  15.         },    
  16.         "spec": {    
  17.             "listeners": [    
  18.                 {    
  19.                     "portMapping": {    
  20.                         "port": 5000,    
  21.                         "protocol""http"    
  22.                     }    
  23.                 }    
  24.             ],    
  25.             "serviceDiscovery": {    
  26.                 "awsCloudMap": {    
  27.                     "namespaceName""demo.local",    
  28.                     "serviceName""api2"    
  29.                 }    
  30.             }    
  31.         },    
  32.         "status": {    
  33.             "status""ACTIVE"    
  34.         },    
  35.         "virtualNodeName""api2"    
  36.     }    
  37. }     

Virtual service

 
Click on Virtual services link in left pane. Click on Create Virtual Service button. For Provider, select Virtual Node. Select virtual node of API1 i.e. api1 which we have created above. Provide name to service which will be used by virtual nodes in App. I will provide name as api1.demoappmesh.local. Create virtual services for API2 virtual node as well.
 
 
To call API2 from API1, we have add API2 as a backend to virtual node of API1. Edit virtual node of API1. Expand Backend section. Enter name of virtual service name of API2 in textbox. Click save to update virtual node.
 
 
AWS CLI command to create virtual service,
  1. input:    
  2. aws appmesh create-virtual-service   
  3. --mesh-name demoappmesh   
  4. --virtual-service-name "api2.demoappmesh.local"   
  5. --spec '{"provider":{"virtualNode":{"virtualNodeName":"api2"}}}'    
  6.     
  7. output:    
  8. {    
  9.     "virtualService": {    
  10.         "meshName""demoappmesh",    
  11.         "metadata": {    
  12.             "arn""arn:aws:appmesh:us-east-1:811179850130:mesh/demoappmesh/virtualService/api2.demoappmesh.local",  
  13.             "createdAt""***""lastUpdatedAt""***""meshOwner""***""resourceOwner""***""uid""***""version": 1       
  14.         },    
  15.         "spec": {    
  16.             "provider": {    
  17.                 "virtualNode": {    
  18.                     "virtualNodeName""api2"    
  19.                 }    
  20.             }    
  21.         },    
  22.         "status": {    
  23.             "status""ACTIVE"    
  24.         },    
  25.         "virtualServiceName""api2.demoappmesh.local"    
  26.     }    
  27. }     

Virtual gateway

 
Virtual gateway will be used to call services in App Mesh by external world. Click on Virtual gateways link in left side pane. Click on Create Virtual Gateway button. Provide name to the gateway. Select protocol and port on which gateway will listen.
 
 
AWS CLI command to create virtual gateway and gateway route,
  1. input:    
  2. aws appmesh create-virtual-gateway   
  3. --mesh-name demoappmesh   
  4. --virtual-gateway-name vgateway   
  5. --spec '{"listeners": [{"portMapping": {"port": 5000,"protocol": "http"}}]}'    
  6.     
  7. output:    
  8. {    
  9.     "virtualGateway": {    
  10.         "meshName""demoappmesh",    
  11.         "metadata": {    
  12.             "arn""arn:aws:appmesh:us-east-1:***:mesh/demoappmesh/virtualGateway/vgateway",  
  13.             "createdAt""***""lastUpdatedAt""***""meshOwner""***""resourceOwner""***""uid""***""version": 1  
  14.         },    
  15.         "spec": {    
  16.             "listeners": [    
  17.                 {    
  18.                     "portMapping": {    
  19.                         "port": 5000,    
  20.                         "protocol""http"    
  21.                     }    
  22.                 }    
  23.             ]    
  24.         },    
  25.         "status": {    
  26.             "status""ACTIVE"    
  27.         },    
  28.         "virtualGatewayName""vgateway"    
  29.     }    
  30. }     
  31. input:    
  32. aws appmesh create-gateway-route --gateway-route-name vgroute --mesh-name demoappmesh --virtual-gateway-name vgateway --spec '{"httpRoute": {"action": {"target": {"virtualService": {"virtualServiceName": "api1.demoappmesh.local"}}},"match": {"prefix": "/"}}}'    
  33.     
  34. output:    
  35. {    
  36.     "gatewayRoute": {    
  37.         "gatewayRouteName""vgroute",    
  38.         "meshName""demoappmesh",    
  39.         "metadata": {    
  40.             "arn""arn:aws:appmesh:us-east-1:***:mesh/demoappmesh/virtualGateway/vgateway/gatewayRoute/vgroute",    
  41.             "createdAt""***""lastUpdatedAt""***""meshOwner""***""resourceOwner""***""uid""***""version": 1    
  42.         },    
  43.         "spec": {    
  44.             "httpRoute": {    
  45.                 "action": {    
  46.                     "target": {    
  47.                         "virtualService": {    
  48.                             "virtualServiceName""api1.demoappmesh.local"    
  49.                         }    
  50.                     }    
  51.                 },    
  52.                 "match": {    
  53.                     "prefix""/"    
  54.                 }    
  55.             }    
  56.         },    
  57.         "status": {    
  58.             "status""ACTIVE"    
  59.         },    
  60.         "virtualGatewayName""vgateway"    
  61.     }    
  62. }   
We have setup AWS Cloud Map and AWS App Mesh for our web services. In the next article, we will deploy web services using Elastic containerization service (ECS) and integrate those with Cloud Map and App Mesh. Until then stay tuned! :)