akello-io / akello

Healthcare OS for interoperability and AI-driven data processing
Apache License 2.0
36 stars 19 forks source link

Enable any user to deploy Akello into their infrastructure #229

Closed vselvarajijay closed 8 months ago

vselvarajijay commented 8 months ago

Make it easier for clinics to run Akello by making the setup into their infrastructure simpler. Use AWS Cloud Development Kit (CDK) to set up AWS resources automatically and update the app easily.

[!TIP] Feel free to re-design the infrastructure as long as it leads to the ideal developer experience

[!CAUTION] This might require some updates to the codebase. If you notice this feel free to make the update yourself or let me know and I can make the fix. The best way to collaborate is via our Discord Server.

Objective

Create a deployment script utilizing AWS Cloud Development Kit (CDK) to automatically provision all necessary AWS resources for a given account ID. This script should also enable the update and deployment of the client application and the Python backend efficiently.

Submission Requirements

[!TIP] The more you communicate your solution and approach the better. Don't worry about creating an audio recording, a screen recording with just click through should be fine.

Here is a sample for a previous submission that was accepted: https://github.com/akello-io/akello/pull/108

Acceptance Criteria

[!IMPORTANT] This is the minimum criteria to accept the pull-request. Make sure all these criterias are met prior to submitting. Feel free to request review with a DRAFT pull-request (pre-fix title with DRAFT)

How to contribute

Questions?

If you would like to discuss any questions or details about this or akello in general feel free to join the discord server by clicking the discord link above.

Ask questions under the #questions channel or feel free to create a new thread under #development with this GH issue ID so we can follow the conversation.


Notes


Developer Experience

[!NOTE] The developer should never need to get on AWS for additional configurations. Changes should be in code via CDK scripts. Once deployed the app should be available in the configured domain.

The developer should be able to run the cdk deployment script into a fresh AWS account and within minutes access a URL with Akello running.

Step
Step 1: Deploy with CDK cdk deploy
Step 2: Access the signup/login page. Once the CDK Deploy completes you should be able to see the login scree (and create account) on the domain you set for R53 Screenshot 2024-02-12 at 1 05 48 PM
Step 3: Review the empty registry. Initially there will be zero registries Screenshot 2024-02-12 at 1 06 16 PM
Step 4: Create a new registry Screenshot 2024-02-12 at 1 06 24 PM
Step 5: Add a new patient Screenshot 2024-02-12 at 1 07 40 PM
Step 6: Confirm the data shows up in the registry Screenshot 2024-02-12 at 1 07 59 PM
Step 7: Confirm the registry is visible in the home dashboard Screenshot 2024-02-12 at 1 08 06 PM

Technical Notes

Current Project Structure

[!NOTE] Use this as a reference, you don't need to follow this guideline completely but we should be able to follow an existing consistent design pattern: AWS recommended structure

akello/
├── agent
├── apps
    └── cocm-registry         # Primary React app
├── cloudstack                # AWS CDK scripts
│   ├── components
│      ├── auth.py
│      ├── ecr.py
│      ├── r53.py
│      ├── storage.py
│   ├── aws_stack.py
├── examples              # Location for additional examples
├── packages
│   ├── core
│   ├── docs
│   ├── react
│   ├── react-hook
├── scripts               # Local development scripts
└── servers
    ├── api-server        # Backend API server
    ├── fhir-server       # Optional FHIR server

Setup Overview

Currently Akello relies on AWS services, in the future we should be able to remove this dependency and keep the application layer independent of the infrastructure it runs on. Core dependencies on AWS include Cognito and DynamoDB.

[!NOTE] In future versions of Akello we would want to decouple the dependency on AWS and allow users to deploy into Azure, GCP or other cloud services.

Environment variable templates are stored under akello/scripts

└── scripts
    ├── .template.api.env     # env variables for the API server
    ├── .template.env         # env variables for the client app

Local deployment example The akello.py script is a python script with a couple functions that help you run akello locally. You can use this as a reference to understand how the project runs.

pip install -r requirements.txt

# make sure your env has output environment variables set
# this also starts up the docker container for cognito and dynamodb 
python scripts/akello.py setup

# starts the API server
python scripts/akello.py start server 

# starts the client app - run this in another shell
python scripts/akello.py start cocm 

AWS resources needed for deployment

AWS Resource Description
S3 The static assets of the react app will be deployed to a S3 bucket
CloudFront CloudFront distributes the S3 assets and is refreshed (invalidated) on each deploy
API Gateway Generated using Open API spec from the Fast API server, it runs the Lambda function for the API server
Route 53 A new hosted zone and aliased subdomain will be created for CloudFront and API Gateway
Cognito Username password auth is configured at first. For testing no MFA
DynamoDB Primary DB for akello except for auth info which is in cognito
Lambda Single lambda function runs the API server (python Fast API)
ECR Docker containers are deployed to ECR which gets pulled by Lambda
IAM Roles/Policies IAM Users should not be created, execution roles are applied to resources
Cloud Monitoring ...

Environment Variables

[!CAUTION] These variables likely need some cleanup. Feel free to take a stab at it or make some suggestions and I can clean it up for you.

Variable Name App Notes
AKELLO_API_URL Client Configured by CDK
AKELLO_COGNITO_URL Client / Server This should not be set for prod
AKELLO_DYNAMODB_LOCAL_URL Server This should not be set for prod
AWS_ACCESS_KEY_ID Github Deployment This should not be set for prod
AWS_ACCOUNT_ID Github Deployment This should not be set for prod
AWS_BUCKET Github Deployment This should not be set for prod
AWS_CLOUD_FRONT_DISTRIBUTION Github Deployment Configured by CDK
AWS_COGNITO_USERPOOL_ID Client / Server Configured by CDK
AWS_COGNITO_APP_CLIENT_ID Client / Server Configured by CDK
AWS_DYNAMODB_TABLE Server Name of the dynamo db table
AWS_REGION Server This should not be set for prod
AWS_SECRET_ACCESS_KEY Github Deployment Should not be used for CDK
AWS_SECRET_NAME Github Deployment Should not be used for CDK

AWS Roles

Make sure new IAM user accounts are not being created. The lambda function should be able to assume an execution role to insert data into DynamoDB and log data.

Cloudwatch Metrics / Alerts

Bonus points for anyone that can setup simple Cloud watch dashboard for monitoring the app

Examples:

DB notes

The script that defines the DynamoDB table. It would be great if this is part of the CDK setup script for DynamoDB. If so for the production deployment we can refactor this out in the startup script from Fast API.

table = dynamodb.create_table(
            TableName=DYNAMODB_TABLE,
            KeySchema=[
                {
                    'AttributeName': 'partition_key',  # registry_id, auth_user_id
                    'KeyType': 'HASH'
                },
                {
                    'AttributeName': 'sort_key',
                    'KeyType': 'RANGE'
                }
            ],
            AttributeDefinitions=[
                {
                    'AttributeName': 'partition_key',
                    'AttributeType': 'S'
                },
                {
                    'AttributeName': 'sort_key',
                    'AttributeType': 'S'
                },

            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 10,
                'WriteCapacityUnits': 10
            }
        )

AWS Diagram

Screenshot 2024-02-13 at 12 41 04 PM
algora-pbc[bot] commented 8 months ago

💎 $100 bounty created by akello-io 🙋 If you'd like to work on this issue, comment below to get assigned 👉 To claim this bounty, submit a pull request that includes the text /claim #229 somewhere in its body 📝 Before proceeding, please make sure you can receive payouts in your country 💵 Payment arrives in your account 2-5 days after the bounty is rewarded 💯 You keep 100% of the bounty award 🙏 Thank you for contributing to akello-io/akello!

👉 Add a bountyShare on socials

oliverqx commented 8 months ago

/attempt #229

Algora profile Completed bounties Tech Active attempts Options
@oliverqx 2 bounties from 2 projects
TypeScript, Python
Cancel attempt
vselvarajijay commented 8 months ago

Resolved by the following PR: https://github.com/akello-io/akello/pull/248