Skip to content

Commit f2ff7df

Browse files
committed
Fix docs and allow to disable scheduler
1 parent 42c1919 commit f2ff7df

File tree

11 files changed

+90
-28
lines changed

11 files changed

+90
-28
lines changed

CHANGELOG

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44

55
## v1.1.0
66

7-
- Upgrade to Amazon Aurora engine 3_08_0 to support Aurora scaling to 0 ACUs
7+
- Upgrade to Amazon Aurora engine 3_08_0 with support to scale to 0 ACUs
88
- Upgrade packages sst 2.48.5
99
- Minor code refactoring and format
1010
- Recommended NodeJS version >= v22.11.0 LTS
11+
- New configuration settings: `db` for custom database options and `cronMinutes` to configure REDCap's scheduler in minutes.
12+
- `cronSecret` will now default to a random digit string.
1113

1214
### Upgrade procedure to v1.1.0
1315

1416
1. Execute `yarn install` to upgrade packages
15-
2. Add to your `stage` in stages.ts file the new database configuration. Here is an example:
17+
2. If you are using a custom database configuration in `stage.db`, please update it to this new type, here is an example:
1618

1719
```json
1820
db: {
@@ -133,7 +135,7 @@ In this case, this project will have deployed an `A Record` in your Route 53 Hos
133135

134136
5. Run `yarn deploy --stage <your_stage>`
135137

136-
6. Remove the added configuration paramter `deployTag` from stages.ts.
138+
6. Remove the added configuration parameter `deployTag` from stages.ts.
137139

138140
## v0.9.0
139141

@@ -168,7 +170,3 @@ In this case, this project will have deployed an `A Record` in your Route 53 Hos
168170

169171
- Remove AWS App Runner autoscaling name, will be auto-generated
170172
- Add option to link NS records with same or external AWS account based on NS records returned by the deploy.
171-
172-
```
173-
174-
```

CHANGELOG.ja.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ JP | [EN](./CHANGELOG)
44

55
## v1.1.0
66

7-
- Amazon Aurora エンジンのバージョンを 3_08_0 にアップグレードし、Aurora のスケーリングを 0 ACU までサポートする
7+
- Amazon Aurora エンジンのバージョン 3_08_0 にアップグレードし、0 ACUまで拡張できるようサポートを追加
88
- パッケージ sst のバージョンを 2.48.5 にアップグレードする
99
- 軽微なコードのリファクタリングと書式設定を行う
1010
- 推奨されるNodeJSのバージョンは、v22.11.0 LTS以上です。
11+
- 新しい設定項目: `db`はカスタムデータベースオプション、`cronMinutes`はREDCapのスケジューラを分単位で設定するためのものです。
12+
- `cronSecret`はランダムな数字の文字列にデフォルト設定されるようになりました。
1113

1214
### v1.1.0へのアップグレード手順
1315

1416
1. `yarn install` を実行してパッケージをアップグレードします。
1517

16-
2. stages.tsファイルの`stage`に新しいデータベース設定を追加します。以下は例です:
18+
2. `stage.db` でカスタムデータベース設定を使用している場合は、新しいタイプに更新してください。以下は例です:
1719

1820
```json
1921
db: {

README.ja.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ cp stages.sample.ts stages.ts
109109
| appRunnerConcurrency [3] | REDCap アプリケーションを動かす App Runner について、1 つのインスタンスが処理するリクエスト数の閾値を設定します。この値を超えると、インスタンスは自動で水平スケールします。 | Number | 10 (\*\*) |
110110
| appRunnerMaxSize | REDCap アプリケーションを動かす App Runner について、インスタンススケール数の上限を設定します。 | Number | 2 |
111111
| appRunnerMinSize | REDCap アプリケーションを動かす App Runner について、インスタンススケール数の下限を設定します。 | Number | 1 |
112-
| cronSecret | `https:<your_domain>/cron.php`にアクセスするためのシークレットを作成するための元になる文字列を指定します。 | String | 'mysecret' |
112+
| cronSecret | `https:<your_domain>/cron.php`にアクセスするためのシークレットを作成するための元になる文字列を指定します。 | String | 10桁のランダムな文字列 |
113+
| cronMinutes | 分単位の数値で、REDCapのcronのスケジュールを設定します。値が0の場合、Amazonのスケジューラが無効になります | Number | 1 |
113114
| cpu | インスタンスあたりの vCPU 数を指定します。 | Cpu | `Cpu.TWO_VCPU` |
114115
| memory | インスタンスあたりのメモリ容量を指定します。 | Memory | `Memory.FOUR_GB` |
115116
| phpTimezone | 例: 'Asia/Tokyo', <https://www.php.net/manual/en/timezones.php> | String | `UTC` |
@@ -352,6 +353,23 @@ yarn deploy --stage <your_stage_name>
352353

353354
デフォルトでは、`MAIL FROM domain``mail.<your_domain.com>` の形式であることを前提としています。 そうでない場合は、[Backend.ts](./stacks/Backend.ts) の `mailFromDomain``SimpleEmailService` コンストラクタに渡し、独自の形式を指定できます。
354355

356+
### 8. データベースのスケールダウンとcronスケジューラの無効化
357+
358+
バージョン v1.1.0 以降、コストを節減するために Amazon Aurora のスケーリング容量を 0 に設定できます。ただし、デフォルトで 1 分ごとに実行されるcronスケジューラを設定または無効化する必要があります。cronMinutes: 0 を使用してください。
359+
360+
例えば、開発環境でコストを最小限に抑えるには、以下のように設定できます:
361+
362+
```json
363+
db: {
364+
dbReaders: 1,
365+
scaling: {
366+
maxCapacityAcu: 2,
367+
minCapacityAcu: 0, // ACUを0まで縮小可能
368+
},
369+
},
370+
cronMinutes: 0, // Amazon EventBridgeスケジューラを無効化
371+
```
372+
355373
---
356374

357375
## REDCap バージョンの更新

README.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ In the provided `stages.sample.ts` there are three pre-configured stages named `
8787
2. If you deploy `prod` stage the removal policy is set to `retain` to prevent accidental deletion.
8888
3. Other stages will follow the default CDK removal policy for the resource unless other policy is specified.
8989

90-
To modified this behaviour please see the [sst.config.ts](./sst.config.ts)
90+
To modified this behavior please see the [sst.config.ts](./sst.config.ts)
9191

9292
For more info please look at [sst-v2 Removal policy](https://docs.sst.dev/advanced/removal-policy) and [cdk-lib RemovalPolicy](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.RemovalPolicy.html).
9393

@@ -111,7 +111,8 @@ Each property described below allows you to configure your deployment.
111111
| appRunnerConcurrency [3] | The number of requests that a single REDCap instance can process. When the value is exceeded, it will trigger the auto-scaling. | Number | 10 |
112112
| appRunnerMaxSize | Sets the upper limit on the number of instance App Runner can scale. | Number | 2 |
113113
| appRunnerMinSize | Sets the minimum number of `warm` instances. | Number | 1 |
114-
| cronSecret | Base string to create a hashed secret to allow access to https:<your_domain>/cron.php | String | 'mysecret' |
114+
| cronSecret | Base string to create a hashed secret to allow access to https:<your_domain>/cron.php | String | Random 10 digit string |
115+
| cronMinutes | Number in minutes that sets the schedule for REDCap's cron, a value of zero will disable the scheduler on Amazon EventBridge | Number | 1 |
115116
| cpu | The number of vCpu assigned to each instance | Cpu | `Cpu.TWO_VCPU` |
116117
| memory | The amount of memory assigned to each instance | Memory | `Memory.FOUR_GB` |
117118
| phpTimezone | Example: 'Asia/Tokyo', <https://www.php.net/manual/en/timezones.php> | String | `UTC` |
@@ -334,7 +335,7 @@ More info:
334335
335336
### 6. Deploy the project
336337
337-
Run deployment by entering the following command.
338+
Execute the deployment by entering the following command.
338339
339340
```sh
340341
yarn deploy --stage <your_stage_name>
@@ -352,6 +353,23 @@ By default, SES is deployed in sandbox mode, meaning that any email you send tha
352353
353354
The installation by default assumes your `MAIL FROM domain` to be in the form of `mail.<your_domain.com>`. If this is not the case, you can modify the [Backend.ts](./stacks/Backend.ts) file and the property `mailFromDomain` to the `SimpleEmailService` constructor to specify one.
354355
356+
### 8. Database scale down and disabling the cron scheduler
357+
358+
Starting from version v1.1.0, you can use Amazon Aurora scaling capacity to 0 for some cost savings. However, you will also need to configure or disable the cron scheduler with `cronMinutes: 0`, that by default executes every 1 minute.
359+
360+
For example, a to minimize costs in a development environment, you could use:
361+
362+
```json
363+
db: {
364+
dbReaders: 1,
365+
scaling: {
366+
maxCapacityAcu: 2,
367+
minCapacityAcu: 0, // Allow to scale down to 0 ACU
368+
},
369+
},
370+
cronMinutes: 0, // Disable the Amazon EventBridge scheduler
371+
```
372+
355373
---
356374
357375
## Updating REDCap versions

docs/en/ptp.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ When you change the parameter group, please restart the DB to reflect the settin
4646
```ts
4747
parameterGroupParameters: {
4848
// Avoid the REDCap system warning. Please change to the required value
49-
max_allowed_packet: '134217728',
49+
max_allowed_packet: '1073741824',
5050
read_rnd_buffer_size: '262144',
5151
sort_buffer_size: '2097152',
5252
},
5353
```
54+
55+
Alternatively, you can configure your `stages.ts` in the `db` object to set the `maxAllowedPacket: '1073741824'` to the

docs/ja/ptp.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ JP | [EN](../en/ptp.md)
4242
```ts
4343
parameterGroupParameters: {
4444
// Avoid the REDCap system warning. Please change to the required value
45-
max_allowed_packet: '134217728',
45+
max_allowed_packet: '1073741824',
4646
read_rnd_buffer_size: '262144',
4747
sort_buffer_size: '2097152',
4848
},
4949
```
50+
51+
別の方法として、`stages.ts`ファイルの`db`オブジェクトで`maxAllowedPacket: '1073741824'`を設定することができます。

prototyping.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface RedCapConfig extends ProtoConfigOptions {
2525
cpu?: Cpu;
2626
memory?: Memory;
2727
cronSecret?: string; // protect cron.php endpoint with a secret parameter https://endpoint/cron.php?secret=<secret>
28+
cronMinutes?: number; // cron execution in minutes, a value of zero means disabled
2829
port?: number;
2930
deployTag?: string; // forces a new AppRunner deployment and tags ECR docker image with this value
3031
rebuildImage?: boolean;

stacks/Backend.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as stage from '../stages';
88

99
import { Cpu, Memory } from '@aws-cdk/aws-apprunner-alpha';
1010
import { Fn, RemovalPolicy, aws_secretsmanager } from 'aws-cdk-lib';
11-
import { assign, get, isEmpty } from 'lodash';
11+
import { assign, get, isEmpty, random } from 'lodash';
1212

1313
// SST
1414
import { Bucket, StackContext, use } from 'sst/constructs';
@@ -49,7 +49,7 @@ export function Backend({ stack, app }: StackContext) {
4949
const subdomain = get(stage, [stack.stage, 'subdomain']);
5050
const hostInRoute53: boolean | string = get(stage, [stack.stage, 'hostInRoute53'], true);
5151
const phpTimezone = get(stage, [stack.stage, 'phpTimezone']);
52-
const cronSecret = get(stage, [stack.stage, 'cronSecret'], 'mysecret');
52+
const cronSecret = get(stage, [stack.stage, 'cronSecret'], random(0, 10).toString());
5353
const allowedIps = get(stage, [stack.stage, 'allowedIps'], []);
5454
const allowedCountries = get(stage, [stack.stage, 'allowedCountries'], undefined);
5555
const ecsConfig = get(stage, [stack.stage, 'ecs']);
@@ -58,6 +58,7 @@ export function Backend({ stack, app }: StackContext) {
5858
const port = get(stage, [stack.stage, 'port']);
5959
const tag = get(stage, [stack.stage, 'deployTag'], 'latest');
6060
const generalLogRetention = get(stage, [stack.stage, 'generalLogRetention'], undefined);
61+
const cronMinutes = get(stage, [stack.stage, 'cronMinutes'], undefined);
6162

6263
// IAM user and group to access AWS S3 service (file system)
6364
const redCapS3AccessUser = new RedCapAwsAccessUser(stack, `${app.stage}-${app.name}-s3-access`, {
@@ -186,6 +187,7 @@ export function Backend({ stack, app }: StackContext) {
186187
logRetention: generalLogRetention,
187188
repository,
188189
searchString,
190+
cronMinutes,
189191
});
190192

191193
if (ecsConfig) {

stacks/Backend/RedCapService.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { ApiDestination } from 'aws-cdk-lib/aws-events-targets';
1616
import { Cpu, Memory } from '@aws-cdk/aws-apprunner-alpha';
1717
import { ServiceProps } from 'sst/constructs';
1818
import { IPublicHostedZone } from 'aws-cdk-lib/aws-route53';
19+
import { isNumber } from 'lodash';
1920

2021
export class RedcapService {
2122
private common;
@@ -48,13 +49,13 @@ export class RedcapService {
4849
repository: Repository;
4950
environmentVariables: Record<string, string>;
5051
searchString: string;
52+
cronMinutes?: number;
5153
logRetention?: ServiceProps['logRetention']; //Only for ECS, AppRunner has no logRetention setting
5254
},
5355
) {
5456
this.common = common;
5557
this.app = app;
5658
this.stack = stack;
57-
5859
this.connection = this.createEventConnection();
5960
}
6061

@@ -63,7 +64,6 @@ export class RedcapService {
6364
this.common.secrets.dbSalt.grantRead(grantee);
6465
this.common.secrets.ses.sesUserCredentials.grantRead(grantee);
6566
this.common.secrets.redCapS3AccessUser.secret.grantRead(grantee);
66-
6767
this.common.databaseCluster.grantConnect(grantee, 'redcap_user');
6868
}
6969

@@ -91,10 +91,18 @@ export class RedcapService {
9191
description: `Call cron on REDCap deployment ${serviceType}`,
9292
});
9393

94-
new aws_events.Rule(this.stack, `${prefixId}-cron`, {
95-
schedule: aws_events.Schedule.rate(Duration.minutes(1)),
96-
targets: [new ApiDestination(destination)],
97-
});
94+
let schedule: aws_events.Schedule | undefined = aws_events.Schedule.rate(Duration.minutes(1));
95+
96+
if (isNumber(this.common.cronMinutes)) {
97+
if (this.common.cronMinutes > 0)
98+
schedule = aws_events.Schedule.rate(Duration.minutes(this.common.cronMinutes));
99+
else schedule = undefined;
100+
}
101+
if (schedule)
102+
new aws_events.Rule(this.stack, `${prefixId}-cron`, {
103+
schedule,
104+
targets: [new ApiDestination(destination)],
105+
});
98106
}
99107

100108
private createEventConnection() {

stacks/Database.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Network } from './Network';
1212
import { get } from 'lodash';
1313

1414
import * as stage from '../stages';
15+
import { RedCapConfig } from '../prototyping';
1516

1617
export function Database({ stack, app }: StackContext) {
1718
const { networkVpc } = use(Network);
@@ -21,13 +22,20 @@ export function Database({ stack, app }: StackContext) {
2122
allowAllOutbound: true,
2223
});
2324

24-
const readers = get(stage, [stack.stage, 'db', 'dbReaders'], undefined);
25-
const scaling = get(stage, [stack.stage, 'db', 'scaling'], {
25+
const dbConfig = get(stage, [stack.stage, 'db']) as RedCapConfig['db'];
26+
27+
if (!dbConfig)
28+
console.warn(
29+
'WARNING: db config is absent in stages.ts, using Amazon Aurora defaults settings',
30+
);
31+
32+
const readers = dbConfig?.dbReaders ?? undefined;
33+
const scaling = dbConfig?.scaling ?? {
2634
maxCapacityAcu: 2,
2735
minCapacityAcu: 0.5,
28-
});
29-
const maxAllowedPacket = get(stage, [stack.stage, 'db', 'maxAllowedPacket'], '4194304');
30-
const snapshotIdentifier = get(stage, [stack.stage, 'db', 'dbSnapshotId'], undefined);
36+
};
37+
const maxAllowedPacket = dbConfig?.maxAllowedPacket ?? '4194304';
38+
const snapshotIdentifier = dbConfig?.dbSnapshotId ?? undefined;
3139
const logRetention = get(stage, [stack.stage, 'generalLogRetention'], undefined);
3240

3341
const auroraClusterV2 = new AuroraServerlessV2(stack, 'RDSV2', {

stages.sample.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const dev: RedCapConfig = {
1616
phpTimezone: 'Asia/Tokyo',
1717
redCapS3Path: 'redcap-binaries/redcap13.7.2.zip',
1818
cronSecret: 'mysecret',
19+
cronMinutes: 1, // a value of 0 means disabled
1920
2021
port: 8080,
2122
db: {
@@ -51,6 +52,7 @@ const prod: RedCapConfig = {
5152
appRunnerMaxSize: 10,
5253
appRunnerMinSize: 2,
5354
cronSecret: 'prodsecret',
55+
cronMinutes: 1,
5456
cpu: Cpu.FOUR_VCPU,
5557
memory: Memory.EIGHT_GB,
5658
ec2ServerStack: {
@@ -70,6 +72,7 @@ const stag: RedCapConfig = {
7072
appRunnerMinSize: 1,
7173
rebuildImage: false,
7274
cronSecret: 'stagsecret',
75+
cronMinutes: 1,
7376
cpu: Cpu.FOUR_VCPU,
7477
memory: Memory.EIGHT_GB,
7578
};

0 commit comments

Comments
 (0)