@exabugs/dynamodb-client 1.5.1 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/server/handler.cjs +10866 -6882
- package/dist/server/handler.cjs.map +4 -4
- package/dist/server/media/magicBytes.d.ts +25 -0
- package/dist/server/media/magicBytes.d.ts.map +1 -0
- package/dist/server/media/magicBytes.js +50 -0
- package/dist/server/media/magicBytes.js.map +1 -0
- package/dist/server/media/media-handler.d.ts +13 -0
- package/dist/server/media/media-handler.d.ts.map +1 -0
- package/dist/server/media/media-handler.js +143 -0
- package/dist/server/media/media-handler.js.map +1 -0
- package/dist/server/media/presign.d.ts +9 -0
- package/dist/server/media/presign.d.ts.map +1 -0
- package/dist/server/media/presign.js +73 -0
- package/dist/server/media/presign.js.map +1 -0
- package/dist/server/media/process-handler-dlq.d.ts +16 -0
- package/dist/server/media/process-handler-dlq.d.ts.map +1 -0
- package/dist/server/media/process-handler-dlq.js +52 -0
- package/dist/server/media/process-handler-dlq.js.map +1 -0
- package/dist/server/media/process-handler.d.ts +12 -0
- package/dist/server/media/process-handler.d.ts.map +1 -0
- package/dist/server/media/process-handler.js +138 -0
- package/dist/server/media/process-handler.js.map +1 -0
- package/dist/server/media/sign.d.ts +11 -0
- package/dist/server/media/sign.d.ts.map +1 -0
- package/dist/server/media/sign.js +49 -0
- package/dist/server/media/sign.js.map +1 -0
- package/dist/server/media/ssmParams.d.ts +29 -0
- package/dist/server/media/ssmParams.d.ts.map +1 -0
- package/dist/server/media/ssmParams.js +74 -0
- package/dist/server/media/ssmParams.js.map +1 -0
- package/dist/server/media/types.d.ts +109 -0
- package/dist/server/media/types.d.ts.map +1 -0
- package/dist/server/media/types.js +2 -0
- package/dist/server/media/types.js.map +1 -0
- package/dist/server/media-handler.cjs +57450 -0
- package/dist/server/media-handler.cjs.map +7 -0
- package/dist/server/media-process-handler-dlq.cjs +36195 -0
- package/dist/server/media-process-handler-dlq.cjs.map +7 -0
- package/dist/server/media-process-handler.cjs +60568 -0
- package/dist/server/media-process-handler.cjs.map +7 -0
- package/dist/server/utils/authHandler.d.ts +40 -1
- package/dist/server/utils/authHandler.d.ts.map +1 -1
- package/dist/server/utils/authHandler.js +14 -33
- package/dist/server/utils/authHandler.js.map +1 -1
- package/dist/sharp-layer.zip +0 -0
- package/package.json +34 -3
- package/terraform/main.tf +36 -2
- package/terraform/media/README.md +64 -0
- package/terraform/media/main.tf +718 -0
- package/terraform/media/outputs.tf +66 -0
- package/terraform/media/variables.tf +84 -0
- package/terraform/modules/parameter-store/main.tf +26 -1
- package/terraform/modules/parameter-store/variables.tf +7 -1
- package/terraform/outputs.tf +10 -0
- package/terraform/variables.tf +6 -0
|
@@ -2,8 +2,46 @@
|
|
|
2
2
|
* 認証ハンドラー
|
|
3
3
|
*
|
|
4
4
|
* IAM認証とCognito JWT認証を処理する
|
|
5
|
+
*
|
|
6
|
+
* このLambdaは2本のFunction URLから呼ばれる:
|
|
7
|
+
* - NONE認証のURL(ブラウザ・Admin UI向け): Cognito JWTのみを受け付ける
|
|
8
|
+
* - AWS_IAM認証のURL(サーバー間呼び出し向け): AWSが署名検証済みのリクエストのみ到達する
|
|
9
|
+
*
|
|
10
|
+
* 旧実装はAuthorization/x-amz-date等のヘッダーの「見た目」でIAM認証とみなしていたが、
|
|
11
|
+
* これらはクライアントが自由に送れる値であり、NONE認証のURL上では一切検証されない
|
|
12
|
+
* (署名検証はAWS_IAM認証のURL上でAWS自身が行うものであり、NONEのURLには存在しない)。
|
|
13
|
+
* そのため誰でも `x-amz-date` 等のヘッダーを送るだけでIAM認証を騙り、全リソースへの
|
|
14
|
+
* 認証なしアクセスが可能になっていた。
|
|
15
|
+
*
|
|
16
|
+
* 修正後は `event.requestContext.authorizer.iam` の有無で判定する。この値はAWS_IAM認証の
|
|
17
|
+
* Function URLが実際に署名検証に成功した場合にのみAWS側が付与するものであり、
|
|
18
|
+
* クライアントが送るヘッダーからは偽装できない。
|
|
5
19
|
*/
|
|
6
20
|
import type { APIGatewayProxyEventV2 } from 'aws-lambda';
|
|
21
|
+
/**
|
|
22
|
+
* AWS_IAM認証のFunction URLがリクエストに付与するコンテキスト
|
|
23
|
+
* (AWS Lambda公式の型定義 APIGatewayEventRequestContextIAMAuthorizer と同じ形)
|
|
24
|
+
*/
|
|
25
|
+
interface IAMAuthorizerContext {
|
|
26
|
+
accessKey: string;
|
|
27
|
+
accountId: string;
|
|
28
|
+
callerId: string;
|
|
29
|
+
cognitoIdentity: null;
|
|
30
|
+
principalOrgId: string;
|
|
31
|
+
userArn: string;
|
|
32
|
+
userId: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* NONE/AWS_IAM両方のFunction URLから届き得るイベント
|
|
36
|
+
* (同一のLambdaコードが両方のURLから呼ばれるため、authorizerはオプショナル)
|
|
37
|
+
*/
|
|
38
|
+
type RecordsEvent = APIGatewayProxyEventV2 & {
|
|
39
|
+
requestContext: {
|
|
40
|
+
authorizer?: {
|
|
41
|
+
iam?: IAMAuthorizerContext;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
7
45
|
/**
|
|
8
46
|
* 認証を処理する
|
|
9
47
|
*
|
|
@@ -12,5 +50,6 @@ import type { APIGatewayProxyEventV2 } from 'aws-lambda';
|
|
|
12
50
|
* @returns 認証が成功した場合はvoid、失敗した場合は例外をスロー
|
|
13
51
|
* @throws {Error} 認証に失敗した場合
|
|
14
52
|
*/
|
|
15
|
-
export declare function handleAuthentication(event:
|
|
53
|
+
export declare function handleAuthentication(event: RecordsEvent, requestId: string): Promise<void>;
|
|
54
|
+
export {};
|
|
16
55
|
//# sourceMappingURL=authHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authHandler.d.ts","sourceRoot":"","sources":["../../../src/server/utils/authHandler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"authHandler.d.ts","sourceRoot":"","sources":["../../../src/server/utils/authHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAazD;;;GAGG;AACH,UAAU,oBAAoB;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,KAAK,YAAY,GAAG,sBAAsB,GAAG;IAC3C,cAAc,EAAE;QACd,UAAU,CAAC,EAAE;YACX,GAAG,CAAC,EAAE,oBAAoB,CAAC;SAC5B,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAYf"}
|
|
@@ -16,47 +16,28 @@ const logger = createLogger({
|
|
|
16
16
|
* @throws {Error} 認証に失敗した場合
|
|
17
17
|
*/
|
|
18
18
|
export async function handleAuthentication(event, requestId) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const hasAmzContentSha = event.headers['x-amz-content-sha256'] || event.headers['X-Amz-Content-Sha256'];
|
|
25
|
-
const hasAwsSigV4Auth = authHeader?.startsWith('AWS4-HMAC-SHA256');
|
|
26
|
-
// デバッグ: ヘッダーをログ出力
|
|
27
|
-
logger.debug('Authentication check', {
|
|
28
|
-
requestId,
|
|
29
|
-
hasAuthHeader: !!authHeader,
|
|
30
|
-
hasAmzDate: !!hasAmzDate,
|
|
31
|
-
hasAmzContentSha: !!hasAmzContentSha,
|
|
32
|
-
hasAwsSigV4Auth: !!hasAwsSigV4Auth,
|
|
33
|
-
authHeaderPrefix: authHeader?.substring(0, 20),
|
|
34
|
-
});
|
|
35
|
-
// IAM認証チェック(AWS SigV4署名の特徴的なヘッダーで判定)
|
|
36
|
-
// 以下のいずれかの条件を満たす場合、IAM認証とみなす:
|
|
37
|
-
// 1. AuthorizationヘッダーがAWS4-HMAC-SHA256で始まる
|
|
38
|
-
// 2. x-amz-dateとx-amz-content-sha256の両方が存在する
|
|
39
|
-
const isIAMAuth = hasAwsSigV4Auth || !!(hasAmzDate && hasAmzContentSha);
|
|
40
|
-
if (isIAMAuth) {
|
|
41
|
-
await handleIAMAuthentication(event, requestId);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
await handleCognitoAuthentication(authHeader, requestId);
|
|
19
|
+
const iam = event.requestContext.authorizer?.iam;
|
|
20
|
+
if (iam) {
|
|
21
|
+
// AWS_IAM認証のFunction URL経由。AWSが署名検証済みであり、この値はクライアントから偽装できない
|
|
22
|
+
handleIAMAuthentication(iam, requestId);
|
|
23
|
+
return;
|
|
45
24
|
}
|
|
25
|
+
// NONE認証のFunction URL経由。Cognito JWTのみを受け付ける
|
|
26
|
+
const authHeader = event.headers.authorization || event.headers.Authorization;
|
|
27
|
+
await handleCognitoAuthentication(authHeader, requestId);
|
|
46
28
|
}
|
|
47
29
|
/**
|
|
48
|
-
* IAM
|
|
30
|
+
* IAM認証済みリクエストを処理する
|
|
49
31
|
*
|
|
50
|
-
* @param
|
|
32
|
+
* @param iam - AWSが検証済みのIAM認証コンテキスト(偽装不可)
|
|
51
33
|
* @param requestId - リクエストID
|
|
52
34
|
*/
|
|
53
|
-
|
|
54
|
-
// IAM認証(スクリプトからのアクセス)
|
|
55
|
-
// Lambda Function URLがNONEの場合、署名検証は行われないため、
|
|
56
|
-
// ここではIAM認証として扱うが、実際の検証はAWS側で行われる
|
|
35
|
+
function handleIAMAuthentication(iam, requestId) {
|
|
57
36
|
logger.info('IAM authenticated request', {
|
|
58
37
|
requestId,
|
|
59
|
-
|
|
38
|
+
userArn: iam.userArn,
|
|
39
|
+
accountId: iam.accountId,
|
|
40
|
+
callerId: iam.callerId,
|
|
60
41
|
});
|
|
61
42
|
}
|
|
62
43
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authHandler.js","sourceRoot":"","sources":["../../../src/server/utils/authHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authHandler.js","sourceRoot":"","sources":["../../../src/server/utils/authHandler.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,GAAG,YAAY,CAAC;IAC1B,OAAO,EAAE,cAAc;IACvB,KAAK,EAAG,OAAO,CAAC,GAAG,CAAC,SAAiD,IAAI,MAAM;CAChF,CAAC,CAAC;AA4BH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAmB,EACnB,SAAiB;IAEjB,MAAM,GAAG,GAAG,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC;IAEjD,IAAI,GAAG,EAAE,CAAC;QACR,4DAA4D;QAC5D,uBAAuB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACxC,OAAO;IACT,CAAC;IAED,4CAA4C;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;IAC9E,MAAM,2BAA2B,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,SAAS,uBAAuB,CAAC,GAAyB,EAAE,SAAiB;IAC3E,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;QACvC,SAAS;QACT,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACvB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,2BAA2B,CACxC,UAA8B,EAC9B,SAAiB;IAEjB,6BAA6B;IAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,QAAQ;IAExD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE5E,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;QACnC,SAAS;QACT,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,KAAK,EAAE,UAAU,CAAC,KAAK;KACxB,CAAC,CAAC;IAEH,kBAAkB;IAClB,uCAAuC;AACzC,CAAC"}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exabugs/dynamodb-client",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "DynamoDB Single-Table Client SDK with MongoDB-like API, Shadow Records, and Lambda implementation for serverless applications",
|
|
5
5
|
"author": "exabugs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -87,7 +87,32 @@
|
|
|
87
87
|
"import": "./dist/mcp/index.js",
|
|
88
88
|
"types": "./dist/mcp/index.d.ts"
|
|
89
89
|
},
|
|
90
|
-
"./
|
|
90
|
+
"./server/media/presign": {
|
|
91
|
+
"import": "./dist/server/media/presign.js",
|
|
92
|
+
"types": "./dist/server/media/presign.d.ts"
|
|
93
|
+
},
|
|
94
|
+
"./server/media-process-handler": {
|
|
95
|
+
"import": "./dist/server/media-process-handler.cjs",
|
|
96
|
+
"types": "./dist/server/media/process-handler.d.ts"
|
|
97
|
+
},
|
|
98
|
+
"./server/media-process-handler-dlq": {
|
|
99
|
+
"import": "./dist/server/media-process-handler-dlq.cjs",
|
|
100
|
+
"types": "./dist/server/media/process-handler-dlq.d.ts"
|
|
101
|
+
},
|
|
102
|
+
"./server/media-handler": {
|
|
103
|
+
"import": "./dist/server/media-handler.cjs",
|
|
104
|
+
"types": "./dist/server/media/media-handler.d.ts"
|
|
105
|
+
},
|
|
106
|
+
"./server/media-sign": {
|
|
107
|
+
"import": "./dist/server/media/sign.js",
|
|
108
|
+
"types": "./dist/server/media/sign.d.ts"
|
|
109
|
+
},
|
|
110
|
+
"./types/media": {
|
|
111
|
+
"import": "./dist/server/media/types.js",
|
|
112
|
+
"types": "./dist/server/media/types.d.ts"
|
|
113
|
+
},
|
|
114
|
+
"./terraform": "./terraform/main.tf",
|
|
115
|
+
"./terraform/media": "./terraform/media/main.tf"
|
|
91
116
|
},
|
|
92
117
|
"peerDependencies": {
|
|
93
118
|
"react-admin": "^5.0.0"
|
|
@@ -99,9 +124,10 @@
|
|
|
99
124
|
},
|
|
100
125
|
"scripts": {
|
|
101
126
|
"prebuild": "npm run generate-types",
|
|
102
|
-
"build": "tsc && node esbuild.config.js",
|
|
127
|
+
"build": "tsc && node esbuild.config.js && npm run build:sharp-layer",
|
|
103
128
|
"build:client": "tsc",
|
|
104
129
|
"build:lambda": "node esbuild.config.js",
|
|
130
|
+
"build:sharp-layer": "bash scripts/build-sharp-layer.sh",
|
|
105
131
|
"clean": "rm -rf dist",
|
|
106
132
|
"lint": "eslint src --ext ts --max-warnings 0",
|
|
107
133
|
"format": "prettier --write .",
|
|
@@ -119,8 +145,12 @@
|
|
|
119
145
|
"dependencies": {
|
|
120
146
|
"@aws-crypto/sha256-js": "5.2.0",
|
|
121
147
|
"@aws-sdk/client-dynamodb": "3.946.0",
|
|
148
|
+
"@aws-sdk/client-s3": "3.946.0",
|
|
149
|
+
"@aws-sdk/client-ssm": "3.946.0",
|
|
150
|
+
"@aws-sdk/cloudfront-signer": "3.946.0",
|
|
122
151
|
"@aws-sdk/credential-provider-node": "3.946.0",
|
|
123
152
|
"@aws-sdk/lib-dynamodb": "3.946.0",
|
|
153
|
+
"@aws-sdk/s3-presigned-post": "3.946.0",
|
|
124
154
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
125
155
|
"@smithy/protocol-http": "5.3.5",
|
|
126
156
|
"@smithy/signature-v4": "5.3.5",
|
|
@@ -146,6 +176,7 @@
|
|
|
146
176
|
"orval": "^8.2.0",
|
|
147
177
|
"prettier": "^3.0.0",
|
|
148
178
|
"react-admin": "^5.0.0",
|
|
179
|
+
"sharp": "^0.35.5",
|
|
149
180
|
"tsx": "^4.21.0",
|
|
150
181
|
"typescript": "^5.3.0",
|
|
151
182
|
"vitest": "^2.0.0",
|
package/terraform/main.tf
CHANGED
|
@@ -116,6 +116,7 @@ resource "aws_lambda_function" "records" {
|
|
|
116
116
|
REGION = var.region
|
|
117
117
|
TABLE_NAME = var.dynamodb_table_name
|
|
118
118
|
COGNITO_USER_POOL_ID = var.cognito_user_pool_id
|
|
119
|
+
COGNITO_CLIENT_ID = var.cognito_client_id
|
|
119
120
|
LOG_LEVEL = var.log_level
|
|
120
121
|
# シャドウ設定(環境変数ベース)
|
|
121
122
|
SHADOW_CREATED_AT_FIELD = var.shadow_created_at_field
|
|
@@ -168,6 +169,38 @@ resource "aws_lambda_permission" "function_url" {
|
|
|
168
169
|
principal = "*"
|
|
169
170
|
function_url_auth_type = "NONE"
|
|
170
171
|
}
|
|
172
|
+
|
|
173
|
+
# サーバー間(Lambda-to-Lambda)呼び出し専用のエイリアス
|
|
174
|
+
# NONE認証のFunction URL(上記)とは別に、AWS_IAM認証のFunction URLをこのエイリアス経由で公開する。
|
|
175
|
+
# 同一のLambda関数コード($LATEST)を指すが、Function URLは修飾子(エイリアス)ごとに1本しか
|
|
176
|
+
# 設定できないため、2本目のURLを持つにはエイリアスが必要。
|
|
177
|
+
resource "aws_lambda_alias" "iam" {
|
|
178
|
+
name = "iam"
|
|
179
|
+
description = "サーバー間呼び出し用(AWS_IAM認証のFunction URL向け)"
|
|
180
|
+
function_name = aws_lambda_function.records.function_name
|
|
181
|
+
function_version = "$LATEST"
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# AWS_IAM認証のLambda Function URL
|
|
185
|
+
# サーバー間呼び出し元(モバイルBFF・weather Lambda・運用スクリプト等)はこちらを使う。
|
|
186
|
+
# NONE認証URLと異なり、呼び出し元のIAMロールにlambda:InvokeFunctionUrl権限が必要で、
|
|
187
|
+
# AWSが実際にSigV4署名を検証する(NONE側のような「なんちゃってIAM認証」ではない)。
|
|
188
|
+
resource "aws_lambda_function_url" "records_iam" {
|
|
189
|
+
function_name = aws_lambda_function.records.function_name
|
|
190
|
+
qualifier = aws_lambda_alias.iam.name
|
|
191
|
+
authorization_type = "AWS_IAM"
|
|
192
|
+
|
|
193
|
+
cors {
|
|
194
|
+
allow_origins = ["*"]
|
|
195
|
+
allow_methods = ["GET", "POST", "PUT", "DELETE"]
|
|
196
|
+
allow_headers = ["content-type", "authorization", "x-amz-date", "x-api-key", "x-amz-security-token"]
|
|
197
|
+
expose_headers = ["content-type", "x-amzn-requestid"]
|
|
198
|
+
allow_credentials = false
|
|
199
|
+
max_age = 86400 # 24時間
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
depends_on = [aws_lambda_alias.iam]
|
|
203
|
+
}
|
|
171
204
|
# Parameter Store モジュール
|
|
172
205
|
module "parameter_store" {
|
|
173
206
|
source = "./modules/parameter-store"
|
|
@@ -178,8 +211,9 @@ module "parameter_store" {
|
|
|
178
211
|
region = var.region
|
|
179
212
|
|
|
180
213
|
# Records Lambda設定
|
|
181
|
-
records_function_url
|
|
182
|
-
|
|
214
|
+
records_function_url = aws_lambda_function_url.records.function_url
|
|
215
|
+
records_iam_function_url = aws_lambda_function_url.records_iam.function_url
|
|
216
|
+
records_function_arn = aws_lambda_function.records.arn
|
|
183
217
|
|
|
184
218
|
# Cognito設定
|
|
185
219
|
cognito_user_pool_id = var.cognito_user_pool_id
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# メディア機能 Terraformモジュール
|
|
2
|
+
|
|
3
|
+
ファイルアップロード・処理(EXIF除去・リサイズ)・配信機能をデプロイするTerraformモジュールです。
|
|
4
|
+
|
|
5
|
+
詳細設計: [../../docs/media-design.md](../../docs/media-design.md)
|
|
6
|
+
決定事項・トレードオフ: [../../docs/adr/0002-media-design.md](../../docs/adr/0002-media-design.md)
|
|
7
|
+
|
|
8
|
+
## 概要
|
|
9
|
+
|
|
10
|
+
このモジュールは、以下のリソースをデプロイします:
|
|
11
|
+
|
|
12
|
+
- S3バケット(raw/master/cache の3プレフィックス、完全非公開)
|
|
13
|
+
- sharp Lambda Layer(`scripts/build-sharp-layer.sh`で事前ビルドが必要)
|
|
14
|
+
- process-handler Lambda(S3 ObjectCreatedトリガー、EXIF除去・リサイズ・master配置)
|
|
15
|
+
- process-handler-dlq Lambda(SQS DLQトリガー、処理失敗時のfailedレコード書き込み)
|
|
16
|
+
- media-handler Lambda(CloudFront `/resize/*` 専用オリジン、オンデマンドリサイズ)
|
|
17
|
+
- CloudFront Distribution(`/master/*`はS3直接配信、`/resize/*`はmedia-handler経由、両方とも署名付きURL必須)
|
|
18
|
+
- CloudFront Public Key / Key Group(署名鍵は呼び出し側がSSM Parameter Storeに別途登録する)
|
|
19
|
+
|
|
20
|
+
**含まないもの**: presign/署名URL発行用のLambda。「誰にpresign/署名URLを発行してよいか」の認可判断はアプリごとに異なるため、呼び出し側は既存のHTTP APIレイヤー(認証・権限チェック済み)から `../../src/server/media/presign.ts`・`sign.ts` を直接呼び出して自前のLambda/ルートに組み込んでください。
|
|
21
|
+
|
|
22
|
+
## 前提条件
|
|
23
|
+
|
|
24
|
+
1. `npm run build`(`scripts/build-sharp-layer.sh`を含む。Dockerが必要)を実行し、`dist/`配下にLambda成果物を生成しておくこと
|
|
25
|
+
2. 署名鍵(RSA 2048bit)を生成し、公開鍵を`signing_public_key_param`で指定するSSM Parameterに登録しておくこと(秘密鍵は呼び出し側のpresign/署名URL発行処理が別途SSM経由で取得する)
|
|
26
|
+
3. image policy(`masterMaxDimension`・`allowedContentTypes`・`maxUploadSize`)のJSONを`image_policy_param`で指定するSSM Parameterに登録しておくこと
|
|
27
|
+
|
|
28
|
+
## 使用方法
|
|
29
|
+
|
|
30
|
+
```hcl
|
|
31
|
+
module "media" {
|
|
32
|
+
source = "github.com/exabugs/dynamodb-client//terraform/media"
|
|
33
|
+
|
|
34
|
+
project_name = "my-project"
|
|
35
|
+
environment = "dev"
|
|
36
|
+
region = "ap-northeast-1"
|
|
37
|
+
|
|
38
|
+
table_name = module.dynamodb.table_name
|
|
39
|
+
table_arn = module.dynamodb.table_arn
|
|
40
|
+
|
|
41
|
+
signing_public_key_param = "/my-project/dev/media/signing-public-key"
|
|
42
|
+
image_policy_param = "/my-project/dev/media/image-policy"
|
|
43
|
+
|
|
44
|
+
# カスタムドメイン使用時のみ(省略時はCloudFrontのデフォルトドメインを使う)
|
|
45
|
+
domain_name = "media.dev.example.com"
|
|
46
|
+
acm_certificate_arn = module.cloudfront.certificate_arn # us-east-1リージョンの証明書
|
|
47
|
+
route53_zone_id = var.route53_zone_id
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`module.media`のoutput(`key_pair_id`・`base_url`)を、presign/署名URL発行を行う呼び出し側のLambdaへ変数として渡してください。
|
|
52
|
+
|
|
53
|
+
## 依存関係の向き
|
|
54
|
+
|
|
55
|
+
本モジュールは呼び出し側の既存CloudFront・テーブルARNに依存しません(片方向)。循環依存を避けるため、呼び出し側のLambdaが`module.media`のoutputに依存する向きで配線してください。
|
|
56
|
+
|
|
57
|
+
## 検証
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
terraform init -backend=false
|
|
61
|
+
terraform validate
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
実際の`terraform plan`/`apply`にはAWS認証情報とダミーでない変数値が必要です。
|