Your AWS Virtual Private Cloud (VPC) is configured based on Amazon's recommended architecture for HIPAA compliant systems. Application servers and databases operate inside private network subnets and are not directly accessible from the public Internet. This guide explains how to establish connectivity to your resources in order to be able to deploy applications and access them from a public address.

AWS resources have private DNS addresses

EC2 virtual machines, RDS databases, and other resources managed by AWS are assigned private IP addresses (example: 10.10.100.20) and  DNS names (example: ip-10-10-100-20.us-east-2.compute.internal), which are based on the address range in your VPC. In addition, Healthcare Blocks created a private ".internal" DNS zone that can be used to manage friendly DNS entries for your resources (example: app-1.customer-name.internal).

By connecting to your AWS environment via your OpenVPN service, you can communicate with your resources using their private DNS addresses. For example, to SSH to an EC2 virtual machine, after connecting to the VPN, all of the following equivalent commands would work from your local machine:

ssh username@10.10.100.20
ssh username@ip-10-10-100-20.us-east-2.compute.internal
ssh username@app-1.customer-name.internal # assumes this DNS entry was created

The various service dashboards (EC2, RDS, etc.) publish the private DNS/IP addresses assigned by AWS, usually on a detailed view for a selected resource.

To view custom private DNS addresses created by Healthcare Blocks, go to the Route53 service dashboard and click the hosted zone associated with "customer-name.internal" to see the detailed records. You can create additional entries in this DNS table (or request assistance from Healthcare Blocks support). Just be sure that any custom entries are handled by your Web server configuration. In Dokku-enabled environments, you would use the "dokku domains:add..." command to register a private address. For non-Dokku environments, you'd configure the Web server (Nginx or Apache) to handle requests from the address. 

Connecting to RDS databases

RDS databases do not have public endpoints by default for security reasons. Therefore, first SSH to one of your EC2 instances and then use the mysql or psql shell to connect to the internal service address assigned by RDS. Connection information is stored in an AWS Secrets Manager secret that was created by Healthcare Blocks and shared with you. Please create a ticket if you need access.

Routing Public Traffic to Applications

An AWS load balancer was provisioned inside your VPC in a public subnet, which can receive traffic from "the outside" over the Internet. The load balancer is associated with one or more AWS resources responsible for operating your application such as EC2 virtual machines or ECS Fargate containers. You will need to create a DNS entry that maps your public domain to the load balancer's network address generated by AWS.

AWS requires that network traffic is encrypted end-to-end for healthcare applications subject to HIPAA requirements. The load balancer is configured with an SSL certificate associated with a domain name that you specified during onboarding. The SSL certificate is generated and managed by Amazon's Certificate Manager service but customers can also request that a previously purchased certificate from another SSL vendor is used instead.

In order to satisfy AWS's requirement for end-to-end encryption, your application endpoints will also need their own SSL certificate. Amazon's load balancers do not validate the certificate authority and expiration of internal certificates when sending traffic to servers/services, therefore you can create a self-signed certificate that can be used by your Web server. Please refer to "Creating self-signed SSL certificates" below for details.

AWS load balancers only route traffic to servers/services that pass an internal "health check" which is typically based on receiving a successful response (HTTP 200) from the endpoint at its root path. Health checks can be configured to accept other response codes and point to other URL paths (example: /status). Please create a ticket if you need a custom health check configured. 

The load balancer is also configured to automatically redirect HTTP requests to an HTTPS endpoint per a common security best practice (and any equivalent functionality in your application can be disabled). 

To recap, when testing an application using its public domain name, confirm that (1) an entry has been configured in your DNS service pointing to the load balancer, (2) an internal SSL certificate has been created and (3) is referenced by the Web server configuration, and (4) the application returns a response code that the health check interprets as valid.

Continuous integration/deployment considerations

CI/CD services such as GitHub Actions can establish a VPN connection to your AWS environment using third-party solutions. Search the respective marketplace or community forum for additional details. For services that do not support VPN functionality, a public-facing proxy (or "jump box") can be added to your environment which will route traffic to your private endpoints. Please create a ticket if you need assistance. Another option is to use the AWS CodeBuild and CodePipeline services which can communicate with private AWS resources and can communicate with external Git repositories.

Reference: creating self-signed SSL certificates

In Dokku environments:

dokku certs:generate <app name> <private subdomain>

In non-Dokku environments:

sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/app.key -out /etc/ssl/app.crt