tf-starter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +421 -0
  3. package/bin/tf-starter.js +88 -0
  4. package/package.json +43 -0
  5. package/scripts/postinstall.js +105 -0
  6. package/setup.py +32 -0
  7. package/tf_starter/__init__.py +3 -0
  8. package/tf_starter/__main__.py +6 -0
  9. package/tf_starter/cli.py +379 -0
  10. package/tf_starter/generator.py +171 -0
  11. package/tf_starter/template_engine.py +80 -0
  12. package/tf_starter/templates/aws/environments/backend.tf.j2 +16 -0
  13. package/tf_starter/templates/aws/environments/main.tf.j2 +85 -0
  14. package/tf_starter/templates/aws/environments/terraform.tfvars.j2 +52 -0
  15. package/tf_starter/templates/aws/environments/variables.tf.j2 +127 -0
  16. package/tf_starter/templates/aws/github/terraform.yml.j2 +133 -0
  17. package/tf_starter/templates/aws/misc/Makefile.j2 +60 -0
  18. package/tf_starter/templates/aws/misc/README.md.j2 +445 -0
  19. package/tf_starter/templates/aws/misc/init.sh.j2 +110 -0
  20. package/tf_starter/templates/aws/misc/pre-commit-config.yaml.j2 +34 -0
  21. package/tf_starter/templates/aws/modules/apigateway/main.tf.j2 +224 -0
  22. package/tf_starter/templates/aws/modules/apigateway/outputs.tf.j2 +28 -0
  23. package/tf_starter/templates/aws/modules/apigateway/variables.tf.j2 +69 -0
  24. package/tf_starter/templates/aws/modules/compute/main.tf.j2 +245 -0
  25. package/tf_starter/templates/aws/modules/compute/outputs.tf.j2 +38 -0
  26. package/tf_starter/templates/aws/modules/compute/variables.tf.j2 +68 -0
  27. package/tf_starter/templates/aws/modules/database/main.tf.j2 +122 -0
  28. package/tf_starter/templates/aws/modules/database/outputs.tf.j2 +33 -0
  29. package/tf_starter/templates/aws/modules/database/variables.tf.j2 +63 -0
  30. package/tf_starter/templates/aws/modules/kubernetes/main.tf.j2 +167 -0
  31. package/tf_starter/templates/aws/modules/kubernetes/outputs.tf.j2 +33 -0
  32. package/tf_starter/templates/aws/modules/kubernetes/variables.tf.j2 +64 -0
  33. package/tf_starter/templates/aws/modules/lambda/main.tf.j2 +215 -0
  34. package/tf_starter/templates/aws/modules/lambda/outputs.tf.j2 +38 -0
  35. package/tf_starter/templates/aws/modules/lambda/variables.tf.j2 +88 -0
  36. package/tf_starter/templates/aws/modules/messaging/main.tf.j2 +85 -0
  37. package/tf_starter/templates/aws/modules/messaging/outputs.tf.j2 +28 -0
  38. package/tf_starter/templates/aws/modules/messaging/variables.tf.j2 +41 -0
  39. package/tf_starter/templates/aws/modules/monitoring/main.tf.j2 +155 -0
  40. package/tf_starter/templates/aws/modules/monitoring/outputs.tf.j2 +23 -0
  41. package/tf_starter/templates/aws/modules/monitoring/variables.tf.j2 +39 -0
  42. package/tf_starter/templates/aws/modules/network/main.tf.j2 +147 -0
  43. package/tf_starter/templates/aws/modules/network/outputs.tf.j2 +33 -0
  44. package/tf_starter/templates/aws/modules/network/variables.tf.j2 +52 -0
  45. package/tf_starter/templates/aws/modules/storage/main.tf.j2 +88 -0
  46. package/tf_starter/templates/aws/modules/storage/outputs.tf.j2 +23 -0
  47. package/tf_starter/templates/aws/modules/storage/variables.tf.j2 +25 -0
  48. package/tf_starter/templates/aws/root/backend.tf.j2 +19 -0
  49. package/tf_starter/templates/aws/root/main.tf.j2 +219 -0
  50. package/tf_starter/templates/aws/root/outputs.tf.j2 +134 -0
  51. package/tf_starter/templates/aws/root/providers.tf.j2 +24 -0
  52. package/tf_starter/templates/aws/root/variables.tf.j2 +300 -0
  53. package/tf_starter/templates/aws/root/versions.tf.j2 +26 -0
  54. package/tf_starter/templates/azure/environments/backend.tf.j2 +11 -0
  55. package/tf_starter/templates/azure/environments/main.tf.j2 +57 -0
  56. package/tf_starter/templates/azure/environments/terraform.tfvars.j2 +14 -0
  57. package/tf_starter/templates/azure/environments/variables.tf.j2 +30 -0
  58. package/tf_starter/templates/azure/github/terraform.yml.j2 +133 -0
  59. package/tf_starter/templates/azure/misc/Makefile.j2 +60 -0
  60. package/tf_starter/templates/azure/misc/README.md.j2 +426 -0
  61. package/tf_starter/templates/azure/misc/init.sh.j2 +110 -0
  62. package/tf_starter/templates/azure/misc/pre-commit-config.yaml.j2 +34 -0
  63. package/tf_starter/templates/azure/modules/apigateway/main.tf.j2 +125 -0
  64. package/tf_starter/templates/azure/modules/apigateway/outputs.tf.j2 +18 -0
  65. package/tf_starter/templates/azure/modules/apigateway/variables.tf.j2 +54 -0
  66. package/tf_starter/templates/azure/modules/compute/main.tf.j2 +114 -0
  67. package/tf_starter/templates/azure/modules/compute/outputs.tf.j2 +9 -0
  68. package/tf_starter/templates/azure/modules/compute/variables.tf.j2 +23 -0
  69. package/tf_starter/templates/azure/modules/database/main.tf.j2 +56 -0
  70. package/tf_starter/templates/azure/modules/database/outputs.tf.j2 +13 -0
  71. package/tf_starter/templates/azure/modules/database/variables.tf.j2 +38 -0
  72. package/tf_starter/templates/azure/modules/kubernetes/main.tf.j2 +50 -0
  73. package/tf_starter/templates/azure/modules/kubernetes/outputs.tf.j2 +19 -0
  74. package/tf_starter/templates/azure/modules/kubernetes/variables.tf.j2 +37 -0
  75. package/tf_starter/templates/azure/modules/lambda/main.tf.j2 +98 -0
  76. package/tf_starter/templates/azure/modules/lambda/outputs.tf.j2 +23 -0
  77. package/tf_starter/templates/azure/modules/lambda/variables.tf.j2 +53 -0
  78. package/tf_starter/templates/azure/modules/messaging/main.tf.j2 +29 -0
  79. package/tf_starter/templates/azure/modules/messaging/outputs.tf.j2 +14 -0
  80. package/tf_starter/templates/azure/modules/messaging/variables.tf.j2 +11 -0
  81. package/tf_starter/templates/azure/modules/monitoring/main.tf.j2 +31 -0
  82. package/tf_starter/templates/azure/modules/monitoring/outputs.tf.j2 +9 -0
  83. package/tf_starter/templates/azure/modules/monitoring/variables.tf.j2 +16 -0
  84. package/tf_starter/templates/azure/modules/network/main.tf.j2 +89 -0
  85. package/tf_starter/templates/azure/modules/network/outputs.tf.j2 +25 -0
  86. package/tf_starter/templates/azure/modules/network/variables.tf.j2 +25 -0
  87. package/tf_starter/templates/azure/modules/storage/main.tf.j2 +41 -0
  88. package/tf_starter/templates/azure/modules/storage/outputs.tf.j2 +17 -0
  89. package/tf_starter/templates/azure/modules/storage/variables.tf.j2 +16 -0
  90. package/tf_starter/templates/azure/root/backend.tf.j2 +11 -0
  91. package/tf_starter/templates/azure/root/main.tf.j2 +181 -0
  92. package/tf_starter/templates/azure/root/outputs.tf.j2 +45 -0
  93. package/tf_starter/templates/azure/root/providers.tf.j2 +18 -0
  94. package/tf_starter/templates/azure/root/variables.tf.j2 +114 -0
  95. package/tf_starter/templates/azure/root/versions.tf.j2 +16 -0
  96. package/tf_starter/templates/gcp/environments/backend.tf.j2 +9 -0
  97. package/tf_starter/templates/gcp/environments/main.tf.j2 +58 -0
  98. package/tf_starter/templates/gcp/environments/terraform.tfvars.j2 +12 -0
  99. package/tf_starter/templates/gcp/environments/variables.tf.j2 +21 -0
  100. package/tf_starter/templates/gcp/github/terraform.yml.j2 +133 -0
  101. package/tf_starter/templates/gcp/misc/Makefile.j2 +60 -0
  102. package/tf_starter/templates/gcp/misc/README.md.j2 +426 -0
  103. package/tf_starter/templates/gcp/misc/init.sh.j2 +110 -0
  104. package/tf_starter/templates/gcp/misc/pre-commit-config.yaml.j2 +34 -0
  105. package/tf_starter/templates/gcp/modules/apigateway/main.tf.j2 +67 -0
  106. package/tf_starter/templates/gcp/modules/apigateway/outputs.tf.j2 +18 -0
  107. package/tf_starter/templates/gcp/modules/apigateway/variables.tf.j2 +34 -0
  108. package/tf_starter/templates/gcp/modules/compute/main.tf.j2 +138 -0
  109. package/tf_starter/templates/gcp/modules/compute/outputs.tf.j2 +13 -0
  110. package/tf_starter/templates/gcp/modules/compute/variables.tf.j2 +33 -0
  111. package/tf_starter/templates/gcp/modules/database/main.tf.j2 +62 -0
  112. package/tf_starter/templates/gcp/modules/database/outputs.tf.j2 +13 -0
  113. package/tf_starter/templates/gcp/modules/database/variables.tf.j2 +29 -0
  114. package/tf_starter/templates/gcp/modules/kubernetes/main.tf.j2 +75 -0
  115. package/tf_starter/templates/gcp/modules/kubernetes/outputs.tf.j2 +14 -0
  116. package/tf_starter/templates/gcp/modules/kubernetes/variables.tf.j2 +38 -0
  117. package/tf_starter/templates/gcp/modules/lambda/main.tf.j2 +122 -0
  118. package/tf_starter/templates/gcp/modules/lambda/outputs.tf.j2 +18 -0
  119. package/tf_starter/templates/gcp/modules/lambda/variables.tf.j2 +77 -0
  120. package/tf_starter/templates/gcp/modules/messaging/main.tf.j2 +44 -0
  121. package/tf_starter/templates/gcp/modules/messaging/outputs.tf.j2 +13 -0
  122. package/tf_starter/templates/gcp/modules/messaging/variables.tf.j2 +20 -0
  123. package/tf_starter/templates/gcp/modules/monitoring/main.tf.j2 +44 -0
  124. package/tf_starter/templates/gcp/modules/monitoring/outputs.tf.j2 +9 -0
  125. package/tf_starter/templates/gcp/modules/monitoring/variables.tf.j2 +13 -0
  126. package/tf_starter/templates/gcp/modules/network/main.tf.j2 +103 -0
  127. package/tf_starter/templates/gcp/modules/network/outputs.tf.j2 +21 -0
  128. package/tf_starter/templates/gcp/modules/network/variables.tf.j2 +22 -0
  129. package/tf_starter/templates/gcp/modules/storage/main.tf.j2 +47 -0
  130. package/tf_starter/templates/gcp/modules/storage/outputs.tf.j2 +13 -0
  131. package/tf_starter/templates/gcp/modules/storage/variables.tf.j2 +16 -0
  132. package/tf_starter/templates/gcp/root/backend.tf.j2 +12 -0
  133. package/tf_starter/templates/gcp/root/main.tf.j2 +210 -0
  134. package/tf_starter/templates/gcp/root/outputs.tf.j2 +61 -0
  135. package/tf_starter/templates/gcp/root/providers.tf.j2 +18 -0
  136. package/tf_starter/templates/gcp/root/variables.tf.j2 +140 -0
  137. package/tf_starter/templates/gcp/root/versions.tf.j2 +23 -0
@@ -0,0 +1,300 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # ROOT VARIABLES
3
+ # Project: {{ project_name }}
4
+ # Generated by tf-starter
5
+ # ---------------------------------------------------------------------------------------------------------------------
6
+
7
+ # ----- General -----
8
+
9
+ variable "region" {
10
+ description = "AWS region for resource deployment"
11
+ type = string
12
+ default = "{{ region }}"
13
+
14
+ validation {
15
+ condition = can(regex("^[a-z]{2}-[a-z]+-[0-9]+$", var.region))
16
+ error_message = "Region must be a valid AWS region identifier (e.g., us-east-1)."
17
+ }
18
+ }
19
+
20
+ variable "environment" {
21
+ description = "Deployment environment"
22
+ type = string
23
+ default = "dev"
24
+
25
+ validation {
26
+ condition = contains({{ environments | tf_list }}, var.environment)
27
+ error_message = "Environment must be one of: {{ environments | join(', ') }}."
28
+ }
29
+ }
30
+
31
+ # ----- Network -----
32
+
33
+ variable "vpc_cidr" {
34
+ description = "CIDR block for the VPC"
35
+ type = string
36
+ default = "10.0.0.0/16"
37
+
38
+ validation {
39
+ condition = can(cidrhost(var.vpc_cidr, 0))
40
+ error_message = "Must be a valid CIDR block."
41
+ }
42
+ }
43
+
44
+ variable "public_subnet_cidrs" {
45
+ description = "CIDR blocks for public subnets"
46
+ type = list(string)
47
+ default = ["10.0.1.0/24", "10.0.2.0/24"]
48
+ }
49
+
50
+ variable "private_subnet_cidrs" {
51
+ description = "CIDR blocks for private subnets"
52
+ type = list(string)
53
+ default = ["10.0.10.0/24", "10.0.11.0/24"]
54
+ }
55
+
56
+ variable "availability_zones" {
57
+ description = "Availability zones to use"
58
+ type = list(string)
59
+ default = ["{{ region }}a", "{{ region }}b"]
60
+ }
61
+
62
+ {% if "compute" in services %}
63
+ # ----- Compute -----
64
+
65
+ variable "instance_type" {
66
+ description = "EC2 instance type for compute nodes"
67
+ type = string
68
+ default = "t3.medium"
69
+ }
70
+
71
+ variable "asg_min_size" {
72
+ description = "Minimum number of instances in the ASG"
73
+ type = number
74
+ default = 1
75
+
76
+ validation {
77
+ condition = var.asg_min_size >= 0
78
+ error_message = "Minimum size must be non-negative."
79
+ }
80
+ }
81
+
82
+ variable "asg_max_size" {
83
+ description = "Maximum number of instances in the ASG"
84
+ type = number
85
+ default = 4
86
+ }
87
+
88
+ variable "asg_desired_capacity" {
89
+ description = "Desired number of instances in the ASG"
90
+ type = number
91
+ default = 2
92
+ }
93
+ {% endif %}
94
+
95
+ {% if "lambda" in services %}
96
+ # ----- Lambda -----
97
+
98
+ variable "lambda_function_name" {
99
+ description = "Short name for the Lambda function"
100
+ type = string
101
+ default = "app"
102
+ }
103
+
104
+ variable "lambda_runtime" {
105
+ description = "Lambda runtime identifier"
106
+ type = string
107
+ default = "python3.12"
108
+ }
109
+
110
+ variable "lambda_handler" {
111
+ description = "Lambda function handler"
112
+ type = string
113
+ default = "index.handler"
114
+ }
115
+
116
+ variable "lambda_timeout" {
117
+ description = "Lambda function timeout in seconds"
118
+ type = number
119
+ default = 30
120
+
121
+ validation {
122
+ condition = var.lambda_timeout >= 1 && var.lambda_timeout <= 900
123
+ error_message = "Timeout must be between 1 and 900 seconds."
124
+ }
125
+ }
126
+
127
+ variable "lambda_memory_size" {
128
+ description = "Lambda function memory in MB"
129
+ type = number
130
+ default = 256
131
+
132
+ validation {
133
+ condition = var.lambda_memory_size >= 128 && var.lambda_memory_size <= 10240
134
+ error_message = "Memory must be between 128 and 10240 MB."
135
+ }
136
+ }
137
+
138
+ variable "lambda_environment_variables" {
139
+ description = "Additional environment variables for the Lambda function"
140
+ type = map(string)
141
+ default = {}
142
+ }
143
+
144
+ variable "lambda_deploy_in_vpc" {
145
+ description = "Deploy the Lambda function inside the VPC"
146
+ type = bool
147
+ default = false
148
+ }
149
+ {% endif %}
150
+
151
+ {% if "apigateway" in services %}
152
+ # ----- API Gateway -----
153
+
154
+ variable "apigw_endpoint_type" {
155
+ description = "API Gateway endpoint type"
156
+ type = string
157
+ default = "REGIONAL"
158
+
159
+ validation {
160
+ condition = contains(["REGIONAL", "EDGE", "PRIVATE"], var.apigw_endpoint_type)
161
+ error_message = "Must be REGIONAL, EDGE, or PRIVATE."
162
+ }
163
+ }
164
+
165
+ variable "apigw_authorization_type" {
166
+ description = "Default authorization type for API methods"
167
+ type = string
168
+ default = "NONE"
169
+ }
170
+
171
+ variable "apigw_throttle_burst_limit" {
172
+ description = "API Gateway throttle burst limit"
173
+ type = number
174
+ default = 100
175
+ }
176
+
177
+ variable "apigw_throttle_rate_limit" {
178
+ description = "API Gateway throttle rate limit (req/sec)"
179
+ type = number
180
+ default = 50
181
+ }
182
+
183
+ variable "apigw_enable_cors" {
184
+ description = "Enable CORS support on the API"
185
+ type = bool
186
+ default = true
187
+ }
188
+ {% endif %}
189
+
190
+ {% if "database" in services %}
191
+ # ----- Database -----
192
+
193
+ variable "db_instance_class" {
194
+ description = "RDS instance class"
195
+ type = string
196
+ default = "db.t3.medium"
197
+ }
198
+
199
+ variable "db_allocated_storage" {
200
+ description = "Allocated storage in GB"
201
+ type = number
202
+ default = 20
203
+
204
+ validation {
205
+ condition = var.db_allocated_storage >= 20 && var.db_allocated_storage <= 65536
206
+ error_message = "Allocated storage must be between 20 and 65536 GB."
207
+ }
208
+ }
209
+
210
+ variable "db_name" {
211
+ description = "Name of the database"
212
+ type = string
213
+ default = "{{ project_name | replace('-', '_') }}_db"
214
+ }
215
+
216
+ variable "db_username" {
217
+ description = "Master username for the database"
218
+ type = string
219
+ default = "dbadmin"
220
+ sensitive = true
221
+ }
222
+ {% endif %}
223
+
224
+ {% if "kubernetes" in services %}
225
+ # ----- Kubernetes (EKS) -----
226
+
227
+ variable "eks_cluster_version" {
228
+ description = "Kubernetes version for the EKS cluster"
229
+ type = string
230
+ default = "1.29"
231
+ }
232
+
233
+ variable "eks_node_instance_type" {
234
+ description = "Instance type for EKS worker nodes"
235
+ type = string
236
+ default = "t3.large"
237
+ }
238
+
239
+ variable "eks_node_desired_size" {
240
+ description = "Desired number of EKS worker nodes"
241
+ type = number
242
+ default = 2
243
+ }
244
+
245
+ variable "eks_node_min_size" {
246
+ description = "Minimum number of EKS worker nodes"
247
+ type = number
248
+ default = 1
249
+ }
250
+
251
+ variable "eks_node_max_size" {
252
+ description = "Maximum number of EKS worker nodes"
253
+ type = number
254
+ default = 5
255
+ }
256
+ {% endif %}
257
+
258
+ {% if "monitoring" in services %}
259
+ # ----- Monitoring -----
260
+
261
+ variable "alarm_email" {
262
+ description = "Email address for CloudWatch alarm notifications"
263
+ type = string
264
+ default = ""
265
+
266
+ ### MUST EDIT THIS ###
267
+ # Set to a valid email for alarm notifications
268
+ }
269
+ {% endif %}
270
+
271
+ {% if "messaging" in services %}
272
+ # ----- Messaging (SQS) -----
273
+
274
+ variable "sqs_message_retention" {
275
+ description = "Message retention period in seconds"
276
+ type = number
277
+ default = 345600 # 4 days
278
+
279
+ validation {
280
+ condition = var.sqs_message_retention >= 60 && var.sqs_message_retention <= 1209600
281
+ error_message = "Retention must be between 60 and 1209600 seconds."
282
+ }
283
+ }
284
+
285
+ variable "sqs_visibility_timeout" {
286
+ description = "Visibility timeout in seconds"
287
+ type = number
288
+ default = 30
289
+ }
290
+ {% endif %}
291
+
292
+ {% if "storage" in services %}
293
+ # ----- Storage (S3) -----
294
+
295
+ variable "s3_enable_versioning" {
296
+ description = "Enable S3 bucket versioning"
297
+ type = bool
298
+ default = true
299
+ }
300
+ {% endif %}
@@ -0,0 +1,26 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # TERRAFORM AND PROVIDER VERSION CONSTRAINTS
3
+ # Project: {{ project_name }}
4
+ # Generated by tf-starter
5
+ # ---------------------------------------------------------------------------------------------------------------------
6
+
7
+ terraform {
8
+ required_version = ">= 1.6.0"
9
+
10
+ required_providers {
11
+ aws = {
12
+ source = "hashicorp/aws"
13
+ version = "~> 5.40"
14
+ }
15
+ {% if "kubernetes" in services %}
16
+ kubernetes = {
17
+ source = "hashicorp/kubernetes"
18
+ version = "~> 2.27"
19
+ }
20
+ {% endif %}
21
+ random = {
22
+ source = "hashicorp/random"
23
+ version = "~> 3.6"
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,11 @@
1
+ # REMOTE BACKEND — {{ environment | upper }} (Azure Storage)
2
+
3
+ terraform {
4
+ backend "azurerm" {
5
+ ### MUST EDIT THIS ###
6
+ resource_group_name = "{{ project_name }}-tfstate-rg"
7
+ storage_account_name = "{{ project_name | replace('-', '') }}tfstate"
8
+ container_name = "tfstate"
9
+ key = "{{ project_name }}/{{ environment }}/terraform.tfstate"
10
+ }
11
+ }
@@ -0,0 +1,57 @@
1
+ # ENVIRONMENT: {{ environment | upper }} — Azure
2
+ # Generated by tf-starter
3
+
4
+ module "{{ project_name | replace('-', '_') }}" {
5
+ source = "../../"
6
+
7
+ environment = "{{ environment }}"
8
+ location = "{{ region }}"
9
+
10
+ vnet_address_space = var.vnet_address_space
11
+ public_subnet_cidr = var.public_subnet_cidr
12
+ private_subnet_cidr = var.private_subnet_cidr
13
+
14
+ {% if "compute" in services %}
15
+ {% if environment == "prod" %}
16
+ vm_size = "Standard_D4s_v3"
17
+ vmss_instance_count = 4
18
+ {% else %}
19
+ vm_size = "Standard_B2s"
20
+ vmss_instance_count = 1
21
+ {% endif %}
22
+ {% endif %}
23
+
24
+ {% if "database" in services %}
25
+ {% if environment == "prod" %}
26
+ db_sku_name = "GP_Standard_D4s_v3"
27
+ db_storage_mb = 65536
28
+ {% else %}
29
+ db_sku_name = "B_Standard_B1ms"
30
+ db_storage_mb = 32768
31
+ {% endif %}
32
+ db_name = "{{ project_name | replace('-', '_') }}_{{ environment }}"
33
+ db_admin_login = var.db_admin_login
34
+ {% endif %}
35
+
36
+ {% if "kubernetes" in services %}
37
+ {% if environment == "prod" %}
38
+ aks_node_vm_size = "Standard_D8s_v3"
39
+ aks_node_count = 3
40
+ aks_node_min_count = 2
41
+ aks_node_max_count = 10
42
+ {% else %}
43
+ aks_node_vm_size = "Standard_D4s_v3"
44
+ aks_node_count = 2
45
+ aks_node_min_count = 1
46
+ aks_node_max_count = 5
47
+ {% endif %}
48
+ {% endif %}
49
+
50
+ {% if "monitoring" in services %}
51
+ alert_email = var.alert_email
52
+ {% endif %}
53
+
54
+ {% if "storage" in services %}
55
+ storage_enable_versioning = {{ (environment == "prod") | tf_bool }}
56
+ {% endif %}
57
+ }
@@ -0,0 +1,14 @@
1
+ # ENVIRONMENT TFVARS: {{ environment | upper }} — Azure
2
+ # ### MUST EDIT THIS ###
3
+
4
+ vnet_address_space = ["10.0.0.0/16"]
5
+ public_subnet_cidr = "10.0.1.0/24"
6
+ private_subnet_cidr = "10.0.10.0/24"
7
+
8
+ {% if "database" in services %}
9
+ db_admin_login = "dbadmin"
10
+ {% endif %}
11
+
12
+ {% if "monitoring" in services %}
13
+ alert_email = "alerts@example.com"
14
+ {% endif %}
@@ -0,0 +1,30 @@
1
+ # ENVIRONMENT VARIABLES: {{ environment | upper }} — Azure
2
+
3
+ variable "vnet_address_space" {
4
+ type = list(string)
5
+ default = ["10.0.0.0/16"]
6
+ }
7
+
8
+ variable "public_subnet_cidr" {
9
+ type = string
10
+ default = "10.0.1.0/24"
11
+ }
12
+
13
+ variable "private_subnet_cidr" {
14
+ type = string
15
+ default = "10.0.10.0/24"
16
+ }
17
+
18
+ {% if "database" in services %}
19
+ variable "db_admin_login" {
20
+ type = string
21
+ sensitive = true
22
+ }
23
+ {% endif %}
24
+
25
+ {% if "monitoring" in services %}
26
+ variable "alert_email" {
27
+ type = string
28
+ default = ""
29
+ }
30
+ {% endif %}
@@ -0,0 +1,133 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # GitHub Actions — Terraform CI/CD
3
+ # Project: {{ project_name }}
4
+ # Generated by tf-starter
5
+ # ---------------------------------------------------------------------------------------------------------------------
6
+
7
+ name: "Terraform"
8
+
9
+ on:
10
+ push:
11
+ branches:
12
+ - main
13
+ - develop
14
+ pull_request:
15
+ branches:
16
+ - main
17
+
18
+ permissions:
19
+ contents: read
20
+ pull-requests: write
21
+
22
+ env:
23
+ TF_LOG: INFO
24
+ {% if provider == "aws" %}
25
+ AWS_REGION: {{ region }}
26
+ {% elif provider == "gcp" %}
27
+ GCP_REGION: {{ region }}
28
+ {% elif provider == "azure" %}
29
+ ARM_LOCATION: {{ region }}
30
+ {% endif %}
31
+
32
+ jobs:
33
+ terraform-fmt:
34
+ name: "Terraform Format"
35
+ runs-on: ubuntu-latest
36
+ steps:
37
+ - name: Checkout
38
+ uses: actions/checkout@v4
39
+
40
+ - name: Setup Terraform
41
+ uses: hashicorp/setup-terraform@v3
42
+ with:
43
+ terraform_version: "1.6.0"
44
+
45
+ - name: Terraform Format Check
46
+ run: terraform fmt -check -recursive -diff
47
+
48
+ terraform-validate:
49
+ name: "Terraform Validate"
50
+ runs-on: ubuntu-latest
51
+ needs: terraform-fmt
52
+ strategy:
53
+ matrix:
54
+ environment: {{ environments | tf_list }}
55
+ steps:
56
+ - name: Checkout
57
+ uses: actions/checkout@v4
58
+
59
+ - name: Setup Terraform
60
+ uses: hashicorp/setup-terraform@v3
61
+ with:
62
+ terraform_version: "1.6.0"
63
+
64
+ - name: Terraform Init
65
+ working-directory: environments/${{ '{{' }} matrix.environment {{ '}}' }}
66
+ run: terraform init -backend=false
67
+
68
+ - name: Terraform Validate
69
+ working-directory: environments/${{ '{{' }} matrix.environment {{ '}}' }}
70
+ run: terraform validate
71
+
72
+ terraform-lint:
73
+ name: "TFLint"
74
+ runs-on: ubuntu-latest
75
+ needs: terraform-fmt
76
+ steps:
77
+ - name: Checkout
78
+ uses: actions/checkout@v4
79
+
80
+ - name: Setup TFLint
81
+ uses: terraform-linters/setup-tflint@v4
82
+ with:
83
+ tflint_version: latest
84
+
85
+ - name: Init TFLint
86
+ run: tflint --init
87
+
88
+ - name: Run TFLint
89
+ run: tflint --recursive --format compact
90
+
91
+ terraform-plan:
92
+ name: "Terraform Plan"
93
+ runs-on: ubuntu-latest
94
+ needs: [terraform-validate, terraform-lint]
95
+ if: github.event_name == 'pull_request'
96
+ strategy:
97
+ matrix:
98
+ environment: {{ environments | tf_list }}
99
+ {% if provider == "aws" %}
100
+ env:
101
+ ### MUST EDIT THIS ###
102
+ # Configure AWS credentials via GitHub Secrets
103
+ AWS_ACCESS_KEY_ID: ${{ '{{' }} secrets.AWS_ACCESS_KEY_ID {{ '}}' }}
104
+ AWS_SECRET_ACCESS_KEY: ${{ '{{' }} secrets.AWS_SECRET_ACCESS_KEY {{ '}}' }}
105
+ {% elif provider == "gcp" %}
106
+ env:
107
+ ### MUST EDIT THIS ###
108
+ GOOGLE_CREDENTIALS: ${{ '{{' }} secrets.GCP_CREDENTIALS {{ '}}' }}
109
+ {% elif provider == "azure" %}
110
+ env:
111
+ ### MUST EDIT THIS ###
112
+ ARM_CLIENT_ID: ${{ '{{' }} secrets.ARM_CLIENT_ID {{ '}}' }}
113
+ ARM_CLIENT_SECRET: ${{ '{{' }} secrets.ARM_CLIENT_SECRET {{ '}}' }}
114
+ ARM_SUBSCRIPTION_ID: ${{ '{{' }} secrets.ARM_SUBSCRIPTION_ID {{ '}}' }}
115
+ ARM_TENANT_ID: ${{ '{{' }} secrets.ARM_TENANT_ID {{ '}}' }}
116
+ {% endif %}
117
+ steps:
118
+ - name: Checkout
119
+ uses: actions/checkout@v4
120
+
121
+ - name: Setup Terraform
122
+ uses: hashicorp/setup-terraform@v3
123
+ with:
124
+ terraform_version: "1.6.0"
125
+
126
+ - name: Terraform Init
127
+ working-directory: environments/${{ '{{' }} matrix.environment {{ '}}' }}
128
+ run: terraform init
129
+
130
+ - name: Terraform Plan
131
+ working-directory: environments/${{ '{{' }} matrix.environment {{ '}}' }}
132
+ run: terraform plan -var-file=terraform.tfvars -no-color
133
+ continue-on-error: true
@@ -0,0 +1,60 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # Makefile for {{ project_name }}
3
+ # Provider: {{ provider | upper }}
4
+ # Generated by tf-starter
5
+ # ---------------------------------------------------------------------------------------------------------------------
6
+
7
+ .PHONY: init plan apply destroy validate fmt clean help
8
+
9
+ ENV ?= dev
10
+ TF_DIR = environments/$(ENV)
11
+
12
+ help: ## Show this help
13
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \
14
+ awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'
15
+
16
+ init: ## Initialize Terraform (ENV=dev|staging|prod)
17
+ @echo "Initializing Terraform for environment: $(ENV)"
18
+ cd $(TF_DIR) && terraform init
19
+
20
+ plan: ## Show execution plan (ENV=dev|staging|prod)
21
+ @echo "Planning Terraform for environment: $(ENV)"
22
+ cd $(TF_DIR) && terraform plan -var-file=terraform.tfvars
23
+
24
+ apply: ## Apply infrastructure changes (ENV=dev|staging|prod)
25
+ @echo "Applying Terraform for environment: $(ENV)"
26
+ cd $(TF_DIR) && terraform apply -var-file=terraform.tfvars
27
+
28
+ destroy: ## Destroy infrastructure (ENV=dev|staging|prod)
29
+ @echo "WARNING: Destroying infrastructure for environment: $(ENV)"
30
+ cd $(TF_DIR) && terraform destroy -var-file=terraform.tfvars
31
+
32
+ validate: ## Validate Terraform configuration
33
+ @echo "Validating Terraform configuration..."
34
+ terraform fmt -check -recursive
35
+ @for dir in environments/*/; do \
36
+ echo "Validating $$dir..."; \
37
+ cd $$dir && terraform init -backend=false > /dev/null 2>&1 && terraform validate && cd ../..; \
38
+ done
39
+ @echo "All configurations valid."
40
+
41
+ fmt: ## Format Terraform files
42
+ @echo "Formatting Terraform files..."
43
+ terraform fmt -recursive
44
+ @echo "Done."
45
+
46
+ clean: ## Remove .terraform directories and lock files
47
+ @echo "Cleaning Terraform cache..."
48
+ find . -type d -name ".terraform" -exec rm -rf {} + 2>/dev/null || true
49
+ find . -name ".terraform.lock.hcl" -delete 2>/dev/null || true
50
+ @echo "Done."
51
+
52
+ output: ## Show Terraform outputs (ENV=dev|staging|prod)
53
+ cd $(TF_DIR) && terraform output
54
+
55
+ state-list: ## List resources in state (ENV=dev|staging|prod)
56
+ cd $(TF_DIR) && terraform state list
57
+
58
+ cost: ## Estimate cost using infracost (requires infracost CLI)
59
+ @command -v infracost >/dev/null 2>&1 || { echo "infracost not installed"; exit 1; }
60
+ cd $(TF_DIR) && infracost breakdown --path .