AWS Public Sector Blog

How to deploy HL7-based provider notifications on AWS Cloud

Electronic notifications of patient events are a vital mechanism for care providers to improve care coordination and promote appropriate follow-up care in a timely manner. In May 2020, the Center for Medicare and Medicaid Services (CMS) issued a final rule requiring all hospitals in the US, including critical access hospitals, to provide patient event notifications electronically for all admissions, transfers, and discharges.

Canada has not yet mandated legislation at a federal level, but individual provinces, including Ontario, have started delivering notifications via their own electronic health record (EHR) solutions (OntarioMD HRM solution).

According to the World Economic Forum, data silos and lack of information exchange historically led to poor patient care and expensive corrective actions, and that “government policies must consider technological capabilities to ensure data’s true potential can be unlocked.” Furthermore, Harvard Business Review states that in data science, 80 percent of the work is involved in data preparation and gathering, and that data silos make that task even tougher.

But data management doesn’t need to be that way. This post shows how a combination of Amazon Web Services (AWS) technologies, like AWS Lambda, Amazon Comprehend Medical, and AWS Fargate, can effectively manage and deliver actionable data to help healthcare customers deliver electronic notifications in a secure and efficient way—aligned with the AWS Well-Architected Framework.

Overview of solution

The proposed architecture provides the capability of delivering notifications directly to the provider based on incoming standard HL7 messaging. By leveraging standard messaging, hospitals can minimize the impact on existing systems and maximize the compatibility of the solution.

The architecture diagram above provides an overview of the end-to-end design. Individual steps are described below in the solution walkthrough section.

Figure 1. The architecture diagram above provides an overview of the end-to-end design. Individual steps are described below in the solution walkthrough section.

Solution walkthrough

We summarized the end-to-end flow of this solution in the following steps:

  1. Since minimal lower layer protocol (MLLP) does not natively support encryption, an AWS Site-to-Site VPN or AWS Direct Connect connection is required to securely transmit protected health information (PHI) to the AWS Cloud.
  2. A fleet of AWS Fargate containers act as the HL7 termination point and place incoming messages into Amazon Simple Queue Service (Amazon SQS) queues.
  3. Amazon SQS decouples processes and supports independent scalability based on incoming message volumes.
  4. AWS Lambda functions prepare and contextualize the notification using Amazon Comprehend Medical. As a security step, patient and provider master data management (MDM) registries will need to be queried to validate the identities of patient, provider, and delivery endpoints contained in the incoming HL7 message.
  5. Amazon Comprehend Medical provides medical named entity extraction (NERe) and medical ontology linking (ICD-10-CM).
  6. Amazon Simple Email Service (Amazon SES) notifies the provider via email.


To deploy this solution, you need the following prerequisites:

  • An AWS account
  • The depth of an MDM solution can enhance the reach of the notifications by involving the patient’s complete circle of care and serve as a key security step where identities and delivery addresses can be validated in order to mitigate the risk of HL7 message injection. It’s up to the reader to leverage MDM vendor specific APIs or, if available, healthcare standards like PIX/PDQ, and perform said validations. This post assumes that patient and provider information are made available transactionally in the incoming HL7 messages as dictated by the standard.
  • The AWS Fargate layer of the solution requires HL7 handling software. We recommend you leverage Apache Camel due to its out-of-the-box support for MLLP and Amazon SQS.

As a security best practice, we will leverage ephemeral credentials rather than specifying static accessKey and secretKey in the Apache Camel route definition. In order to do this, we will gather the task role credentials hosted under the following URL which is accessible from inside the container:$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI

Retrieval of credentials from the URL will be managed by Apache Camel when the option useDefaultCredentialsProvider is set to true.

The Amazon Elastic Container Service (Amazon ECS) agent populates the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variable in the Env object (available with the docker inspect container_id command) for all containers that belong to the task with the following relative URI:


public class MyRouteBuilder extends org.apache.camel.builder.RouteBuilder {

	public void configure() {
		.process(new MyLogProcessor())
		.bean(new MyTransformer(),"TransformContent")
		.to("aws2-sqs://arn:aws:sqs:region:accNum:queueName?useDefaultCredentialsProvider=true" );

You must make sure that a proper AWS Identity and Access Management (IAM) role is configured to access any services that AWS Fargate task relies on (e.g. Amazon SQS, Amazon CloudWatch)

The code above runs the following inside the AWS Fargate task:

    1. Creates an MLLP HL7 listener on local port 17000.
    2. Processes any logging and transformations via MyLogProcessor and MyTransformer classes respectively.
    3. Forwards messages to Amazon SQS queue named queueName using ephemeral credentials.

Once the Apache Camel route is in place, you can use the following dockerfile example to build your container image. After the build process is complete, go ahead and register your container image with Amazon Elastic Container Registry (Amazon ECR).

FROM maven:3.8.1-amazoncorretto-8 AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package

FROM amazoncorretto:8
COPY --from=build /home/app/target/hl7receiver-0.0.1-SNAPSHOT.jar /usr/local/hl7receiver/demo.jar
COPY --from=build /home/app/target/classes /usr/local/hl7receiver/classes
COPY --from=build /home/app/target/lib /usr/local/hl7receiver/lib
RUN yum -y install procps
EXPOSE 17000
ENTRYPOINT ["java","-jar","/usr/local/hl7receiver/demo.jar"]

Make sure that all build dependencies are packaged with the build.


Follow the steps below to deploy HL7 based provider notifications.

Step 1 – Configure a network load balancer and AWS Fargate task

Assuming that the site-to-site VPN (or AWS Direct Connect) is in place and active, the first thing to stand up is an instance of a network load balancer to handle inbound MLLP connections and distribute them across AWS Fargate container instances registered in the target group.

Once the load balancer and target group are in place, you can define the AWS Fargate task that will run the containers with Apache Camel. We selected port 17000 as the incoming traffic port.

Figure 2. The basic settings for the Amazon ECS Cluster running the AWS Fargate task.

Figure 2. The basic settings for the Amazon ECS Cluster running the AWS Fargate task.

An important configuration item for the container tasks is the health check that will allow the task to join the target group for the load balancer. In our case, since Apache Camel is a Java-based application, we’re using the following check:

ps -elf | grep java | grep hl7receiver || exit 1

Once health checks pass, the container tasks will self-register with the load balancer’s target group so that traffic can start being routed. These containers will terminate the incoming HL7 v2 connection and will pass the HL7 payload to an encrypted Amazon SQS queue.

Step 2 – Setup an Amazon SQS queue and AWS Lambda parser

Next, our parsing and enrichment logic is written in Python running on AWS Lambda. It starts triggering as soon as messages arrive in the AWS SQS queue. An AWS Lambda layer was created for additional libraries needed by the parsing logic. It exposes an HL7 parsing library called hl7apy and it has been packaged as a zip file.

Figure 3. Our AWS Lambda parser is configured as an Amazon SQS destination.

Figure 3. Our AWS Lambda parser is configured as an Amazon SQS destination.

An environment variable is required to identify the sending email address for notifications. This will need to be a validated identity inside Amazon SES.

Figure 4. An environment variable called sender is required to hold the previously validated identity of the Amazon SES sender account.

Figure 4. An environment variable called sender is required to hold the previously validated identity of the Amazon SES sender account.

The source code for the hl7receiver lambda function is available on AWS GitHub.

If the hl7receiver function fails to process a message multiple times (maxReceiveCount), Amazon SQS can send it to a previously configured dead-letter queue. These queues are useful for handling the lifecycle of unconsumed messages, determining why their processing didn’t succeed, and avoiding message loss.

To give messages a better chance to be processed before sending them to the dead-letter queue, set the maxReceiveCount on the source queue’s redrive policy to a value high enough to allow for sufficient retries.

As of December 1, 2021, AWS enhanced the dead-letter queue management experience for Amazon SQS, making it more simple for you to inspect a sample of the failed messages and move them back to the source queue for reprocessing with the click of a button.

Below is a sample JSON test event that can be used with the provided lambda function. The function itself will leverage services like Amazon Comprehend Medical and Amazon SES. You must make sure that a proper IAM role is configured to access any services that the parsing function relies on.

  "Records": [
      "messageId": "1ff1dfb4-6bf2-4052-af55-cf126d9913e4",
      "receiptHandle": "AQEBxa/5tJUk1mM+m/LdHxBeDhcFOPQPks3TCEu6rzH30Nqaq+4n8ZF76xW5WMKNWroTC5SEnDtsxFUVln50aGPNkp/Zpc5V6XBWcRf1b0Qn4EptzirHDmS6SVsPSgPca4qDpxBcPu08dTx7OyNTwTRxaZtTwwa2mGQC++WIgfT32196pcisY+w/QUVHbd1HdcFQ20NsZQ1BM7MzFevU8zRFOAmT2MMs3+92+H+QiOf4UVm9ievr4N56Z3aKKeGPDb0qlk97k+P45WsB+GFvvZucD07WyqqNkc+UIUpXPUebPrI=",
      "body": "MSH|^~\\&|test|test|testsystem|testfacility|20010101000000||ADT^A04|q123456789t123456789x123456|p|2.3\rEVN|A04|20010101000000|||^jones^michael^^^^^^^current\rPID|1||123456789|0123456789^aa^^jp|martin^steven||19850101000000|m|||123 fake street^suite1^nice town^al^a1b2c3^jp^home^^1234|1234|(555)555-0123^home^jp:1234567|||s|msh|12345678|||||||0|||||n\rPD1|1|||^smith^john\rOBX|1|st|||42 year old Caucasian female admitted on 7/16/13 from Mercy General to Room 115B. Diagnosis for this admission is s/p PE. Pt admitted for PT/OT/pain control/IV ABT. She had a sitter at the hospital d/t severe agitation and discomfort with the IV line. According to hospital records, two days prior to transfer, her cognitive status improved and she no longer required the sitter. Co-morbid diagnoses include bipolar disorder, chronic fatigue syndrome, diabetes and a-fib. Patient has been taking propanolol 10Mg\r"

Include admission notes in the observations and results segment (OBX.5) so that Amazon Comprehend Medical can extract and isolate medical conditions and medications upon admission or discharge. The goal is to condense as much information as possible for the provider in a format that is both informative and easy to transmit.

The following is an Amazon Comprehend Medical output visual representation based on the admission notes (OBX.5) in the example above:

Figure 5. Visual representation of Amazon Comprehend Medical output based on admission notes (OBX.5).

Figure 5. Visual representation of Amazon Comprehend Medical output based on admission notes (OBX.5).

In this scenario, we can use the whole text included in OBX.5 and end up with the following JSON object after it has been processed by Amazon Comprehend Medical:

{         "MEDICATION":"PROPANOLOL"       }
{         "MEDICAL_CONDITION":"PE."      },
{         "MEDICAL_CONDITION":"PAIN"      },
{         "MEDICAL_CONDITION":"DIABETES"      },
{         "MEDICAL_CONDITION":"A-FIB"      }

Once medical data has been parsed and extracted from free text form, it becomes an asset that is both actionable and reportable.

Step 3 – Amazon SES email distribution

At the end of the flow, Amazon SES delivers the notifications to the healthcare providers. The destination email address of the provider is expected in PD1, and as a security best practice should be validated against an existing MDM solution for ownership and authenticity.

You can follow these instructions to setup Amazon SES for the first time. You will need to validate the originating email address.


Healthcare provider notifications in response to patient events are quickly becoming operating requirements for health information custodians and patient points of care. AWS provides the building blocks to satisfy these requirements without the need to enter long and costly negotiation and implementation cycles with established electronic medical record (EMR) vendors. By combining a handful of AWS’s core services, both patient and provider can benefit from an effective health information exchange without the tax of additional operational burdens.

Take the integration patterns and source code presented in this blog post and deploy HL7-based provider notifications today. With AWS’s pay-as-you-go billing model and its depth and breadth of services, the cost and effort of initial setup and experimentation is significantly lower than traditional non-cloud native alternatives. Event driven solutions like this one can quickly improve care coordination and proper patient follow.

To learn more about the work AWS is doing in healthcare and life sciences across the globe, visit AWS for Health and AWS Healthcare Solutions.

Learn more cloud solutions in these AWS in healthcare stories:

Subscribe to the AWS Public Sector Blog newsletter to get the latest in AWS tools, solutions, and innovations from the public sector delivered to your inbox, or contact us.

Please take a few minutes to share insights regarding your experience with the AWS Public Sector Blog in this survey, and we’ll use feedback from the survey to create more content aligned with the preferences of our readers.