Skip to content

chaudhariatul/host-openemr-on-aws-fargate

 
 

Repository files navigation

OpenEMR on AWS Fargate

Disclaimers

Third Party Packages

This package depends on and may incorporate or retrieve a number of third-party software packages (such as open source packages) at install-time or build-time or run-time ("External Dependencies"). The External Dependencies are subject to license terms that you must accept in order to use this package. If you do not accept all of the applicable license terms, you should not use this package. We recommend that you consult your company’s open source approval policy before proceeding.

Provided below is a list of External Dependencies and the applicable license identification as indicated by the documentation associated with the External Dependencies as of Amazon's most recent review.

THIS INFORMATION IS PROVIDED FOR CONVENIENCE ONLY. AMAZON DOES NOT PROMISE THAT THE LIST OR THE APPLICABLE TERMS AND CONDITIONS ARE COMPLETE, ACCURATE, OR UP-TO-DATE, AND AMAZON WILL HAVE NO LIABILITY FOR ANY INACCURACIES. YOU SHOULD CONSULT THE DOWNLOAD SITES FOR THE EXTERNAL DEPENDENCIES FOR THE MOST COMPLETE AND UP-TO-DATE LICENSING INFORMATION.

YOUR USE OF THE EXTERNAL DEPENDENCIES IS AT YOUR SOLE RISK. IN NO EVENT WILL AMAZON BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION ANY DIRECT, INDIRECT, CONSEQUENTIAL, SPECIAL, INCIDENTAL, OR PUNITIVE DAMAGES (INCLUDING FOR ANY LOSS OF GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS OR DATA, OR COMPUTER FAILURE OR MALFUNCTION) ARISING FROM OR RELATING TO THE EXTERNAL DEPENDENCIES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, EVEN IF AMAZON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS AND DISCLAIMERS APPLY EXCEPT TO THE EXTENT PROHIBITED BY APPLICABLE LAW.

General

AWS does not represent or warrant that this AWS Content is production ready. You are responsible for making your own independent assessment of the information, guidance, code and other AWS Content provided by AWS, which may include you performing your own independent testing, securing, and optimizing. You should take independent measures to ensure that you comply with your own specific quality control practices and standards, and to ensure that you comply with the local rules, laws, regulations, licenses and terms that apply to you and your content. If you are in a regulated industry, you should take extra care to ensure that your use of this AWS Content, in combination with your own content, complies with applicable regulations (for example, the Health Insurance Portability and Accountability Act of 1996). AWS does not make any representations, warranties or guarantees that this AWS Content will result in a particular outcome or result.

Instructions

1. Installing dependencies

This project is set up like a standard Python project. The initialization process also creates a virtualenv within this project, stored under the .venv directory. To create the virtualenv it assumes that there is a python3 (or python for Windows) executable in your path with access to the venv package. If for any reason the automatic creation of the virtualenv fails, you can create the virtualenv manually.

To manually create a virtualenv on MacOS and Linux:

$ python3 -m venv .venv

After the init process completes and the virtualenv is created, you can use the following step to activate your virtualenv.

$ source .venv/bin/activate

If you are a Windows platform, you would activate the virtualenv like this:

% .venv\Scripts\activate.bat

Once the virtualenv is activated, you can install the required dependencies.

$ pip install -r requirements.txt

Create ECS Service accounts.

$ aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com --description "ECS Service Role"
$ aws iam create-service-linked-role --aws-service-name ecs.application-autoscaling.amazonaws.com --description "ECS Service Role for Application Autoscaling"

At this point you can now synthesize the CloudFormation template for this code.

$ cdk synth

You can also deploy using CDK as well.

$ cdk deploy

To add additional dependencies, for example other CDK libraries, just add them to your setup.py file and rerun the pip install -r requirements.txt command.

2. IP Range Access

By default, if you run cdk deploy, the security group that is assigned to the load balancer won't be open to the public internet. This is for security purposes. Instead we need to allowlist an IP range using the cdk.json file. As an example:

"security_group_ip_range": null

could be set to

"security_group_ip_range": "31.89.197.141/32",

Which will give access to only 31.89.197.141.

3. Accessing OpenEMR

After we run cdk deploy, we will receive a url in the terminal. Going to that URL on our browser will take us to the OpenEMR authentication page.

alt text

Username is admin and password can be retrieved from AWS Secrets Manager. Navigate to the AWS console and go the Secrets Manager service. You will see a secret there which has a name that starts with Password....

alt text

After entering username and password we should be able to get access to the OpenEMR UI.

alt text

Architecture

This solution uses a variety of AWS services including Amazon ECS, AWS Fargate, AWS WAF, Amazon CloudWatch. For a full list you can review the cdk stack. Architecture diagram below shows how this solution comes together.

alt text

Customizing Architecture Attributes

There are some additional parameters you can set in cdk.json that you can use to customize some attributes of your architecture.

  • elasticache_cache_node_type The cache node type used by Elasticache. Defaults to "cache.t3.small".
  • openemr_service_fargate_minimum_capacity Minimum number of fargate tasks running in your ECS cluster for your ECS service running OpenEMR. Defaults to 3.
  • openemr_service_fargate_maximum_capacity Maximum number of fargate tasks running in your ECS cluster for your ECS service running OpenEMR. Defaults to 100.
  • openemr_service_fargate_cpu_autoscaling_percentage Percent of average CPU utilization across your ECS cluster that will trigger an autoscaling event for your ECS service running OpenEMR. Defaults to 40.
  • openemr_service_fargate_memory_autoscaling_percentage Percent of average memory utilization across your ECS cluster that will trigger an autoscaling event for your ECS service running OpenEMR. Defaults to 40.
  • proxy_service_fargate_minimum_capacity Minimum number of fargate tasks running in your ECS cluster for your ECS service running your virtual gateway. Defaults to 3.
  • proxy_service_fargate_maximum_capacity Maximum number of fargate tasks running in your ECS cluster for your ECS service running your virtual gateway. Defaults to 100.
  • proxy_service_fargate_cpu_autoscaling_percentage Percent of average CPU utilization across your ECS cluster that will trigger an autoscaling event for your ECS service running your virtual gateway. Defaults to 40.
  • proxy_service_fargate_memory_autoscaling_percentage Percent of average memory utilization across your ECS cluster that will trigger an autoscaling event for your ECS service running your virtual gateway. Defaults to 40.
  • enable_ecs_exec Can be used to toggle ECS Exec functionality. Set to a value other than "true" to disable this functionality. Please note that this should generally be disabled while running in production for most workloads. Defaults to "true".
  • certificate_arn If specified will enable HTTPS for client to load balancer communications and will associate the specified certificate with the application load balancer for this architecture. This value, if specified, should be a string of an ARN in AWS Certificate Manager.
  • activate_openemr_apis Setting this value to "true" will enable both the REST and FHIR APIs. You'll need to authorize and generate a token to use most of the functionality of both APIs. Documentation on how authorization works can be found here. When the OpenEMR APIs are activated the "/apis/" and "/oauth2" paths will be accessible. To disable the REST and FHIR APIs for OpenEMR set this value to something other than "true". For more information about this functionality see the REST and FHIR APIs section of this documention. Defaults to "false".

Enabling HTTPS for Client to Load Balancer Communication

If the value for certificate_arn is specified to be a string referring to the ARN of a certificate in AWS Certificate Manager this will enable HTTPS on the load balancer.

Incoming requests on port 80 will be automatically redirected to port 443 and port 443 will be accepting HTTPS traffic and the load balancer will be associated with the certificate specified.

The certificate used must be a public certificate. For documentation on how to issue and manage certificates with AWS Certificate Manager see here. For documentation on how to import certificates to AWS Certificate Manager see here.

One of the advantages of issuing a certificate from AWS Certificate Manager is that AWS Certificate Manager provides managed renewal for AWS issued TLS/SSL certificates. For documentation on managed renewal in AWS Certificate Manager see here.

How AWS Backup is Used in this Architecture

This architecture comes set up to use AWS Backup and has automatic backups set up for both AWS EFSs and the RDS database.

The backup plan used is daily_weekly_monthly7_year_retention which will take daily, weekly and monthly backups with 7 year retention.

For documentation on AWS Backup see here.

How AppMesh is Used in this Architecture

This architecture comes set up to use AWS AppMesh out of the box. This is used to provide certificates to enable TLS communication between the load balancer and ECS tasks that will run the application code.

This architecture creates an AWS Private Certificate Authority which is used to issue the certificates that are used for TLS communication between the load balancer and a gateway proxy service and also for TLS communication between the gateway proxy service and the backend service running OpenEMR.

If used in conjunction with HTTPS set up for traffic from clients to the load balancer this provides TLS/SSL for traffic all the way from an end user to the application code.

Using XRay

This architecture comes set up to use AWS XRay which can be used to help benchmark and debug applications. For more information on AWS Xray see here.

An example of what the AWS XRay service map for this architecture looks like can be found here:

alt text

Using ECS Exec

This architecture allows you to use ECS Exec to get a root command line prompt on a running container. Please note that this should generally be disabled while running in production for most workloads. For information on how to toggle this functionality see the enable_ecs_exec parameter in the Customizing Architecture Attributes section of this documentation.

For more instructions on how to use ECS Exec see here.

For an example of a command that could be run either in AWS CloudShell or elsewhere to get root access to a container see the code below:

aws ecs execute-command --cluster $name_of_ecs_cluster \
    --task $arn_of_fargate_task \
    --container openemr \
    --interactive \
    --command "/bin/sh"

Notes on HIPAA Compliance in General

If you are an AWS customer who is a HIPAA covered entity you would need to sign a business associate addendum (BAA) before running anything that would be considered in-scope for HIPAA on AWS.

Please note that you would have to sign a separate business associate addendum for each AWS account where you would want to run anything that would be considered in-scope for HIPAA on AWS.

Documentation on HIPAA compliance on AWS in general and how one would sign a BAA can be found here.

You can use AWS Artifact in the AWS console to find and agree to the BAA. Documentation on getting started with using AWS Artifact can be found here.

While this may assist with complying with certain aspects of HIPAA we make no claims that this alone will result in compliance with HIPAA. Please see the general disclaimer at the top of this README for more information.

REST and FHIR APIs

OpenEMR has functionality for both FHIR and REST APIs. You can toggle both of these APIs on or off for this architecture by changing the value for activate_openemr_apis in the cdk.json. Setting this value to "true" will enable both the REST and FHIR APIs.

You'll need to authorize and generate a token to use most of the functionality of both APIs. Documentation on how authorization works can be found here.

When the OpenEMR APIs are activated the "/apis/" and "/oauth2" paths will be accessible.

An example call you can make to test the FHIR API that you don't need to authenticate for is a call to the metadata endpoint. An example of that call can be found below:

curl -X GET '<url_for_your_alb_or_a_dns_record_pointing_to_your_alb>/apis/default/fhir/metadata

If that call goes well you should get back a decently sized JSON in response.

Regarding Security

Using cdk_nag

We instrumented this project with cdk_nag. In your app.py file we placed 2 commented out cdk_nag checks.

from cdk_nag import AwsSolutionsChecks, HIPAASecurityChecks

app = cdk.App()
cdk.Aspects.of(app).add(AwsSolutionsChecks(verbose=True))
cdk.Aspects.of(app).add(HIPAASecurityChecks(verbose=True))

If you'd like you can enable the cdk_nag checks and fix any issues found therein. While this may assist with complying with certain aspects of HIPAA we make no claims that this alone will result in compliance with HIPAA. Please see the general disclaimer at the top of this README for more information.

Container Vulnerabilities

We recommend periodically scanning the container image used in this project. There are multiple ways to achieve that goal. 2 of them are:

  1. Upload the container image to ECR and enable scanning
  2. You can use trivy

Useful commands

  • cdk ls list all stacks in the app
  • cdk synth emits the synthesized CloudFormation template
  • cdk deploy deploy this stack to your default AWS account/region
  • cdk diff compare deployed stack with current state
  • cdk docs open CDK documentation

About

No description, website, or topics provided.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 99.2%
  • Batchfile 0.8%