Skip to content

Commit 5766837

Browse files
committed
Merge branch 'update_doc'
2 parents 7b18abb + af8cbeb commit 5766837

File tree

2 files changed

+40
-20
lines changed

2 files changed

+40
-20
lines changed

README.md

+40-20
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
# Deploy-time Build
2-
AWS CDK L3 construct that enables you to build apps during deploy time, which aims to resolve the problme when we deploy frontend apps.
2+
AWS CDK L3 construct that enables you to build apps during deploy time, which aims to resolve the problem when we deploy frontend apps from CDK.
3+
4+
![architecture](./imgs/architecture.png)
35

46
## Usage
57
```ts
68
import { NodejsBuild } from 'deploy-time-build';
79

810
declare const api: apigateway.RestApi;
9-
declare const dstBucket: s3.IBucket;
11+
declare const destinationBucket: s3.IBucket;
1012
declare const distribution: cloudfront.IDistribution;
1113
new NodejsBuild(this, 'ExampleBuild', {
1214
assets: [
1315
{
14-
assetProps: {
1516
path: 'example-app',
1617
exclude: ['dist', 'node_modules'],
17-
},
18-
commands: ['npm install'],
1918
},
2019
],
21-
destinationBucket: dstBucket,
22-
outputSourceDirectory: 'dist',
20+
destinationBucket,
2321
distribution,
22+
outputSourceDirectory: 'dist',
23+
buildCommands: ['npm ci', 'npm run build'],
2424
buildEnvironment: {
2525
VITE_API_ENDPOINT: api.url,
2626
},
@@ -35,16 +35,12 @@ You can specify multiple input assets by `assets` property. These assets are ext
3535
```ts
3636
assets: [
3737
{
38-
assetProps: {
39-
path: 'example-app',
40-
exclude: ['dist', 'node_modules'],
41-
},
38+
path: 'example-app',
39+
exclude: ['dist', 'node_modules'],
4240
commands: ['npm install'],
4341
},
4442
{
45-
assetProps: {
46-
path: 'module1',
47-
}
43+
path: 'module1',
4844
},
4945
],
5046
```
@@ -62,14 +58,38 @@ Then, the extracted directories will be located as the following:
6258

6359
Please check https://github.com/tmokmss/deploy-time-build/tree/main/example for a complete example.
6460

65-
## Background
66-
Previously,
61+
## Why do we need this construct?
62+
Previously, there are a few different ways to deploy frontend applications from CDK (1 and 2 below). But none is perfect with different pros and cons. This construct adds another option to deploy frontend apps.
6763

68-
### Build locally and deploy
64+
### 1. Deploy depending resources first, then build frontend apps
65+
Deploy depending resources (e.g. backend API or cognito user pools) first, then get required values (e.g. API endpoint or userPoolId) from stack outputs, and build the frontend app locally and deploy it.
6966

70-
### Use `S3Deployment.Source.data` to inject deploy-time values
67+
This pattern is easy to use but the disadvantages are the following:
7168

72-
## Solution
69+
1. we cannot define frontend constructs and depending constructs in a single stack
70+
2. we need some operation to get values from stack output and inject it to frontend build process. (e.g. manually copy-paste or run a shell script using CFn API.)
7371

74-
## Considerations
72+
Especially #1 is sometimes annoying when you want to keep you CDK app as simple as possible.
73+
74+
### 2. Use `S3Deployment.Source.data` to inject deploy-time values
75+
Use [`s3-deployment.Source.data/jsonData`](https://github.com/aws/aws-cdk/pull/18659) to store deploy-time values in an S3 Bucket as a file, and load it from apps on runtime.
7576

77+
In this case we can define both frontend and backend into a single stack and deploy them at once. However, it requires another network request for apps to load those values, which is not very efficient and required additional implementation on app side to support this mechanism. Also, the CDK internal implementation for this feature is somewhat complex (basically it resolves token on the construct's bind time by its own code unlike other constructs) and currently has [cross-stack bugs](https://github.com/aws/aws-cdk/issues/19257) that might be difficult to resolve.
78+
79+
You can see the working example of this pattern [in this repository](https://github.com/aws-samples/nextjs-authentication-ui-using-amplify-ui-with-cognito#deploy-cdk-stacks).
80+
81+
Now, the construct `NodejsBuild` resolves above disadvantages and makes world a better place.
82+
83+
### 3. Deploy-time build
84+
The root cause of the problem is that you cannot know the required values (e.g. API endpoint) unless you deploy the resources, and you cannot build and deploy frontend apps unless you know these values. To resolve this issue, you can build your frontend app during CloudFormation deployment. By this, you can inject deploy-time values such as API endpoint to your frontend build environment and deploy it all at once.
85+
86+
The advantages of this way is:
87+
88+
1. The deploy process can totally be completed inside CDK. No need to use any additional shell script unlike pattern #1.
89+
2. The implementation of frontend is CDK agnostic. You can just use environment variables to inject API endpoint, unlike pattern #2.
90+
3. We can use both single stack strategy as well as multi-stacks strategy, without such complex mechanism as pattern #2.
91+
92+
There are, however, a few considerations to be discussed when you use this constuct. Please check the next section.
93+
94+
## Considerations
95+
Since this construct builds your frontend apps every time you deploy the stack and there is any change in input assets (and currently without any "smart" build cache!), the time deployment takes tends to be longer (e.g. a few minutes even for the simple app in `example` directory.) This might results in worse developer experience if you define this construct and other resources (e.g. backend API) in a single stack and you change both frontend and backend code frequently (imagine `cdk watch` deployment always re-build your frontend app). Considering that, it is recommended that you create a separate stack for your frontend app especially in development environment.

imgs/architecture.png

78.6 KB
Loading

0 commit comments

Comments
 (0)