@swovohq/fuel 0.2.2-alpha.88 → 0.2.2-alpha.89

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 (148) hide show
  1. package/README.md +65 -2
  2. package/dist/commands/create-app.d.ts.map +1 -1
  3. package/dist/commands/create-app.js +9 -3
  4. package/dist/commands/create-app.js.map +1 -1
  5. package/dist/commands/infra-deploy.d.ts.map +1 -1
  6. package/dist/commands/infra-deploy.js +3 -0
  7. package/dist/commands/infra-deploy.js.map +1 -1
  8. package/dist/commands/infra-init.d.ts.map +1 -1
  9. package/dist/commands/infra-init.js +63 -6
  10. package/dist/commands/infra-init.js.map +1 -1
  11. package/dist/infra/credentials.d.ts.map +1 -1
  12. package/dist/infra/credentials.js +5 -2
  13. package/dist/infra/credentials.js.map +1 -1
  14. package/dist/infra/github-client.d.ts +6 -0
  15. package/dist/infra/github-client.d.ts.map +1 -1
  16. package/dist/infra/github-client.js +30 -0
  17. package/dist/infra/github-client.js.map +1 -1
  18. package/dist/infra/github-token-link.d.ts +4 -0
  19. package/dist/infra/github-token-link.d.ts.map +1 -0
  20. package/dist/infra/github-token-link.js +28 -0
  21. package/dist/infra/github-token-link.js.map +1 -0
  22. package/dist/infra/orchestrator.d.ts +4 -1
  23. package/dist/infra/orchestrator.d.ts.map +1 -1
  24. package/dist/infra/orchestrator.js +16 -7
  25. package/dist/infra/orchestrator.js.map +1 -1
  26. package/dist/infra/preflight.d.ts.map +1 -1
  27. package/dist/infra/preflight.js +9 -1
  28. package/dist/infra/preflight.js.map +1 -1
  29. package/dist/infra/template-engine.d.ts +0 -4
  30. package/dist/infra/template-engine.d.ts.map +1 -1
  31. package/dist/infra/template-engine.js +36 -12
  32. package/dist/infra/template-engine.js.map +1 -1
  33. package/dist/infra/types.d.ts.map +1 -1
  34. package/dist/infra/types.js +58 -6
  35. package/dist/infra/types.js.map +1 -1
  36. package/dist/infra-templates/TODO-azure-prod.md +119 -0
  37. package/dist/infra-templates/modules/azure-container-app/main.tf +124 -0
  38. package/dist/infra-templates/modules/azure-container-app/outputs.tf +24 -0
  39. package/dist/infra-templates/modules/azure-container-app/variables.tf +80 -0
  40. package/dist/infra-templates/modules/azure-container-apps-environment/main.tf +18 -0
  41. package/dist/infra-templates/modules/azure-container-apps-environment/outputs.tf +14 -0
  42. package/dist/infra-templates/modules/azure-container-apps-environment/variables.tf +24 -0
  43. package/dist/infra-templates/modules/azure-container-registry/main.tf +10 -0
  44. package/dist/infra-templates/modules/azure-container-registry/outputs.tf +14 -0
  45. package/dist/infra-templates/modules/azure-container-registry/variables.tf +20 -0
  46. package/dist/infra-templates/modules/azure-front-door/main.tf +80 -0
  47. package/dist/infra-templates/modules/azure-front-door/outputs.tf +20 -0
  48. package/dist/infra-templates/modules/azure-front-door/variables.tf +26 -0
  49. package/dist/infra-templates/modules/azure-github-oidc/main.tf +48 -0
  50. package/dist/infra-templates/modules/azure-github-oidc/outputs.tf +9 -0
  51. package/dist/infra-templates/modules/azure-github-oidc/variables.tf +69 -0
  52. package/dist/infra-templates/modules/azure-key-vault/main.tf +21 -0
  53. package/dist/infra-templates/modules/azure-key-vault/outputs.tf +11 -0
  54. package/dist/infra-templates/modules/azure-key-vault/variables.tf +43 -0
  55. package/dist/infra-templates/modules/azure-monitor/main.tf +29 -0
  56. package/dist/infra-templates/modules/azure-monitor/outputs.tf +17 -0
  57. package/dist/infra-templates/modules/azure-monitor/variables.tf +32 -0
  58. package/dist/infra-templates/modules/azure-network/main.tf +134 -0
  59. package/dist/infra-templates/modules/azure-network/outputs.tf +44 -0
  60. package/dist/infra-templates/modules/azure-network/variables.tf +56 -0
  61. package/dist/infra-templates/modules/azure-postgresql-flexible/main.tf +34 -0
  62. package/dist/infra-templates/modules/azure-postgresql-flexible/outputs.tf +20 -0
  63. package/dist/infra-templates/modules/azure-postgresql-flexible/variables.tf +54 -0
  64. package/dist/infra-templates/modules/azure-redis-cache/main.tf +32 -0
  65. package/dist/infra-templates/modules/azure-redis-cache/outputs.tf +15 -0
  66. package/dist/infra-templates/modules/azure-redis-cache/variables.tf +30 -0
  67. package/dist/infra-templates/modules/azure-resource-group/main.tf +5 -0
  68. package/dist/infra-templates/modules/azure-resource-group/outputs.tf +11 -0
  69. package/dist/infra-templates/modules/azure-resource-group/variables.tf +16 -0
  70. package/dist/infra-templates/modules/azure-sql-database/main.tf +63 -0
  71. package/dist/infra-templates/modules/azure-sql-database/outputs.tf +20 -0
  72. package/dist/infra-templates/modules/azure-sql-database/variables.tf +78 -0
  73. package/dist/infra-templates/modules/azure-storage-account/main.tf +13 -0
  74. package/dist/infra-templates/modules/azure-storage-account/outputs.tf +16 -0
  75. package/dist/infra-templates/modules/azure-storage-account/variables.tf +38 -0
  76. package/dist/infra-templates/modules/cloud-watch/event-bridge.tf +15 -0
  77. package/dist/infra-templates/modules/cloud-watch/lambda.tf +84 -0
  78. package/dist/infra-templates/modules/cloud-watch/lambda_function.zip +0 -0
  79. package/dist/infra-templates/modules/cloud-watch/lambda_function_deploy.zip +0 -0
  80. package/dist/infra-templates/modules/cloud-watch/main.tf +156 -0
  81. package/dist/infra-templates/modules/cloud-watch/sns.tf +3 -0
  82. package/dist/infra-templates/modules/cloud-watch/variables.tf +38 -0
  83. package/dist/infra-templates/modules/ecs-core/alb.tf +126 -0
  84. package/dist/infra-templates/modules/ecs-core/cloudwatch.tf +48 -0
  85. package/dist/infra-templates/modules/ecs-core/iam.tf +95 -0
  86. package/dist/infra-templates/modules/ecs-core/main.tf +12 -0
  87. package/dist/infra-templates/modules/ecs-core/outputs.tf +44 -0
  88. package/dist/infra-templates/modules/ecs-core/secrets.tf +9 -0
  89. package/dist/infra-templates/modules/ecs-core/security_groups.tf +73 -0
  90. package/dist/infra-templates/modules/ecs-core/variables.tf +96 -0
  91. package/dist/infra-templates/modules/ecs-service/ecs_autoscaling.tf +51 -0
  92. package/dist/infra-templates/modules/ecs-service/ecs_service.tf +39 -0
  93. package/dist/infra-templates/modules/ecs-service/ecs_task_definition.tf +56 -0
  94. package/dist/infra-templates/modules/ecs-service/variables.tf +170 -0
  95. package/dist/infra-templates/modules/elastic-container-registry/main.tf +32 -0
  96. package/dist/infra-templates/modules/elastic-container-registry/outputs.tf +9 -0
  97. package/dist/infra-templates/modules/elastic-container-registry/variables.tf +25 -0
  98. package/dist/infra-templates/modules/github-oidc-role/main.tf +46 -0
  99. package/dist/infra-templates/modules/github-oidc-role/outputs.tf +4 -0
  100. package/dist/infra-templates/modules/github-oidc-role/variables.tf +11 -0
  101. package/dist/infra-templates/modules/guardduty/main.tf +8 -0
  102. package/dist/infra-templates/modules/iam/main.tf +205 -0
  103. package/dist/infra-templates/modules/iam/outputs.tf +3 -0
  104. package/dist/infra-templates/modules/iam/variables.tf +4 -0
  105. package/dist/infra-templates/modules/random-key/main.tf +11 -0
  106. package/dist/infra-templates/modules/random-key/outputs.tf +4 -0
  107. package/dist/infra-templates/modules/random-key/variables.tf +10 -0
  108. package/dist/infra-templates/modules/redis/main.tf +47 -0
  109. package/dist/infra-templates/modules/redis/outputs.tf +8 -0
  110. package/dist/infra-templates/modules/redis/variables.tf +20 -0
  111. package/dist/infra-templates/modules/relational-database-service/main.tf +44 -0
  112. package/dist/infra-templates/modules/relational-database-service/outputs.tf +13 -0
  113. package/dist/infra-templates/modules/relational-database-service/security-group.tf +15 -0
  114. package/dist/infra-templates/modules/relational-database-service/variables.tf +50 -0
  115. package/dist/infra-templates/modules/secret/main.tf +14 -0
  116. package/dist/infra-templates/modules/secret/outputs.tf +3 -0
  117. package/dist/infra-templates/modules/secret/variables.tf +8 -0
  118. package/dist/infra-templates/modules/simple-storage-service/main.tf +28 -0
  119. package/dist/infra-templates/modules/simple-storage-service/variables.tf +4 -0
  120. package/dist/infra-templates/modules/vpc/data.tf +2 -0
  121. package/dist/infra-templates/modules/vpc/main.tf +76 -0
  122. package/dist/infra-templates/modules/vpc/outputs.tf +23 -0
  123. package/dist/infra-templates/modules/vpc/variables.tf +5 -0
  124. package/dist/infra-templates/package.json +6 -0
  125. package/dist/infra-templates/templates/azure/MANUAL_DEPLOY.md +168 -0
  126. package/dist/infra-templates/templates/azure/backend.tf +8 -0
  127. package/dist/infra-templates/templates/azure/data.tf +21 -0
  128. package/dist/infra-templates/templates/azure/default.tfvars +0 -0
  129. package/dist/infra-templates/templates/azure/locals.tf +116 -0
  130. package/dist/infra-templates/templates/azure/main.tf +421 -0
  131. package/dist/infra-templates/templates/azure/outputs.tf +40 -0
  132. package/dist/infra-templates/templates/azure/providers.tf +65 -0
  133. package/dist/infra-templates/templates/azure/variables.tf +69 -0
  134. package/dist/infra-templates/templates/azure/workflows/build_and_deploy.yml +155 -0
  135. package/dist/infra-templates/templates/azure/workflows/tests.yml +63 -0
  136. package/dist/infra-templates/templates/ecs/README.md +225 -0
  137. package/dist/infra-templates/templates/ecs/backend.tf +7 -0
  138. package/dist/infra-templates/templates/ecs/data.tf +6 -0
  139. package/dist/infra-templates/templates/ecs/default.tfvars +1 -0
  140. package/dist/infra-templates/templates/ecs/locals.tf +97 -0
  141. package/dist/infra-templates/templates/ecs/main.tf +185 -0
  142. package/dist/infra-templates/templates/ecs/outputs.tf +42 -0
  143. package/dist/infra-templates/templates/ecs/providers.tf +21 -0
  144. package/dist/infra-templates/templates/ecs/variables.tf +105 -0
  145. package/dist/infra-templates/templates/ecs/workflows/build_and_deploy.yml +188 -0
  146. package/dist/infra-templates/templates/ecs/workflows/tests.yml +65 -0
  147. package/package.json +2 -2
  148. package/schema/fuel.schema.json +78 -44
@@ -0,0 +1,15 @@
1
+ output "hostname" {
2
+ value = azurerm_managed_redis.this.hostname
3
+ description = "Hostname of the Azure Managed Redis instance"
4
+ }
5
+
6
+ output "ssl_port" {
7
+ value = azurerm_managed_redis.this.default_database[0].port
8
+ description = "TLS port of the Azure Managed Redis instance"
9
+ }
10
+
11
+ output "primary_access_key" {
12
+ value = azurerm_managed_redis.this.default_database[0].primary_access_key
13
+ sensitive = true
14
+ description = "Primary access key for the Azure Managed Redis default database"
15
+ }
@@ -0,0 +1,30 @@
1
+ variable "name" {
2
+ description = "Name of the Redis Enterprise cluster"
3
+ type = string
4
+ }
5
+
6
+ variable "resource_group_name" {
7
+ description = "Name of the resource group where the Redis Enterprise cluster will be created"
8
+ type = string
9
+ }
10
+
11
+ variable "location" {
12
+ description = "Azure region where the Redis Enterprise cluster will be created"
13
+ type = string
14
+ }
15
+
16
+ variable "sku_name" {
17
+ description = "SKU name for the Redis Enterprise cluster (Azure Managed Redis 'Balanced' tier, e.g. Balanced_B0, Balanced_B1, Balanced_B5)"
18
+ type = string
19
+ default = "Balanced_B0"
20
+ }
21
+
22
+ variable "private_endpoint_subnet_id" {
23
+ description = "Subnet for the Private Link endpoint (non-delegated, network policies disabled)"
24
+ type = string
25
+ }
26
+
27
+ variable "private_dns_zone_id" {
28
+ description = "Private DNS zone (privatelink.redis.azure.net) linked to the same VNet as private_endpoint_subnet_id"
29
+ type = string
30
+ }
@@ -0,0 +1,5 @@
1
+ resource "azurerm_resource_group" "this" {
2
+ name = var.name
3
+ location = var.location
4
+ tags = var.tags
5
+ }
@@ -0,0 +1,11 @@
1
+ output "name" {
2
+ value = azurerm_resource_group.this.name
3
+ }
4
+
5
+ output "id" {
6
+ value = azurerm_resource_group.this.id
7
+ }
8
+
9
+ output "location" {
10
+ value = azurerm_resource_group.this.location
11
+ }
@@ -0,0 +1,16 @@
1
+ variable "name" {
2
+ type = string
3
+ description = "Resource group name"
4
+ }
5
+
6
+ variable "location" {
7
+ type = string
8
+ description = "Azure region"
9
+ default = "eastus"
10
+ }
11
+
12
+ variable "tags" {
13
+ type = map(string)
14
+ description = "Tags applied to the resource group"
15
+ default = {}
16
+ }
@@ -0,0 +1,63 @@
1
+ resource "random_password" "this" {
2
+ length = 24
3
+ special = true
4
+ override_special = "!#$%&*()-_=+[]{}<>:?"
5
+ }
6
+
7
+ locals {
8
+ effective_password = var.admin_password != "" ? var.admin_password : random_password.this.result
9
+ }
10
+
11
+ resource "azurerm_mssql_server" "this" {
12
+ name = var.server_name
13
+ resource_group_name = var.resource_group_name
14
+ location = var.location
15
+ administrator_login = var.admin_username
16
+ administrator_login_password = local.effective_password
17
+ version = "12.0"
18
+ minimum_tls_version = "1.2"
19
+
20
+ public_network_access_enabled = false
21
+ }
22
+
23
+ resource "azurerm_private_endpoint" "this" {
24
+ name = "${var.server_name}-pe"
25
+ resource_group_name = var.resource_group_name
26
+ location = var.location
27
+ subnet_id = var.private_endpoint_subnet_id
28
+
29
+ private_service_connection {
30
+ name = "${var.server_name}-psc"
31
+ private_connection_resource_id = azurerm_mssql_server.this.id
32
+ subresource_names = ["sqlServer"]
33
+ is_manual_connection = false
34
+ }
35
+
36
+ private_dns_zone_group {
37
+ name = "default"
38
+ private_dns_zone_ids = [var.private_dns_zone_id]
39
+ }
40
+ }
41
+
42
+ resource "azurerm_mssql_database" "this" {
43
+ name = var.database_name
44
+ server_id = azurerm_mssql_server.this.id
45
+ sku_name = var.sku_name
46
+ min_capacity = var.min_capacity
47
+ auto_pause_delay_in_minutes = var.auto_pause_delay_in_minutes
48
+ storage_account_type = var.storage_account_type
49
+
50
+ short_term_retention_policy {
51
+ retention_days = var.pitr_retention_days
52
+ }
53
+
54
+ # Azure rejects long-term retention on a serverless database while auto-pause is
55
+ # enabled (LtrConfigPolicyUnsupportedIfAutoPauseEnabled) — only apply LTR once
56
+ # auto-pause is explicitly disabled (-1), e.g. for provisioned prod databases.
57
+ dynamic "long_term_retention_policy" {
58
+ for_each = var.auto_pause_delay_in_minutes == -1 ? [1] : []
59
+ content {
60
+ weekly_retention = var.ltr_weekly_retention
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,20 @@
1
+ output "fqdn" {
2
+ value = azurerm_mssql_server.this.fully_qualified_domain_name
3
+ description = "Fully qualified domain name of the SQL Server"
4
+ }
5
+
6
+ output "database_name" {
7
+ value = azurerm_mssql_database.this.name
8
+ description = "Name of the SQL database"
9
+ }
10
+
11
+ output "admin_username" {
12
+ value = var.admin_username
13
+ description = "Administrator username for the SQL Server"
14
+ }
15
+
16
+ output "admin_password" {
17
+ value = local.effective_password
18
+ sensitive = true
19
+ description = "Effective administrator password for the SQL Server"
20
+ }
@@ -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
+ }