DEV Community

Cover image for Empowering Amazon CodeCatalyst: Workflows as Code with CodeCatalyst-Blueprints

Empowering Amazon CodeCatalyst: Workflows as Code with CodeCatalyst-Blueprints

Abstract

  • This blog introduces how to optimize workflow management within the Amazon ecosystem using codecatalyst-blueprints. By employing a blueprint.ts file, developers can succinctly express workflows as code, promoting readability and collaboration without CodeCatalyst Enterprise tier

Table Of Contents


πŸš€ Blueprints introduction

  • Blueprints are code generators used to create and maintain projects in Amazon CodeCatalyst. You can build your own blueprint (Custom Blueprints) today by upgrading to the CodeCatalyst Enterprise tier. An integral aspect of Blueprints involves workflow generation. Disregarding the CodeCatalyst Enterprise tier, we can utilize this feature to create CodeCatalyst workflows as code, utilizing the preferred programming language, such as Typescript.

πŸš€ Init Blueprint project using Projen

  • We cannot use Projen to init a blueprint project as AWS CDK or CDK8S, but we can do a trick by init TypeScript project and then update .projenrc.ts as ProjenBlueprint

  • While we cannot directly use Projen to initialize a blueprint project such as AWS CDK or CDK8S, we can employ a workaround. Initialize a TypeScript project first, and then update the .projenrc.ts file using ProjenBlueprint

  • To initialize a TypeScript project using Projen, you can use the following command

  ➜  projen new typescript --no-git --projenrc-ts --github false --dev-deps "@amazon-codecatalyst/blueprint-util.projen-blueprint" "@amazon-codecatalyst/blueprint-util.cli"
  πŸ‘Ύ Project definition file was created at /private/tmp/blueprint/.projenrc.ts
  πŸ‘Ύ Installing dependencies...
  πŸ‘Ύ install | yarn install --check-files
  yarn install v1.22.19
Enter fullscreen mode Exit fullscreen mode
  • Override the .projenrc.ts with the following code
  import { ProjenBlueprint } from '@amazon-codecatalyst/blueprint-util.projen-blueprint';

  const project = new ProjenBlueprint({
    name: 'cdk-todo-web-app',
    defaultReleaseBranch: 'main',
    projenrcTs: true,
    sampleCode: false,
    github: false,
    tsconfig: {
      compilerOptions: {
        esModuleInterop: true,
        noImplicitAny: false,
      },
    },
    deps: [
      'projen',
      '@amazon-codecatalyst/blueprints.blueprint',
      '@amazon-codecatalyst/blueprint-component.workflows',
      '@amazon-codecatalyst/blueprint-component.source-repositories',
      '@amazon-codecatalyst/blueprint-component.dev-environments',
      '@amazon-codecatalyst/blueprint-component.environments',
    ],
    devDeps: [
      'ts-node@^10',
      'typescript',
      '@amazon-codecatalyst/blueprint-util.projen-blueprint',
      '@amazon-codecatalyst/blueprint-util.cli',
    ],
  });

  project.synth();
Enter fullscreen mode Exit fullscreen mode
  • Then run projen to update the package.json, .projen, and other files managed by Projen
  ➜  projen
  πŸ‘Ύ default | ts-node --project tsconfig.dev.json .projenrc.ts
  πŸ‘Ύ Installing dependencies...
  πŸ‘Ύ install | yarn install --check-files
  yarn install v1.22.19
Enter fullscreen mode Exit fullscreen mode

πŸš€ Write blueprint.ts to build worksflow

  • If you've utilized CodeCatalyst custom blueprints, you are likely familiar with blueprint.ts, which contains code for generating UI options, environment settings, source repository configurations, and workflows. When creating a custom blueprint, these elements are automatically generated. However, if your goal is to leverage the CI/CD capabilities of the CodeCatalyst workspace without requiring all components, you specifically need the workflow generation part.

  • In short, the blueprint.ts file encompasses the following elements:

    1. Source repository - serves as a reference point for workflow configurations
    const repository = new SourceRepository(this, {
      title: "cdk-todo-web-app",
    });
    
  1. Environment - Where we define the CI/CD environment, including the connection to the AWS account.

    const environment = new Environment(this, {
      name: "default_environment",
      environmentType: "DEVELOPMENT",
      description: "Blueprint environment",
      awsAccount: {
        cdkRole: { name: CDK_DEFAULT_ROLE },
        id: CDK_DEFAULT_ACCOUNT,
        name: CDK_DEFAULT_ACCOUNT,
      },
    });
    
  2. Workflow Actions

    • An Action includes the following major components
      export interface ActionProps {
        actionName: string;
        identifier: string;
        steps: string[];
        environment?: WorkflowEnvironment;
        dependancies?: string[];
        inputs?: { [key: string]: any[] };
        outputs?: { [key: string]: any };
      }
    
- A wrapper function that generates a workflow Action based on the interface
Enter fullscreen mode Exit fullscreen mode
  ```
  /**
  * Generate an action for the workflow
  * @param props ActionProps
  * @returns Action
  */
  export function GenerateAction(props: ActionProps) {
    return {
      [props.actionName]: {
        Identifier: props.identifier,
        Inputs: props.inputs ? props.inputs : { Sources: ["WorkflowSource"] },
        Outputs: props.outputs
          ? props.outputs
          : {
              AutoDiscoverReports: {
                IncludePaths: ["**/*"],
                ExcludePaths: ["*/.codecatalyst/workflows/*"],
                ReportNamePrefix: "AutoDiscovered",
                Enabled: true,
              },
            },
        Configuration: {
          Steps: props.steps.map((step) => ({ Run: step })),
        },
        Environment: props.environment,
        DependsOn: (props.dependancies) ? props.dependancies : undefined,
      },
    };
  }
  ```
Enter fullscreen mode Exit fullscreen mode
- We will have following actions
  1. `FrontendBuildAndPackage`
  2. `FrontendTest`
  3. `CDKBootstrapAction`
  4. `CDKDeploy`
Enter fullscreen mode Exit fullscreen mode
  1. WorkflowBuilder - Responsible for defining the workflow name, compute type, trigger type, and the required actions

    const workflowBuilder = new WorkflowBuilder(this, {
      Name: "main_fullstack_workflow",
      Compute: {
        Type: ComputeType.EC2,
        Fleet: ComputeFleet.LINUX_X86_64_LARGE,
      },
      Triggers: [
        {
          Branches: ["main"],
          Type: TriggerType.PUSH,
        },
      ],
      Actions: {
        ...frontendBuildAndPackage,
        ...frontendTest,
        ...cdkBootstrapAction,
        ...cdkDeploy,
      },
    });
    
  2. Workflow - Collects all WorkflowBuilder instances and incorporates them into the source code repository

    new Workflow(this, repository, workflowBuilder.getDefinition());
    

πŸš€ Generate workflow yaml file

  • Run yarn blueprint:synth (This script is from package.json)
  ➜  cdk-todo-web-app git:(main) βœ— yarn blueprint:synth
  yarn run v1.22.19
  $ blueprint drive-synth --blueprint ./ --outdir ./synth --default-options ./src/defaults.json --additional-options ./src/wizard-configurations $*
  [1706372494181] INFO (5048 on Daos-MBP): Running in quick mode. Run this command with --cache to emulate the wizard
  [1706372494192] INFO (5048 on Daos-MBP): ==========================================
  [1706372494192] INFO (5048 on Daos-MBP): [00.synth.defaults.json]
  [1706372494192] INFO (5048 on Daos-MBP): npx blueprint synth --options merge[./src/defaults.json,./src/defaults.json] --blueprint ./ --outdir synth/00.synth.defaults.json/proposed-bundle
  [1706372494192] INFO (5048 on Daos-MBP): ==========================================
  ===== Starting synthesis =====
  options:  {}
  outputDir:  synth/00.synth.defaults.json/proposed-bundle
  Instantiations location not specified
  running synthesis into /codecatalyst/cdk-todo-web-app/synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app
  ===== Ending synthesis =====
  ✨  Done in 2.10s.
Enter fullscreen mode Exit fullscreen mode
  • We have the generated files in synth/00.synth.defaults.json/proposed-bundle and we have our workflow YAML file is located at synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst/workflows/main_fullstack_workflow.yaml
  ➜  cdk-todo-web-app git:(main) βœ— tree synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst
  synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst
  └── workflows
      └── main_fullstack_workflow.yaml

  2 directories, 1 file
Enter fullscreen mode Exit fullscreen mode
  • Copy the YAML file
  ➜  cdk-todo-web-app git:(main) βœ— cp synth/00.synth.defaults.json/proposed-bundle/src/cdk-todo-web-app/.codecatalyst/workflows/main_fullstack_workflow.yaml .codecatalyst/workflows/main_fullstack_workflow.yaml
Enter fullscreen mode Exit fullscreen mode
  • Now we can push the code to the repository and check the workflow run

πŸš€ Conclusion

  • Congratulations! You have successfully generated CodeCatalyst workflows as code using codecatalyst-blueprints without enabling the CodeCatalyst Enterprise tier.
  • You can create an Action to automatically generate and update the workflow YAML file by pushing a new commit to the main branch, reflecting changes from the blueprint.ts file.

🌠 Blog · Github · stackoverflow · Linkedin · Group · Page · Twitter 🌠

Top comments (0)