HealthTech Starter Kit: HIPAA
For telehealth companies, EHR vendors, health data platforms, and any company about to handle Protected Health Information (PHI) for the first time. The infrastructure decisions that cost weeks to retrofit later (RDS encryption at creation, S3 Object Lock for retention, PHI network isolation) are built in from the start.
GitHub: compliancetf/starter-kit-healthtech-hipaa
Registry: hipaa.compliance.tf
Resources deployed: approximately 140
RDS encryption must be enabled at database creation
HIPAA requires encryption for electronic PHI (ePHI). storage_encrypted = true on RDS must be set when the database is first created. It cannot be added to an existing unencrypted instance without destroying and recreating it, which means migrating data, updating connection strings, and rebuilding dependent infrastructure. This kit enforces encryption by default. Do not disable it.
Architecture

PHI data stores are isolated in private subnets with no public routes. The API Gateway and ALB handle authorized ingress. EKS and Lambda process PHI within the VPC. OpenSearch provides audit log search and retention. S3 Object Lock enforces the PHI retention period.
Quick Start
Prerequisites: Terraform >= 1.3, AWS credentials, a compliance.tf account, a Route 53 hosted zone, and an S3 replication IAM role + destination bucket (required for §164.308(a)(7)(ii)(A) data backup). See Create the replication prerequisites if you do not have those yet.
git clone https://github.com/compliancetf/starter-kit-healthtech-hipaa.git
cd starter-kit-healthtech-hipaa
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars: set project_name, domain_name, route53_zone_id,
# availability_zones, s3_replication_role_arn, s3_replication_destination_bucket_arn
terraform login hipaa.compliance.tf
terraform init
terraform plan
terraform applyterraform plan fails if any HIPAA control is violated. The error names the specific control and the module that triggered it. Fix the issue and re-run.
Module Inventory
| Module | Version | Purpose | Key HIPAA Requirements |
|---|---|---|---|
vpc | ~> 6.0 | PHI network isolation, flow logs | §164.312(a)(1) (access control), §164.312(b) (audit controls) |
alb | ~> 10.0 | HTTPS load balancing, access logs | §164.312(e)(1) (transmission security), §164.312(b) (access logs) |
apigateway | ~> 6.0 | API Gateway with PHI route access logging | §164.312(b) (audit controls) |
waf | ~> 1.0 | Web Application Firewall | §164.312(e)(1) (guard against unauthorized access to ePHI in transit) |
acm | ~> 6.0 | TLS certificate | §164.312(e)(1) (transmission security) |
kms | ~> 4.0 | Customer-managed key wired to EKS, Lambda, RDS, EFS, and OpenSearch | §164.312(a)(2)(iv) (encryption and decryption) |
lambda | ~> 8.0 | VPC-attached PHI processing, KMS encryption | §164.312(a)(1) (restrict access to authorized programs) |
ec2_instance | ~> 6.0 | Private worker nodes, IMDSv2, IAM instance profile | §164.312(a)(1) (access control) |
eks | ~> 21.0 | Kubernetes cluster, private endpoint, encrypted secrets | §164.312(a)(2)(iv) (encryption), §164.312(b) (audit controls) |
rds | ~> 7.0 | Standard RDS PostgreSQL, encrypted at creation | §164.312(a)(2)(iv) (critical: encryption must be set at creation) |
rds_aurora | ~> 10.0 | Aurora PostgreSQL, Multi-AZ, automated backups | §164.312(c)(1) (integrity), §164.308(a)(7)(ii)(A) (data backup plan) |
dynamodb | ~> 5.0 | Key-value store, KMS encryption, point-in-time recovery | §164.312(a)(2)(iv) (encryption), §164.312(c)(1) (integrity) |
s3_bucket_phi | ~> 5.0 | PHI storage, Object Lock, 7-year retention, cross-region replication | §164.312(c)(1) (integrity), §164.308(a)(7)(ii)(A) (data backup plan) |
s3_bucket_logs | ~> 5.0 | Audit log storage, versioning, cross-region replication, 365-day lifecycle | §164.312(b) (audit controls), §164.308(a)(7)(ii)(A) (data backup plan) |
efs | ~> 2.0 | Encrypted file storage, KMS encryption | §164.312(a)(2)(iv) (encryption and decryption) |
sqs | ~> 5.0 | Message queue with dead-letter queue | §164.312(a)(2)(iv) (encryption) |
elasticache | ~> 1.0 | Redis, encrypted at rest and in transit, Redis AUTH | §164.312(d) (authentication), §164.312(e)(1) (transmission security) |
opensearch | ~> 2.0 | VPC-only search, KMS encryption, HTTPS, fine-grained access, audit logs | §164.312(a)(1) (access control), §164.312(b) (audit controls) |
cloudwatch | ~> 5.0 | Application log group, 365-day retention | §164.312(b) (audit controls) |
Two databases are provisioned
The kit deploys a standard RDS PostgreSQL instance and an Aurora PostgreSQL cluster. Aurora (writer plus reader) is the primary PHI store; the standard instance is sized for lower-tier PHI data at roughly a seventh of the cost (compare the two rows in the cost estimate below). Most teams need one of the two — delete the module block you do not use, along with its output in outputs.tf, before the first apply. Neither module references the other, so removing one leaves the rest of the kit intact.
CloudTrail is not in this kit
§164.312(b) requires audit controls that record activity in systems containing ePHI, and an auditor will expect the AWS control plane trail alongside the resource-level logs this kit configures. CloudTrail is account-wide rather than module-level, so no module creates it. Enable it separately; the compliance.tf get started guide covers account-level prerequisites.
HIPAA Security Rule Coverage
| HIPAA Requirement | Description | Module(s) | What's Enforced |
|---|---|---|---|
| §164.312(a)(1) | Access Control | RDS, S3, EFS, OpenSearch, Lambda | IAM authentication, no public access, VPC isolation |
| §164.312(a)(2)(iv) | Encryption and Decryption | All data modules, KMS | KMS encryption at rest for all PHI data stores |
| §164.312(c)(1) | Integrity | S3, DynamoDB, RDS Aurora | Object lock, versioning, point-in-time recovery |
| §164.312(d) | Person or Entity Authentication | RDS, ElastiCache, OpenSearch | IAM auth, Redis AUTH, fine-grained access control |
| §164.312(e)(1) | Transmission Security | ALB, ElastiCache, OpenSearch | TLS 1.2+ enforced on all connections |
| §164.312(e)(2)(ii) | Encryption in Transit | All network modules | HTTPS/TLS required throughout |
| §164.308(a)(7)(ii)(A) | Data Backup Plan | RDS, RDS Aurora, S3 PHI | Automated backups, PITR, cross-region replication |
| §164.312(b) | Audit Controls | All modules | VPC flow logs, API Gateway access logs, CloudWatch log groups |
PHI Retention Configuration
What the 6-year HIPAA retention rule actually covers
HIPAA's 6-year retention requirement (45 CFR §164.316(b)(2)(i)) applies to Security Rule documentation (policies, procedures, risk analyses), not to clinical PHI records. Clinical record retention is governed by state law. Most states require 5-10 years; some go longer for pediatric records.
This kit defaults to 7 years, covering the federal documentation minimum and the majority of state law requirements. Set it in terraform.tfvars:
phi_retention_years = 7 # adjust to match your jurisdictionThe s3_bucket_phi module enforces this via S3 Object Lock in GOVERNANCE mode. Objects cannot be deleted until the retention period expires, unless a user holds s3:BypassGovernanceRetention.
For stricter enforcement, switch to COMPLIANCE mode in main.tf. Compliance mode locks out even the AWS root account; do not enable it unless you are certain of the retention period, since there is no override.
HIPAA-Eligible AWS Services
All services in this kit are on the AWS HIPAA-eligible services list. Before adding any service to your architecture, confirm it is on that list.
Not every AWS service is HIPAA-eligible
Only services on the AWS BAA may store or process PHI, and the list changes over time — check the current AWS HIPAA-eligible services reference before integrating any AWS service. If you route PHI through an ineligible service, it falls outside the BAA and AWS will not assist with breach notification for that data.
Business Associate Agreements (BAAs)
compliance.tf does not manage BAAs. You are responsible for:
- Signing an AWS BAA before any PHI touches AWS infrastructure (done in the AWS Artifact console)
- BAAs with any third-party vendor that receives or processes PHI (analytics, monitoring, CDN, support tooling)
- BAAs with subcontractors who have access to systems that handle PHI
The AWS BAA covers the services in this kit at the infrastructure level. Application-level PHI handling, access controls, and workforce training are your responsibility under the HIPAA Privacy Rule and administrative safeguards.
What compliance.tf Covers vs. What You Own
What this kit handles
- KMS encryption at rest for all PHI data stores (pass your own key ARNs for customer-managed keys)
- S3 Object Lock for PHI record immutability during the retention period
- Cross-region replication on the PHI bucket and the logs bucket
- TLS 1.2+ on all endpoints, enforced at ALB and within cluster networking
- PHI network isolation; data stores have no public routes
- IAM authentication required for RDS, Aurora, DynamoDB, and OpenSearch
- API Gateway access logging and VPC flow logs for all PHI network traffic
- Multi-AZ Aurora and ElastiCache failover; 7-day minimum backup retention (14 days in prod)
- Deletion protection on databases and ALB in
environment = "prod"
What you own
- Business Associate Agreements with AWS and every third-party vendor that touches PHI
- Application-level PHI access controls and audit logging at the field level
- Security awareness training (§164.308(a)(5)) and information access management (§164.308(a)(4))
- Security incident response procedures (§164.308(a)(6))
- Breach notification to affected individuals, HHS, and media when required (45 CFR §164.400-414)
- Risk analysis and risk management (§164.308(a)(1)(ii)(A)-(B))
- Physical device safeguards for workstations and portable media
- Privacy Rule compliance and patient rights management
compliance.tf covers the technical safeguards of the HIPAA Security Rule. A HIPAA privacy officer still needs to handle the administrative safeguards and the Privacy Rule.
Common Customizations
Disable a specific control
If a control does not apply to your use case, disable it with a query parameter on the module source. Query parameters require the HTTPS URL format (the Registry format does not support them):
module "dynamodb" {
source = "https://hipaa.compliance.tf/terraform-aws-modules/dynamodb-table/aws?version=5.0.0&disable=dynamodb_table_auto_scaling_enabled"
# ...
}That example turns off the DynamoDB auto scaling control, which applies to provisioned-capacity tables; the kit's table uses PAY_PER_REQUEST, where there is no provisioned capacity to scale. Do not use this to switch off an encryption, Object Lock, or audit logging control on a module that touches PHI — those map to Security Rule safeguards, and an auditor will ask why the control is absent.
Control identifiers are listed in the controls catalog; see Customize modules for the full enable/disable interface.
Cost Estimate
| Component | Dev | Prod |
|---|---|---|
| VPC + NAT Gateway | ~$35 | ~$100 |
| ALB | ~$25 | ~$25+ |
| EKS control plane | ~$75 | ~$75 |
| EKS nodes (t3.medium) | ~$60 | ~$120+ |
| RDS PostgreSQL (db.t3.medium) | ~$30 | ~$60 |
| Aurora PostgreSQL (db.r6g.large) | ~$200 | ~$400 |
| ElastiCache (cache.t4g.micro) | ~$10 | ~$20 |
| OpenSearch (t3.small.search) | ~$20 | ~$60 |
| EFS | ~$5 | ~$10+ |
| S3 PHI (with Object Lock) | ~$5 | ~$10+ |
| Lambda + SQS + EC2 | ~$30 | ~$60+ |
| Total | ~$550-800 | ~$1,700-2,800 |
Next Steps
- HIPAA Framework Reference: full control list per requirement
- Audit Evidence Guide: how to prepare infrastructure evidence for HIPAA audits
- Brownfield Migration Kit: if you have existing Terraform to migrate rather than starting fresh
- Version Compatibility Matrix: supported module versions