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
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# ---------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
# ENVIRONMENT: {{ environment | upper }} — GCP
|
|
3
|
+
# Generated by tf-starter
|
|
4
|
+
# ---------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
module "{{ project_name | replace('-', '_') }}" {
|
|
7
|
+
source = "../../"
|
|
8
|
+
|
|
9
|
+
environment = "{{ environment }}"
|
|
10
|
+
region = "{{ region }}"
|
|
11
|
+
project_id = var.project_id
|
|
12
|
+
|
|
13
|
+
{% if "compute" in services %}
|
|
14
|
+
{% if environment == "prod" %}
|
|
15
|
+
machine_type = "e2-standard-4"
|
|
16
|
+
mig_min_replicas = 2
|
|
17
|
+
mig_max_replicas = 8
|
|
18
|
+
mig_target_size = 4
|
|
19
|
+
{% else %}
|
|
20
|
+
machine_type = "e2-medium"
|
|
21
|
+
mig_min_replicas = 1
|
|
22
|
+
mig_max_replicas = 2
|
|
23
|
+
mig_target_size = 1
|
|
24
|
+
{% endif %}
|
|
25
|
+
{% endif %}
|
|
26
|
+
|
|
27
|
+
{% if "database" in services %}
|
|
28
|
+
{% if environment == "prod" %}
|
|
29
|
+
db_tier = "db-custom-4-15360"
|
|
30
|
+
{% else %}
|
|
31
|
+
db_tier = "db-custom-2-7680"
|
|
32
|
+
{% endif %}
|
|
33
|
+
db_name = "{{ project_name | replace('-', '_') }}_{{ environment }}"
|
|
34
|
+
db_user = var.db_user
|
|
35
|
+
{% endif %}
|
|
36
|
+
|
|
37
|
+
{% if "kubernetes" in services %}
|
|
38
|
+
{% if environment == "prod" %}
|
|
39
|
+
gke_node_machine_type = "e2-standard-8"
|
|
40
|
+
gke_node_count = 3
|
|
41
|
+
gke_node_min_count = 2
|
|
42
|
+
gke_node_max_count = 10
|
|
43
|
+
{% else %}
|
|
44
|
+
gke_node_machine_type = "e2-standard-4"
|
|
45
|
+
gke_node_count = 2
|
|
46
|
+
gke_node_min_count = 1
|
|
47
|
+
gke_node_max_count = 5
|
|
48
|
+
{% endif %}
|
|
49
|
+
{% endif %}
|
|
50
|
+
|
|
51
|
+
{% if "monitoring" in services %}
|
|
52
|
+
notification_email = var.notification_email
|
|
53
|
+
{% endif %}
|
|
54
|
+
|
|
55
|
+
{% if "storage" in services %}
|
|
56
|
+
gcs_enable_versioning = {{ (environment == "prod") | tf_bool }}
|
|
57
|
+
{% endif %}
|
|
58
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# ENVIRONMENT TFVARS: {{ environment | upper }} — GCP
|
|
2
|
+
# ### MUST EDIT THIS ###
|
|
3
|
+
|
|
4
|
+
project_id = "your-gcp-project-id"
|
|
5
|
+
|
|
6
|
+
{% if "database" in services %}
|
|
7
|
+
db_user = "dbadmin"
|
|
8
|
+
{% endif %}
|
|
9
|
+
|
|
10
|
+
{% if "monitoring" in services %}
|
|
11
|
+
notification_email = "alerts@example.com"
|
|
12
|
+
{% endif %}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# ENVIRONMENT VARIABLES: {{ environment | upper }} — GCP
|
|
2
|
+
|
|
3
|
+
variable "project_id" {
|
|
4
|
+
description = "GCP project ID"
|
|
5
|
+
type = string
|
|
6
|
+
### MUST EDIT THIS ###
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
{% if "database" in services %}
|
|
10
|
+
variable "db_user" {
|
|
11
|
+
type = string
|
|
12
|
+
sensitive = true
|
|
13
|
+
}
|
|
14
|
+
{% endif %}
|
|
15
|
+
|
|
16
|
+
{% if "monitoring" in services %}
|
|
17
|
+
variable "notification_email" {
|
|
18
|
+
type = string
|
|
19
|
+
default = ""
|
|
20
|
+
}
|
|
21
|
+
{% 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 .
|
|
@@ -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
|
+
Internet
|
|
77
|
+
|
|
|
78
|
+
{% if "apigateway" in services %}
|
|
79
|
+
+------------------+
|
|
80
|
+
| API Gateway |
|
|
81
|
+
+------------------+
|
|
82
|
+
|
|
|
83
|
+
+------------------+
|
|
84
|
+
| Cloud Functions |
|
|
85
|
+
+------------------+
|
|
86
|
+
{% elif "kubernetes" in services %}
|
|
87
|
+
+------------------+
|
|
88
|
+
| Cloud Load Bal. |
|
|
89
|
+
+------------------+
|
|
90
|
+
|
|
|
91
|
+
+------------------+
|
|
92
|
+
| GKE Cluster |
|
|
93
|
+
+------------------+
|
|
94
|
+
{% elif "compute" in services %}
|
|
95
|
+
+------------------+
|
|
96
|
+
| Cloud Load Bal. |
|
|
97
|
+
+------------------+
|
|
98
|
+
|
|
|
99
|
+
+------------------+
|
|
100
|
+
| Managed Inst. |
|
|
101
|
+
| Group |
|
|
102
|
+
+------------------+
|
|
103
|
+
{% elif "lambda" in services %}
|
|
104
|
+
+------------------+
|
|
105
|
+
| Cloud Functions |
|
|
106
|
+
+------------------+
|
|
107
|
+
{% else %}
|
|
108
|
+
+------------------+
|
|
109
|
+
| VPC Network |
|
|
110
|
+
+------------------+
|
|
111
|
+
{% endif %}
|
|
112
|
+
{% if "database" in services %}
|
|
113
|
+
|
|
|
114
|
+
+------------------+
|
|
115
|
+
| Cloud SQL |
|
|
116
|
+
| PostgreSQL |
|
|
117
|
+
+------------------+
|
|
118
|
+
{% endif %}
|
|
119
|
+
{% if "messaging" in services %}
|
|
120
|
+
|
|
|
121
|
+
+------------------+
|
|
122
|
+
| Pub/Sub |
|
|
123
|
+
+------------------+
|
|
124
|
+
{% endif %}
|
|
125
|
+
{% if "storage" in services %}
|
|
126
|
+
|
|
|
127
|
+
+------------------+
|
|
128
|
+
| GCS Bucket |
|
|
129
|
+
+------------------+
|
|
130
|
+
{% endif %}
|
|
131
|
+
```
|
|
132
|
+
{% elif provider == "azure" %}
|
|
133
|
+
```
|
|
134
|
+
{% if "kubernetes" in services %}
|
|
135
|
+
Internet
|
|
136
|
+
|
|
|
137
|
+
+------------------+
|
|
138
|
+
| App Gateway |
|
|
139
|
+
+------------------+
|
|
140
|
+
|
|
|
141
|
+
+------------------+
|
|
142
|
+
| AKS Cluster |
|
|
143
|
+
+------------------+
|
|
144
|
+
{% elif "compute" in services %}
|
|
145
|
+
Internet
|
|
146
|
+
|
|
|
147
|
+
+------------------+
|
|
148
|
+
| App Gateway |
|
|
149
|
+
+------------------+
|
|
150
|
+
|
|
|
151
|
+
+------------------+
|
|
152
|
+
| VMSS |
|
|
153
|
+
+------------------+
|
|
154
|
+
{% else %}
|
|
155
|
+
Internet
|
|
156
|
+
|
|
|
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*
|