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,426 @@
1
+ # {{ project_name }}
2
+
3
+ > Infrastructure-as-Code project generated by **tf-starter** for **{{ provider | upper }}**
4
+
5
+ ---
6
+
7
+ ## Architecture
8
+
9
+ {% if provider == "aws" %}
10
+ ```
11
+ {% if "kubernetes" in services %}
12
+ Internet
13
+ |
14
+ +---------------+
15
+ | Route 53 |
16
+ +---------------+
17
+ |
18
+ +---------------+
19
+ {% if "compute" in services %}
20
+ | ALB |
21
+ +---------------+
22
+ |
23
+ +------------+------------+
24
+ | |
25
+ +-------+--------+ +----------+-------+
26
+ | EKS Cluster | | Auto Scaling EC2 |
27
+ +-------+--------+ +----------+-------+
28
+ {% else %}
29
+ | ALB |
30
+ +---------------+
31
+ |
32
+ +---------------+
33
+ | EKS Cluster |
34
+ +---------------+
35
+ {% endif %}
36
+ {% elif "compute" in services %}
37
+ Internet
38
+ |
39
+ +---------------+
40
+ | ALB |
41
+ +---------------+
42
+ |
43
+ +---------------+
44
+ | Auto Scaling |
45
+ | EC2 |
46
+ +---------------+
47
+ {% else %}
48
+ Internet
49
+ |
50
+ +---------------+
51
+ | VPC |
52
+ +---------------+
53
+ {% endif %}
54
+ {% if "database" in services %}
55
+ |
56
+ +---------------+
57
+ | RDS PostgreSQL|
58
+ | (Multi-AZ) |
59
+ +---------------+
60
+ {% endif %}
61
+ {% if "messaging" in services %}
62
+ |
63
+ +---------------+
64
+ | SQS Queue |
65
+ +---------------+
66
+ {% endif %}
67
+ {% if "storage" in services %}
68
+ |
69
+ +---------------+
70
+ | S3 Bucket |
71
+ +---------------+
72
+ {% endif %}
73
+ ```
74
+ {% elif provider == "gcp" %}
75
+ ```
76
+ {% if "kubernetes" in services %}
77
+ Internet
78
+ |
79
+ +------------------+
80
+ | Cloud Load Bal. |
81
+ +------------------+
82
+ |
83
+ +------------------+
84
+ | GKE Cluster |
85
+ +------------------+
86
+ {% elif "compute" in services %}
87
+ Internet
88
+ |
89
+ +------------------+
90
+ | Cloud Load Bal. |
91
+ +------------------+
92
+ |
93
+ +------------------+
94
+ | Managed Inst. |
95
+ | Group |
96
+ +------------------+
97
+ {% else %}
98
+ Internet
99
+ |
100
+ +------------------+
101
+ | VPC Network |
102
+ +------------------+
103
+ {% endif %}
104
+ {% if "database" in services %}
105
+ |
106
+ +------------------+
107
+ | Cloud SQL |
108
+ | PostgreSQL |
109
+ +------------------+
110
+ {% endif %}
111
+ {% if "messaging" in services %}
112
+ |
113
+ +------------------+
114
+ | Pub/Sub |
115
+ +------------------+
116
+ {% endif %}
117
+ {% if "storage" in services %}
118
+ |
119
+ +------------------+
120
+ | GCS Bucket |
121
+ +------------------+
122
+ {% endif %}
123
+ ```
124
+ {% elif provider == "azure" %}
125
+ ```
126
+ Internet
127
+ |
128
+ {% if "apigateway" in services %}
129
+ +------------------+
130
+ | API Management |
131
+ +------------------+
132
+ |
133
+ +------------------+
134
+ | Azure Functions |
135
+ +------------------+
136
+ {% elif "kubernetes" in services %}
137
+ +------------------+
138
+ | App Gateway |
139
+ +------------------+
140
+ |
141
+ +------------------+
142
+ | AKS Cluster |
143
+ +------------------+
144
+ {% elif "compute" in services %}
145
+ +------------------+
146
+ | App Gateway |
147
+ +------------------+
148
+ |
149
+ +------------------+
150
+ | VMSS |
151
+ +------------------+
152
+ {% elif "lambda" in services %}
153
+ +------------------+
154
+ | Azure Functions |
155
+ +------------------+
156
+ {% else %}
157
+ +------------------+
158
+ | VNet |
159
+ +------------------+
160
+ {% endif %}
161
+ {% if "database" in services %}
162
+ |
163
+ +------------------+
164
+ | Azure PostgreSQL |
165
+ | Flexible Server |
166
+ +------------------+
167
+ {% endif %}
168
+ {% if "messaging" in services %}
169
+ |
170
+ +------------------+
171
+ | Service Bus |
172
+ +------------------+
173
+ {% endif %}
174
+ {% if "storage" in services %}
175
+ |
176
+ +------------------+
177
+ | Storage Account |
178
+ +------------------+
179
+ {% endif %}
180
+ ```
181
+ {% endif %}
182
+
183
+ ---
184
+
185
+ ## Project Overview
186
+
187
+ This project provisions cloud infrastructure on **{{ provider | upper }}** using Terraform.
188
+ It was generated using the `tf-starter` CLI tool and follows enterprise-grade
189
+ infrastructure-as-code best practices.
190
+
191
+ ### Enabled Services
192
+
193
+ | Service | Status |
194
+ |---------|--------|
195
+ | Network | Enabled (always) |
196
+ {% for svc in services %}
197
+ {% if svc != "network" %}
198
+ | {{ svc | capitalize }} | Enabled |
199
+ {% endif %}
200
+ {% endfor %}
201
+
202
+ ---
203
+
204
+ ## Folder Structure
205
+
206
+ ```
207
+ {{ project_name }}/
208
+ ├── environments/ # Per-environment configurations
209
+ {% for env in environments %}
210
+ │ ├── {{ env }}/
211
+ │ │ ├── main.tf
212
+ │ │ ├── variables.tf
213
+ │ │ ├── terraform.tfvars
214
+ {% if enable_backend %}
215
+ │ │ └── backend.tf
216
+ {% endif %}
217
+ {% endfor %}
218
+ ├── modules/ # Reusable Terraform modules
219
+ {% for svc in services %}
220
+ │ ├── {{ svc }}/
221
+ {% endfor %}
222
+ ├── main.tf # Root module composition
223
+ ├── providers.tf # Provider configuration
224
+ ├── variables.tf # Input variables
225
+ ├── outputs.tf # Output values
226
+ ├── versions.tf # Terraform & provider versions
227
+ {% if enable_backend %}
228
+ ├── backend.tf # Remote state backend
229
+ {% endif %}
230
+ ├── Makefile # Automation targets
231
+ ├── init.sh # Bootstrap script
232
+ └── README.md # This file
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Environments
238
+
239
+ | Environment | Description |
240
+ |-------------|-------------|
241
+ {% for env in environments %}
242
+ {% if env == "prod" %}
243
+ | **{{ env }}** | Production — HA enabled, deletion protection on, extended backups |
244
+ {% elif env == "staging" %}
245
+ | **{{ env }}** | Staging — mirrors production at reduced scale for pre-release testing |
246
+ {% elif env == "dev" %}
247
+ | **{{ env }}** | Development — minimal resources, fast iteration |
248
+ {% else %}
249
+ | **{{ env }}** | Custom environment |
250
+ {% endif %}
251
+ {% endfor %}
252
+
253
+ Each environment has its own `terraform.tfvars` file. Edit these to customize
254
+ resource sizing, networking CIDRs, and service-specific parameters.
255
+
256
+ ---
257
+
258
+ {% if enable_backend %}
259
+ ## Remote Backend
260
+
261
+ This project uses a remote backend for Terraform state:
262
+
263
+ {% if provider == "aws" %}
264
+ - **State storage:** S3 bucket (`{{ project_name }}-terraform-state`)
265
+ - **State locking:** DynamoDB table (`{{ project_name }}-terraform-lock`)
266
+ {% elif provider == "gcp" %}
267
+ - **State storage:** GCS bucket (`{{ project_name }}-terraform-state`)
268
+ {% elif provider == "azure" %}
269
+ - **State storage:** Azure Storage Account
270
+ {% endif %}
271
+
272
+ > **Important:** You must create the backend resources before running `terraform init`.
273
+ > Use the `init.sh` script to bootstrap them.
274
+
275
+ ---
276
+ {% endif %}
277
+
278
+ ## Deployment
279
+
280
+ ### Prerequisites
281
+
282
+ - [Terraform](https://www.terraform.io/downloads) >= 1.6.0
283
+ {% if provider == "aws" %}
284
+ - [AWS CLI](https://aws.amazon.com/cli/) configured with credentials
285
+ {% elif provider == "gcp" %}
286
+ - [Google Cloud SDK](https://cloud.google.com/sdk) with `gcloud auth application-default login`
287
+ {% elif provider == "azure" %}
288
+ - [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/) with `az login`
289
+ {% endif %}
290
+
291
+ ### Quick Start
292
+
293
+ ```bash
294
+ # 1. Navigate to your target environment
295
+ cd environments/dev
296
+
297
+ # 2. Initialize Terraform
298
+ terraform init
299
+
300
+ # 3. Review the execution plan
301
+ terraform plan
302
+
303
+ # 4. Apply the changes
304
+ terraform apply
305
+ ```
306
+
307
+ ### Using the Makefile
308
+
309
+ ```bash
310
+ # Initialize
311
+ make init
312
+
313
+ # Plan changes
314
+ make plan
315
+
316
+ # Apply changes
317
+ make apply
318
+
319
+ # Format code
320
+ make fmt
321
+
322
+ # Validate configuration
323
+ make validate
324
+
325
+ # Destroy infrastructure
326
+ make destroy
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Destroy Instructions
332
+
333
+ ```bash
334
+ # Review what will be destroyed
335
+ terraform plan -destroy
336
+
337
+ # Destroy all resources
338
+ terraform destroy
339
+
340
+ # Or use Makefile
341
+ make destroy
342
+ ```
343
+
344
+ > **Warning:** Destroying production infrastructure is irreversible. Ensure you
345
+ > have backups and have communicated with your team before proceeding.
346
+
347
+ ---
348
+
349
+ ## Security Considerations
350
+
351
+ - All data-at-rest is encrypted
352
+ {% if "database" in services %}
353
+ - Database credentials are managed via Terraform (consider using Vault or Secrets Manager)
354
+ - Database is deployed in private subnets only
355
+ {% endif %}
356
+ {% if "storage" in services %}
357
+ - S3/GCS/Blob public access is blocked by default
358
+ {% endif %}
359
+ - Security groups follow the principle of least privilege
360
+ - All resources are tagged for cost allocation and ownership tracking
361
+ {% if enable_backend %}
362
+ - Terraform state is encrypted at rest
363
+ {% endif %}
364
+
365
+ ---
366
+
367
+ ## Scaling
368
+
369
+ {% if "compute" in services %}
370
+ ### Compute
371
+ Adjust `asg_min_size`, `asg_max_size`, and `asg_desired_capacity` in
372
+ your environment's `terraform.tfvars` to scale horizontally.
373
+ {% endif %}
374
+
375
+ {% if "kubernetes" in services %}
376
+ ### Kubernetes
377
+ Adjust `eks_node_min_size`, `eks_node_max_size`, and `eks_node_desired_size`
378
+ to control the cluster node pool. Consider enabling Cluster Autoscaler.
379
+ {% endif %}
380
+
381
+ {% if "database" in services %}
382
+ ### Database
383
+ - Vertical scaling: change `db_instance_class`
384
+ - Storage auto-scaling is enabled (up to 2x allocated storage)
385
+ - Production uses Multi-AZ for high availability
386
+ {% endif %}
387
+
388
+ ---
389
+
390
+ ## Adding New Modules
391
+
392
+ 1. Create a new directory under `modules/`:
393
+ ```bash
394
+ mkdir -p modules/my-module
395
+ ```
396
+
397
+ 2. Add `main.tf`, `variables.tf`, and `outputs.tf` inside it.
398
+
399
+ 3. Reference it in the root `main.tf`:
400
+ ```hcl
401
+ module "my_module" {
402
+ source = "./modules/my-module"
403
+ # pass variables
404
+ }
405
+ ```
406
+
407
+ 4. Add corresponding variables to `variables.tf` and outputs to `outputs.tf`.
408
+
409
+ ---
410
+
411
+ ## Customizing Variables
412
+
413
+ 1. Open the relevant environment's `terraform.tfvars` file.
414
+ 2. Override any variable defined in `variables.tf`.
415
+ 3. Run `terraform plan` to preview changes.
416
+ 4. Run `terraform apply` to apply.
417
+
418
+ For sensitive values, use environment variables:
419
+ ```bash
420
+ export TF_VAR_db_username="admin"
421
+ terraform plan
422
+ ```
423
+
424
+ ---
425
+
426
+ *Generated by [tf-starter](https://github.com/tf-starter) v1.0.0*
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env bash
2
+ # ---------------------------------------------------------------------------------------------------------------------
3
+ # Bootstrap script for {{ project_name }}
4
+ # Creates remote backend resources (if enabled) and initializes Terraform.
5
+ # Generated by tf-starter
6
+ # ---------------------------------------------------------------------------------------------------------------------
7
+
8
+ set -euo pipefail
9
+
10
+ PROJECT_NAME="{{ project_name }}"
11
+ REGION="{{ region }}"
12
+
13
+ echo "============================================="
14
+ echo " {{ project_name }} — Infrastructure Bootstrap"
15
+ echo "============================================="
16
+ echo ""
17
+
18
+ {% if enable_backend %}
19
+ {% if provider == "aws" %}
20
+ # ----- Create S3 bucket for Terraform state -----
21
+
22
+ BUCKET_NAME="${PROJECT_NAME}-terraform-state"
23
+ TABLE_NAME="${PROJECT_NAME}-terraform-lock"
24
+
25
+ echo "Creating S3 bucket for Terraform state: ${BUCKET_NAME}"
26
+ if aws s3api head-bucket --bucket "${BUCKET_NAME}" 2>/dev/null; then
27
+ echo " Bucket already exists. Skipping."
28
+ else
29
+ aws s3api create-bucket \
30
+ --bucket "${BUCKET_NAME}" \
31
+ --region "${REGION}" \
32
+ $([ "${REGION}" != "us-east-1" ] && echo "--create-bucket-configuration LocationConstraint=${REGION}")
33
+
34
+ aws s3api put-bucket-versioning \
35
+ --bucket "${BUCKET_NAME}" \
36
+ --versioning-configuration Status=Enabled
37
+
38
+ aws s3api put-bucket-encryption \
39
+ --bucket "${BUCKET_NAME}" \
40
+ --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'
41
+
42
+ aws s3api put-public-access-block \
43
+ --bucket "${BUCKET_NAME}" \
44
+ --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
45
+
46
+ echo " Bucket created."
47
+ fi
48
+
49
+ # ----- Create DynamoDB table for state locking -----
50
+
51
+ echo "Creating DynamoDB table for state locking: ${TABLE_NAME}"
52
+ if aws dynamodb describe-table --table-name "${TABLE_NAME}" --region "${REGION}" >/dev/null 2>&1; then
53
+ echo " Table already exists. Skipping."
54
+ else
55
+ aws dynamodb create-table \
56
+ --table-name "${TABLE_NAME}" \
57
+ --attribute-definitions AttributeName=LockID,AttributeType=S \
58
+ --key-schema AttributeName=LockID,KeyType=HASH \
59
+ --billing-mode PAY_PER_REQUEST \
60
+ --region "${REGION}"
61
+
62
+ echo " Table created."
63
+ fi
64
+ {% elif provider == "gcp" %}
65
+ BUCKET_NAME="${PROJECT_NAME}-terraform-state"
66
+
67
+ echo "Creating GCS bucket for Terraform state: ${BUCKET_NAME}"
68
+ if gsutil ls -b "gs://${BUCKET_NAME}" 2>/dev/null; then
69
+ echo " Bucket already exists. Skipping."
70
+ else
71
+ gsutil mb -l "${REGION}" "gs://${BUCKET_NAME}"
72
+ gsutil versioning set on "gs://${BUCKET_NAME}"
73
+ echo " Bucket created."
74
+ fi
75
+ {% elif provider == "azure" %}
76
+ RESOURCE_GROUP="${PROJECT_NAME}-tfstate-rg"
77
+ STORAGE_ACCOUNT=$(echo "${PROJECT_NAME}tfstate" | tr -d '-' | head -c 24)
78
+ CONTAINER_NAME="tfstate"
79
+
80
+ echo "Creating Azure Storage for Terraform state..."
81
+ az group create --name "${RESOURCE_GROUP}" --location "${REGION}" || true
82
+
83
+ az storage account create \
84
+ --resource-group "${RESOURCE_GROUP}" \
85
+ --name "${STORAGE_ACCOUNT}" \
86
+ --sku Standard_LRS \
87
+ --encryption-services blob 2>/dev/null || echo " Storage account already exists."
88
+
89
+ az storage container create \
90
+ --name "${CONTAINER_NAME}" \
91
+ --account-name "${STORAGE_ACCOUNT}" 2>/dev/null || echo " Container already exists."
92
+ {% endif %}
93
+
94
+ echo ""
95
+ {% endif %}
96
+
97
+ # ----- Initialize Terraform -----
98
+
99
+ echo "Initializing Terraform..."
100
+ for env_dir in environments/*/; do
101
+ env_name=$(basename "${env_dir}")
102
+ echo " Initializing environment: ${env_name}"
103
+ (cd "${env_dir}" && terraform init)
104
+ done
105
+
106
+ echo ""
107
+ echo "============================================="
108
+ echo " Bootstrap complete!"
109
+ echo " Run 'make plan ENV=dev' to preview changes."
110
+ echo "============================================="
@@ -0,0 +1,34 @@
1
+ # Pre-commit configuration for {{ project_name }}
2
+ # Install: pip install pre-commit && pre-commit install
3
+ # Generated by tf-starter
4
+
5
+ repos:
6
+ - repo: https://github.com/antonbabenko/pre-commit-terraform
7
+ rev: v1.88.0
8
+ hooks:
9
+ - id: terraform_fmt
10
+ name: Terraform fmt
11
+ description: Rewrites Terraform config to canonical format
12
+
13
+ - id: terraform_validate
14
+ name: Terraform validate
15
+ description: Validates Terraform configuration
16
+ args:
17
+ - --hook-config=--retry-once-with-cleanup=true
18
+
19
+ - id: terraform_tflint
20
+ name: Terraform tflint
21
+ description: Lints Terraform configuration
22
+
23
+ - id: terraform_docs
24
+ name: Terraform docs
25
+ description: Generates documentation from Terraform modules
26
+
27
+ - repo: https://github.com/pre-commit/pre-commit-hooks
28
+ rev: v4.5.0
29
+ hooks:
30
+ - id: trailing-whitespace
31
+ - id: end-of-file-fixer
32
+ - id: check-yaml
33
+ - id: check-merge-conflict
34
+ - id: detect-private-key
@@ -0,0 +1,125 @@
1
+ # ---------------------------------------------------------------------------------------------------------------------
2
+ # API GATEWAY MODULE — Azure API Management
3
+ # Project: {{ project_name }}
4
+ # Generated by tf-starter
5
+ # ---------------------------------------------------------------------------------------------------------------------
6
+
7
+ locals {
8
+ name_prefix = "${var.project_name}-${var.environment}"
9
+ apim_name = "${local.name_prefix}-apim"
10
+ }
11
+
12
+ # ---------------------------------------------------------------------------------------------------------------------
13
+ # API MANAGEMENT INSTANCE
14
+ # ---------------------------------------------------------------------------------------------------------------------
15
+
16
+ resource "azurerm_api_management" "main" {
17
+ name = local.apim_name
18
+ resource_group_name = var.resource_group_name
19
+ location = var.location
20
+ publisher_name = var.publisher_name
21
+ publisher_email = var.publisher_email
22
+ sku_name = var.sku_name
23
+
24
+ identity {
25
+ type = "SystemAssigned"
26
+ }
27
+
28
+ tags = merge(var.tags, {
29
+ Name = local.apim_name
30
+ })
31
+ }
32
+
33
+ # ---------------------------------------------------------------------------------------------------------------------
34
+ # API DEFINITION
35
+ # ---------------------------------------------------------------------------------------------------------------------
36
+
37
+ resource "azurerm_api_management_api" "main" {
38
+ name = "${local.name_prefix}-api"
39
+ resource_group_name = var.resource_group_name
40
+ api_management_name = azurerm_api_management.main.name
41
+ revision = "1"
42
+ display_name = "${var.project_name} API"
43
+ path = "api"
44
+ protocols = ["https"]
45
+
46
+ subscription_required = false
47
+ }
48
+
49
+ # ---------------------------------------------------------------------------------------------------------------------
50
+ # API OPERATION — catch-all proxy to Function App
51
+ # ---------------------------------------------------------------------------------------------------------------------
52
+
53
+ resource "azurerm_api_management_api_operation" "proxy" {
54
+ operation_id = "proxy"
55
+ api_name = azurerm_api_management_api.main.name
56
+ api_management_name = azurerm_api_management.main.name
57
+ resource_group_name = var.resource_group_name
58
+ display_name = "Proxy"
59
+ method = "POST"
60
+ url_template = "/{path}"
61
+
62
+ template_parameter {
63
+ name = "path"
64
+ required = true
65
+ type = "string"
66
+ }
67
+ }
68
+
69
+ # ---------------------------------------------------------------------------------------------------------------------
70
+ # BACKEND — Function App
71
+ # ---------------------------------------------------------------------------------------------------------------------
72
+
73
+ resource "azurerm_api_management_backend" "function" {
74
+ name = "${local.name_prefix}-backend"
75
+ resource_group_name = var.resource_group_name
76
+ api_management_name = azurerm_api_management.main.name
77
+ protocol = "http"
78
+ url = "https://${var.function_app_hostname}/api"
79
+ }
80
+
81
+ # ---------------------------------------------------------------------------------------------------------------------
82
+ # CORS POLICY
83
+ # ---------------------------------------------------------------------------------------------------------------------
84
+
85
+ resource "azurerm_api_management_api_policy" "cors" {
86
+ api_name = azurerm_api_management_api.main.name
87
+ api_management_name = azurerm_api_management.main.name
88
+ resource_group_name = var.resource_group_name
89
+
90
+ xml_content = <<-XML
91
+ <policies>
92
+ <inbound>
93
+ <base />
94
+ <cors allow-credentials="false">
95
+ <allowed-origins>
96
+ <origin>*</origin>
97
+ </allowed-origins>
98
+ <allowed-methods>
99
+ <method>GET</method>
100
+ <method>POST</method>
101
+ <method>PUT</method>
102
+ <method>DELETE</method>
103
+ <method>OPTIONS</method>
104
+ </allowed-methods>
105
+ <allowed-headers>
106
+ <header>*</header>
107
+ </allowed-headers>
108
+ </cors>
109
+ <set-backend-service backend-id="${local.name_prefix}-backend" />
110
+ </inbound>
111
+ <backend>
112
+ <base />
113
+ </backend>
114
+ <outbound>
115
+ <base />
116
+ </outbound>
117
+ <on-error>
118
+ <base />
119
+ </on-error>
120
+ </policies>
121
+ XML
122
+
123
+ ### MUST EDIT THIS ###
124
+ # For production, restrict allowed-origins to your domain.
125
+ }