
- Simple ToDo App, allows to signup, signin, CRUD tasks and mark as done.
- Using NestJS stack with GraphQL, NATS with a microservice arquitecture.
- MariaDB database on AWS RDS.
- User Management using AWS Cognito.
- Frontend app using Vite, React, Redux, Apollo Client. Deployed statically on S3 and cached using Cloudfront.
- /frontend contains the files related to the Vite React app.
- /terraform contains the infrastructure related files.
- /apps contain the microservice apps from NestJS.
- Install Terraform v1.4.6
- Install and configure aws cli
- Run
terraform plan
to see potential changes andterraform apply
to create the stack. - Optionally, install infracost for cost estimates.
- Create terraform.tfvars in the /terraform dir, check variables.tf to see which vars are required.
- This projects relies on AWS Fargate and ECR for storing docker images, so if it is desired to update the task definitions after a docker image update, run:
terraform apply -replace="aws_ecs_task_definition.main"
- Developed and tested on Node v18
- Install NestJS CLI
brew install nats-streaming-server
- Install a mysql 8 compatible db locally. Or containerized version.
- Create .env file using .env.example template, in the root dir.
- An output of the terraform stack is the url of the ECR repository. To publish a new version:
docker build . --tag <ecr-repo-url>/<image-name>
docker push <ecr-repo-url>/<image-name>
- If docker is not authenticated with AWS:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.us-east-1.amazonaws.com
- Create .env.local and .env.production files, follow .env.example to see which env vars are expected.
- To build run
npm run build
ornpm run build --mode=production
. - To deploy, if the infrastructure is already deployed and the aws cli is ready to use:
aws s3 sync ./dist s3://<bucket-name>
- PKCE Authentication is used with Cognito, the flow is like this:
- React App attemps to read token stored in the Redux store.
- When token is found
- Attach as Bearer token to any graphql requests until a expired or invalid code is returned.
- Graphql Gateway verifies jwt token using Cognito APIs. Cognito randomized username is then used as identity id in the microservices.
- When token is not found.
- Redirects to cognito hosted page for authentication so the user can sign in or sign up. Code challenge/verifier pair is generated and challenge is passed as param.
- Cognito Auth page will redirect to the origin passing a single use token.
- React App retrieves Cognito token endpoint passing the single use token and the code verifier is passed as param.
- If successful, Cognito responds with jwt tokens.
- React App saves jwt tokens in redux store which are attached to future graphql requests.
- RBAC, but for now any user is hardcoded with the
user
role. Manual testing was done to verify a potential admin role, but no feature requires this.
- MariaDB for production (AWS RDS), mysql 8 used locally.
- Migrations and ORM is done using TypeORM
- Production containers run on AWS ECS Fargate, tasks and services are described in fargate.tf
- Public/Private subnets on a non-default VPC in AWS. NAT Gateway provisioned by AWS that should be turned off when not in usage to avoid costs (~$30/mo).
- RDS public access blocked.
- S3 for static files public access is not blocked for now, it should be and add an origin policy to ensure only cloudfront has read access to it. Pending
- Review network.tf, vpc.tf, subnets.tf, security_groups, route53, iam.tf and others.
- Write me a DM for access to a hosted app or use a domain of your choice.
- Review network.tf, vpc.tf, subnets.tf, security_groups, route53, iam.tf and others.