Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ ServerlessWebappStarterKitStack.FrontendDomainName = https://web.exmaple.com

Opening the URL in `FrontendDomainName` output, you can now try the sample app on your browser.

### WebApp Deployment

The Next.js webapp is built and deployed during the CDK deployment process using [deploy-time-build](https://github.com/tmokmss/deploy-time-build). This approach ensures your application is containerized and deployed to AWS Lambda as part of the infrastructure deployment. See the [implementation](./cdk/lib/constructs/webapp.ts) for details.

### Database Migration

Database migrations are automatically executed during CDK deployment using a [CDK Trigger](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.triggers-readme.html). The migration runs with the default `deploy` command. See the [implementation](./cdk/lib/constructs/webapp.ts) and [migration runner](./webapp/src/jobs/migration-runner.ts) for details.

To manually run migrations with different commands:

```sh
aws lambda invoke \
--function-name <MigrationFunctionName from CDK output> \
--payload '{"command":"deploy"}' \
--cli-binary-format raw-in-base64-out \
/dev/stdout
```

Available commands: `deploy` (default), `force` (with --accept-data-loss).

## Add your own features
To implement your own features, you may want to add frontend pages, API routes, or async jobs. The project uses Next.js App Router, which provides a unified approach for both frontend and backend development. You can follow the conventional Next.js patterns to add pages and API routes. For more details, please refer to the [`webapp/README.md`](./webapp/README.md) guide.

Expand Down
7 changes: 6 additions & 1 deletion cdk/lib/constructs/webapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,18 @@ export class Webapp extends Construct {
});
migrationRunner.connections.allowToDefaultPort(database);

// run database migration during CDK deployment
// Run database migration during CDK deployment
// The Trigger construct automatically invokes the migration runner with default payload (command: 'deploy')
// To manually run migrations with different commands (e.g., 'force'), use the AWS CLI command shown in the CDK output below
const trigger = new Trigger(this, 'MigrationTrigger', {
handler: migrationRunner,
});
// make sure migration is executed after the database cluster is available.
trigger.node.addDependency(database.cluster);

// Output migration-related information for manual invocation
// Available commands: "deploy" (default), "force" (with --accept-data-loss)
// Example: aws lambda invoke --function-name <FUNCTION_NAME> --payload '{"command":"force"}' --cli-binary-format raw-in-base64-out /dev/stdout
new CfnOutput(Stack.of(this), 'MigrationFunctionName', { value: migrationRunner.functionName });
new CfnOutput(Stack.of(this), 'MigrationCommand', {
value: `aws lambda invoke --function-name ${migrationRunner.functionName} --payload '{"command":"deploy"}' --cli-binary-format raw-in-base64-out /dev/stdout`,
Expand Down
6 changes: 6 additions & 0 deletions webapp/src/jobs/migration-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { execFile } from 'child_process';
import path from 'path';

export const handler: Handler = async (event, _) => {
// This Lambda function is invoked in two contexts:
// 1. CDK Trigger: Automatically invoked during `cdk deploy` with default payload (no command specified, defaults to 'deploy')
// 2. Manual Invocation: Use AWS CLI to invoke with custom commands
// Example: aws lambda invoke --function-name <FUNCTION_NAME> --payload '{"command":"force"}' --cli-binary-format raw-in-base64-out /dev/stdout
// The function name and command template are available in the CloudFormation stack outputs after deployment
//
// Available commands are:
// deploy: create new database if absent and apply all migrations to the existing database.
// reset: delete existing database, create new one, and apply all migrations. NOT for production environment.
Expand Down