aws / aws-pdk

The AWS PDK provides building blocks for common patterns together with development tools to manage and build your projects.
https://aws.github.io/aws-pdk/
Apache License 2.0
385 stars 75 forks source link

[FEATURE] Manage Amplify projects with pdk #780

Closed OperationalFallacy closed 5 months ago

OperationalFallacy commented 6 months ago

Describe the feature

Can pdk manage a full cycle of Amplify projects?

Use Case

We develop Amplify projects. Repo setup, upgrades and adding resources, especially lambda functions is a major pita. So we developed Projen setup to manage all aspects of Amplify projects, it helps manage repos when it's fully configured - which takes time to do even with projen, so it is still not very scalable.

Proposed Solution

I'd rather use pdk if it can manage full cycle of Amplify projects. It could alleviate some of the shortcomings of amplify, for example it can't have properties files for function per environment.

Other Information

No response

Acknowledgements

PDK version used

v0.23.37

What languages will this feature affect?

Typescript

Environment details (OS name and version, etc.)

Mac

agdimech commented 6 months ago

Hi - it really depends on what you are trying to do.

A lot of PDK constructs on offer can be used as alternatives to amplify i.e: auth, website and api. Can you elaborate on your use case?

OperationalFallacy commented 6 months ago

Hi - it really depends on what you are trying to do.

A lot of PDK constructs on offer can be used as alternatives to amplify i.e: auth, website and api. Can you elaborate on your use case?

The use case is configuring Amplify projects consistently, with separated backend and web clients. I'm doing it with a custom projen config. Here's some pieces of it to illustrate the setup:

import { JsonFile, Project, SampleFile, YamlFile } from "projen";
import {
  NodePackageManager,
  TypeScriptJsxMode,
  TypeScriptModuleResolution,
} from "projen/lib/javascript";
import { ReleaseTrigger } from "projen/lib/release";
import { TypeScriptAppProject, TypeScriptProject } from "projen/lib/typescript";
import { NextJsTypeScriptProject } from "projen/lib/web";
import { LambdaConfig } from "./projectConfigurator";
import { AwsCdkTypeScriptApp } from "projen/lib/awscdk";

const basePrj = new Project({
  name: "base",
  outdir: "",
  gitIgnoreOptions: {  },
  ...LambdaConfig.getProjectDefaults(),
});

const refreshProjects = new LambdaConfig({
  name: "refreshProjects",
  description: "Lambda Function to refresh projects",
  parentProject: basePrj,
});

...
refreshProjects.setupLambdaProject([
  "otpauth",
  "date-fns",
  "@smithy/signature-v4",
  "@smithy/protocol-http",
  "@aws-lambda-powertools/parameters",
  "date-fns",
  "openai@4.16.2",
  "prettyjson",
  "@aws-crypto/sha256-js@^5.1.0"
]);

...
const apiProject = new TypeScriptAppProject({
  name: "@prjmgmt/api",
  packageName: "prjmgmt-api",
  minNodeVersion: "18.13.0",
  projenrcTs: true,
  testdir: "", // normally would be 'test' (by default)
  parent: basePrj,

... 
// some very Amplify specific settings to manage its config files 

new YamlFile(apiProject, ".graphqlconfig.yml", {
  readonly: false,
  obj: {
    projects: {
      sharedlibs: {
        schemaPath: "amplify/backend/api/xxx/build/schema.graphql",
        includes: ["projects/graphql-shared/src/generated/*.ts"],
        excludes: [
          "amplify/**",
          "projects/graphql-shared/src/generated/API.ts",
          "projects/graphql-shared/src/generated/index.ts",
        ],
        extensions: {
          amplify: {
            codeGenTarget: "typescript",
            docsFilePath: "projects/graphql-shared/src/generated",
            generatedFileName: "projects/graphql-shared/src/generated/API.ts",
            region: "us-east-1",
            // apiId: null,
            maxDepth: 3
          },
        },
      },
    },
    extensions: {
      amplify: {
        version: 3,
      },
    },
  },
});

... and it goes for a few more hundreds lines
... and configures projen managed backend and front-end directories 

apiProject.eslint?.addOverride(overrides);
feProject.eslint?.addOverride(overrides);

apiProject.eslint?.addExtends("eslint:recommended");
feProject.eslint?.addExtends("eslint:recommended");
feProject.eslint?.addExtends("next/core-web-vitals");

basePrj.synth();

Based on your commend, I think PDK can manage parts of Amplify backend, if user wishes swap it out for a custom implementation.

I'm looking at higher level: how to manage with code the whole amplify setup.

agdimech commented 5 months ago

I see.

You can definitely create consistent project configurations from Amplify using Projen like you have shown, however the PDK will not be adding support for Amplify projects for a couple of reasons:

1.) The PDK already provides higher level abstractions for certain patterns that already exist in amplify (i.e: auth, api, website) and by also providing abstractions around Amplify, this may confuse users as to which one to choose. We want to be flexible but also provide a fairly prescriptive base set of constructs. 2.) Amplify tries to do something similar to what the PDK/Projen is doing in terms of configuring your various components in a simplistic manner. It however does this using a completely different mechanism with state managed in the cloud. The PDK/Projen take a different approach, being Projects as Code and conflating the two would cause more confusion with customers. Trying to debug an issue would also be a nightmare as your problem space would extend between PDK/Projen, Amplify, CDK, etc.

In summary, we will not be supporting any Amplify constructs directly in the PDK - however you can definitely build your own and use the PDK/Projen for other areas which Amplify is not fit for purpose (i.e: polyglot builds).