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.
- package/LICENSE +21 -0
- package/README.md +421 -0
- package/bin/tf-starter.js +88 -0
- package/package.json +43 -0
- package/scripts/postinstall.js +105 -0
- package/setup.py +32 -0
- package/tf_starter/__init__.py +3 -0
- package/tf_starter/__main__.py +6 -0
- package/tf_starter/cli.py +379 -0
- package/tf_starter/generator.py +171 -0
- package/tf_starter/template_engine.py +80 -0
- package/tf_starter/templates/aws/environments/backend.tf.j2 +16 -0
- package/tf_starter/templates/aws/environments/main.tf.j2 +85 -0
- package/tf_starter/templates/aws/environments/terraform.tfvars.j2 +52 -0
- package/tf_starter/templates/aws/environments/variables.tf.j2 +127 -0
- package/tf_starter/templates/aws/github/terraform.yml.j2 +133 -0
- package/tf_starter/templates/aws/misc/Makefile.j2 +60 -0
- package/tf_starter/templates/aws/misc/README.md.j2 +445 -0
- package/tf_starter/templates/aws/misc/init.sh.j2 +110 -0
- package/tf_starter/templates/aws/misc/pre-commit-config.yaml.j2 +34 -0
- package/tf_starter/templates/aws/modules/apigateway/main.tf.j2 +224 -0
- package/tf_starter/templates/aws/modules/apigateway/outputs.tf.j2 +28 -0
- package/tf_starter/templates/aws/modules/apigateway/variables.tf.j2 +69 -0
- package/tf_starter/templates/aws/modules/compute/main.tf.j2 +245 -0
- package/tf_starter/templates/aws/modules/compute/outputs.tf.j2 +38 -0
- package/tf_starter/templates/aws/modules/compute/variables.tf.j2 +68 -0
- package/tf_starter/templates/aws/modules/database/main.tf.j2 +122 -0
- package/tf_starter/templates/aws/modules/database/outputs.tf.j2 +33 -0
- package/tf_starter/templates/aws/modules/database/variables.tf.j2 +63 -0
- package/tf_starter/templates/aws/modules/kubernetes/main.tf.j2 +167 -0
- package/tf_starter/templates/aws/modules/kubernetes/outputs.tf.j2 +33 -0
- package/tf_starter/templates/aws/modules/kubernetes/variables.tf.j2 +64 -0
- package/tf_starter/templates/aws/modules/lambda/main.tf.j2 +215 -0
- package/tf_starter/templates/aws/modules/lambda/outputs.tf.j2 +38 -0
- package/tf_starter/templates/aws/modules/lambda/variables.tf.j2 +88 -0
- package/tf_starter/templates/aws/modules/messaging/main.tf.j2 +85 -0
- package/tf_starter/templates/aws/modules/messaging/outputs.tf.j2 +28 -0
- package/tf_starter/templates/aws/modules/messaging/variables.tf.j2 +41 -0
- package/tf_starter/templates/aws/modules/monitoring/main.tf.j2 +155 -0
- package/tf_starter/templates/aws/modules/monitoring/outputs.tf.j2 +23 -0
- package/tf_starter/templates/aws/modules/monitoring/variables.tf.j2 +39 -0
- package/tf_starter/templates/aws/modules/network/main.tf.j2 +147 -0
- package/tf_starter/templates/aws/modules/network/outputs.tf.j2 +33 -0
- package/tf_starter/templates/aws/modules/network/variables.tf.j2 +52 -0
- package/tf_starter/templates/aws/modules/storage/main.tf.j2 +88 -0
- package/tf_starter/templates/aws/modules/storage/outputs.tf.j2 +23 -0
- package/tf_starter/templates/aws/modules/storage/variables.tf.j2 +25 -0
- package/tf_starter/templates/aws/root/backend.tf.j2 +19 -0
- package/tf_starter/templates/aws/root/main.tf.j2 +219 -0
- package/tf_starter/templates/aws/root/outputs.tf.j2 +134 -0
- package/tf_starter/templates/aws/root/providers.tf.j2 +24 -0
- package/tf_starter/templates/aws/root/variables.tf.j2 +300 -0
- package/tf_starter/templates/aws/root/versions.tf.j2 +26 -0
- package/tf_starter/templates/azure/environments/backend.tf.j2 +11 -0
- package/tf_starter/templates/azure/environments/main.tf.j2 +57 -0
- package/tf_starter/templates/azure/environments/terraform.tfvars.j2 +14 -0
- package/tf_starter/templates/azure/environments/variables.tf.j2 +30 -0
- package/tf_starter/templates/azure/github/terraform.yml.j2 +133 -0
- package/tf_starter/templates/azure/misc/Makefile.j2 +60 -0
- package/tf_starter/templates/azure/misc/README.md.j2 +426 -0
- package/tf_starter/templates/azure/misc/init.sh.j2 +110 -0
- package/tf_starter/templates/azure/misc/pre-commit-config.yaml.j2 +34 -0
- package/tf_starter/templates/azure/modules/apigateway/main.tf.j2 +125 -0
- package/tf_starter/templates/azure/modules/apigateway/outputs.tf.j2 +18 -0
- package/tf_starter/templates/azure/modules/apigateway/variables.tf.j2 +54 -0
- package/tf_starter/templates/azure/modules/compute/main.tf.j2 +114 -0
- package/tf_starter/templates/azure/modules/compute/outputs.tf.j2 +9 -0
- package/tf_starter/templates/azure/modules/compute/variables.tf.j2 +23 -0
- package/tf_starter/templates/azure/modules/database/main.tf.j2 +56 -0
- package/tf_starter/templates/azure/modules/database/outputs.tf.j2 +13 -0
- package/tf_starter/templates/azure/modules/database/variables.tf.j2 +38 -0
- package/tf_starter/templates/azure/modules/kubernetes/main.tf.j2 +50 -0
- package/tf_starter/templates/azure/modules/kubernetes/outputs.tf.j2 +19 -0
- package/tf_starter/templates/azure/modules/kubernetes/variables.tf.j2 +37 -0
- package/tf_starter/templates/azure/modules/lambda/main.tf.j2 +98 -0
- package/tf_starter/templates/azure/modules/lambda/outputs.tf.j2 +23 -0
- package/tf_starter/templates/azure/modules/lambda/variables.tf.j2 +53 -0
- package/tf_starter/templates/azure/modules/messaging/main.tf.j2 +29 -0
- package/tf_starter/templates/azure/modules/messaging/outputs.tf.j2 +14 -0
- package/tf_starter/templates/azure/modules/messaging/variables.tf.j2 +11 -0
- package/tf_starter/templates/azure/modules/monitoring/main.tf.j2 +31 -0
- package/tf_starter/templates/azure/modules/monitoring/outputs.tf.j2 +9 -0
- package/tf_starter/templates/azure/modules/monitoring/variables.tf.j2 +16 -0
- package/tf_starter/templates/azure/modules/network/main.tf.j2 +89 -0
- package/tf_starter/templates/azure/modules/network/outputs.tf.j2 +25 -0
- package/tf_starter/templates/azure/modules/network/variables.tf.j2 +25 -0
- package/tf_starter/templates/azure/modules/storage/main.tf.j2 +41 -0
- package/tf_starter/templates/azure/modules/storage/outputs.tf.j2 +17 -0
- package/tf_starter/templates/azure/modules/storage/variables.tf.j2 +16 -0
- package/tf_starter/templates/azure/root/backend.tf.j2 +11 -0
- package/tf_starter/templates/azure/root/main.tf.j2 +181 -0
- package/tf_starter/templates/azure/root/outputs.tf.j2 +45 -0
- package/tf_starter/templates/azure/root/providers.tf.j2 +18 -0
- package/tf_starter/templates/azure/root/variables.tf.j2 +114 -0
- package/tf_starter/templates/azure/root/versions.tf.j2 +16 -0
- package/tf_starter/templates/gcp/environments/backend.tf.j2 +9 -0
- package/tf_starter/templates/gcp/environments/main.tf.j2 +58 -0
- package/tf_starter/templates/gcp/environments/terraform.tfvars.j2 +12 -0
- package/tf_starter/templates/gcp/environments/variables.tf.j2 +21 -0
- package/tf_starter/templates/gcp/github/terraform.yml.j2 +133 -0
- package/tf_starter/templates/gcp/misc/Makefile.j2 +60 -0
- package/tf_starter/templates/gcp/misc/README.md.j2 +426 -0
- package/tf_starter/templates/gcp/misc/init.sh.j2 +110 -0
- package/tf_starter/templates/gcp/misc/pre-commit-config.yaml.j2 +34 -0
- package/tf_starter/templates/gcp/modules/apigateway/main.tf.j2 +67 -0
- package/tf_starter/templates/gcp/modules/apigateway/outputs.tf.j2 +18 -0
- package/tf_starter/templates/gcp/modules/apigateway/variables.tf.j2 +34 -0
- package/tf_starter/templates/gcp/modules/compute/main.tf.j2 +138 -0
- package/tf_starter/templates/gcp/modules/compute/outputs.tf.j2 +13 -0
- package/tf_starter/templates/gcp/modules/compute/variables.tf.j2 +33 -0
- package/tf_starter/templates/gcp/modules/database/main.tf.j2 +62 -0
- package/tf_starter/templates/gcp/modules/database/outputs.tf.j2 +13 -0
- package/tf_starter/templates/gcp/modules/database/variables.tf.j2 +29 -0
- package/tf_starter/templates/gcp/modules/kubernetes/main.tf.j2 +75 -0
- package/tf_starter/templates/gcp/modules/kubernetes/outputs.tf.j2 +14 -0
- package/tf_starter/templates/gcp/modules/kubernetes/variables.tf.j2 +38 -0
- package/tf_starter/templates/gcp/modules/lambda/main.tf.j2 +122 -0
- package/tf_starter/templates/gcp/modules/lambda/outputs.tf.j2 +18 -0
- package/tf_starter/templates/gcp/modules/lambda/variables.tf.j2 +77 -0
- package/tf_starter/templates/gcp/modules/messaging/main.tf.j2 +44 -0
- package/tf_starter/templates/gcp/modules/messaging/outputs.tf.j2 +13 -0
- package/tf_starter/templates/gcp/modules/messaging/variables.tf.j2 +20 -0
- package/tf_starter/templates/gcp/modules/monitoring/main.tf.j2 +44 -0
- package/tf_starter/templates/gcp/modules/monitoring/outputs.tf.j2 +9 -0
- package/tf_starter/templates/gcp/modules/monitoring/variables.tf.j2 +13 -0
- package/tf_starter/templates/gcp/modules/network/main.tf.j2 +103 -0
- package/tf_starter/templates/gcp/modules/network/outputs.tf.j2 +21 -0
- package/tf_starter/templates/gcp/modules/network/variables.tf.j2 +22 -0
- package/tf_starter/templates/gcp/modules/storage/main.tf.j2 +47 -0
- package/tf_starter/templates/gcp/modules/storage/outputs.tf.j2 +13 -0
- package/tf_starter/templates/gcp/modules/storage/variables.tf.j2 +16 -0
- package/tf_starter/templates/gcp/root/backend.tf.j2 +12 -0
- package/tf_starter/templates/gcp/root/main.tf.j2 +210 -0
- package/tf_starter/templates/gcp/root/outputs.tf.j2 +61 -0
- package/tf_starter/templates/gcp/root/providers.tf.j2 +18 -0
- package/tf_starter/templates/gcp/root/variables.tf.j2 +140 -0
- package/tf_starter/templates/gcp/root/versions.tf.j2 +23 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tf-starter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# tf-starter
|
|
2
|
+
|
|
3
|
+
**Enterprise-grade Terraform Infrastructure-as-Code project generator.**
|
|
4
|
+
|
|
5
|
+
Generate production-ready Terraform projects for AWS, GCP, or Azure in seconds. `tf-starter` scaffolds a complete, modular IaC project with best practices baked in — multi-environment support, remote state, CI/CD pipelines, and more.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
_ __ _ _
|
|
9
|
+
| | / _| ___| |_ __ _ _ __| |_ ___ _ __
|
|
10
|
+
| __| |_ _____ / __| __/ _` | '__| __/ _ \ '__|
|
|
11
|
+
| |_| _|_____|\__ \ || (_| | | | || __/ |
|
|
12
|
+
\__|_| |___/\__\__,_|_| \__\___|_|
|
|
13
|
+
|
|
14
|
+
Enterprise Terraform Project Generator v1.0.0
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
- [Features](#features)
|
|
22
|
+
- [Supported Providers](#supported-providers)
|
|
23
|
+
- [Available Modules](#available-modules)
|
|
24
|
+
- [Installation](#installation)
|
|
25
|
+
- [Usage](#usage)
|
|
26
|
+
- [Interactive Prompts](#interactive-prompts)
|
|
27
|
+
- [Generated Project Structure](#generated-project-structure)
|
|
28
|
+
- [What Gets Generated](#what-gets-generated)
|
|
29
|
+
- [Module Details](#module-details)
|
|
30
|
+
- [Environment-Aware Configuration](#environment-aware-configuration)
|
|
31
|
+
- [Dependencies & Smart Defaults](#dependencies--smart-defaults)
|
|
32
|
+
- [Requirements](#requirements)
|
|
33
|
+
- [License](#license)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Multi-cloud support** — AWS, GCP, and Azure with provider-specific best practices
|
|
40
|
+
- **Interactive CLI** — Guided prompts for environments, services, region, and backend configuration
|
|
41
|
+
- **Modular architecture** — Pick only the services you need; each generates an isolated Terraform module
|
|
42
|
+
- **9 service modules** — Network, Compute, Lambda, API Gateway, Database, Kubernetes, Monitoring, Messaging, Storage
|
|
43
|
+
- **Multi-environment** — Generate separate configurations for dev, staging, prod, or custom environments
|
|
44
|
+
- **Environment-aware defaults** — Production gets HA, multi-AZ, higher resources; dev gets cost-optimized settings
|
|
45
|
+
- **Remote state backend** — Optional S3+DynamoDB (AWS), GCS (GCP), or Azure Storage backend
|
|
46
|
+
- **CI/CD pipeline** — GitHub Actions workflow for Terraform plan/apply with environment-based triggers
|
|
47
|
+
- **Makefile** — Pre-configured `make init`, `make plan`, `make apply`, `make destroy` commands
|
|
48
|
+
- **Pre-commit hooks** — terraform fmt, validate, tflint, and tfsec checks
|
|
49
|
+
- **Auto-generated README** — Project documentation with architecture diagram tailored to selected services
|
|
50
|
+
- **Dependency enforcement** — Kubernetes auto-enables Compute; API Gateway auto-enables Lambda
|
|
51
|
+
- **Jinja2 template engine** — Dynamic rendering with conditional blocks based on selected services
|
|
52
|
+
- **Dual installation** — Install via pip (Python) or npm (Node.js)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Supported Providers
|
|
57
|
+
|
|
58
|
+
| Provider | Network | Compute | Serverless | Database | Kubernetes | Monitoring | Messaging | Storage |
|
|
59
|
+
|----------|---------|---------|------------|----------|------------|------------|-----------|---------|
|
|
60
|
+
| **AWS** | VPC, Subnets, IGW, NAT | EC2, ALB, ASG | Lambda, API Gateway | RDS PostgreSQL | EKS | CloudWatch, SNS | SQS | S3 |
|
|
61
|
+
| **GCP** | VPC, Subnets, Firewall | GCE, Load Balancer | Cloud Functions, API Gateway | Cloud SQL | GKE | Cloud Monitoring | Pub/Sub | GCS |
|
|
62
|
+
| **Azure** | VNet, Subnets, NSG | VM Scale Sets, LB | Azure Functions, API Management | Azure Database for PostgreSQL | AKS | Azure Monitor | Service Bus | Blob Storage |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Available Modules
|
|
67
|
+
|
|
68
|
+
| Module | Description | Always Included |
|
|
69
|
+
|--------|-------------|:---------------:|
|
|
70
|
+
| **network** | VPC/VNet, subnets (public + private), internet gateway, NAT, route tables | Yes |
|
|
71
|
+
| **compute** | Virtual machines, load balancer, auto-scaling group, launch templates | No |
|
|
72
|
+
| **lambda** | Serverless functions with IAM roles, CloudWatch logs, VPC deployment option | No |
|
|
73
|
+
| **apigateway** | REST API with proxy integration to Lambda, throttling, CORS, access logging | No |
|
|
74
|
+
| **database** | Managed PostgreSQL with encryption, multi-AZ (prod), automated backups | No |
|
|
75
|
+
| **kubernetes** | Managed Kubernetes cluster with node groups, IAM/RBAC, cluster logging | No |
|
|
76
|
+
| **monitoring** | Alarms, dashboards, log groups, notification topics | No |
|
|
77
|
+
| **messaging** | Message queues with dead-letter queues, encryption, access policies | No |
|
|
78
|
+
| **storage** | Object storage with versioning, encryption, lifecycle rules, public access block | No |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Installation
|
|
83
|
+
|
|
84
|
+
### Option 1: pip (Python)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Clone the repository
|
|
88
|
+
git clone https://github.com/your-org/tf-starter.git
|
|
89
|
+
cd tf-starter
|
|
90
|
+
|
|
91
|
+
# Create a virtual environment and install
|
|
92
|
+
python3 -m venv .venv
|
|
93
|
+
source .venv/bin/activate
|
|
94
|
+
pip install -e .
|
|
95
|
+
|
|
96
|
+
# Run
|
|
97
|
+
tf-starter --provider aws --project-name myapp
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Option 2: npm (Node.js)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Clone the repository
|
|
104
|
+
git clone https://github.com/your-org/tf-starter.git
|
|
105
|
+
cd tf-starter
|
|
106
|
+
|
|
107
|
+
# Install (automatically sets up Python venv via postinstall)
|
|
108
|
+
npm install
|
|
109
|
+
|
|
110
|
+
# Run
|
|
111
|
+
npx tf-starter --provider aws --project-name myapp
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Option 3: npm global install
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm install -g tf-starter
|
|
118
|
+
tf-starter --provider aws --project-name myapp
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Usage
|
|
124
|
+
|
|
125
|
+
### Basic Command
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
tf-starter --provider <aws|gcp|azure> --project-name <name> [--output-dir <path>]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Arguments
|
|
132
|
+
|
|
133
|
+
| Argument | Required | Description |
|
|
134
|
+
|----------|:--------:|-------------|
|
|
135
|
+
| `--provider` | Yes | Cloud provider: `aws`, `gcp`, or `azure` |
|
|
136
|
+
| `--project-name` | Yes | Name of the project (alphanumeric, hyphens, underscores) |
|
|
137
|
+
| `--output-dir` | No | Output directory (default: current directory) |
|
|
138
|
+
|
|
139
|
+
### Examples
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Generate an AWS project
|
|
143
|
+
tf-starter --provider aws --project-name my-platform
|
|
144
|
+
|
|
145
|
+
# Generate a GCP project in a specific directory
|
|
146
|
+
tf-starter --provider gcp --project-name gcp-infra --output-dir ./projects
|
|
147
|
+
|
|
148
|
+
# Generate an Azure project
|
|
149
|
+
tf-starter --provider azure --project-name azure-stack
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Interactive Prompts
|
|
155
|
+
|
|
156
|
+
After running the command, `tf-starter` guides you through four interactive prompts:
|
|
157
|
+
|
|
158
|
+
### 1. Environments
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
? Select environments to create:
|
|
162
|
+
[x] dev
|
|
163
|
+
[ ] staging
|
|
164
|
+
[ ] prod
|
|
165
|
+
[ ] custom
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Select one or more environments. Each gets its own `terraform.tfvars` with environment-specific values. Choose "custom" to enter a custom environment name.
|
|
169
|
+
|
|
170
|
+
### 2. Services
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
? Select service categories to enable:
|
|
174
|
+
[x] Compute (EC2, ALB, Auto Scaling)
|
|
175
|
+
[ ] Lambda (Serverless Functions)
|
|
176
|
+
[ ] API Gateway (REST API + Lambda Integration)
|
|
177
|
+
[ ] Database (RDS PostgreSQL)
|
|
178
|
+
[ ] Kubernetes (EKS)
|
|
179
|
+
[ ] Monitoring (CloudWatch, SNS)
|
|
180
|
+
[ ] Messaging (SQS)
|
|
181
|
+
[ ] Storage (S3)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Select the infrastructure modules you need. The **Network** module is always included automatically.
|
|
185
|
+
|
|
186
|
+
### 3. Region
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
? Select AWS region:
|
|
190
|
+
us-east-1
|
|
191
|
+
us-east-2
|
|
192
|
+
us-west-1
|
|
193
|
+
...
|
|
194
|
+
Other (type manually)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Choose from common regions or type a custom one.
|
|
198
|
+
|
|
199
|
+
### 4. Remote Backend
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
? Enable remote backend (recommended for teams)? (Y/n)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Enables provider-specific remote state storage (S3+DynamoDB for AWS, GCS for GCP, Azure Storage for Azure).
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Generated Project Structure
|
|
210
|
+
|
|
211
|
+
After generation, you get a complete, ready-to-use Terraform project:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
my-platform/
|
|
215
|
+
├── main.tf # Root module — wires all service modules together
|
|
216
|
+
├── variables.tf # Root-level variable declarations
|
|
217
|
+
├── outputs.tf # Root-level outputs
|
|
218
|
+
├── providers.tf # Provider configuration
|
|
219
|
+
├── versions.tf # Terraform & provider version constraints
|
|
220
|
+
├── backend.tf # Remote state backend (if enabled)
|
|
221
|
+
├── Makefile # make init / plan / apply / destroy
|
|
222
|
+
├── README.md # Auto-generated docs with architecture diagram
|
|
223
|
+
├── .pre-commit-config.yaml # Pre-commit hooks (fmt, validate, tflint, tfsec)
|
|
224
|
+
├── scripts/
|
|
225
|
+
│ └── init.sh # Backend initialization script
|
|
226
|
+
├── .github/
|
|
227
|
+
│ └── workflows/
|
|
228
|
+
│ └── terraform.yml # CI/CD pipeline (plan on PR, apply on merge)
|
|
229
|
+
├── modules/
|
|
230
|
+
│ ├── network/ # VPC, subnets, gateways, route tables
|
|
231
|
+
│ │ ├── main.tf
|
|
232
|
+
│ │ ├── variables.tf
|
|
233
|
+
│ │ └── outputs.tf
|
|
234
|
+
│ ├── compute/ # EC2, ALB, ASG (if selected)
|
|
235
|
+
│ ├── lambda/ # Lambda functions (if selected)
|
|
236
|
+
│ ├── apigateway/ # API Gateway (if selected)
|
|
237
|
+
│ ├── database/ # RDS PostgreSQL (if selected)
|
|
238
|
+
│ ├── kubernetes/ # EKS cluster (if selected)
|
|
239
|
+
│ ├── monitoring/ # CloudWatch alarms (if selected)
|
|
240
|
+
│ ├── messaging/ # SQS queues (if selected)
|
|
241
|
+
│ └── storage/ # S3 buckets (if selected)
|
|
242
|
+
└── environments/
|
|
243
|
+
├── dev/
|
|
244
|
+
│ ├── main.tf # References root module
|
|
245
|
+
│ ├── variables.tf # Environment variable declarations
|
|
246
|
+
│ ├── terraform.tfvars # Dev-specific values (smaller instances, no HA)
|
|
247
|
+
│ └── backend.tf # Environment-specific backend config
|
|
248
|
+
├── staging/
|
|
249
|
+
│ └── ...
|
|
250
|
+
└── prod/
|
|
251
|
+
└── ... # Prod gets HA, multi-AZ, larger instances
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## What Gets Generated
|
|
257
|
+
|
|
258
|
+
### Root Module (`main.tf`)
|
|
259
|
+
|
|
260
|
+
Wires all selected service modules together with proper dependency references. For example, the compute module receives VPC and subnet IDs from the network module.
|
|
261
|
+
|
|
262
|
+
### Environment Configurations
|
|
263
|
+
|
|
264
|
+
Each environment gets its own directory with `terraform.tfvars` containing environment-appropriate values. This allows you to run `terraform apply` per environment independently.
|
|
265
|
+
|
|
266
|
+
### CI/CD Pipeline (`.github/workflows/terraform.yml`)
|
|
267
|
+
|
|
268
|
+
A GitHub Actions workflow that:
|
|
269
|
+
- Runs `terraform fmt -check` and `terraform validate` on every pull request
|
|
270
|
+
- Runs `terraform plan` on PRs targeting the main branch
|
|
271
|
+
- Runs `terraform apply` on merge to main
|
|
272
|
+
- Supports environment-based deployment strategy
|
|
273
|
+
|
|
274
|
+
### Makefile
|
|
275
|
+
|
|
276
|
+
Pre-configured targets for common operations:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
make init # Initialize Terraform and backend
|
|
280
|
+
make plan # Run terraform plan
|
|
281
|
+
make apply # Apply changes
|
|
282
|
+
make destroy # Destroy all resources
|
|
283
|
+
make fmt # Format Terraform files
|
|
284
|
+
make validate # Validate configuration
|
|
285
|
+
make lint # Run tflint
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Pre-commit Hooks
|
|
289
|
+
|
|
290
|
+
Configured checks that run before every git commit:
|
|
291
|
+
- `terraform fmt` — Consistent formatting
|
|
292
|
+
- `terraform validate` — Configuration validation
|
|
293
|
+
- `tflint` — Terraform linter
|
|
294
|
+
- `tfsec` — Security scanner
|
|
295
|
+
|
|
296
|
+
### Auto-generated README
|
|
297
|
+
|
|
298
|
+
Each generated project includes a README with:
|
|
299
|
+
- Architecture diagram (dynamically generated based on selected services)
|
|
300
|
+
- Quick-start instructions
|
|
301
|
+
- Module documentation
|
|
302
|
+
- Scaling and operational guidance
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Module Details
|
|
307
|
+
|
|
308
|
+
### AWS Modules
|
|
309
|
+
|
|
310
|
+
| Module | Resources Created |
|
|
311
|
+
|--------|-------------------|
|
|
312
|
+
| **network** | VPC, 2 public subnets, 2 private subnets, Internet Gateway, NAT Gateway, route tables, elastic IP |
|
|
313
|
+
| **compute** | Application Load Balancer, security groups, launch template (Amazon Linux 2023, IMDSv2), Auto Scaling Group, scaling policies |
|
|
314
|
+
| **lambda** | IAM execution role, Lambda function, CloudWatch log group, optional VPC deployment, conditional SQS/RDS access policies |
|
|
315
|
+
| **apigateway** | REST API, `{proxy+}` catch-all resource, Lambda proxy integration, deployment, stage with throttling/logging, CORS support |
|
|
316
|
+
| **database** | RDS PostgreSQL 16.2, DB subnet group, security group, multi-AZ (prod), encryption at rest, SSM parameter for password, auto-scaling storage |
|
|
317
|
+
| **kubernetes** | EKS cluster, managed node group, IAM roles (cluster + node), cluster logging, security group |
|
|
318
|
+
| **monitoring** | SNS topic, CloudWatch alarms (CPU, storage, connections — conditional on compute/database), log groups with retention |
|
|
319
|
+
| **messaging** | SQS queue, dead-letter queue, redrive policy, server-side encryption, IAM access policy |
|
|
320
|
+
| **storage** | S3 bucket, versioning, AES-256 encryption, public access block, lifecycle rules (Intelligent Tiering, Glacier archival) |
|
|
321
|
+
|
|
322
|
+
### GCP Modules
|
|
323
|
+
|
|
324
|
+
| Module | Resources Created |
|
|
325
|
+
|--------|-------------------|
|
|
326
|
+
| **network** | VPC, subnets, firewall rules, Cloud NAT, Cloud Router |
|
|
327
|
+
| **compute** | GCE instances, instance groups, load balancer, health checks |
|
|
328
|
+
| **lambda** | Cloud Functions (2nd Gen), service account, GCS source bucket, Cloud Run IAM |
|
|
329
|
+
| **apigateway** | API Gateway, API config (OpenAPI spec), gateway deployment |
|
|
330
|
+
| **database** | Cloud SQL PostgreSQL, private networking, automated backups |
|
|
331
|
+
| **kubernetes** | GKE cluster, node pools, workload identity |
|
|
332
|
+
| **monitoring** | Cloud Monitoring alert policies, notification channels, log sinks |
|
|
333
|
+
| **messaging** | Pub/Sub topics and subscriptions, dead-letter topics |
|
|
334
|
+
| **storage** | GCS buckets, versioning, lifecycle rules, IAM |
|
|
335
|
+
|
|
336
|
+
### Azure Modules
|
|
337
|
+
|
|
338
|
+
| Module | Resources Created |
|
|
339
|
+
|--------|-------------------|
|
|
340
|
+
| **network** | VNet, subnets, NSG, NAT Gateway, public IP |
|
|
341
|
+
| **compute** | VM Scale Sets, load balancer, availability sets |
|
|
342
|
+
| **lambda** | Azure Function App (Linux), App Service Plan, Storage Account, Application Insights, managed identity |
|
|
343
|
+
| **apigateway** | API Management service, API definition, proxy operations, backend configuration, CORS policy |
|
|
344
|
+
| **database** | Azure Database for PostgreSQL Flexible Server, private DNS |
|
|
345
|
+
| **kubernetes** | AKS cluster, node pools, managed identity, Azure CNI |
|
|
346
|
+
| **monitoring** | Azure Monitor, alert rules, action groups, Log Analytics workspace |
|
|
347
|
+
| **messaging** | Service Bus namespace, queues, topics, subscriptions |
|
|
348
|
+
| **storage** | Storage Account, blob containers, lifecycle management |
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Environment-Aware Configuration
|
|
353
|
+
|
|
354
|
+
Generated `terraform.tfvars` files are automatically tuned per environment:
|
|
355
|
+
|
|
356
|
+
| Setting | Dev | Staging | Prod |
|
|
357
|
+
|---------|-----|---------|------|
|
|
358
|
+
| Instance type | `t3.micro` | `t3.small` | `t3.medium` |
|
|
359
|
+
| Min instances | 1 | 1 | 2 |
|
|
360
|
+
| Max instances | 2 | 3 | 6 |
|
|
361
|
+
| Multi-AZ (DB) | No | No | Yes |
|
|
362
|
+
| DB instance class | `db.t3.micro` | `db.t3.small` | `db.r6g.large` |
|
|
363
|
+
| Lambda memory | 128 MB | 256 MB | 512 MB |
|
|
364
|
+
| Lambda timeout | 30s | 60s | 120s |
|
|
365
|
+
| API throttle rate | 100 rps | 500 rps | 2000 rps |
|
|
366
|
+
| Deploy Lambda in VPC | No | No | Yes |
|
|
367
|
+
| Monitoring retention | 7 days | 14 days | 30 days |
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Dependencies & Smart Defaults
|
|
372
|
+
|
|
373
|
+
`tf-starter` enforces module dependencies automatically:
|
|
374
|
+
|
|
375
|
+
- **Kubernetes** requires **Compute** — EKS needs VPC networking and node instances. If you select Kubernetes without Compute, Compute is auto-enabled.
|
|
376
|
+
- **API Gateway** requires **Lambda** — The API Gateway module is configured as a Lambda proxy integration. Selecting API Gateway without Lambda auto-enables Lambda.
|
|
377
|
+
- **Network** is always included — All modules depend on VPC/subnet infrastructure.
|
|
378
|
+
|
|
379
|
+
Conditional cross-module integrations:
|
|
380
|
+
- **Lambda** automatically gets IAM policies for **SQS** access if Messaging is selected
|
|
381
|
+
- **Lambda** automatically gets IAM policies for **RDS** access if Database is selected
|
|
382
|
+
- **Monitoring** generates alarms for **Compute** metrics (CPU) and **Database** metrics (storage, connections) only when those modules are selected
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Requirements
|
|
387
|
+
|
|
388
|
+
- **Python** 3.9 or higher
|
|
389
|
+
- **Node.js** 16+ (only if installing via npm)
|
|
390
|
+
- **Terraform** 1.0+ (to use the generated projects)
|
|
391
|
+
|
|
392
|
+
### Optional (for generated projects)
|
|
393
|
+
|
|
394
|
+
- [pre-commit](https://pre-commit.com/) — For pre-commit hooks
|
|
395
|
+
- [tflint](https://github.com/terraform-linters/tflint) — Terraform linter
|
|
396
|
+
- [tfsec](https://github.com/aquasecurity/tfsec) — Security scanner
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Quick Start
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# 1. Install
|
|
404
|
+
git clone https://github.com/your-org/tf-starter.git && cd tf-starter
|
|
405
|
+
npm install
|
|
406
|
+
|
|
407
|
+
# 2. Generate a project
|
|
408
|
+
npx tf-starter --provider aws --project-name my-platform
|
|
409
|
+
|
|
410
|
+
# 3. Use the generated project
|
|
411
|
+
cd my-platform
|
|
412
|
+
make init
|
|
413
|
+
make plan
|
|
414
|
+
make apply
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## License
|
|
420
|
+
|
|
421
|
+
MIT
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* tf-starter — Enterprise Terraform IaC Project Generator
|
|
5
|
+
*
|
|
6
|
+
* Thin Node.js wrapper that delegates to the Python CLI.
|
|
7
|
+
* The Python venv is created automatically during `npm install` (postinstall).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { spawn } = require("child_process");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
|
|
14
|
+
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
15
|
+
const VENV_DIR = path.join(PKG_ROOT, ".venv");
|
|
16
|
+
|
|
17
|
+
// Resolve the Python binary inside the managed venv
|
|
18
|
+
function getVenvPython() {
|
|
19
|
+
const isWin = process.platform === "win32";
|
|
20
|
+
const bin = isWin
|
|
21
|
+
? path.join(VENV_DIR, "Scripts", "python.exe")
|
|
22
|
+
: path.join(VENV_DIR, "bin", "python3");
|
|
23
|
+
return fs.existsSync(bin) ? bin : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Fallback: try system python
|
|
27
|
+
function getSystemPython() {
|
|
28
|
+
const candidates = process.platform === "win32"
|
|
29
|
+
? ["python", "python3"]
|
|
30
|
+
: ["python3", "python"];
|
|
31
|
+
|
|
32
|
+
for (const cmd of candidates) {
|
|
33
|
+
try {
|
|
34
|
+
require("child_process").execSync(`${cmd} --version`, { stdio: "ignore" });
|
|
35
|
+
return cmd;
|
|
36
|
+
} catch {
|
|
37
|
+
// not found, try next
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function main() {
|
|
44
|
+
let pythonBin = getVenvPython();
|
|
45
|
+
|
|
46
|
+
if (!pythonBin) {
|
|
47
|
+
// Venv not set up — try system python with the module directly
|
|
48
|
+
pythonBin = getSystemPython();
|
|
49
|
+
if (!pythonBin) {
|
|
50
|
+
console.error(
|
|
51
|
+
"Error: Python 3.9+ is required but was not found.\n" +
|
|
52
|
+
"Install Python from https://www.python.org/downloads/ and try again.\n" +
|
|
53
|
+
"Or run: npm run postinstall"
|
|
54
|
+
);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.error(
|
|
59
|
+
"Warning: tf-starter venv not found. Run `npm run postinstall` to set it up.\n" +
|
|
60
|
+
`Falling back to system Python: ${pythonBin}\n`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Forward all CLI arguments to the Python entry point
|
|
65
|
+
const args = ["-m", "tf_starter.cli", ...process.argv.slice(2)];
|
|
66
|
+
|
|
67
|
+
const child = spawn(pythonBin, args, {
|
|
68
|
+
cwd: PKG_ROOT,
|
|
69
|
+
stdio: "inherit",
|
|
70
|
+
env: {
|
|
71
|
+
...process.env,
|
|
72
|
+
PYTHONPATH: PKG_ROOT,
|
|
73
|
+
// Ensure the venv's site-packages are on the path
|
|
74
|
+
VIRTUAL_ENV: VENV_DIR,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
child.on("error", (err) => {
|
|
79
|
+
console.error(`Failed to start Python process: ${err.message}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
child.on("close", (code) => {
|
|
84
|
+
process.exit(code ?? 0);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tf-starter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Enterprise-grade Terraform Infrastructure-as-Code project generator",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"terraform",
|
|
7
|
+
"infrastructure-as-code",
|
|
8
|
+
"iac",
|
|
9
|
+
"aws",
|
|
10
|
+
"gcp",
|
|
11
|
+
"azure",
|
|
12
|
+
"devops",
|
|
13
|
+
"scaffolding",
|
|
14
|
+
"generator"
|
|
15
|
+
],
|
|
16
|
+
"author": "DevOps Team",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"bin": {
|
|
19
|
+
"tf-starter": "./bin/tf-starter.js"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"postinstall": "node scripts/postinstall.js",
|
|
23
|
+
"test": "node bin/tf-starter.js --help"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"bin/",
|
|
27
|
+
"scripts/",
|
|
28
|
+
"tf_starter/",
|
|
29
|
+
"setup.py"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=16.0.0"
|
|
33
|
+
},
|
|
34
|
+
"os": [
|
|
35
|
+
"darwin",
|
|
36
|
+
"linux",
|
|
37
|
+
"win32"
|
|
38
|
+
],
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/your-org/tf-starter"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* postinstall — creates a Python venv and installs tf-starter dependencies.
|
|
5
|
+
*
|
|
6
|
+
* Runs automatically after `npm install`.
|
|
7
|
+
* Can also be triggered manually: `node scripts/postinstall.js`
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { execSync } = require("child_process");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
|
|
14
|
+
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
15
|
+
const VENV_DIR = path.join(PKG_ROOT, ".venv");
|
|
16
|
+
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Helpers
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
function findPython() {
|
|
22
|
+
const candidates = process.platform === "win32"
|
|
23
|
+
? ["python", "python3"]
|
|
24
|
+
: ["python3", "python"];
|
|
25
|
+
|
|
26
|
+
for (const cmd of candidates) {
|
|
27
|
+
try {
|
|
28
|
+
const version = execSync(`${cmd} --version`, { encoding: "utf-8" }).trim();
|
|
29
|
+
// Ensure it's Python 3.9+
|
|
30
|
+
const match = version.match(/Python (\d+)\.(\d+)/);
|
|
31
|
+
if (match) {
|
|
32
|
+
const major = parseInt(match[1], 10);
|
|
33
|
+
const minor = parseInt(match[2], 10);
|
|
34
|
+
if (major >= 3 && minor >= 9) {
|
|
35
|
+
return cmd;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} catch {
|
|
39
|
+
// not found
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function run(cmd, opts = {}) {
|
|
46
|
+
console.log(` $ ${cmd}`);
|
|
47
|
+
execSync(cmd, { stdio: "inherit", cwd: PKG_ROOT, ...opts });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Main
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
function main() {
|
|
55
|
+
console.log("\n tf-starter postinstall — setting up Python environment\n");
|
|
56
|
+
|
|
57
|
+
// 1. Find Python
|
|
58
|
+
const python = findPython();
|
|
59
|
+
if (!python) {
|
|
60
|
+
console.warn(
|
|
61
|
+
" ⚠ Python 3.9+ not found. tf-starter requires Python.\n" +
|
|
62
|
+
" Install Python from https://www.python.org/downloads/\n" +
|
|
63
|
+
" Then run: npm run postinstall\n"
|
|
64
|
+
);
|
|
65
|
+
// Don't fail the npm install — user may install Python later
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const version = execSync(`${python} --version`, { encoding: "utf-8" }).trim();
|
|
70
|
+
console.log(` ✔ Found ${version}\n`);
|
|
71
|
+
|
|
72
|
+
// 2. Create venv if it doesn't exist
|
|
73
|
+
if (!fs.existsSync(VENV_DIR)) {
|
|
74
|
+
console.log(" Creating Python virtual environment...");
|
|
75
|
+
run(`${python} -m venv "${VENV_DIR}"`);
|
|
76
|
+
console.log(" ✔ Virtual environment created\n");
|
|
77
|
+
} else {
|
|
78
|
+
console.log(" ✔ Virtual environment already exists\n");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 3. Determine pip path
|
|
82
|
+
const isWin = process.platform === "win32";
|
|
83
|
+
const pip = isWin
|
|
84
|
+
? path.join(VENV_DIR, "Scripts", "pip.exe")
|
|
85
|
+
: path.join(VENV_DIR, "bin", "pip3");
|
|
86
|
+
|
|
87
|
+
// 4. Upgrade pip
|
|
88
|
+
console.log(" Upgrading pip...");
|
|
89
|
+
run(`"${pip}" install --upgrade pip --quiet`);
|
|
90
|
+
|
|
91
|
+
// 5. Install the package in editable mode
|
|
92
|
+
console.log("\n Installing tf-starter and dependencies...");
|
|
93
|
+
run(`"${pip}" install -e "${PKG_ROOT}" --quiet`);
|
|
94
|
+
|
|
95
|
+
console.log("\n ✔ tf-starter installed successfully!");
|
|
96
|
+
console.log(" Usage: tf-starter --provider aws --project-name myapp\n");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
main();
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.error(`\n ⚠ postinstall failed: ${err.message}`);
|
|
103
|
+
console.error(" You can retry with: npm run postinstall\n");
|
|
104
|
+
// Don't fail npm install
|
|
105
|
+
}
|