I had a (not) lovely dream

Before we start, let me introduce Jack. Jack is a Java programmer and he is passionate about the IT. He is always looking for the best solutions, he never gives up. Even that he has been working on a monolith for years, he knew there is a better world somewhere in the universe where people run microservices in a lightweight containerization environment. One night, he met Amazon ECS and fell asleep…

I need to try it, it looks really easy…

Sample app v1

In that simple idea he wanted to implement an application consisting of:

  • TextProcessor - user interface, it returns language and sentiment for a given text input
  • TextApi - worker, detects language and sentiment using Amazon Comprehend service

So far, so good. I need a Load Balancer, internet facing of course…

Sample app v2

In the above, internet facing Application Load Balancer was added. That way the TextProcessor is accessible via the URL path specified.

Well, now these two services need to talk to each other. What can I do?! Got it! I can just add another path to the load balancer!

Sample app v3

Since the Application Load Balancer is used (7th layer), two paths can be specified: one for the TextProcessor service and another one for the TextApi service. Great! Actually… not.

Argh! But it’s internet facing… I can add another load balancer, internal one! And then configure it… And maintain… And maybe automate adding Route53 entry… And pay for it… Oh, and it doesn’t look like clean architecture! What a nightmare!

Sample app v4

Jack suddenly woke up screaming: THERE MUST BE A BETTER APPROACH!

There is a better approach, trust me Jack

What do you think when you hear the term microservices? The following words come to my mind: lightweight, dynamic, small, fast, independent. The same when it comes to containers. Looking at the last diagram from the previous paragraph we all agree it’s not even close to these fancy words, don’t we? For that reason, in this article I will present Service Discovery based on practical example in Amazon ECS and Java.

The simplest explanation of what a Service Discovery is can be found on Wikipedia:

Service discovery is the automatic detection of devices and services offered by these devices on a computer network.

In the microservices world, service instances change dynamically because of autoscaling, failures, and upgrades. Thus, the traditional approach of having static service locations configured, doesn’t fit best here. Not only does the service discovery let the client access target instance but also simplifies configuration, health checking and debugging.

If you want to learn more, I can recommend the following document: Service Discovery in a Microservices Architecture.

A good example of such a tool can be Consul which also can be easily integreted with a Java application using Spring Cloud Consul.

In this article I will focus on Service Discovery available in the Amazon Elastic Container Service (ECS) out of the box. In fact, it’s powered by the AWS Cloud Map service which can be used in another scenarios as well.

I will cover the following:

  • preparing a sample Java application
  • running it in ECS
  • configuring ECS Service Discovery with dynamic port mapping enabled
  • explaining SRV records
  • using it to call the service inside the VPC
  • using it to call the service from the Java app, including SDK and DNS
  • configuring and testing health check
  • debugging

Prerequisites:

  • at least minimum experience with ECS allowing to run the application (it’s not covered here but there will be another post presenting AWS CI/CD goodies)

Enough talking, let’s make our hands dirty!

What we gonna build

Jack has already provided us with a sample idea. Let’s just add Service Discovery and implement it in Java.

Sample app v5

The code is publicly available here. While working on the implementation, I will mention the tag, so you will be able to check it anytime. All the instructions are provided in the readme file as well.

What does it require?

  • Java v11
  • SpringBoot v2.x
  • Gradle v6.4.x

How does it work?

From the user perspective, there is a single REST endpoint exposed by the TextProcessor service which detects language and sentiment for a given piece of text. Check the example:

How does it run?

It runs using the Amazon Container Service (ECS). Both of the components are SpringBoot applications packaged into Docker image and placed into Elastic Container Registry (ECR). Deployment steps will be provided further in this post.

Deploying the API

Git tag: api-implemented

In this step, the TextApi application will be deployed to the ECS and we will access it from inside the AWS. I assume you have already built and pushed the Docker image to the ECR. Please find the instructions in the readme file.

Create task definition

Navigate to the ECS console, create task definition and select EC2 launch type in the first step.

Fill up basic data:

TextApi - task definition, basic info

Specify the names as you want. Just remember that the application needs Amazon Comprehend access. For testing, you can use the following policies in the IAM role:

  • CloudWatchFullAccess
  • ComprehendFullAccess

Regarding task size, 256 MiB of memory and 512 units of CPU should be enough. Configure the container:

TextApi - task definition, container

Provide the Docker image and set the port mappings. Be careful as dynamic port mapping is used here. This way, on the EC2 host instance side, a random number will be assigned to the docker process and thus we will be able to run multiple tasks inside a single EC2 machine. More info can be found here.

Another important thing is to enable logging to the CloudWatch.

TextApi - task definition, container

For the other settings, leave defaults and create the task.

Create service

Navigate to the ECS console and specify the task definition you just created:

TextApi - service, basic info

Move further and configure service discovery:

TextApi - service discovery configuration

Health checking is another important part that I will address later in this article. For now let’s follow defaults. Go ahead and create the service. As a result, two tasks should be running:

TextApi - service, running tasks

So far, so good! Let me show you what happened under the hood!

I don’t know where you are, but I will find you, and I will… call you!

Navigate to AWS Cloud Map and check that the new namespace is created. This is the way to group your services and make them available using AWS SDK. Also, you can enable DNS discovery as well.

Please compare Cloud Map namespace:

TextApi - Cloud Map, namespace

And Route53 hosted zones:

TextApi - Route53, private domain

As you can see, namespace corresponds to the private hosted zone.

Let’s dive deeper and find the TextApi service instances. In AWS Cloud Map, you should see one service available and inside it - two service instances:

TextApi - Cloud Map, service

To call the application, we need its address and port number. And this is exactly what Cloud Map service represents.

Compare it with Route53 records:

TextApi - Route53, records

There are SRV records that allow to create multiple entries with more than a hostname. In this example we have port number specified.

Now we have everything to call the service from inside the VPC. Remember, the addresses above are not publicly available which is in plus when it comes to security.

You NEED to start asking questions, Jack

Before we go further, I want you to understand one thing: why do we need that SRV records?!

Our primary goal is to make our application running smoothly. No doubts. But also, we want to minimize the costs by maximizing resource usage.

How?

In this example, the ECS cluster consists of 2 EC2 instances. There are 2 ECS services, each running 2 tasks. So there are 4 containers, and we want them to use 8080 port to communicate with each other. Each of the EC2 instance will run more than 1 task. It means we need to setup port mapping to satisfy these dependencies.

While creating task definition, the following network modes are available:

  • none - No external connectivity at all.
  • host - Maps container ports to the EC2 instance’s network interface directly. You can’t run multiple instantiations of the same task on a single EC2 instance when port mappings are used. You can’t use dynamic port mapping.
  • awsvpc - Every task that is launched from that task definition gets its own elastic network interface (ENI) and a primary private IP address. You cannot take advantage of dynamic host port mappings.
  • bridge - The task utilizes Docker’s built-in virtual network which runs inside each container instance. You can run multiple tasks over the same host using multiple random host ports by using dynamic port mapping.

We want to run multiple tasks over the same host, so we choose bridge network mode, and we configure dynamic port mapping.

Well, what options do we have now?

  • Load Balancing - Application Load Balancer (HTTP) or Network Load Balancer (TCP). Classic Load Balancer doesn’t support dynamic port mapping. All in all, we won’t pay for it and choose Service Discovery.
  • Service Discovery - SDK or DNS. In case of DNS, only SRV supports dynamic port mapping because it specifies both: host and port number. A records can be used only in case of awsvpc network mode.

You may know that Java’s subsystem doesn’t resolve SRV records by default, but we will address it as well.

ECS Service Discovery using aws-cli

In this chapter I will show how to find out the service location and call it from inside the VPC. For testing, it will be good to have EC2 instance in the same VPC so that we can easily call the TextApi service.

Wherever you have aws cli installed, issue the below to get a list of running instances. Remember that you need to specify AWS credentials before any operation. Just set the parameters in accordance to your setup.

A response should be similar to this:

{
    "Instances": [
        {
            "InstanceId": "fd69d2ca-e09e-44cb-ac92-b3ef17981af2",
            "NamespaceName": "pm-text-detection",
            "ServiceName": "textapi",
            "HealthStatus": "HEALTHY",
            "Attributes": {
                "AVAILABILITY_ZONE": "eu-west-1b",
                "AWS_INIT_HEALTH_STATUS": "HEALTHY",
                "AWS_INSTANCE_IPV4": "10.13.11.239",
                "AWS_INSTANCE_PORT": "32780",
                "EC2_INSTANCE_ID": "i-06564877401cd110d",
                "ECS_CLUSTER_NAME": "textapi-textapi-ecs-ECSCluster-KwKxaJskbN9P",
                "ECS_SERVICE_NAME": "textapi-service",
                "ECS_TASK_DEFINITION_FAMILY": "textapi-task-def",
                "REGION": "eu-west-1"
            }
        },
        {
            "InstanceId": "3723cb62-45bc-4022-a24f-785caf1eb253",
            "NamespaceName": "pm-text-detection",
            "ServiceName": "textapi",
            "HealthStatus": "HEALTHY",
            "Attributes": {
                "AVAILABILITY_ZONE": "eu-west-1c",
                "AWS_INIT_HEALTH_STATUS": "HEALTHY",
                "AWS_INSTANCE_IPV4": "10.13.12.177",
                "AWS_INSTANCE_PORT": "32769",
                "EC2_INSTANCE_ID": "i-02c9167f301d3bcd0",
                "ECS_CLUSTER_NAME": "textapi-textapi-ecs-ECSCluster-KwKxaJskbN9P",
                "ECS_SERVICE_NAME": "textapi-service",
                "ECS_TASK_DEFINITION_FAMILY": "textapi-task-def",
                "REGION": "eu-west-1"
            }
        }
    ]
}

As you can see, it’s exactly the same as what we have in AWS Cloud Map. Having instance’s private IP address and the application’s port number, we can call the service from inside the VPC:

Easy peasy!

ECS Service Discovery using DNS resolver

As you remember, once Service Discovery is enabled, there are also DNS entries in the Route53 added. That means we should be able to retrieve service’s location without using AWS SDK at all.

All the operations below need to be executed from inside the VPC.

Issue the below to find out SRV records:

And now let’s ask DNS server for a instance’s address:

Again, we have everything to call the TextApi service. That confirms everything is configured properly so it’s a right time to glue everything together, deploy TextProcessor service and test it end-to-end.

ECS Service Discovery using Java SDK

Git tag: sdk-service-discovery

In this part, we will implement service discovery in the TextProcessor app using AWS Cloud Map SDK. Then the service will be deployed to ECS together with ALB (internet facing) and we will test it end-to-end.

Implement service discovery

In the beginning, add another dependency to the project:

And take a look at the interface:

The idea is to provide the implementation that can be injected into com.patternmatch.ecs.textprocessor.service.TextApiClient to lookup TextApi service location before calling it.

An example code can look like this:

Simple as it is! List of instances is retrieved, then one is randomly selected and service location is returned back. Please notice that you can filter the instances at the API level.

That two parameters cloudMapNamespace and cloudMapService are the ones you see in the AWS Cloud Map.

Run it!

Deploying TextProcessor

In this step we will deploy TextProcessor to the ECS. I assume you have already built the Docker images and pushed them to the ECR. If not, please find the instructions in the readme file.

Once it’s done, create an ECS Task Definition. It’s pretty much the same what you did for TextApi. The only difference is the Docker image of course and the IAM role. For the TextProcessor we need the following policies:

  • CloudWatchFullAccess
  • AWSCloudMapFullAccess

Remember: it’s just for testing. A good practice is to specify the policies as tight as you can!

If the cloudMapNamespace and cloudMapService are different for you, you can provide them as environment variables while creating task definition:

TextProcessor - container, environment variables

Now let’s create an ECS Service. There will be a one major difference - we need to expose Application Load Balancer (ALB) to make the service available for a user.

Assuming you already created ALB, select it from the dropdown list:

TextProcessor - Application Load Balancer

And configure the Target Group. The final configuration should be similar to the one below.

TextProcessor - Target Group

ALB listeners should look like this:

TextProcessor - ALB Listeners

Load Balancing and Target Groups are out of scope for this article. Please find more information in the official AWS docs.

That should be it! Now we can test it from the local machine using ALB’s public name.

You think that’s all?! It’s not. If you are not really interested in programming and just want a battle tested team to do it for you, don’t hesitate and contact us!

Better communication, better results

You like effective communication. Your IT system should love it too. Don’t waste your money.

Estimate my project

ECS Service Discovery using DNS lookup

Git tag: dns-service-discovery

In this part, we will implement service discovery in the TextProcessor app using DNS lookup. Then we will simply redeploy the TextProcessor service and we will test it end-to-end once more.

Implement service discovery

We already have the interface as presented in the previous part so now let’s provide another implementation.

Add the dependency:

And provide another implementation of the com.patternmatch.ecs.textprocessor.service.ServiceLocationResolver interface.

It can look similar to the one below.

Please notice the usage of @ConditionalOnProperty(value = "servicediscovery.method", havingValue = "dns"). Based on the SpringBoot properties, we will be able to switch between the SDK and DNS service discovery.

Deploying it will be simple now. Just build the Docker image and push it to the ECR. Don’t forget about the tagging! Then just kill the tasks of the TextProcessor service and new tasks will be started with the latest Docker image.

DNS service discovery is configured as default, but you can change it anytime using the SERVICE_DISCOVERY_METHOD environment variable in the task definition.

Test it once more and join me in the next part to find out what the hell is that health checking!

Don’t worry, be healthy!

Health checking is a crucial part in making your service highly available. Let’s see what are the options in this regard.

Simulating the issue

For testing, we need a way to put the application down without killing the container. So, there are two endpoints exposed in both TextApi and TextProcessor applications.

First is the standard health checking endpoint that comes from SpringBoot: /actuator/health.

It simply returns the status like this:

{
   "status":"UP"
}

To have a control over it, I implemented a custom health checker and exposed another endpoint to manage it.

Keeping the status is even simpler:

And you can manage it using this endpoint: POST "http://<host>:<port>/<path>/status?healthy=[true,false]"

Ok, let’s check how the ECS handles it!

No health check definition

As you remember, no health check was defined while defining a container in a task definition. But still the service was able to check if the app is alive or need to be terminated and ran again. How?

Exactly as you think! It just monitors the docker process.

To confirm it, let’s SSH to one of the EC2 machines and kill the container.

[ec2-user@ip-10-13-11-239 ~]$ docker ps
CONTAINER ID        IMAGE                                                                                 COMMAND               CREATED             STATUS                  PORTS                     NAMES
753a0d3e1f9f        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textprocessor:latest   "java -jar app.jar"   13 hours ago        Up 13 hours (healthy)   0.0.0.0:32785->8080/tcp   ecs-textprocessor-task-def-1-textprocessor-container-e4dbaaf285eb84dabe01
61e63040dc13        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textapi:latest         "java -jar app.jar"   2 days ago          Up 2 days (healthy)     0.0.0.0:32780->8080/tcp   ecs-textapi-task-def-1-textapi-container-d884b6d7f19aa5ffdb01
d49092e71fc0        amazon/amazon-ecs-agent:latest                                                        "/agent"              7 days ago          Up 7 days (healthy)                               ecs-agent
[ec2-user@ip-10-13-11-239 ~]$
[ec2-user@ip-10-13-11-239 ~]$ docker kill 61e63040dc13

Once issued, you can see that the task is being terminated:

Default health checking

You can also notice that in a second new container is created:

[ec2-user@ip-10-13-11-239 ~]$ docker ps
CONTAINER ID        IMAGE                                                                                 COMMAND               CREATED             STATUS                      PORTS                     NAMES
a81873b8d2f8        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textapi:latest         "java -jar app.jar"   22 seconds ago      Up 19 seconds (unhealthy)   0.0.0.0:32786->8080/tcp   ecs-textapi-task-def-1-textapi-container-a6ebcfaafc89f8a5d501
753a0d3e1f9f        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textprocessor:latest   "java -jar app.jar"   13 hours ago        Up 13 hours (healthy)       0.0.0.0:32785->8080/tcp   ecs-textprocessor-task-def-1-textprocessor-container-e4dbaaf285eb84dabe01
d49092e71fc0        amazon/amazon-ecs-agent:latest

Such simple healthcheck is enough for our test application but probably your case will be more complex. See what to do!

HEALTHCHECK command in the Dockerfile

Check the Dockerfile of any of the services and you will notice the following:

It defines a way of checking that the application is alive by calling the command: curl --fail --silent http://localhost:8080/actuator/health || exit 1

Looks good. Let’s see how it works.

From the inside of the EC2 machine, change the status of the healthcheck and then check the status of container:

[ec2-user@ip-10-13-11-239 ~]$ docker ps
CONTAINER ID        IMAGE                                                                                 COMMAND               CREATED             STATUS                    PORTS                     NAMES
a81873b8d2f8        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textapi:latest         "java -jar app.jar"   13 minutes ago      Up 13 minutes (healthy)   0.0.0.0:32786->8080/tcp   ecs-textapi-task-def-1-textapi-container-a6ebcfaafc89f8a5d501
753a0d3e1f9f        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textprocessor:latest   "java -jar app.jar"   13 hours ago        Up 13 hours (healthy)     0.0.0.0:32785->8080/tcp   ecs-textprocessor-task-def-1-textprocessor-container-e4dbaaf285eb84dabe01
d49092e71fc0        amazon/amazon-ecs-agent:latest                                                        "/agent"              7 days ago          Up 7 days (healthy)                                 ecs-agent
[ec2-user@ip-10-13-11-239 ~]$
[ec2-user@ip-10-13-11-239 ~]$ curl http://localhost:32786/actuator/health
{"status":"UP"}[ec2-user@ip-10-13-11-239 ~]$
[ec2-user@ip-10-13-11-239 ~]$ curl  -X POST "http://localhost:32786/textapi/status?healthy=false"
[ec2-user@ip-10-13-11-239 ~]$ docker ps
CONTAINER ID        IMAGE                                                                                 COMMAND               CREATED             STATUS                      PORTS                     NAMES
a81873b8d2f8        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textapi:latest         "java -jar app.jar"   15 minutes ago      Up 15 minutes (unhealthy)   0.0.0.0:32786->8080/tcp   ecs-textapi-task-def-1-textapi-container-a6ebcfaafc89f8a5d501
753a0d3e1f9f        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textprocessor:latest   "java -jar app.jar"   13 hours ago        Up 13 hours (healthy)       0.0.0.0:32785->8080/tcp   ecs-textprocessor-task-def-1-textprocessor-container-e4dbaaf285eb84dabe01
d49092e71fc0        amazon/amazon-ecs-agent:latest                                                        "/agent"              7 days ago          Up 7 days (healthy)                                   ecs-agent
[ec2-user@ip-10-13-11-239 ~]$
[ec2-user@ip-10-13-11-239 ~]$ curl http://localhost:32786/actuator/health
{"status":"DOWN"}

It’s down as expected.

If you need more detailed information, issue the following: docker inspect --format "{{json .State.Health }}" <container-id>

The output will be similar to the below and I think no additional explanation is needed here.

{
   "Status":"unhealthy",
   "FailingStreak":25,
   "Log":[
      {
         "Start":"2020-07-22T11:06:51.723301407Z",
         "End":"2020-07-22T11:06:52.182106091Z",
         "ExitCode":1,
         "Output":""
      },
      {
         "Start":"2020-07-22T11:06:54.190151859Z",
         "End":"2020-07-22T11:06:54.603770433Z",
         "ExitCode":1,
         "Output":""
      },
      {
         "Start":"2020-07-22T11:06:56.610801597Z",
         "End":"2020-07-22T11:06:57.010355196Z",
         "ExitCode":1,
         "Output":""
      },
      {
         "Start":"2020-07-22T11:06:59.015958813Z",
         "End":"2020-07-22T11:06:59.399007623Z",
         "ExitCode":1,
         "Output":""
      },
      {
         "Start":"2020-07-22T11:07:01.404468968Z",
         "End":"2020-07-22T11:07:01.883671388Z",
         "ExitCode":1,
         "Output":""
      }
   ]
}

What about ECS?

Health checking in the Dockerfile

Nothing changed. Without any further comments, let’s just do it correctly!

Health checking in an ECS container

Let’s create a new revision of the task definition for any of our services. For me it will be TextApi.

The only thing we want to add is health checking in the container definition. So go ahead and modify it as below.

Health checking in the ECS Task Definition

Upgrade the task definition version in the corresponding ECS Service and kill the running tasks ,so the new ones will be started with the newest version.

Let’s repeat our testing procedure.

But before that, notice the new attribute added in the console:

ECS Task - Health Status

Ok, let’s put the container down.

[ec2-user@ip-10-13-11-239 ~]$ docker ps
CONTAINER ID        IMAGE                                                                                 COMMAND               CREATED             STATUS                    PORTS                     NAMES
ba02bd298d79        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textapi:latest         "java -jar app.jar"   11 minutes ago      Up 11 minutes (healthy)   0.0.0.0:32787->8080/tcp   ecs-textapi-task-def-2-textapi-container-b8cbac9ecad39c998d01
753a0d3e1f9f        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textprocessor:latest   "java -jar app.jar"   14 hours ago        Up 14 hours (healthy)     0.0.0.0:32785->8080/tcp   ecs-textprocessor-task-def-1-textprocessor-container-e4dbaaf285eb84dabe01
d49092e71fc0        amazon/amazon-ecs-agent:latest                                                        "/agent"              7 days ago          Up 7 days (healthy)                                 ecs-agent
[ec2-user@ip-10-13-11-239 ~]$
[ec2-user@ip-10-13-11-239 ~]$ curl http://localhost:32787/actuator/health
{"status":"UP"}[ec2-user@ip-10-13-11-239 ~]$
[ec2-user@ip-10-13-11-239 ~]$ curl  -X POST "http://localhost:32787/textapi/status?healthy=false"

After a few seconds you should see the following:

[ec2-user@ip-10-13-11-239 ~]$ docker ps
CONTAINER ID        IMAGE                                                                                 COMMAND               CREATED             STATUS                      PORTS                     NAMES
ba02bd298d79        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textapi:latest         "java -jar app.jar"   12 minutes ago      Up 12 minutes (unhealthy)   0.0.0.0:32787->8080/tcp   ecs-textapi-task-def-2-textapi-container-b8cbac9ecad39c998d01
753a0d3e1f9f        xxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/aws-pattern-match-textprocessor:latest   "java -jar app.jar"   14 hours ago        Up 14 hours (healthy)       0.0.0.0:32785->8080/tcp   ecs-textprocessor-task-def-1-textprocessor-container-e4dbaaf285eb84dabe01
d49092e71fc0        amazon/amazon-ecs-agent:latest                                                        "/agent"              7 days ago          Up 7 days (healthy)                                   ecs-agent
[ec2-user@ip-10-13-11-239 ~]$
[ec2-user@ip-10-13-11-239 ~]$ curl http://localhost:32787/actuator/health
{"status":"DOWN"}

And check the status in the AWS console:

ECS Task - Container fails health checking

WooHoo! Works!

I can’t imagine you are still there, but if you are then probably you have one additional question: HOW TO DEBUG IT?

Hello, where are you?

If the communication between the services doesn’t work, there are many ways to debug it.

Typical actions apply:

  • checking networking - security groups at first
  • checking CloudWatch logs - that way you can at least check which of the components received the request
  • logging into EC2 instance and checking Docker containers

You probably can add more to that list.

There is one another thing which probably won’t be your first guess.

You can enable Flow Logs in your VPC and send it to CloudWatch or S3.

VPC Flow Logs

That way you can check the traffic inside your VPC and maybe find out where the request fails.

This is example log. The header describes the fields. If you remember access log in the application server, it can be somehow familiar for you.

version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
2 xxxxxxxxxxxx eni-0cd8a397895e01c8c 94.102.51.28 10.13.11.239 43985 25965 6 1 40 1595329800 1595329805 REJECT OK
2 xxxxxxxxxxxx eni-0cd8a397895e01c8c 52.95.124.197 10.13.11.239 443 60338 6 5 301 1595329800 1595329805 ACCEPT OK
2 xxxxxxxxxxxx eni-0cd8a397895e01c8c 10.13.11.239 52.95.124.197 60338 443 6 5 200 1595329800 1595329805 ACCEPT OK
2 xxxxxxxxxxxx eni-0cd8a397895e01c8c 182.246.16.189 10.13.11.239 63954 5555 6 1 40 1595329800 1595329805 REJECT OK

What’s the most important here, you can see the source and destination of your request and finally - it’s status. Just another way to put the dots together.

Yeah! Take a breath! I have nothing more to add!

Sleep safe, Jack.

That was a huge journey. Thank you for joining!

In this article I walked through the Service Discovery in the Elastic Container Service. I presented how to configure it and how to run it. I explained how to check it from inside the VPC. Then, I showed an example implementation in Java. I covered health checking as well. Finally, everything was tested end-to-end and I described some methods of debugging it. I prepared a dedicated application to show how it works. If you found it interesting, please leave a star in the repo.

In Pattern Match we love sharing our knowledge. But even more we love to make things happen. If you need a hand or you are interested in a practical training prepared by the professionals - don’t hesitate to contact us!

Better communication, better results

You like effective communication. Your IT system should love it too. Don’t waste your money.

Estimate my project