/terraform-cdk-graphql-federation-api

Serverless Graphql Federation API's built with: mercurius, fastify, nestjs; infrastructure automation with Terraform & Terraform CDK

Primary LanguageTypeScript

Serverless Terraform CDK Graphql Federation API



Example project demonstrating how to take advantage of both Terraform & Terraform CDK (Typescript) to deploy graphql federated API's to a serverless environment (AWS Lambda).

Application Architecture


The application code in this iteration is very MVP, as the intention was more of devops and infrastructure as code automation.


Primary Application Libraries:

Helpful Library Docs:


Terraform IAS (Infrastructure as Code) Setup

Terraform specific project code

├── app
│   ├── admin
│   │   └── main.tf.ts
│   ├── gateway
│   │   └── main.tf.ts
│   └── products
│       └── main.tf.ts
├── infrastructure
│   └── dev
└── packages
    └── cdktf-constructs
  • This iteration is demonstrating storing state locally. So this does not demonstrate how to manage terraform state for a production environment. For that purpose I would highly recommend Terraform Cloud (a little biased) or other Terraform Backend options.
  • Each application directory contains its own Terraform CDK Stack within: main.tf.ts.
  • They all resuse the same construct defined in the @packages/cdktf-constructs pnpm workspace package
  • The terraform packages have two levels in terms of sibling dependencies.
    • Infrastructure is required to be deployed prior to any other package since it contains the S3 bucket for lambda deployment artifacts.
    • Both products & admin packages need to be deployed prior to the gateway package. For service discovery, the gateway needs to aware of each subgraph in order to stitch schema requests. Managed services like Apollo Studio or self managed isolated microservice to manage that is preferred in a production environment.
    • The dependency order of package deployments is handled by TurboRepo pipelines
  • As mentioned previously, since state is stored locally, each package references other terraform stacks output(s) via the DataTerraformRemoteStateLocal construct

Tooling Setup


Deploy to AWS

  • Setup your access key & secret access for AWS
    • If not exported in your environment shell can do the following:
      • Add .env.local to each app/[package] directory
        AWS_ACCESS_KEY_ID=''
        AWS_SECRET_ACCESS_KEY=''
        
      • Within infrastructure/ copy auto.tfvars.example to auto.tfvars and add your credentials there
  • Then Deploy!
    pnpm run deploy:turbo
    
  • Once finished, remember to destory the resources you created by:
    pnpm run destroy:turbo
    
    if it fails, can run pnpm run destroy:infrastructure & turbo run destroy separately

Retrospective

  • I would consolidate Terraform CDK Stacks into a single application to deploy from. Terraform cdktf deploy command allows the user to specify a particular stack to deploy.
  • Since this iteration uses local state, would recommend persisting terraform state remotely with Terraform Cloud, S3, or other Terraform Backend solutions
  • I would also update the gateway application code to fetch the other subgraph api gateway endpoint urls at runtime (with caching). That way each subgraph and package can be deployed independently, without the need of re-deploying the gateway to update an environment variable.
  • Research adding another useful library to compliment NestJS Nestjs-query