@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,95 @@
1
+ ########################################################################################################################
2
+ ## IAM Role for ECS Task execution
3
+ ########################################################################################################################
4
+
5
+ resource "aws_iam_role" "ecs_task_execution_role" {
6
+ name = "${var.project_name}_ECS_TaskExecutionRole"
7
+ assume_role_policy = data.aws_iam_policy_document.task_assume_role_policy.json
8
+
9
+
10
+ tags = {
11
+ Scenario = var.scenario
12
+ }
13
+ }
14
+
15
+ data "aws_iam_policy_document" "task_assume_role_policy" {
16
+ statement {
17
+ actions = ["sts:AssumeRole"]
18
+
19
+ principals {
20
+ type = "Service"
21
+ identifiers = ["ecs-tasks.amazonaws.com"]
22
+ }
23
+ }
24
+ }
25
+
26
+
27
+ resource "aws_iam_role_policy_attachment" "ecs_task_execution_secrets_role_policy" {
28
+ role = aws_iam_role.ecs_task_execution_role.name
29
+ policy_arn = "arn:aws:iam::aws:policy/SecretsManagerReadWrite"
30
+ }
31
+
32
+ resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
33
+ role = aws_iam_role.ecs_task_execution_role.name
34
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
35
+ }
36
+
37
+ ########################################################################################################################
38
+ ## IAM Role for ECS Task
39
+ ########################################################################################################################
40
+
41
+ # Create an IAM policy
42
+ resource "aws_iam_policy" "ecs_task_policy" {
43
+ name = "${var.project_name}-ecs-task-policy"
44
+
45
+ policy = jsonencode({
46
+ "Version": "2012-10-17",
47
+ "Statement": [
48
+ {
49
+ "Effect": "Allow",
50
+ "Action": [
51
+ "ecr:GetAuthorizationToken",
52
+ "ecr:BatchCheckLayerAvailability",
53
+ "ecr:GetDownloadUrlForLayer",
54
+ "ecr:BatchGetImage",
55
+ "ecs:ExecuteCommand",
56
+ "ssmmessages:CreateControlChannel",
57
+ "ssmmessages:CreateDataChannel",
58
+ "ssmmessages:OpenControlChannel",
59
+ "ssmmessages:OpenDataChannel",
60
+ "logs:CreateLogStream",
61
+ "logs:PutLogEvents"
62
+ ],
63
+ "Resource": "*"
64
+ }
65
+ ]
66
+ })
67
+
68
+ tags = {
69
+ Scenario = var.scenario
70
+ }
71
+ }
72
+
73
+ resource "aws_iam_role" "task_exec_role" {
74
+ name = "${var.project_name}-ecs-task-role"
75
+
76
+ assume_role_policy = jsonencode({
77
+ "Version": "2012-10-17",
78
+ "Statement": [
79
+ {
80
+ "Effect": "Allow",
81
+ "Principal": {
82
+ "Service": "ecs-tasks.amazonaws.com"
83
+ },
84
+ "Action": "sts:AssumeRole"
85
+ }
86
+ ]
87
+ })
88
+ }
89
+
90
+ # Attach the IAM policy to the IAM role
91
+ resource "aws_iam_policy_attachment" "iam_role_policy_attachment" {
92
+ name = "Policy Attachement"
93
+ policy_arn = aws_iam_policy.ecs_task_policy.arn
94
+ roles = [aws_iam_role.task_exec_role.name]
95
+ }
@@ -0,0 +1,12 @@
1
+ ########################################################################################################################
2
+ ## Creates an ECS Cluster
3
+ ########################################################################################################################
4
+
5
+ resource "aws_ecs_cluster" "default" {
6
+ name = var.project_name
7
+
8
+ tags = {
9
+ Name = "${var.project_name}_ECSCluster"
10
+ Scenario = var.scenario
11
+ }
12
+ }
@@ -0,0 +1,44 @@
1
+ output "alb_dns" {
2
+ description = "The CNAME for the ALB"
3
+ value = aws_alb.alb.dns_name
4
+ }
5
+
6
+ output "ecs_log_group_name" {
7
+ description = "The name of the cloudwatch log group for ECS"
8
+ value = aws_cloudwatch_log_group.cb_log_group.name
9
+ }
10
+
11
+ output "ecs_task_execution_role_arn" {
12
+ description = "The ARN of the IAM execution role"
13
+ value = aws_iam_role.ecs_task_execution_role.arn
14
+ }
15
+
16
+ output "ecs_task_role_arn" {
17
+ description = "The ARN of the IAM rask role"
18
+ value = aws_iam_role.task_exec_role.arn
19
+ }
20
+
21
+ output "ecs_cluster_id" {
22
+ description = "The ARN of the IAM execution role"
23
+ value = aws_ecs_cluster.default.id
24
+ }
25
+
26
+ output "ecs_container_security_group_id" {
27
+ description = "ECS Container Security Group ID"
28
+ value = aws_security_group.ecs_container_instance.id
29
+ }
30
+
31
+ output "ecs_cluster_name" {
32
+ description = "The name of the cluster"
33
+ value = aws_ecs_cluster.default.name
34
+ }
35
+
36
+ output "ecs_secret_arn" {
37
+ description = "ARN of the secrets for the app"
38
+ value = aws_secretsmanager_secret.secret.arn
39
+ }
40
+
41
+ output "aws_alb_target_groups" {
42
+ description = "ALB target groups"
43
+ value = aws_alb_target_group.app_service_target_group
44
+ }
@@ -0,0 +1,9 @@
1
+ resource "random_id" "secret_suffix" {
2
+ byte_length = 4
3
+ }
4
+
5
+ resource "aws_secretsmanager_secret" "secret" {
6
+ name = "${var.project_name}_secrets_${random_id.secret_suffix.hex}"
7
+ description = "Secret"
8
+ recovery_window_in_days = 0
9
+ }
@@ -0,0 +1,73 @@
1
+ resource "aws_security_group" "ecs_container_instance" {
2
+ name = "${var.project_name}_ECS_Task_SecurityGroup"
3
+ description = "Security group for ECS task running on Fargate"
4
+ vpc_id = var.vpc_id
5
+
6
+ ingress {
7
+ description = "Allow ingress traffic from ALB on HTTP only"
8
+ from_port = var.container_port
9
+ to_port = var.container_port
10
+ protocol = "tcp"
11
+ security_groups = [aws_security_group.alb.id]
12
+ }
13
+
14
+ egress {
15
+ description = "Allow all egress traffic"
16
+ from_port = 0
17
+ to_port = 0
18
+ protocol = -1
19
+ cidr_blocks = ["0.0.0.0/0"]
20
+ }
21
+
22
+ tags = {
23
+ Name = "${var.project_name}_ECS_Task_SecurityGroup"
24
+ Scenario = var.scenario
25
+ }
26
+ }
27
+
28
+ resource "aws_security_group" "alb" {
29
+ name = "${var.project_name}_ALB_SecurityGroup"
30
+ description = "Security group for ALB"
31
+ vpc_id = var.vpc_id
32
+ revoke_rules_on_delete = true
33
+
34
+ tags = {
35
+ Name = "${var.project_name}_ALB_SecurityGroup"
36
+ Scenario = var.scenario
37
+ }
38
+ }
39
+
40
+ # ------------------------------------------------------------------------------
41
+ # Alb Security Group Rules - INBOUND
42
+ # ------------------------------------------------------------------------------
43
+ resource "aws_security_group_rule" "alb_http_ingress" {
44
+ type = "ingress"
45
+ from_port = 80
46
+ to_port = 80
47
+ protocol = "TCP"
48
+ description = "Allow http inbound traffic from internet"
49
+ security_group_id = aws_security_group.alb.id
50
+ cidr_blocks = ["0.0.0.0/0"]
51
+ }
52
+ resource "aws_security_group_rule" "alb_https_ingress" {
53
+ type = "ingress"
54
+ from_port = 443
55
+ to_port = 443
56
+ protocol = "TCP"
57
+ description = "Allow https inbound traffic from internet"
58
+ security_group_id = aws_security_group.alb.id
59
+ cidr_blocks = ["0.0.0.0/0"]
60
+ }
61
+
62
+ # ------------------------------------------------------------------------------
63
+ # Alb Security Group Rules - OUTBOUND
64
+ # ------------------------------------------------------------------------------
65
+ resource "aws_security_group_rule" "alb_egress" {
66
+ type = "egress"
67
+ from_port = 0
68
+ to_port = 0
69
+ protocol = "-1"
70
+ description = "Allow outbound traffic from alb"
71
+ security_group_id = aws_security_group.alb.id
72
+ cidr_blocks = ["0.0.0.0/0"]
73
+ }
@@ -0,0 +1,96 @@
1
+
2
+ ########################################################################################################################
3
+ ## Service variables
4
+ ########################################################################################################################
5
+
6
+ variable "ingress_ssl_arn" {
7
+ description = "ACM ARN"
8
+ type = string
9
+ }
10
+
11
+ variable "namespace" {
12
+ description = "Namespace for resource names"
13
+ type = string
14
+ }
15
+
16
+ variable "project_name" {
17
+ description = "A Docker image-compatible name for the service"
18
+ type = string
19
+ }
20
+
21
+ variable "scenario" {
22
+ description = "Scenario name for tags"
23
+ default = "scenario-ecs-fargate"
24
+ type = string
25
+ }
26
+
27
+ ########################################################################################################################
28
+ ## Cloudwatch
29
+ ########################################################################################################################
30
+
31
+ variable "retention_in_days" {
32
+ description = "Retention period for Cloudwatch logs"
33
+ default = 7
34
+ type = number
35
+ }
36
+
37
+ ########################################################################################################################
38
+ ## ALB
39
+ ########################################################################################################################
40
+
41
+ variable "healthcheck_endpoint" {
42
+ description = "Endpoint for ALB healthcheck"
43
+ type = string
44
+ default = "/"
45
+ }
46
+
47
+ variable "healthcheck_matcher" {
48
+ description = "HTTP status code matcher for healthcheck"
49
+ type = string
50
+ default = "200-299"
51
+ }
52
+
53
+ variable "aws_region" {
54
+ description = "AWS Region"
55
+ type = string
56
+ }
57
+
58
+ variable "vpc_id" {
59
+ description = "VPC id"
60
+ type = string
61
+ }
62
+
63
+ variable "public_subnets" {
64
+ description = "The public subnets for ingress resources."
65
+ default = ""
66
+ }
67
+
68
+ variable "private_subnets" {
69
+ description = "The private subnets for ingress resources."
70
+ default = ""
71
+ }
72
+
73
+ variable "default_security_group_id" {
74
+ description = "VPC Security Group"
75
+ type = string
76
+ }
77
+
78
+ variable "container_port" {
79
+ description = "Port of the container"
80
+ type = number
81
+ default = 3000
82
+ }
83
+
84
+ variable "apps" {
85
+ description = "An array of apps from config.json"
86
+ type = set(object({
87
+ app_name = string
88
+ domain = string
89
+ port = number
90
+ health_check_path = string
91
+ }))
92
+ }
93
+
94
+ variable "log_group_name" {
95
+ description = "CloudWatch log group name"
96
+ }
@@ -0,0 +1,51 @@
1
+ ########################################################################################################################
2
+ ## Define Target Tracking on ECS Cluster Task level
3
+ ########################################################################################################################
4
+
5
+ resource "aws_appautoscaling_target" "ecs_target" {
6
+ max_capacity = var.ecs_task_max_count
7
+ min_capacity = var.ecs_task_min_count
8
+ resource_id = "service/${var.ecs_cluster_name}/${aws_ecs_service.backend_service.name}"
9
+ scalable_dimension = "ecs:service:DesiredCount"
10
+ service_namespace = "ecs"
11
+ }
12
+
13
+ ########################################################################################################################
14
+ ## Policy for CPU tracking
15
+ ########################################################################################################################
16
+
17
+ resource "aws_appautoscaling_policy" "ecs_cpu_policy" {
18
+ name = "${var.app_name}_CPUTargetTrackingScaling"
19
+ policy_type = "TargetTrackingScaling"
20
+ resource_id = aws_appautoscaling_target.ecs_target.resource_id
21
+ scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension
22
+ service_namespace = aws_appautoscaling_target.ecs_target.service_namespace
23
+
24
+ target_tracking_scaling_policy_configuration {
25
+ target_value = var.cpu_target_tracking_desired_value
26
+
27
+ predefined_metric_specification {
28
+ predefined_metric_type = "ECSServiceAverageCPUUtilization"
29
+ }
30
+ }
31
+ }
32
+
33
+ ########################################################################################################################
34
+ ## Policy for memory tracking
35
+ ########################################################################################################################
36
+
37
+ resource "aws_appautoscaling_policy" "ecs_memory_policy" {
38
+ name = "${var.app_name}_MemoryTargetTrackingScaling"
39
+ policy_type = "TargetTrackingScaling"
40
+ resource_id = aws_appautoscaling_target.ecs_target.resource_id
41
+ scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension
42
+ service_namespace = aws_appautoscaling_target.ecs_target.service_namespace
43
+
44
+ target_tracking_scaling_policy_configuration {
45
+ target_value = var.memory_target_tracking_desired_value
46
+
47
+ predefined_metric_specification {
48
+ predefined_metric_type = "ECSServiceAverageMemoryUtilization"
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,39 @@
1
+ resource "aws_ecs_service" "backend_service" {
2
+ name = "${var.app_name}"
3
+ cluster = var.ecs_cluster_id
4
+ task_definition = aws_ecs_task_definition.backend_task_definition.arn
5
+ desired_count = var.ecs_task_desired_count
6
+ deployment_minimum_healthy_percent = var.ecs_task_deployment_minimum_healthy_percent
7
+ deployment_maximum_percent = var.ecs_task_deployment_maximum_percent
8
+ launch_type = "FARGATE"
9
+ enable_execute_command = true
10
+
11
+ dynamic "load_balancer" {
12
+ for_each = var.connect_to_alb == true ? [1]: []
13
+
14
+ content {
15
+ target_group_arn = var.aws_alb_target_group_arn
16
+ container_name = var.app_name
17
+ container_port = var.container_port
18
+ }
19
+ }
20
+
21
+ network_configuration {
22
+ security_groups = [var.ecs_container_security_group_id, var.default_security_group_id]
23
+ subnets = var.private_subnets
24
+ assign_public_ip = false
25
+ }
26
+
27
+ deployment_circuit_breaker {
28
+ enable = var.ecs_circuit_breaker
29
+ rollback = var.ecs_rollback
30
+ }
31
+
32
+ tags = {
33
+ Scenario = var.scenario
34
+ }
35
+
36
+ lifecycle {
37
+ ignore_changes = [task_definition]
38
+ }
39
+ }
@@ -0,0 +1,56 @@
1
+ ########################################################################################################################
2
+ ## Creates ECS Task Definition
3
+ ########################################################################################################################
4
+
5
+ locals {
6
+ secretKeys = keys(var.env_vars)
7
+ }
8
+
9
+ locals {
10
+ secrets_list = [
11
+ for name in local.secretKeys : {
12
+ name = name
13
+ valueFrom = "${var.ecs_secret_arn}:${name}::"
14
+ }
15
+ ]
16
+ }
17
+
18
+ resource "aws_ecs_task_definition" "backend_task_definition" {
19
+ family = var.app_name
20
+ network_mode = "awsvpc"
21
+ requires_compatibilities = ["FARGATE"]
22
+ execution_role_arn = var.ecs_task_execution_role_arn
23
+ task_role_arn = var.ecs_task_role_arn
24
+ cpu = var.cpu_units
25
+ memory = var.memory
26
+
27
+ container_definitions = jsonencode([
28
+ {
29
+ name = var.app_name
30
+ image = var.repository_url
31
+ cpu = var.cpu_units
32
+ memory = var.memory
33
+ essential = true
34
+ portMappings = [
35
+ {
36
+ containerPort = var.container_port
37
+ hostPort = var.container_port
38
+ protocol = "tcp"
39
+ }
40
+ ]
41
+ secrets = local.secrets_list
42
+ logConfiguration = {
43
+ logDriver = "awslogs"
44
+ options = {
45
+ "awslogs-group" = var.ecs_log_group_name
46
+ "awslogs-region" = var.aws_region
47
+ "awslogs-stream-prefix" = "${var.app_name}-log-stream"
48
+ }
49
+ }
50
+ }
51
+ ])
52
+
53
+ tags = {
54
+ Scenario = var.scenario
55
+ }
56
+ }
@@ -0,0 +1,170 @@
1
+ ########################################################################################################################
2
+ ## Service variables
3
+ ########################################################################################################################
4
+
5
+ variable "app_name" {
6
+ description = "A Docker image-compatible name for the service"
7
+ type = string
8
+ }
9
+
10
+ variable "scenario" {
11
+ description = "Scenario name for tags"
12
+ default = "scenario-ecs-fargate"
13
+ type = string
14
+ }
15
+
16
+ ########################################################################################################################
17
+ ## ECS variables
18
+ ########################################################################################################################
19
+
20
+ variable "ecs_task_desired_count" {
21
+ description = "How many ECS tasks should run in parallel"
22
+ type = number
23
+ default = 1
24
+ }
25
+
26
+ variable "ecs_task_min_count" {
27
+ description = "How many ECS tasks should minimally run in parallel"
28
+ default = 1
29
+ type = number
30
+ }
31
+
32
+ variable "ecs_task_max_count" {
33
+ description = "How many ECS tasks should maximally run in parallel"
34
+ default = 10
35
+ type = number
36
+ }
37
+
38
+ # if you have multiple tasks running this should be 50%, but for 1 task
39
+ # it has to be zero so ecs can drain the task to replace it (making the service unstable for a few minutes)
40
+ variable "ecs_task_deployment_minimum_healthy_percent" {
41
+ description = "How many percent of a service must be running to still execute a safe deployment"
42
+ default = 100
43
+ type = number
44
+ }
45
+
46
+ variable "ecs_task_deployment_maximum_percent" {
47
+ description = "How many additional tasks are allowed to run (in percent) while a deployment is executed"
48
+ default = 200
49
+ type = number
50
+ }
51
+
52
+ variable "cpu_target_tracking_desired_value" {
53
+ description = "Target tracking for CPU usage in %"
54
+ default = 70
55
+ type = number
56
+ }
57
+
58
+ variable "memory_target_tracking_desired_value" {
59
+ description = "Target tracking for memory usage in %"
60
+ default = 80
61
+ type = number
62
+ }
63
+
64
+ variable "target_capacity" {
65
+ description = "Amount of resources of container instances that should be used for task placement in %"
66
+ default = 100
67
+ type = number
68
+ }
69
+
70
+ variable "container_port" {
71
+ description = "Port of the container"
72
+ type = number
73
+ default = 3000
74
+ }
75
+
76
+ variable "cpu_units" {
77
+ description = "Amount of CPU units for a single ECS task"
78
+ default = 1024
79
+ type = number
80
+ }
81
+
82
+ variable "memory" {
83
+ description = "Amount of memory in MB for a single ECS task"
84
+ default = 2048
85
+ type = number
86
+ }
87
+
88
+ variable "aws_region" {
89
+ description = "AWS Region"
90
+ type = string
91
+ }
92
+
93
+ variable "repository_url" {
94
+ description = "Image URL"
95
+ type = string
96
+ }
97
+
98
+ variable "default_security_group_id" {
99
+ description = "VPC Security Group"
100
+ type = string
101
+ }
102
+
103
+ variable "ecs_task_execution_role_arn" {
104
+ description = "ARN for the task execution role"
105
+ type = string
106
+ }
107
+
108
+ variable "ecs_task_role_arn" {
109
+ description = "ARN for the task role"
110
+ type = string
111
+ }
112
+
113
+ variable "ecs_log_group_name" {
114
+ description = "Log group name for ECS"
115
+ type = string
116
+ }
117
+
118
+ variable "ecs_cluster_id" {
119
+ description = "ECS cluster id to attach services to"
120
+ }
121
+
122
+ variable "ecs_cluster_name" {
123
+ description = "ECS cluster name"
124
+ }
125
+
126
+ variable "aws_alb_target_group_arn" {
127
+ description = "AWS ALB target group ARN"
128
+ type = string
129
+ }
130
+
131
+ variable "ecs_container_security_group_id" {
132
+ description = "ECS Container Security Group ID"
133
+ type = string
134
+ }
135
+
136
+ variable "private_subnets" {
137
+ description = "Private subnets for the ECS cluster"
138
+ default = ""
139
+ }
140
+
141
+ variable "ecs_secret_arn" {
142
+ description = "ARN for secrets"
143
+ type = string
144
+ }
145
+
146
+ variable "connect_to_alb" {
147
+ description = "Is this a public service?"
148
+ type = bool
149
+ }
150
+
151
+ variable "secret_name" {
152
+ description = "Name of the secret to use"
153
+ type = string
154
+ }
155
+
156
+ variable "env_vars" {
157
+ type = map(string)
158
+ default = {}
159
+ }
160
+ variable "ecs_circuit_breaker" {
161
+ description = "Enable Circuit Breaker"
162
+ type = bool
163
+ default = true
164
+ }
165
+
166
+ variable "ecs_rollback" {
167
+ description = "Automatically rollback if failure occurs"
168
+ type = bool
169
+ default = true
170
+ }
@@ -0,0 +1,32 @@
1
+ locals {
2
+ all_apps = merge(
3
+ { for app in var.apps : app.app_name => app },
4
+ { for worker in var.workers : worker.worker_name => worker }
5
+ )
6
+ }
7
+
8
+ module "ecr" {
9
+ source = "terraform-aws-modules/ecr/aws"
10
+ version = "2.2.0"
11
+
12
+ repository_name = "${var.project_name}-application"
13
+ repository_force_delete = true
14
+ repository_image_tag_mutability = "MUTABLE"
15
+ repository_lifecycle_policy = jsonencode({
16
+ rules = [
17
+ for idx, app_key in zipmap(range(length(keys(local.all_apps))), keys(local.all_apps)) : {
18
+ rulePriority = idx + 1
19
+ description = "Keep 5 most recent images with prefix '${app_key}'"
20
+ selection = {
21
+ tagStatus = "tagged"
22
+ tagPrefixList = [app_key]
23
+ countType = "imageCountMoreThan"
24
+ countNumber = 5
25
+ }
26
+ action = {
27
+ type = "expire"
28
+ }
29
+ }
30
+ ]
31
+ })
32
+ }
@@ -0,0 +1,9 @@
1
+ output "repository_url" {
2
+ description = "The URL of the repository."
3
+ value = module.ecr.repository_url
4
+ }
5
+
6
+ output "registry_id" {
7
+ description = "The registry ID"
8
+ value = module.ecr.repository_registry_id
9
+ }