@exabugs/dynamodb-client 0.1.0

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.
Files changed (230) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.md +283 -0
  4. package/dist/client/Collection.d.ts +57 -0
  5. package/dist/client/Collection.d.ts.map +1 -0
  6. package/dist/client/Collection.js +174 -0
  7. package/dist/client/Collection.js.map +1 -0
  8. package/dist/client/Database.d.ts +35 -0
  9. package/dist/client/Database.d.ts.map +1 -0
  10. package/dist/client/Database.js +48 -0
  11. package/dist/client/Database.js.map +1 -0
  12. package/dist/client/DynamoClient.d.ts +43 -0
  13. package/dist/client/DynamoClient.d.ts.map +1 -0
  14. package/dist/client/DynamoClient.js +62 -0
  15. package/dist/client/DynamoClient.js.map +1 -0
  16. package/dist/client/FindCursor.d.ts +174 -0
  17. package/dist/client/FindCursor.d.ts.map +1 -0
  18. package/dist/client/FindCursor.js +256 -0
  19. package/dist/client/FindCursor.js.map +1 -0
  20. package/dist/client/aws-sigv4.d.ts +10 -0
  21. package/dist/client/aws-sigv4.d.ts.map +1 -0
  22. package/dist/client/aws-sigv4.js +54 -0
  23. package/dist/client/aws-sigv4.js.map +1 -0
  24. package/dist/client/index.cognito.d.ts +34 -0
  25. package/dist/client/index.cognito.d.ts.map +1 -0
  26. package/dist/client/index.cognito.js +30 -0
  27. package/dist/client/index.cognito.js.map +1 -0
  28. package/dist/client/index.d.ts +12 -0
  29. package/dist/client/index.d.ts.map +1 -0
  30. package/dist/client/index.iam.d.ts +34 -0
  31. package/dist/client/index.iam.d.ts.map +1 -0
  32. package/dist/client/index.iam.js +28 -0
  33. package/dist/client/index.iam.js.map +1 -0
  34. package/dist/client/index.js +12 -0
  35. package/dist/client/index.js.map +1 -0
  36. package/dist/client/index.token.d.ts +33 -0
  37. package/dist/client/index.token.d.ts.map +1 -0
  38. package/dist/client/index.token.js +28 -0
  39. package/dist/client/index.token.js.map +1 -0
  40. package/dist/dynamodb.d.ts +20 -0
  41. package/dist/dynamodb.d.ts.map +1 -0
  42. package/dist/dynamodb.js +31 -0
  43. package/dist/dynamodb.js.map +1 -0
  44. package/dist/errors.d.ts +100 -0
  45. package/dist/errors.d.ts.map +1 -0
  46. package/dist/errors.js +146 -0
  47. package/dist/errors.js.map +1 -0
  48. package/dist/index.d.ts +10 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +7 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/integrations/react-admin/dataProvider.d.ts +59 -0
  53. package/dist/integrations/react-admin/dataProvider.d.ts.map +1 -0
  54. package/dist/integrations/react-admin/dataProvider.js +364 -0
  55. package/dist/integrations/react-admin/dataProvider.js.map +1 -0
  56. package/dist/integrations/react-admin/index.d.ts +24 -0
  57. package/dist/integrations/react-admin/index.d.ts.map +1 -0
  58. package/dist/integrations/react-admin/index.js +23 -0
  59. package/dist/integrations/react-admin/index.js.map +1 -0
  60. package/dist/integrations/react-admin/types.d.ts +47 -0
  61. package/dist/integrations/react-admin/types.d.ts.map +1 -0
  62. package/dist/integrations/react-admin/types.js +5 -0
  63. package/dist/integrations/react-admin/types.js.map +1 -0
  64. package/dist/logger.d.ts +61 -0
  65. package/dist/logger.d.ts.map +1 -0
  66. package/dist/logger.js +87 -0
  67. package/dist/logger.js.map +1 -0
  68. package/dist/scripts/repair-shadows.d.ts +3 -0
  69. package/dist/scripts/repair-shadows.d.ts.map +1 -0
  70. package/dist/scripts/repair-shadows.js +190 -0
  71. package/dist/scripts/repair-shadows.js.map +1 -0
  72. package/dist/server/handler.cjs +31378 -0
  73. package/dist/server/handler.cjs.map +7 -0
  74. package/dist/server/handler.d.ts +18 -0
  75. package/dist/server/handler.d.ts.map +1 -0
  76. package/dist/server/handler.js +435 -0
  77. package/dist/server/handler.js.map +1 -0
  78. package/dist/server/handler.zip +0 -0
  79. package/dist/server/index.d.ts +8 -0
  80. package/dist/server/index.d.ts.map +1 -0
  81. package/dist/server/index.js +8 -0
  82. package/dist/server/index.js.map +1 -0
  83. package/dist/server/operations/deleteMany.d.ts +18 -0
  84. package/dist/server/operations/deleteMany.d.ts.map +1 -0
  85. package/dist/server/operations/deleteMany.js +222 -0
  86. package/dist/server/operations/deleteMany.js.map +1 -0
  87. package/dist/server/operations/deleteOne.d.ts +17 -0
  88. package/dist/server/operations/deleteOne.d.ts.map +1 -0
  89. package/dist/server/operations/deleteOne.js +87 -0
  90. package/dist/server/operations/deleteOne.js.map +1 -0
  91. package/dist/server/operations/find.d.ts +18 -0
  92. package/dist/server/operations/find.d.ts.map +1 -0
  93. package/dist/server/operations/find.js +382 -0
  94. package/dist/server/operations/find.js.map +1 -0
  95. package/dist/server/operations/findMany.d.ts +13 -0
  96. package/dist/server/operations/findMany.d.ts.map +1 -0
  97. package/dist/server/operations/findMany.js +61 -0
  98. package/dist/server/operations/findMany.js.map +1 -0
  99. package/dist/server/operations/findManyReference.d.ts +18 -0
  100. package/dist/server/operations/findManyReference.d.ts.map +1 -0
  101. package/dist/server/operations/findManyReference.js +150 -0
  102. package/dist/server/operations/findManyReference.js.map +1 -0
  103. package/dist/server/operations/findOne.d.ts +14 -0
  104. package/dist/server/operations/findOne.d.ts.map +1 -0
  105. package/dist/server/operations/findOne.js +56 -0
  106. package/dist/server/operations/findOne.js.map +1 -0
  107. package/dist/server/operations/insertMany.d.ts +19 -0
  108. package/dist/server/operations/insertMany.d.ts.map +1 -0
  109. package/dist/server/operations/insertMany.js +243 -0
  110. package/dist/server/operations/insertMany.js.map +1 -0
  111. package/dist/server/operations/insertOne.d.ts +18 -0
  112. package/dist/server/operations/insertOne.d.ts.map +1 -0
  113. package/dist/server/operations/insertOne.js +85 -0
  114. package/dist/server/operations/insertOne.js.map +1 -0
  115. package/dist/server/operations/updateMany.d.ts +20 -0
  116. package/dist/server/operations/updateMany.d.ts.map +1 -0
  117. package/dist/server/operations/updateMany.js +316 -0
  118. package/dist/server/operations/updateMany.js.map +1 -0
  119. package/dist/server/operations/updateOne.d.ts +20 -0
  120. package/dist/server/operations/updateOne.d.ts.map +1 -0
  121. package/dist/server/operations/updateOne.js +159 -0
  122. package/dist/server/operations/updateOne.js.map +1 -0
  123. package/dist/server/query/converter.d.ts +85 -0
  124. package/dist/server/query/converter.d.ts.map +1 -0
  125. package/dist/server/query/converter.js +161 -0
  126. package/dist/server/query/converter.js.map +1 -0
  127. package/dist/server/query/index.d.ts +5 -0
  128. package/dist/server/query/index.d.ts.map +1 -0
  129. package/dist/server/query/index.js +5 -0
  130. package/dist/server/query/index.js.map +1 -0
  131. package/dist/server/shadow/config.d.ts +147 -0
  132. package/dist/server/shadow/config.d.ts.map +1 -0
  133. package/dist/server/shadow/config.js +162 -0
  134. package/dist/server/shadow/config.js.map +1 -0
  135. package/dist/server/shadow/differ.d.ts +42 -0
  136. package/dist/server/shadow/differ.d.ts.map +1 -0
  137. package/dist/server/shadow/differ.js +66 -0
  138. package/dist/server/shadow/differ.js.map +1 -0
  139. package/dist/server/shadow/generator.d.ts +104 -0
  140. package/dist/server/shadow/generator.d.ts.map +1 -0
  141. package/dist/server/shadow/generator.js +148 -0
  142. package/dist/server/shadow/generator.js.map +1 -0
  143. package/dist/server/shadow/index.d.ts +11 -0
  144. package/dist/server/shadow/index.d.ts.map +1 -0
  145. package/dist/server/shadow/index.js +11 -0
  146. package/dist/server/shadow/index.js.map +1 -0
  147. package/dist/server/shadow/types.d.ts +44 -0
  148. package/dist/server/shadow/types.d.ts.map +1 -0
  149. package/dist/server/shadow/types.js +2 -0
  150. package/dist/server/shadow/types.js.map +1 -0
  151. package/dist/server/types.d.ts +295 -0
  152. package/dist/server/types.d.ts.map +1 -0
  153. package/dist/server/types.js +7 -0
  154. package/dist/server/types.js.map +1 -0
  155. package/dist/server/utils/auth.d.ts +43 -0
  156. package/dist/server/utils/auth.d.ts.map +1 -0
  157. package/dist/server/utils/auth.js +123 -0
  158. package/dist/server/utils/auth.js.map +1 -0
  159. package/dist/server/utils/bulkOperations.d.ts +81 -0
  160. package/dist/server/utils/bulkOperations.d.ts.map +1 -0
  161. package/dist/server/utils/bulkOperations.js +147 -0
  162. package/dist/server/utils/bulkOperations.js.map +1 -0
  163. package/dist/server/utils/chunking.d.ts +96 -0
  164. package/dist/server/utils/chunking.d.ts.map +1 -0
  165. package/dist/server/utils/chunking.js +225 -0
  166. package/dist/server/utils/chunking.js.map +1 -0
  167. package/dist/server/utils/dynamodb.d.ts +41 -0
  168. package/dist/server/utils/dynamodb.d.ts.map +1 -0
  169. package/dist/server/utils/dynamodb.js +83 -0
  170. package/dist/server/utils/dynamodb.js.map +1 -0
  171. package/dist/server/utils/filter.d.ts +152 -0
  172. package/dist/server/utils/filter.d.ts.map +1 -0
  173. package/dist/server/utils/filter.js +270 -0
  174. package/dist/server/utils/filter.js.map +1 -0
  175. package/dist/server/utils/pagination.d.ts +27 -0
  176. package/dist/server/utils/pagination.d.ts.map +1 -0
  177. package/dist/server/utils/pagination.js +56 -0
  178. package/dist/server/utils/pagination.js.map +1 -0
  179. package/dist/server/utils/timestamps.d.ts +31 -0
  180. package/dist/server/utils/timestamps.d.ts.map +1 -0
  181. package/dist/server/utils/timestamps.js +84 -0
  182. package/dist/server/utils/timestamps.js.map +1 -0
  183. package/dist/server/utils/ttl.d.ts +17 -0
  184. package/dist/server/utils/ttl.d.ts.map +1 -0
  185. package/dist/server/utils/ttl.js +62 -0
  186. package/dist/server/utils/ttl.js.map +1 -0
  187. package/dist/server/utils/validation.d.ts +40 -0
  188. package/dist/server/utils/validation.d.ts.map +1 -0
  189. package/dist/server/utils/validation.js +54 -0
  190. package/dist/server/utils/validation.js.map +1 -0
  191. package/dist/shadows/config.d.ts +54 -0
  192. package/dist/shadows/config.d.ts.map +1 -0
  193. package/dist/shadows/config.js +95 -0
  194. package/dist/shadows/config.js.map +1 -0
  195. package/dist/shadows/differ.d.ts +42 -0
  196. package/dist/shadows/differ.d.ts.map +1 -0
  197. package/dist/shadows/differ.js +66 -0
  198. package/dist/shadows/differ.js.map +1 -0
  199. package/dist/shadows/generator.d.ts +63 -0
  200. package/dist/shadows/generator.d.ts.map +1 -0
  201. package/dist/shadows/generator.js +107 -0
  202. package/dist/shadows/generator.js.map +1 -0
  203. package/dist/shadows/index.d.ts +15 -0
  204. package/dist/shadows/index.d.ts.map +1 -0
  205. package/dist/shadows/index.js +17 -0
  206. package/dist/shadows/index.js.map +1 -0
  207. package/dist/shadows/types.d.ts +44 -0
  208. package/dist/shadows/types.d.ts.map +1 -0
  209. package/dist/shadows/types.js +2 -0
  210. package/dist/shadows/types.js.map +1 -0
  211. package/dist/types.d.ts +165 -0
  212. package/dist/types.d.ts.map +1 -0
  213. package/dist/types.js +2 -0
  214. package/dist/types.js.map +1 -0
  215. package/dist/ulid.d.ts +46 -0
  216. package/dist/ulid.d.ts.map +1 -0
  217. package/dist/ulid.js +66 -0
  218. package/dist/ulid.js.map +1 -0
  219. package/package.json +136 -0
  220. package/terraform/README.md +222 -0
  221. package/terraform/examples/advanced/README.md +129 -0
  222. package/terraform/examples/advanced/main.tf +158 -0
  223. package/terraform/examples/advanced/shadow.config.json +35 -0
  224. package/terraform/examples/advanced/variables.tf +28 -0
  225. package/terraform/examples/basic/README.md +53 -0
  226. package/terraform/examples/basic/main.tf +99 -0
  227. package/terraform/examples/basic/variables.tf +17 -0
  228. package/terraform/main.tf +159 -0
  229. package/terraform/outputs.tf +56 -0
  230. package/terraform/variables.tf +59 -0
@@ -0,0 +1,129 @@
1
+ # Advanced Example
2
+
3
+ This example demonstrates an advanced deployment with:
4
+
5
+ - Multi-environment support (dev/stg/prd)
6
+ - External shadow configuration file
7
+ - CloudWatch Alarms
8
+ - TTL configuration
9
+ - Point-in-time Recovery (production only)
10
+ - MFA configuration (production only)
11
+ - Environment-specific settings
12
+
13
+ ## What This Example Creates
14
+
15
+ - DynamoDB table with TTL and PITR
16
+ - Cognito User Pool with advanced security settings
17
+ - Cognito App Client with token validity configuration
18
+ - Records Lambda function with Function URL
19
+ - CloudWatch Alarms for error monitoring
20
+ - IAM roles and policies
21
+ - CloudWatch Logs
22
+
23
+ ## Usage
24
+
25
+ 1. Review and customize `shadow.config.json`:
26
+
27
+ ```bash
28
+ cat shadow.config.json
29
+ ```
30
+
31
+ 2. Initialize Terraform:
32
+
33
+ ```bash
34
+ terraform init
35
+ ```
36
+
37
+ 3. Review the plan:
38
+
39
+ ```bash
40
+ terraform plan -var="environment=dev"
41
+ ```
42
+
43
+ 4. Apply the configuration:
44
+
45
+ ```bash
46
+ terraform apply -var="environment=dev"
47
+ ```
48
+
49
+ 5. Get the outputs:
50
+
51
+ ```bash
52
+ terraform output
53
+ ```
54
+
55
+ ## Environment-Specific Settings
56
+
57
+ ### Development (dev)
58
+ - Log retention: 7 days
59
+ - Log level: debug
60
+ - MFA: Optional
61
+ - PITR: Disabled
62
+
63
+ ### Staging (stg)
64
+ - Log retention: 7 days
65
+ - Log level: info
66
+ - MFA: Optional
67
+ - PITR: Disabled
68
+
69
+ ### Production (prd)
70
+ - Log retention: 30 days
71
+ - Log level: warn
72
+ - MFA: Required
73
+ - PITR: Enabled
74
+
75
+ ## Shadow Configuration
76
+
77
+ The `shadow.config.json` file defines sortable fields for each resource:
78
+
79
+ ```json
80
+ {
81
+ "$schemaVersion": "1.0",
82
+ "resources": {
83
+ "articles": {
84
+ "sortDefaults": {
85
+ "field": "updatedAt",
86
+ "order": "DESC"
87
+ },
88
+ "shadows": {
89
+ "title": { "type": "string" },
90
+ "status": { "type": "string" },
91
+ "publishedAt": { "type": "datetime" },
92
+ "createdAt": { "type": "datetime" },
93
+ "updatedAt": { "type": "datetime" }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## CloudWatch Alarms
101
+
102
+ The example includes a CloudWatch Alarm that triggers when:
103
+ - Lambda function errors exceed 10 in a 5-minute period
104
+
105
+ To receive notifications, provide an SNS topic ARN:
106
+
107
+ ```bash
108
+ terraform apply -var="sns_topic_arn=arn:aws:sns:us-east-1:123456789012:alerts"
109
+ ```
110
+
111
+ ## Clean Up
112
+
113
+ To destroy all resources:
114
+
115
+ ```bash
116
+ terraform destroy
117
+ ```
118
+
119
+ ## Customization
120
+
121
+ You can customize the deployment by modifying variables:
122
+
123
+ ```bash
124
+ terraform apply \
125
+ -var="project_name=my-app" \
126
+ -var="environment=prd" \
127
+ -var="region=ap-northeast-1" \
128
+ -var="sns_topic_arn=arn:aws:sns:..."
129
+ ```
@@ -0,0 +1,158 @@
1
+ # Advanced Example: Multi-Environment with External Shadow Config
2
+
3
+ terraform {
4
+ required_version = ">= 1.5.0"
5
+
6
+ required_providers {
7
+ aws = {
8
+ source = "hashicorp/aws"
9
+ version = "~> 5.0"
10
+ }
11
+ }
12
+ }
13
+
14
+ provider "aws" {
15
+ region = var.region
16
+ }
17
+
18
+ # DynamoDB Table with TTL
19
+ resource "aws_dynamodb_table" "main" {
20
+ name = "${var.project_name}-${var.environment}-records"
21
+ billing_mode = "PAY_PER_REQUEST"
22
+ hash_key = "PK"
23
+ range_key = "SK"
24
+
25
+ attribute {
26
+ name = "PK"
27
+ type = "S"
28
+ }
29
+
30
+ attribute {
31
+ name = "SK"
32
+ type = "S"
33
+ }
34
+
35
+ # TTL Configuration
36
+ ttl {
37
+ attribute_name = "ttl"
38
+ enabled = true
39
+ }
40
+
41
+ # Point-in-time Recovery
42
+ point_in_time_recovery {
43
+ enabled = var.environment == "prd"
44
+ }
45
+
46
+ tags = {
47
+ Name = "${var.project_name}-${var.environment}-records"
48
+ Environment = var.environment
49
+ }
50
+ }
51
+
52
+ # Cognito User Pool with Advanced Settings
53
+ resource "aws_cognito_user_pool" "main" {
54
+ name = "${var.project_name}-${var.environment}-users"
55
+
56
+ # Password Policy
57
+ password_policy {
58
+ minimum_length = 8
59
+ require_lowercase = true
60
+ require_numbers = true
61
+ require_symbols = true
62
+ require_uppercase = true
63
+ }
64
+
65
+ # MFA Configuration
66
+ mfa_configuration = var.environment == "prd" ? "REQUIRED" : "OPTIONAL"
67
+
68
+ tags = {
69
+ Name = "${var.project_name}-${var.environment}-users"
70
+ Environment = var.environment
71
+ }
72
+ }
73
+
74
+ # Cognito App Client
75
+ resource "aws_cognito_user_pool_client" "main" {
76
+ name = "${var.project_name}-${var.environment}-client"
77
+ user_pool_id = aws_cognito_user_pool.main.id
78
+
79
+ explicit_auth_flows = [
80
+ "ALLOW_USER_SRP_AUTH",
81
+ "ALLOW_REFRESH_TOKEN_AUTH"
82
+ ]
83
+
84
+ # Token Validity
85
+ access_token_validity = 1 # 1 hour
86
+ id_token_validity = 1 # 1 hour
87
+ refresh_token_validity = 30 # 30 days
88
+
89
+ token_validity_units {
90
+ access_token = "hours"
91
+ id_token = "hours"
92
+ refresh_token = "days"
93
+ }
94
+ }
95
+
96
+ # Records Lambda Module with External Config
97
+ module "lambda_records" {
98
+ source = "../../"
99
+
100
+ project_name = var.project_name
101
+ environment = var.environment
102
+ region = var.region
103
+
104
+ # DynamoDB
105
+ dynamodb_table_name = aws_dynamodb_table.main.name
106
+ dynamodb_table_arn = aws_dynamodb_table.main.arn
107
+
108
+ # Cognito
109
+ cognito_user_pool_id = aws_cognito_user_pool.main.id
110
+ cognito_client_id = aws_cognito_user_pool_client.main.id
111
+
112
+ # Shadow Config from External File
113
+ shadow_config = base64encode(file("${path.module}/shadow.config.json"))
114
+
115
+ # Logging (environment-specific)
116
+ log_retention_days = var.environment == "prd" ? 30 : 7
117
+ log_level = var.environment == "prd" ? "warn" : "debug"
118
+ }
119
+
120
+ # CloudWatch Alarm for Lambda Errors
121
+ resource "aws_cloudwatch_metric_alarm" "lambda_errors" {
122
+ alarm_name = "${var.project_name}-${var.environment}-lambda-errors"
123
+ comparison_operator = "GreaterThanThreshold"
124
+ evaluation_periods = 1
125
+ metric_name = "Errors"
126
+ namespace = "AWS/Lambda"
127
+ period = 300
128
+ statistic = "Sum"
129
+ threshold = 10
130
+ alarm_description = "Lambda function error rate is too high"
131
+
132
+ dimensions = {
133
+ FunctionName = module.lambda_records.function_name
134
+ }
135
+
136
+ alarm_actions = var.sns_topic_arn != "" ? [var.sns_topic_arn] : []
137
+ }
138
+
139
+ # Outputs
140
+ output "function_url" {
141
+ description = "Lambda Function URL"
142
+ value = module.lambda_records.function_url
143
+ }
144
+
145
+ output "function_name" {
146
+ description = "Lambda Function Name"
147
+ value = module.lambda_records.function_name
148
+ }
149
+
150
+ output "cognito_user_pool_id" {
151
+ description = "Cognito User Pool ID"
152
+ value = aws_cognito_user_pool.main.id
153
+ }
154
+
155
+ output "cognito_client_id" {
156
+ description = "Cognito App Client ID"
157
+ value = aws_cognito_user_pool_client.main.id
158
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schemaVersion": "1.0",
3
+ "resources": {
4
+ "articles": {
5
+ "sortDefaults": {
6
+ "field": "updatedAt",
7
+ "order": "DESC"
8
+ },
9
+ "shadows": {
10
+ "title": { "type": "string" },
11
+ "status": { "type": "string" },
12
+ "publishedAt": { "type": "datetime" },
13
+ "createdAt": { "type": "datetime" },
14
+ "updatedAt": { "type": "datetime" }
15
+ },
16
+ "ttl": {
17
+ "days": 90
18
+ }
19
+ },
20
+ "tasks": {
21
+ "sortDefaults": {
22
+ "field": "priority",
23
+ "order": "DESC"
24
+ },
25
+ "shadows": {
26
+ "title": { "type": "string" },
27
+ "status": { "type": "string" },
28
+ "priority": { "type": "number" },
29
+ "dueDate": { "type": "datetime" },
30
+ "createdAt": { "type": "datetime" },
31
+ "updatedAt": { "type": "datetime" }
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,28 @@
1
+ variable "project_name" {
2
+ description = "Project name"
3
+ type = string
4
+ default = "my-project"
5
+ }
6
+
7
+ variable "environment" {
8
+ description = "Environment (dev/stg/prd)"
9
+ type = string
10
+ default = "dev"
11
+
12
+ validation {
13
+ condition = contains(["dev", "stg", "prd"], var.environment)
14
+ error_message = "Environment must be dev, stg, or prd."
15
+ }
16
+ }
17
+
18
+ variable "region" {
19
+ description = "AWS Region"
20
+ type = string
21
+ default = "us-east-1"
22
+ }
23
+
24
+ variable "sns_topic_arn" {
25
+ description = "SNS Topic ARN for CloudWatch Alarms (optional)"
26
+ type = string
27
+ default = ""
28
+ }
@@ -0,0 +1,53 @@
1
+ # Basic Example
2
+
3
+ This example demonstrates a basic deployment of the DynamoDB Client Lambda function with minimal configuration.
4
+
5
+ ## What This Example Creates
6
+
7
+ - DynamoDB table (Single-Table design)
8
+ - Cognito User Pool (for authentication)
9
+ - Records Lambda function with Function URL
10
+ - IAM roles and policies
11
+ - CloudWatch Logs
12
+
13
+ ## Usage
14
+
15
+ 1. Initialize Terraform:
16
+
17
+ ```bash
18
+ terraform init
19
+ ```
20
+
21
+ 2. Review the plan:
22
+
23
+ ```bash
24
+ terraform plan
25
+ ```
26
+
27
+ 3. Apply the configuration:
28
+
29
+ ```bash
30
+ terraform apply
31
+ ```
32
+
33
+ 4. Get the Function URL:
34
+
35
+ ```bash
36
+ terraform output function_url
37
+ ```
38
+
39
+ ## Clean Up
40
+
41
+ To destroy all resources:
42
+
43
+ ```bash
44
+ terraform destroy
45
+ ```
46
+
47
+ ## Customization
48
+
49
+ You can customize the deployment by modifying `variables.tf` or passing variables:
50
+
51
+ ```bash
52
+ terraform apply -var="project_name=my-app" -var="environment=prod"
53
+ ```
@@ -0,0 +1,99 @@
1
+ # Basic Example: DynamoDB Client Lambda Deployment
2
+
3
+ terraform {
4
+ required_version = ">= 1.5.0"
5
+
6
+ required_providers {
7
+ aws = {
8
+ source = "hashicorp/aws"
9
+ version = "~> 5.0"
10
+ }
11
+ }
12
+ }
13
+
14
+ provider "aws" {
15
+ region = var.region
16
+ }
17
+
18
+ # DynamoDB Table
19
+ resource "aws_dynamodb_table" "main" {
20
+ name = "${var.project_name}-${var.environment}-records"
21
+ billing_mode = "PAY_PER_REQUEST"
22
+ hash_key = "PK"
23
+ range_key = "SK"
24
+
25
+ attribute {
26
+ name = "PK"
27
+ type = "S"
28
+ }
29
+
30
+ attribute {
31
+ name = "SK"
32
+ type = "S"
33
+ }
34
+
35
+ tags = {
36
+ Name = "${var.project_name}-${var.environment}-records"
37
+ Environment = var.environment
38
+ }
39
+ }
40
+
41
+ # Cognito User Pool
42
+ resource "aws_cognito_user_pool" "main" {
43
+ name = "${var.project_name}-${var.environment}-users"
44
+
45
+ tags = {
46
+ Name = "${var.project_name}-${var.environment}-users"
47
+ Environment = var.environment
48
+ }
49
+ }
50
+
51
+ # Records Lambda Module
52
+ module "lambda_records" {
53
+ source = "../../"
54
+
55
+ project_name = var.project_name
56
+ environment = var.environment
57
+ region = var.region
58
+
59
+ # DynamoDB
60
+ dynamodb_table_name = aws_dynamodb_table.main.name
61
+ dynamodb_table_arn = aws_dynamodb_table.main.arn
62
+
63
+ # Cognito
64
+ cognito_user_pool_id = aws_cognito_user_pool.main.id
65
+
66
+ # Shadow Config
67
+ shadow_config = base64encode(jsonencode({
68
+ "$schemaVersion" = "1.0"
69
+ resources = {
70
+ articles = {
71
+ sortDefaults = {
72
+ field = "updatedAt"
73
+ order = "DESC"
74
+ }
75
+ shadows = {
76
+ title = { type = "string" }
77
+ status = { type = "string" }
78
+ createdAt = { type = "datetime" }
79
+ updatedAt = { type = "datetime" }
80
+ }
81
+ }
82
+ }
83
+ }))
84
+
85
+ # Logging
86
+ log_retention_days = 7
87
+ log_level = "info"
88
+ }
89
+
90
+ # Outputs
91
+ output "function_url" {
92
+ description = "Lambda Function URL"
93
+ value = module.lambda_records.function_url
94
+ }
95
+
96
+ output "function_name" {
97
+ description = "Lambda Function Name"
98
+ value = module.lambda_records.function_name
99
+ }
@@ -0,0 +1,17 @@
1
+ variable "project_name" {
2
+ description = "Project name"
3
+ type = string
4
+ default = "my-project"
5
+ }
6
+
7
+ variable "environment" {
8
+ description = "Environment (dev/stg/prd)"
9
+ type = string
10
+ default = "dev"
11
+ }
12
+
13
+ variable "region" {
14
+ description = "AWS Region"
15
+ type = string
16
+ default = "us-east-1"
17
+ }
@@ -0,0 +1,159 @@
1
+ # Records Lambda関数モジュール
2
+
3
+ # Records Lambda専用IAMロール
4
+ # 最小権限の原則に従い、DynamoDBとCloudWatch Logsのみにアクセス可能
5
+ resource "aws_iam_role" "lambda_records" {
6
+ name = "${var.project_name}-${var.environment}-records-lambda-role"
7
+
8
+ assume_role_policy = jsonencode({
9
+ Version = "2012-10-17"
10
+ Statement = [
11
+ {
12
+ Action = "sts:AssumeRole"
13
+ Effect = "Allow"
14
+ Principal = {
15
+ Service = "lambda.amazonaws.com"
16
+ }
17
+ }
18
+ ]
19
+ })
20
+
21
+ tags = {
22
+ Name = "${var.project_name}-${var.environment}-records-lambda-role"
23
+ Environment = var.environment
24
+ ManagedBy = "terraform"
25
+ Purpose = "records-lambda"
26
+ }
27
+ }
28
+
29
+ # AWSマネージドポリシー: CloudWatch Logs
30
+ resource "aws_iam_role_policy_attachment" "records_basic_execution" {
31
+ role = aws_iam_role.lambda_records.name
32
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
33
+ }
34
+
35
+ # AWSマネージドポリシー: X-Ray
36
+ resource "aws_iam_role_policy_attachment" "records_xray" {
37
+ role = aws_iam_role.lambda_records.name
38
+ policy_arn = "arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess"
39
+ }
40
+
41
+ # カスタムインラインポリシー: DynamoDBアクセス
42
+ # Records Lambdaは特定テーブルへの読み書きのみ可能
43
+ resource "aws_iam_role_policy" "records_dynamodb" {
44
+ name = "dynamodb-access"
45
+ role = aws_iam_role.lambda_records.id
46
+
47
+ policy = jsonencode({
48
+ Version = "2012-10-17"
49
+ Statement = [
50
+ {
51
+ Effect = "Allow"
52
+ Action = [
53
+ "dynamodb:GetItem",
54
+ "dynamodb:PutItem",
55
+ "dynamodb:UpdateItem",
56
+ "dynamodb:DeleteItem",
57
+ "dynamodb:Query",
58
+ "dynamodb:Scan",
59
+ "dynamodb:BatchGetItem",
60
+ "dynamodb:TransactWriteItems"
61
+ ]
62
+ Resource = var.dynamodb_table_arn
63
+ }
64
+ ]
65
+ })
66
+ }
67
+
68
+ # CloudWatch Logsロググループ
69
+ resource "aws_cloudwatch_log_group" "lambda_records" {
70
+ name = "/aws/lambda/${var.project_name}-${var.environment}-records"
71
+ retention_in_days = var.log_retention_days
72
+
73
+ tags = {
74
+ Name = "${var.project_name}-${var.environment}-records-logs"
75
+ }
76
+ }
77
+
78
+ # Lambda関数のZIPファイルを作成
79
+ data "archive_file" "lambda_records" {
80
+ type = "zip"
81
+ source_file = "${path.module}/../dist/server/handler.cjs"
82
+ output_path = "${path.module}/../dist/server/handler.zip"
83
+ }
84
+
85
+ # Lambda関数
86
+ resource "aws_lambda_function" "records" {
87
+ function_name = "${var.project_name}-${var.environment}-records"
88
+ description = "Records Lambda - CRUD operations with shadow management"
89
+ role = aws_iam_role.lambda_records.arn
90
+
91
+ # ビルド成果物
92
+ filename = data.archive_file.lambda_records.output_path
93
+ source_code_hash = "${data.archive_file.lambda_records.output_base64sha256}-${base64sha256(var.shadow_config)}"
94
+
95
+ # ランタイム設定
96
+ runtime = "nodejs22.x"
97
+ architectures = ["arm64"]
98
+ handler = "handler.handler"
99
+
100
+ # パフォーマンス設定
101
+ timeout = 30
102
+ memory_size = 512
103
+
104
+ # 環境変数
105
+ environment {
106
+ variables = {
107
+ ENV = var.environment
108
+ REGION = var.region
109
+ TABLE_NAME = var.dynamodb_table_name
110
+ COGNITO_USER_POOL_ID = var.cognito_user_pool_id
111
+ COGNITO_CLIENT_ID = var.cognito_client_id
112
+ COGNITO_REGION = var.region
113
+ SHADOW_CONFIG = var.shadow_config
114
+ LOG_LEVEL = var.log_level
115
+ }
116
+ }
117
+
118
+ # X-Ray有効化
119
+ tracing_config {
120
+ mode = "Active"
121
+ }
122
+
123
+ # CloudWatch Logsへの依存関係を明示
124
+ depends_on = [
125
+ aws_cloudwatch_log_group.lambda_records,
126
+ aws_iam_role_policy.records_dynamodb
127
+ ]
128
+
129
+ tags = {
130
+ Name = "${var.project_name}-${var.environment}-records"
131
+ }
132
+ }
133
+
134
+ # Lambda Function URL
135
+ resource "aws_lambda_function_url" "records" {
136
+ function_name = aws_lambda_function.records.function_name
137
+ authorization_type = "NONE" # JWT検証はLambda内で実施
138
+
139
+ # CORS設定
140
+ cors {
141
+ allow_origins = ["*"]
142
+ allow_methods = ["POST"]
143
+ allow_headers = ["content-type", "authorization", "x-amz-date", "x-api-key", "x-amz-security-token"]
144
+ expose_headers = ["content-type", "x-amzn-requestid"]
145
+ allow_credentials = false
146
+ max_age = 86400 # 24時間
147
+ }
148
+
149
+ depends_on = [aws_lambda_function.records]
150
+ }
151
+
152
+ # Lambda Function URLのリソースベースポリシー
153
+ resource "aws_lambda_permission" "function_url" {
154
+ statement_id = "AllowFunctionURLInvoke"
155
+ action = "lambda:InvokeFunctionUrl"
156
+ function_name = aws_lambda_function.records.function_name
157
+ principal = "*"
158
+ function_url_auth_type = "NONE"
159
+ }