Home > front end >  Best Practices to deploy serverless app (s3, api gateway, lambda, cognito...) with AWS CDK
Best Practices to deploy serverless app (s3, api gateway, lambda, cognito...) with AWS CDK

Time:12-06

I started to build an App using the serverless services of AWS and I am now on the point where I want to put it all into AWS CDK. I also want to create a CICD pipeline using CodePipeline to automatically deploy the infrastructure by changes.

To use the API gateway interfaces, I generated the SDK for Javascript from the AWS console, and included it into the website folder manually.

  1. Is it possible to generate the SDK and include it in the project or maybe some random bucket automatically with CDK?

  2. Are there some best practices regarding the provisioning of such a Infrastructure in an automated way using a CICD Pipeline?

CodePudding user response:

Is it possible to generate the SDK and include it in the project or maybe some random bucket automatically with CDK?

Based on the documentation, you can generate the SDK two ways. Through the AWS console or using AWS CLI (Reference: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk.html)

You could write a script that generates the SDK using AWS CLI and upload it to the website folder or bucket.

Are there some best practices regarding the provisioning of such a Infrastructure in an automated way using a CICD Pipeline?

This is a very general question. This article talks about Best practices using CDK (https://aws.amazon.com/blogs/devops/best-practices-for-developing-cloud-applications-with-aws-cdk/).

aws-samples Github repo is also useful and includes samples like this one: https://github.com/aws-samples/aws-serverless-app-sam-cdk

CodePudding user response:

Add a Custom Resource to your CDK stack. As the CloudFormation docs say,

Custom resources enable you to write custom provisioning logic ... that AWS CloudFormation runs anytime you create, update (if you changed the custom resource), or delete stacks.

In other words, you can natively extract the API client SDKs to a bucket each time the stack's API definition changes.

You define a lambda that uses the apigateway and s3 SDK clients to generate the API client .zip output and saves it to a bucket. You then integrate this into the stack lifecycle events with custom resource logic. CloudFormation handles calling the lambda on create-update-delete and the responses.

(Note: the term "Custom Resource" can be confusing. Yes, they can help fill in CDK/CloudFormation's gaps to actually create infrastructure resources using API calls. But a CustomResource does not have to create any infrastructure at all. They are used for lookups, running tests and seeding initial data. What you can do is up to your lambda.)

aws-cdk-samples has an example of a custom resource implementation. Here is a skeleton of the custom resource plumbing for your use case:

export class ExportApigCustomResource extends Construct {
  constructor(scope: Construct, id: string, props: ExportApigCustomResourceProps) {
    super(scope, id);

    // the provider handles the orchestration
    // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#custom-resource-providers
    const provider = new cr.Provider(this, 'Provider', {
      // CloudFormation will call this lambda on create-update-delete
      onEventHandler: new lambda.NodejsFunction(this, 'ExportApigLambda', {
          entry: path.join(__dirname, 'exportApi.ts'),
          role: new iam.Role(this, 'CrLambdaRole', {...add the right policies});
        })
    });

    // information for the getSdk call that is passed to the lambda in the triggered lifecycle events
    // use a strongly typed input type for safety
    const properties: ExportApigCustomResourceProperties = {
      restApiId: props.api.restApiId,
      bucketName: props.bucket.bucketName,
      stageName: 'prod',
      sdkType: 'javascript',
    };

    // the actual custom resource
    // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CustomResource.html
    new cdk.CustomResource(this, 'Resource', {
      resourceType: 'Custom::ExportApi',
      serviceToken: provider.serviceToken,
      properties,
    });
  }
}

Custom Resources are fiddly to set up. But they are well-supported in the CDK and an elegant way to keep provisioning logic in the same place as your infrastructure code.

  • Related