@swovohq/fuel 0.2.2-alpha.9 → 0.2.2-alpha.91

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 (232) hide show
  1. package/README.md +173 -69
  2. package/dist/bin/fuel.js +77 -31
  3. package/dist/bin/fuel.js.map +1 -1
  4. package/dist/cleanup/finalize.d.ts.map +1 -1
  5. package/dist/cleanup/finalize.js +11 -3
  6. package/dist/cleanup/finalize.js.map +1 -1
  7. package/dist/commands/config-verify.d.ts.map +1 -1
  8. package/dist/commands/config-verify.js +14 -6
  9. package/dist/commands/config-verify.js.map +1 -1
  10. package/dist/commands/create-app.d.ts.map +1 -1
  11. package/dist/commands/create-app.js +41 -7
  12. package/dist/commands/create-app.js.map +1 -1
  13. package/dist/commands/infra-deploy.d.ts +15 -1
  14. package/dist/commands/infra-deploy.d.ts.map +1 -1
  15. package/dist/commands/infra-deploy.js +164 -18
  16. package/dist/commands/infra-deploy.js.map +1 -1
  17. package/dist/commands/infra-destroy.d.ts.map +1 -1
  18. package/dist/commands/infra-destroy.js +3 -3
  19. package/dist/commands/infra-destroy.js.map +1 -1
  20. package/dist/commands/infra-init.d.ts +91 -0
  21. package/dist/commands/infra-init.d.ts.map +1 -1
  22. package/dist/commands/infra-init.js +644 -113
  23. package/dist/commands/infra-init.js.map +1 -1
  24. package/dist/commands/infra-pull.d.ts +8 -0
  25. package/dist/commands/infra-pull.d.ts.map +1 -0
  26. package/dist/commands/infra-pull.js +81 -0
  27. package/dist/commands/infra-pull.js.map +1 -0
  28. package/dist/commands/list-modules.d.ts.map +1 -1
  29. package/dist/commands/list-modules.js +10 -3
  30. package/dist/commands/list-modules.js.map +1 -1
  31. package/dist/engines/convention.d.ts +2 -2
  32. package/dist/engines/convention.d.ts.map +1 -1
  33. package/dist/engines/convention.js +8 -6
  34. package/dist/engines/convention.js.map +1 -1
  35. package/dist/engines/dependencies.d.ts +2 -0
  36. package/dist/engines/dependencies.d.ts.map +1 -1
  37. package/dist/engines/dependencies.js.map +1 -1
  38. package/dist/engines/monorepo.d.ts.map +1 -1
  39. package/dist/engines/monorepo.js.map +1 -1
  40. package/dist/engines/template-source.d.ts.map +1 -1
  41. package/dist/engines/template-source.js +3 -1
  42. package/dist/engines/template-source.js.map +1 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/infra/azure-defaults.d.ts +49 -0
  46. package/dist/infra/azure-defaults.d.ts.map +1 -0
  47. package/dist/infra/azure-defaults.js +52 -0
  48. package/dist/infra/azure-defaults.js.map +1 -0
  49. package/dist/infra/azure-keyvault-client.d.ts +4 -0
  50. package/dist/infra/azure-keyvault-client.d.ts.map +1 -0
  51. package/dist/infra/azure-keyvault-client.js +57 -0
  52. package/dist/infra/azure-keyvault-client.js.map +1 -0
  53. package/dist/infra/azure-rbac.d.ts +11 -0
  54. package/dist/infra/azure-rbac.d.ts.map +1 -0
  55. package/dist/infra/azure-rbac.js +49 -0
  56. package/dist/infra/azure-rbac.js.map +1 -0
  57. package/dist/infra/azure-state-storage.d.ts +20 -0
  58. package/dist/infra/azure-state-storage.d.ts.map +1 -0
  59. package/dist/infra/azure-state-storage.js +229 -0
  60. package/dist/infra/azure-state-storage.js.map +1 -0
  61. package/dist/infra/config-loader.d.ts.map +1 -1
  62. package/dist/infra/config-loader.js.map +1 -1
  63. package/dist/infra/config-writer.js +1 -1
  64. package/dist/infra/credentials.d.ts +2 -2
  65. package/dist/infra/credentials.d.ts.map +1 -1
  66. package/dist/infra/credentials.js +8 -4
  67. package/dist/infra/credentials.js.map +1 -1
  68. package/dist/infra/dependency-checker.d.ts.map +1 -1
  69. package/dist/infra/dependency-checker.js.map +1 -1
  70. package/dist/infra/deployment-detect.d.ts +9 -0
  71. package/dist/infra/deployment-detect.d.ts.map +1 -0
  72. package/dist/infra/deployment-detect.js +53 -0
  73. package/dist/infra/deployment-detect.js.map +1 -0
  74. package/dist/infra/git-client.d.ts.map +1 -1
  75. package/dist/infra/git-client.js +6 -10
  76. package/dist/infra/git-client.js.map +1 -1
  77. package/dist/infra/github-client.d.ts +7 -0
  78. package/dist/infra/github-client.d.ts.map +1 -1
  79. package/dist/infra/github-client.js +47 -7
  80. package/dist/infra/github-client.js.map +1 -1
  81. package/dist/infra/github-secrets-client.d.ts.map +1 -1
  82. package/dist/infra/github-secrets-client.js +2 -2
  83. package/dist/infra/github-secrets-client.js.map +1 -1
  84. package/dist/infra/github-token-link.d.ts +4 -0
  85. package/dist/infra/github-token-link.d.ts.map +1 -0
  86. package/dist/infra/github-token-link.js +32 -0
  87. package/dist/infra/github-token-link.js.map +1 -0
  88. package/dist/infra/orchestrator.d.ts +4 -1
  89. package/dist/infra/orchestrator.d.ts.map +1 -1
  90. package/dist/infra/orchestrator.js +218 -63
  91. package/dist/infra/orchestrator.js.map +1 -1
  92. package/dist/infra/port-utils.d.ts.map +1 -1
  93. package/dist/infra/port-utils.js.map +1 -1
  94. package/dist/infra/preflight.d.ts.map +1 -1
  95. package/dist/infra/preflight.js +25 -11
  96. package/dist/infra/preflight.js.map +1 -1
  97. package/dist/infra/remote-secret.d.ts +14 -0
  98. package/dist/infra/remote-secret.d.ts.map +1 -0
  99. package/dist/infra/remote-secret.js +42 -0
  100. package/dist/infra/remote-secret.js.map +1 -0
  101. package/dist/infra/s3-state-bucket.d.ts.map +1 -1
  102. package/dist/infra/s3-state-bucket.js +8 -4
  103. package/dist/infra/s3-state-bucket.js.map +1 -1
  104. package/dist/infra/secrets-manager-client.d.ts.map +1 -1
  105. package/dist/infra/secrets-manager-client.js +8 -5
  106. package/dist/infra/secrets-manager-client.js.map +1 -1
  107. package/dist/infra/subprocess.js +1 -1
  108. package/dist/infra/template-engine.d.ts +14 -5
  109. package/dist/infra/template-engine.d.ts.map +1 -1
  110. package/dist/infra/template-engine.js +157 -39
  111. package/dist/infra/template-engine.js.map +1 -1
  112. package/dist/infra/tofu-runner.d.ts +4 -3
  113. package/dist/infra/tofu-runner.d.ts.map +1 -1
  114. package/dist/infra/tofu-runner.js +40 -34
  115. package/dist/infra/tofu-runner.js.map +1 -1
  116. package/dist/infra/types.d.ts +241 -17
  117. package/dist/infra/types.d.ts.map +1 -1
  118. package/dist/infra/types.js +419 -22
  119. package/dist/infra/types.js.map +1 -1
  120. package/dist/infra-templates/TODO-azure-prod.md +127 -0
  121. package/dist/infra-templates/modules/azure-container-app/main.tf +124 -0
  122. package/dist/infra-templates/modules/azure-container-app/outputs.tf +24 -0
  123. package/dist/infra-templates/modules/azure-container-app/variables.tf +80 -0
  124. package/dist/infra-templates/modules/azure-container-apps-environment/main.tf +18 -0
  125. package/dist/infra-templates/modules/azure-container-apps-environment/outputs.tf +14 -0
  126. package/dist/infra-templates/modules/azure-container-apps-environment/variables.tf +24 -0
  127. package/dist/infra-templates/modules/azure-container-registry/main.tf +10 -0
  128. package/dist/infra-templates/modules/azure-container-registry/outputs.tf +14 -0
  129. package/dist/infra-templates/modules/azure-container-registry/variables.tf +20 -0
  130. package/dist/infra-templates/modules/azure-front-door/main.tf +80 -0
  131. package/dist/infra-templates/modules/azure-front-door/outputs.tf +20 -0
  132. package/dist/infra-templates/modules/azure-front-door/variables.tf +26 -0
  133. package/dist/infra-templates/modules/azure-github-oidc/main.tf +48 -0
  134. package/dist/infra-templates/modules/azure-github-oidc/outputs.tf +9 -0
  135. package/dist/infra-templates/modules/azure-github-oidc/variables.tf +69 -0
  136. package/dist/infra-templates/modules/azure-key-vault/main.tf +21 -0
  137. package/dist/infra-templates/modules/azure-key-vault/outputs.tf +11 -0
  138. package/dist/infra-templates/modules/azure-key-vault/variables.tf +43 -0
  139. package/dist/infra-templates/modules/azure-monitor/main.tf +29 -0
  140. package/dist/infra-templates/modules/azure-monitor/outputs.tf +17 -0
  141. package/dist/infra-templates/modules/azure-monitor/variables.tf +32 -0
  142. package/dist/infra-templates/modules/azure-network/main.tf +134 -0
  143. package/dist/infra-templates/modules/azure-network/outputs.tf +44 -0
  144. package/dist/infra-templates/modules/azure-network/variables.tf +56 -0
  145. package/dist/infra-templates/modules/azure-postgresql-flexible/main.tf +34 -0
  146. package/dist/infra-templates/modules/azure-postgresql-flexible/outputs.tf +20 -0
  147. package/dist/infra-templates/modules/azure-postgresql-flexible/variables.tf +54 -0
  148. package/dist/infra-templates/modules/azure-redis-cache/main.tf +32 -0
  149. package/dist/infra-templates/modules/azure-redis-cache/outputs.tf +15 -0
  150. package/dist/infra-templates/modules/azure-redis-cache/variables.tf +30 -0
  151. package/dist/infra-templates/modules/azure-resource-group/main.tf +5 -0
  152. package/dist/infra-templates/modules/azure-resource-group/outputs.tf +11 -0
  153. package/dist/infra-templates/modules/azure-resource-group/variables.tf +16 -0
  154. package/dist/infra-templates/modules/azure-sql-database/main.tf +63 -0
  155. package/dist/infra-templates/modules/azure-sql-database/outputs.tf +20 -0
  156. package/dist/infra-templates/modules/azure-sql-database/variables.tf +78 -0
  157. package/dist/infra-templates/modules/azure-storage-account/main.tf +13 -0
  158. package/dist/infra-templates/modules/azure-storage-account/outputs.tf +16 -0
  159. package/dist/infra-templates/modules/azure-storage-account/variables.tf +38 -0
  160. package/dist/infra-templates/modules/cloud-watch/event-bridge.tf +15 -0
  161. package/dist/infra-templates/modules/cloud-watch/lambda.tf +84 -0
  162. package/dist/infra-templates/modules/cloud-watch/lambda_function.zip +0 -0
  163. package/dist/infra-templates/modules/cloud-watch/lambda_function_deploy.zip +0 -0
  164. package/dist/infra-templates/modules/cloud-watch/main.tf +156 -0
  165. package/dist/infra-templates/modules/cloud-watch/sns.tf +3 -0
  166. package/dist/infra-templates/modules/cloud-watch/variables.tf +38 -0
  167. package/dist/infra-templates/modules/ecs-core/alb.tf +126 -0
  168. package/dist/infra-templates/modules/ecs-core/cloudwatch.tf +48 -0
  169. package/dist/infra-templates/modules/ecs-core/iam.tf +95 -0
  170. package/dist/infra-templates/modules/ecs-core/main.tf +12 -0
  171. package/dist/infra-templates/modules/ecs-core/outputs.tf +44 -0
  172. package/dist/infra-templates/modules/ecs-core/secrets.tf +9 -0
  173. package/dist/infra-templates/modules/ecs-core/security_groups.tf +73 -0
  174. package/dist/infra-templates/modules/ecs-core/variables.tf +96 -0
  175. package/dist/infra-templates/modules/ecs-service/ecs_autoscaling.tf +51 -0
  176. package/dist/infra-templates/modules/ecs-service/ecs_service.tf +39 -0
  177. package/dist/infra-templates/modules/ecs-service/ecs_task_definition.tf +56 -0
  178. package/dist/infra-templates/modules/ecs-service/variables.tf +170 -0
  179. package/dist/infra-templates/modules/elastic-container-registry/main.tf +32 -0
  180. package/dist/infra-templates/modules/elastic-container-registry/outputs.tf +9 -0
  181. package/dist/infra-templates/modules/elastic-container-registry/variables.tf +25 -0
  182. package/dist/infra-templates/modules/github-oidc-role/main.tf +46 -0
  183. package/dist/infra-templates/modules/github-oidc-role/outputs.tf +4 -0
  184. package/dist/infra-templates/modules/github-oidc-role/variables.tf +11 -0
  185. package/dist/infra-templates/modules/guardduty/main.tf +8 -0
  186. package/dist/infra-templates/modules/iam/main.tf +205 -0
  187. package/dist/infra-templates/modules/iam/outputs.tf +3 -0
  188. package/dist/infra-templates/modules/iam/variables.tf +4 -0
  189. package/dist/infra-templates/modules/random-key/main.tf +11 -0
  190. package/dist/infra-templates/modules/random-key/outputs.tf +4 -0
  191. package/dist/infra-templates/modules/random-key/variables.tf +10 -0
  192. package/dist/infra-templates/modules/redis/main.tf +47 -0
  193. package/dist/infra-templates/modules/redis/outputs.tf +8 -0
  194. package/dist/infra-templates/modules/redis/variables.tf +20 -0
  195. package/dist/infra-templates/modules/relational-database-service/main.tf +44 -0
  196. package/dist/infra-templates/modules/relational-database-service/outputs.tf +13 -0
  197. package/dist/infra-templates/modules/relational-database-service/security-group.tf +15 -0
  198. package/dist/infra-templates/modules/relational-database-service/variables.tf +50 -0
  199. package/dist/infra-templates/modules/secret/main.tf +14 -0
  200. package/dist/infra-templates/modules/secret/outputs.tf +3 -0
  201. package/dist/infra-templates/modules/secret/variables.tf +8 -0
  202. package/dist/infra-templates/modules/simple-storage-service/main.tf +28 -0
  203. package/dist/infra-templates/modules/simple-storage-service/variables.tf +4 -0
  204. package/dist/infra-templates/modules/vpc/data.tf +2 -0
  205. package/dist/infra-templates/modules/vpc/main.tf +76 -0
  206. package/dist/infra-templates/modules/vpc/outputs.tf +23 -0
  207. package/dist/infra-templates/modules/vpc/variables.tf +5 -0
  208. package/dist/infra-templates/package.json +6 -0
  209. package/dist/infra-templates/templates/azure/MANUAL_DEPLOY.md +168 -0
  210. package/dist/infra-templates/templates/azure/backend.tf +8 -0
  211. package/dist/infra-templates/templates/azure/data.tf +21 -0
  212. package/dist/infra-templates/templates/azure/default.tfvars +0 -0
  213. package/dist/infra-templates/templates/azure/locals.tf +116 -0
  214. package/dist/infra-templates/templates/azure/main.tf +421 -0
  215. package/dist/infra-templates/templates/azure/outputs.tf +40 -0
  216. package/dist/infra-templates/templates/azure/providers.tf +65 -0
  217. package/dist/infra-templates/templates/azure/variables.tf +69 -0
  218. package/dist/infra-templates/templates/azure/workflows/build_and_deploy.yml +155 -0
  219. package/dist/infra-templates/templates/azure/workflows/tests.yml +63 -0
  220. package/dist/infra-templates/templates/ecs/README.md +235 -0
  221. package/dist/infra-templates/templates/ecs/backend.tf +7 -0
  222. package/dist/infra-templates/templates/ecs/data.tf +6 -0
  223. package/dist/infra-templates/templates/ecs/default.tfvars +1 -0
  224. package/dist/infra-templates/templates/ecs/locals.tf +97 -0
  225. package/dist/infra-templates/templates/ecs/main.tf +185 -0
  226. package/dist/infra-templates/templates/ecs/outputs.tf +42 -0
  227. package/dist/infra-templates/templates/ecs/providers.tf +21 -0
  228. package/dist/infra-templates/templates/ecs/variables.tf +105 -0
  229. package/dist/infra-templates/templates/ecs/workflows/build_and_deploy.yml +188 -0
  230. package/dist/infra-templates/templates/ecs/workflows/tests.yml +65 -0
  231. package/package.json +10 -2
  232. package/schema/fuel.schema.json +570 -91
@@ -0,0 +1,78 @@
1
+ variable "server_name" {
2
+ description = "Name of the Azure SQL Server. Must be globally unique."
3
+ type = string
4
+ }
5
+
6
+ variable "database_name" {
7
+ description = "Name of the Azure SQL Database"
8
+ type = string
9
+ }
10
+
11
+ variable "resource_group_name" {
12
+ description = "Name of the resource group where the SQL server will be created"
13
+ type = string
14
+ }
15
+
16
+ variable "location" {
17
+ description = "Azure region where the SQL server will be created"
18
+ type = string
19
+ }
20
+
21
+ variable "admin_username" {
22
+ description = "Administrator login for the SQL Server"
23
+ type = string
24
+ default = "sqladmin"
25
+ }
26
+
27
+ variable "admin_password" {
28
+ description = "Administrator password for the SQL Server. Leave empty to auto-generate."
29
+ type = string
30
+ default = ""
31
+ sensitive = true
32
+ }
33
+
34
+ variable "sku_name" {
35
+ description = "SKU name for the database (General Purpose Serverless, Standard-series Gen5)"
36
+ type = string
37
+ default = "GP_S_Gen5_4"
38
+ }
39
+
40
+ variable "min_capacity" {
41
+ description = "Minimum vCores the database will always have allocated, if not paused"
42
+ type = number
43
+ default = 0.5
44
+ }
45
+
46
+ variable "auto_pause_delay_in_minutes" {
47
+ description = "Time in minutes after which the database is automatically paused. Set to -1 to disable auto-pause — required for long_term_retention_policy to take effect (Azure disallows LTR on a serverless database with auto-pause enabled)."
48
+ type = number
49
+ default = 60
50
+ }
51
+
52
+ variable "storage_account_type" {
53
+ description = "Storage account type used to store backups. Valid values are Geo, GeoZone, Local, Zone (not to be confused with Storage Account LRS/GRS naming; 'Local' is the SQL backup equivalent of LRS)."
54
+ type = string
55
+ default = "Local"
56
+ }
57
+
58
+ variable "pitr_retention_days" {
59
+ description = "Point-in-time restore (short term retention) in days"
60
+ type = number
61
+ default = 20
62
+ }
63
+
64
+ variable "ltr_weekly_retention" {
65
+ description = "Long term retention weekly retention, in ISO 8601 format"
66
+ type = string
67
+ default = "P21W"
68
+ }
69
+
70
+ variable "private_endpoint_subnet_id" {
71
+ description = "Subnet for the Private Link endpoint (non-delegated, network policies disabled)"
72
+ type = string
73
+ }
74
+
75
+ variable "private_dns_zone_id" {
76
+ description = "Private DNS zone (privatelink.database.windows.net) linked to the same VNet as private_endpoint_subnet_id"
77
+ type = string
78
+ }
@@ -0,0 +1,13 @@
1
+ # NOTE: the azurerm provider does not support `access_tier` on BlockBlobStorage
2
+ # accounts (it's only valid for StorageV2/BlobStorage). We pass null in that
3
+ # case so the attribute is omitted instead of failing a plan/apply.
4
+ resource "azurerm_storage_account" "this" {
5
+ name = var.name
6
+ resource_group_name = var.resource_group_name
7
+ location = var.location
8
+ account_kind = var.account_kind
9
+ account_tier = var.account_tier
10
+ account_replication_type = var.account_replication_type
11
+ access_tier = var.account_kind == "BlockBlobStorage" ? null : var.access_tier
12
+ min_tls_version = "TLS1_2"
13
+ }
@@ -0,0 +1,16 @@
1
+ output "id" {
2
+ value = azurerm_storage_account.this.id
3
+ }
4
+
5
+ output "name" {
6
+ value = azurerm_storage_account.this.name
7
+ }
8
+
9
+ output "primary_blob_endpoint" {
10
+ value = azurerm_storage_account.this.primary_blob_endpoint
11
+ }
12
+
13
+ output "primary_access_key" {
14
+ value = azurerm_storage_account.this.primary_access_key
15
+ sensitive = true
16
+ }
@@ -0,0 +1,38 @@
1
+ variable "name" {
2
+ type = string
3
+ description = "Storage account name (3-24 chars, lowercase alphanumeric). Not validated here; caller is responsible for compliance."
4
+ }
5
+
6
+ variable "resource_group_name" {
7
+ type = string
8
+ description = "Resource group where the storage account is created"
9
+ }
10
+
11
+ variable "location" {
12
+ type = string
13
+ description = "Azure region"
14
+ }
15
+
16
+ variable "account_kind" {
17
+ type = string
18
+ description = "Storage account kind"
19
+ default = "BlockBlobStorage"
20
+ }
21
+
22
+ variable "account_tier" {
23
+ type = string
24
+ description = "Storage account tier. BlockBlobStorage kind only exists in the Premium tier."
25
+ default = "Premium"
26
+ }
27
+
28
+ variable "account_replication_type" {
29
+ type = string
30
+ description = "Storage account replication type"
31
+ default = "LRS"
32
+ }
33
+
34
+ variable "access_tier" {
35
+ type = string
36
+ description = "Storage account access tier (ignored for BlockBlobStorage, which does not support this attribute)"
37
+ default = "Hot"
38
+ }
@@ -0,0 +1,15 @@
1
+ resource "aws_cloudwatch_event_rule" "ecs_deploy_events" {
2
+ count = var.ecs ? 1 : 0
3
+
4
+ name = "${var.project_name}-ecs-deploy-events"
5
+ description = "This rule is used to send notifications to Slack for success or failure in the deployment process"
6
+ event_pattern = jsonencode({
7
+ "source" : ["aws.ecs"],
8
+ "detail-type" : ["ECS Deployment State Change"],
9
+ "region" : [var.aws_region],
10
+ "detail" : {
11
+ "clusterArn": [var.ecs_cluster_id],
12
+ "eventName" : ["SERVICE_DEPLOYMENT_FAILED", "SERVICE_DEPLOYMENT_COMPLETED"]
13
+ }
14
+ })
15
+ }
@@ -0,0 +1,84 @@
1
+ resource "aws_iam_role" "lambda_execution_role" {
2
+ name = "lambda_execution_role_${var.project_name}"
3
+
4
+ assume_role_policy = jsonencode({
5
+ Version = "2012-10-17",
6
+ Statement = [
7
+ {
8
+ Action = "sts:AssumeRole",
9
+ Principal = {
10
+ Service = "lambda.amazonaws.com",
11
+ },
12
+ Effect = "Allow",
13
+ },
14
+ ],
15
+ })
16
+ }
17
+
18
+ resource "aws_lambda_function" "sns_to_slack" {
19
+ function_name = "snsToSlack-${var.project_name}"
20
+ handler = "index.lambda_handler"
21
+ runtime = "python3.9"
22
+ role = aws_iam_role.lambda_execution_role.arn
23
+
24
+ filename = "${path.module}/lambda_function.zip"
25
+ source_code_hash = filebase64sha256("${path.module}/lambda_function.zip")
26
+
27
+ environment {
28
+ variables = {
29
+ SLACK_WEBHOOK_URL = var.slack_webhook_url
30
+ }
31
+ }
32
+ }
33
+
34
+ resource "aws_lambda_permission" "sns" {
35
+ statement_id = "AllowExecutionFromSNS"
36
+ action = "lambda:InvokeFunction"
37
+ function_name = aws_lambda_function.sns_to_slack.arn
38
+ principal = "sns.amazonaws.com"
39
+ source_arn = aws_sns_topic.rds_alarm_topic.arn
40
+ }
41
+
42
+ resource "aws_sns_topic_subscription" "lambda_subscription" {
43
+ topic_arn = aws_sns_topic.rds_alarm_topic.arn
44
+ protocol = "lambda"
45
+ endpoint = aws_lambda_function.sns_to_slack.arn
46
+ }
47
+
48
+
49
+ resource "aws_lambda_function" "sns_deploy_to_slack" {
50
+ count = var.ecs ? 1 : 0
51
+
52
+ function_name = "snsDeployInfoToSlack-${var.project_name}"
53
+ handler = "index.handler"
54
+ runtime = "nodejs22.x"
55
+ role = aws_iam_role.lambda_execution_role.arn
56
+
57
+ filename = "${path.module}/lambda_function_deploy.zip"
58
+ source_code_hash = filebase64sha256("${path.module}/lambda_function_deploy.zip")
59
+
60
+ environment {
61
+ variables = {
62
+ SLACK_WEBHOOK_URL = var.slack_webhook_url
63
+ }
64
+ }
65
+
66
+ }
67
+
68
+ resource "aws_cloudwatch_event_target" "trigger_lambda" {
69
+ count = var.ecs ? 1 : 0
70
+
71
+ rule = aws_cloudwatch_event_rule.ecs_deploy_events[0].name
72
+ target_id = "SendToLambda"
73
+ arn = aws_lambda_function.sns_deploy_to_slack[0].arn
74
+ }
75
+
76
+ resource "aws_lambda_permission" "allow_eventbridge" {
77
+ count = var.ecs ? 1 : 0
78
+
79
+ statement_id = "AllowExecutionFromEventBridge"
80
+ action = "lambda:InvokeFunction"
81
+ function_name = aws_lambda_function.sns_deploy_to_slack[0].function_name
82
+ principal = "events.amazonaws.com"
83
+ source_arn = aws_cloudwatch_event_rule.ecs_deploy_events[0].arn
84
+ }
@@ -0,0 +1,156 @@
1
+
2
+ resource "aws_cloudwatch_metric_alarm" "high_cpu_utilization" {
3
+ alarm_name = "high-cpu-utilization-${var.project_name}"
4
+ comparison_operator = "GreaterThanThreshold"
5
+ evaluation_periods = "2"
6
+ metric_name = "CPUUtilization"
7
+ namespace = "AWS/RDS"
8
+ period = "120"
9
+ statistic = "Average"
10
+ threshold = "70"
11
+ alarm_description = "This metric monitors RDS CPU utilization"
12
+ actions_enabled = true
13
+ alarm_actions = [aws_sns_topic.rds_alarm_topic.arn]
14
+ dimensions = {
15
+ DBInstanceIdentifier = "${var.project_name}"
16
+ }
17
+ }
18
+
19
+ resource "aws_cloudwatch_metric_alarm" "low_free_storage_space" {
20
+ alarm_name = "low-free-storage-space-${var.project_name}"
21
+ comparison_operator = "LessThanThreshold"
22
+ evaluation_periods = "1"
23
+ metric_name = "FreeStorageSpace"
24
+ namespace = "AWS/RDS"
25
+ period = "300"
26
+ statistic = "Average"
27
+ threshold = "10000000000"
28
+ alarm_description = "This metric monitors RDS free storage space"
29
+ actions_enabled = true
30
+ alarm_actions = [aws_sns_topic.rds_alarm_topic.arn]
31
+ dimensions = {
32
+ DBInstanceIdentifier = "${var.project_name}"
33
+ }
34
+ }
35
+
36
+ resource "aws_cloudwatch_metric_alarm" "low_freeable_memory" {
37
+ alarm_name = "low-freeable-memory-${var.project_name}"
38
+ comparison_operator = "LessThanThreshold"
39
+ evaluation_periods = "1"
40
+ metric_name = "FreeableMemory"
41
+ namespace = "AWS/RDS"
42
+ period = "300"
43
+ statistic = "Average"
44
+ threshold = 209715200
45
+ alarm_description = "This metric monitors RDS freeable memory"
46
+ actions_enabled = true
47
+ alarm_actions = [aws_sns_topic.rds_alarm_topic.arn]
48
+ dimensions = {
49
+ DBInstanceIdentifier = "${var.project_name}"
50
+ }
51
+ }
52
+
53
+ resource "aws_cloudwatch_metric_alarm" "high_database_connections" {
54
+ alarm_name = "high-database-connections-${var.project_name}"
55
+ comparison_operator = "GreaterThanThreshold"
56
+ evaluation_periods = "1"
57
+ metric_name = "DatabaseConnections"
58
+ namespace = "AWS/RDS"
59
+ period = "300"
60
+ statistic = "Average"
61
+ threshold = "30"
62
+ alarm_description = "This metric monitors RDS database connections"
63
+ actions_enabled = true
64
+ alarm_actions = [aws_sns_topic.rds_alarm_topic.arn]
65
+ dimensions = {
66
+ DBInstanceIdentifier = "${var.project_name}"
67
+ }
68
+ }
69
+
70
+ resource "aws_cloudwatch_metric_alarm" "freespace" {
71
+ for_each = { for app in var.apps : app.app_name => app if app.postgres }
72
+
73
+ actions_enabled = true
74
+ alarm_name = "FreeStorageSpace - ${each.value.app_name} - DB"
75
+ comparison_operator = "LessThanOrEqualToThreshold"
76
+ datapoints_to_alarm = 1
77
+
78
+ dimensions = {
79
+ DBInstanceIdentifier = each.value.app_name
80
+ }
81
+
82
+ evaluation_periods = 1
83
+ metric_name = "FreeStorageSpace"
84
+ namespace = "AWS/RDS"
85
+ period = 300
86
+ statistic = "Average"
87
+ threshold = 30 * 0.1 * pow(1024, 3)
88
+ treat_missing_data = "missing"
89
+ }
90
+
91
+ resource "aws_cloudwatch_metric_alarm" "high-cpu" {
92
+ for_each = { for app in var.apps : app.app_name => app if app.postgres }
93
+
94
+ actions_enabled = "true"
95
+ alarm_name = "High CPU Usage - ${each.value.app_name} -db"
96
+ comparison_operator = "GreaterThanThreshold"
97
+ datapoints_to_alarm = "1"
98
+
99
+ dimensions = {
100
+ DBInstanceIdentifier = each.value.app_name
101
+ }
102
+
103
+ evaluation_periods = "1"
104
+ metric_name = "CPUUtilization"
105
+ namespace = "AWS/RDS"
106
+ period = "300"
107
+ statistic = "Average"
108
+ threshold = "90"
109
+ treat_missing_data = "missing"
110
+ }
111
+
112
+
113
+ resource "aws_cloudwatch_metric_alarm" "freeable_memory" {
114
+ for_each = { for app in var.apps : app.app_name => app if app.postgres }
115
+
116
+ actions_enabled = true
117
+ alarm_description = "500Mb available for use"
118
+ alarm_name = "High Memory Usage - ${each.value.app_name} - DB"
119
+ comparison_operator = "LessThanOrEqualToThreshold"
120
+ datapoints_to_alarm = 1
121
+
122
+ dimensions = {
123
+ DBInstanceIdentifier = each.value.app_name
124
+ }
125
+
126
+ evaluation_periods = 1
127
+ metric_name = "FreeableMemory"
128
+ namespace = "AWS/RDS"
129
+ period = 60
130
+ statistic = "Maximum"
131
+ threshold = 500000000
132
+ treat_missing_data = "missing"
133
+ }
134
+
135
+ resource "aws_cloudwatch_metric_alarm" "readiops" {
136
+ for_each = { for app in var.apps : app.app_name => app if app.postgres }
137
+
138
+ actions_enabled = true
139
+ alarm_name = "ReadIOPS - ${each.value.app_name} - DB"
140
+ comparison_operator = "GreaterThanThreshold"
141
+ datapoints_to_alarm = 1
142
+
143
+ dimensions = {
144
+ DBInstanceIdentifier = each.value.app_name
145
+ }
146
+
147
+ evaluation_periods = 1
148
+ metric_name = "ReadIOPS"
149
+ namespace = "AWS/RDS"
150
+ period = 300
151
+ statistic = "Maximum"
152
+ threshold = 1000
153
+ treat_missing_data = "missing"
154
+ }
155
+
156
+
@@ -0,0 +1,3 @@
1
+ resource "aws_sns_topic" "rds_alarm_topic" {
2
+ name = "rds-alarm-topic-${var.project_name}"
3
+ }
@@ -0,0 +1,38 @@
1
+ variable "project_name" {
2
+ description = "Repository name will be created based on project name"
3
+ default = ""
4
+ }
5
+
6
+ variable "slack_webhook_url" {
7
+ description = "The Slack webhook URL for sending notifications"
8
+ type = string
9
+ default = "https://hooks.slack.com/services/YOUR_WORKSPACE_ID/YOUR_CHANNEL_ID/YOUR_WEBHOOK_TOKEN"
10
+ }
11
+
12
+
13
+ variable "aws_region" {
14
+ description = "Aws Region"
15
+ type = string
16
+ }
17
+
18
+ variable "ecs_cluster_id" {
19
+ description = "cluster Arn"
20
+ default = ""
21
+ }
22
+
23
+ variable "ecs" {
24
+ description = "Whether ECS resources are deployed"
25
+ type = bool
26
+ default = true
27
+ }
28
+
29
+ variable "apps" {
30
+ description = "An array of apps from config.json"
31
+ type = set(object({
32
+ app_name = string
33
+ technology = string
34
+ dockerfile = optional(string)
35
+ build_env = optional(string)
36
+ postgres = optional(string)
37
+ }))
38
+ }
@@ -0,0 +1,126 @@
1
+ ########################################################################################################################
2
+ ## Application Load Balancer in public subnets with HTTP default listener that redirects traffic to HTTPS
3
+ ########################################################################################################################
4
+
5
+ resource "aws_alb" "alb" {
6
+ name = "${var.project_name}-ALB"
7
+ security_groups = [aws_security_group.alb.id, var.default_security_group_id]
8
+ subnets = var.public_subnets
9
+
10
+ tags = {
11
+ Scenario = var.scenario
12
+ }
13
+ }
14
+
15
+ ########################################################################################################################
16
+ ## Default HTTPS listener that blocks all traffic without valid custom origin header
17
+ ########################################################################################################################
18
+
19
+ resource "aws_alb_listener" "alb_default_listener_https" {
20
+ load_balancer_arn = aws_alb.alb.arn
21
+ port = "443"
22
+ protocol = "HTTPS"
23
+ certificate_arn = var.ingress_ssl_arn
24
+
25
+ default_action {
26
+ type = "forward"
27
+ target_group_arn = aws_alb_target_group.service_target_group.arn
28
+ }
29
+
30
+ tags = {
31
+ Scenario = var.scenario
32
+ }
33
+ }
34
+
35
+ resource "aws_alb_listener" "redirect" {
36
+ load_balancer_arn = aws_alb.alb.arn
37
+ port = "80"
38
+ protocol = "HTTP"
39
+
40
+ default_action {
41
+ type = "redirect"
42
+
43
+ redirect {
44
+ port = "443"
45
+ protocol = "HTTPS"
46
+ status_code = "HTTP_301"
47
+ }
48
+ }
49
+ }
50
+
51
+ resource "aws_alb_listener_rule" "frontend_listener" {
52
+ for_each = {
53
+ for index, app in var.apps : app.app_name => app
54
+ }
55
+
56
+ listener_arn = aws_alb_listener.alb_default_listener_https.arn
57
+
58
+ action {
59
+ type = "forward"
60
+ target_group_arn = aws_alb_target_group.app_service_target_group[each.key].arn
61
+ }
62
+
63
+ condition {
64
+ host_header {
65
+ values = ["${each.value.domain}"]
66
+ }
67
+ }
68
+ }
69
+
70
+ ########################################################################################################################
71
+ ## Target Group for our service
72
+ ########################################################################################################################
73
+
74
+ resource "aws_alb_target_group" "service_target_group" {
75
+ name = "${var.project_name}-TargetGroup"
76
+ port = var.container_port
77
+ protocol = "HTTP"
78
+ vpc_id = var.vpc_id
79
+ deregistration_delay = 5
80
+ target_type = "ip"
81
+
82
+ health_check {
83
+ healthy_threshold = 2
84
+ unhealthy_threshold = 2
85
+ interval = 60
86
+ matcher = var.healthcheck_matcher
87
+ path = var.healthcheck_endpoint
88
+ port = "traffic-port"
89
+ protocol = "HTTP"
90
+ timeout = 30
91
+ }
92
+
93
+ tags = {
94
+ Scenario = var.scenario
95
+ }
96
+
97
+ depends_on = [aws_alb.alb]
98
+ }
99
+
100
+ resource "aws_alb_target_group" "app_service_target_group" {
101
+ for_each = { for app in var.apps : app.app_name => app }
102
+
103
+ name = each.value.app_name
104
+ port = each.value.port
105
+ protocol = "HTTP"
106
+ vpc_id = var.vpc_id
107
+ deregistration_delay = 5
108
+ target_type = "ip"
109
+
110
+ health_check {
111
+ healthy_threshold = 2
112
+ unhealthy_threshold = 2
113
+ interval = 90
114
+ matcher = var.healthcheck_matcher
115
+ path = each.value.health_check_path
116
+ port = "traffic-port"
117
+ protocol = "HTTP"
118
+ timeout = 60
119
+ }
120
+
121
+ tags = {
122
+ Scenario = var.scenario
123
+ }
124
+
125
+ depends_on = [aws_alb.alb]
126
+ }
@@ -0,0 +1,48 @@
1
+ # logs.tf
2
+
3
+ # Set up CloudWatch group and log stream and retain logs for 30 days
4
+ resource "aws_cloudwatch_log_group" "cb_log_group" {
5
+ name = var.log_group_name
6
+ retention_in_days = 30
7
+ }
8
+
9
+ resource "aws_cloudwatch_log_stream" "cb_log_stream" {
10
+ name = var.project_name
11
+ log_group_name = aws_cloudwatch_log_group.cb_log_group.name
12
+ }
13
+
14
+ resource "aws_cloudwatch_metric_alarm" "targetResponseTime" {
15
+ actions_enabled = true
16
+ alarm_name = "TargetResponseTimeALB"
17
+ comparison_operator = "GreaterThanThreshold"
18
+ datapoints_to_alarm = 1
19
+
20
+ dimensions = {
21
+ DBInstanceIdentifier = aws_alb.alb.arn_suffix
22
+ }
23
+
24
+ evaluation_periods = 1
25
+ metric_name = "TargetResponseTime"
26
+ namespace = "AWS/ApplicationELB"
27
+ period = 300
28
+ statistic = "Maximum"
29
+ threshold = 4
30
+ }
31
+
32
+ resource "aws_cloudwatch_metric_alarm" "httpCodeTarget5XXCount" {
33
+ actions_enabled = true
34
+ alarm_name = "HTTPCode_Target_5XX_Count"
35
+ comparison_operator = "GreaterThanThreshold"
36
+ datapoints_to_alarm = 1
37
+
38
+ dimensions = {
39
+ DBInstanceIdentifier = aws_alb.alb.arn_suffix
40
+ }
41
+
42
+ evaluation_periods = 1
43
+ metric_name = "HTTPCode_Target_5XX_Count"
44
+ namespace = "AWS/ApplicationELB"
45
+ period = 300
46
+ statistic = "Maximum"
47
+ threshold = 1
48
+ }