Skip to content

Commit 5750338

Browse files
committed
split infra and code base
1 parent 4b57119 commit 5750338

50 files changed

Lines changed: 235 additions & 3068 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/GITHUB_ACTIONS_CICD.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# GitHub Actions CI/CD Guide
22

3-
Reference for CI validation and deployment workflows in this repository.
3+
Reference for CI validation and app deployment workflows in this repository.
44

55
## Workflows
66

@@ -9,6 +9,8 @@ Reference for CI validation and deployment workflows in this repository.
99
- `release.yml` — semantic release and production deploy flow
1010
- `_smoke-test.yml` — reusable post-deploy health check
1111

12+
Terraform source of truth now lives in sibling repository `mypythonproject1-infra`.
13+
1214
## `ci.yml`
1315

1416
Triggers:
@@ -24,7 +26,7 @@ Responsibilities:
2426
- Frontend lint + type-check + build
2527
- Trivy + GitGuardian scan
2628
- Snyk dependency audit
27-
- Terraform fmt/validate/plan (no apply)
29+
- Terraform fmt/validate/plan (no apply, executed against checked-out `mypythonproject1-infra`)
2830
- Final `quality-gate` status
2931

3032
## `staging.yml`
@@ -37,7 +39,7 @@ Triggers:
3739
Responsibilities:
3840

3941
- Build/push backend and frontend images to ECR
40-
- Apply staging Terraform
42+
- Apply staging Terraform from checked-out `mypythonproject1-infra`
4143
- Force ECS rolling deploy for both services
4244
- Run reusable smoke test against `vars.APP_URL`
4345

@@ -56,7 +58,7 @@ Two flows:
5658
2. Production deploy flow
5759
- Trigger: tag push `v*`
5860
- Builds/pushes images to ECR
59-
- Runs Terraform apply for production
61+
- Runs Terraform apply for production from checked-out `mypythonproject1-infra`
6062
- Forces ECS deploy
6163
- Runs smoke test against `vars.APP_URL`
6264

@@ -71,7 +73,6 @@ Config model:
7173
- `DATABASE_USER`
7274
- `DATABASE_PASSWORD`
7375
- `DATABASE_NAME`
74-
- `DATABASE_PORT`
7576
- `AWS_ROLE_TO_ASSUME`
7677
- `GITGUARDIAN_API_KEY`
7778
- `SNYK_TOKEN`
@@ -112,3 +113,4 @@ Infrastructure init now uses `use_lockfile=true` for backend locking.
112113
- `.github/workflows/staging.yml`
113114
- `.github/workflows/release.yml`
114115
- `.github/workflows/_smoke-test.yml`
116+
- `../mypythonproject1-infra/.github/workflows/terraform-infra.yml`

.github/actions/terraform/apply/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ inputs:
1717
working-directory:
1818
description: "Terraform working directory"
1919
required: false
20-
default: "./infra"
20+
default: "./mypythonproject1-infra"
2121
terraform-version:
2222
description: "Terraform version to install"
2323
required: false

.github/actions/terraform/plan/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ inputs:
1616
working-directory:
1717
description: "Terraform working directory"
1818
required: false
19-
default: "./infra"
19+
default: "./mypythonproject1-infra"
2020
terraform-version:
2121
description: "Terraform version"
2222
required: false

.github/actions/terraform/validate/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ inputs:
1515
working-directory:
1616
description: "Terraform working directory"
1717
required: false
18-
default: "./infra"
18+
default: "./mypythonproject1-infra"
1919
terraform-version:
2020
description: "Terraform version"
2121
required: false

.github/dependabot.yml

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ version: 2
1010
# Ecosystem Coverage:
1111
# ✓ Python (Poetry) - /backend
1212
# ✓ Docker (Base images) - /backend, /frontend
13-
# ✓ Terraform (Providers/Modules) - /infra
13+
# ✓ Terraform (Providers/Modules) - moved to infra repository
1414
# ✓ GitHub Actions (Workflow versions) - /
1515
#
1616
# CI Integration:
@@ -130,47 +130,7 @@ updates:
130130
prefix: "build(docker):"
131131
include: "scope"
132132

133-
# ============================================================================
134-
# TERRAFORM: Infrastructure as Code
135-
# ============================================================================
136-
# Manages AWS provider versions and Terraform modules
137-
#
138-
# Strategy:
139-
# - Weekly updates (Tuesday 04:00 UTC)
140-
# - Max 3 open PRs (moderate: requires infrastructure review)
141-
# - All versions allowed (Terraform handles most upgrades)
142-
# - Security-focused: Always on latest provider versions
143-
#
144-
# Why Terraform Updates?
145-
# - AWS provider includes new resources and bug fixes
146-
# - Terraform maintains compatibility across major versions
147-
# - Infrastructure tests validate changes via CI
148-
# - ECS Fargate deployment orchestrated through Terraform
149-
#
150-
# NOTE: Do NOT modify Terraform code directly
151-
# - Dependabot only updates provider/module versions
152-
# - Resource configurations remain unchanged
153-
# - CI validates all infrastructure changes
154-
# ============================================================================
155-
- package-ecosystem: "terraform"
156-
directory: "/infra"
157-
schedule:
158-
interval: "weekly"
159-
day: "tuesday"
160-
time: "04:00"
161-
open-pull-requests-limit: 3
162-
labels:
163-
- "infra"
164-
- "dependencies"
165-
- "terraform"
166-
pull-request-branch-name:
167-
separator: "/"
168-
commit-message:
169-
prefix: "build(terraform):"
170-
include: "scope"
171-
# Allow major version updates for terraform to ensure latest provider support
172-
allow:
173-
- dependency-type: "all"
133+
# Terraform dependency updates are managed in mypythonproject1-infra.
174134

175135
# ============================================================================
176136
# GITHUB ACTIONS: Workflow Versions

.github/workflows/ci.yml

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ jobs:
8686
outputs:
8787
backend: ${{ steps.filter.outputs.backend }}
8888
frontend: ${{ steps.filter.outputs.frontend }}
89-
infra: ${{ steps.filter.outputs.infra }}
9089
ci: ${{ steps.filter.outputs.ci }}
9190
steps:
9291
- uses: actions/checkout@v4
@@ -99,8 +98,6 @@ jobs:
9998
- 'backend/**'
10099
frontend:
101100
- 'frontend/**'
102-
infra:
103-
- 'infra/**'
104101
ci:
105102
- '.github/**'
106103
- 'package.json'
@@ -346,7 +343,7 @@ jobs:
346343
timeout-minutes: 15
347344
needs: [changes]
348345
if: |
349-
(needs.changes.outputs.infra == 'true' || needs.changes.outputs.ci == 'true') &&
346+
needs.changes.outputs.ci == 'true' &&
350347
github.event_name == 'pull_request'
351348
strategy:
352349
matrix:
@@ -360,6 +357,12 @@ jobs:
360357
steps:
361358
- uses: actions/checkout@v4
362359

360+
- name: Checkout infra repository
361+
uses: actions/checkout@v4
362+
with:
363+
repository: ${{ github.repository_owner }}/mypythonproject1-infra
364+
path: mypythonproject1-infra
365+
363366
- name: Load CI environment
364367
run: |
365368
grep -v '^\s*#' config/.env.test | grep -v '^\s*$' >> $GITHUB_ENV
@@ -375,20 +378,20 @@ jobs:
375378
aws-region: ${{ env.AWS_REGION }}
376379

377380
- name: Terraform fmt check
378-
working-directory: infra
381+
working-directory: mypythonproject1-infra
379382
run: terraform fmt -check -recursive
380383

381384
- name: Terraform init (no remote state — validation only)
382-
working-directory: infra
385+
working-directory: mypythonproject1-infra
383386
run: terraform init -backend=false
384387

385388
- name: Terraform validate
386-
working-directory: infra
389+
working-directory: mypythonproject1-infra
387390
run: terraform validate
388391

389392
- name: Terraform plan
390393
id: plan
391-
working-directory: infra
394+
working-directory: mypythonproject1-infra
392395
env:
393396
TF_VAR_environment: ${{ matrix.environment }}
394397
TF_VAR_aws_region: ${{ env.AWS_REGION }}
@@ -402,7 +405,7 @@ jobs:
402405
with:
403406
script: |
404407
const fs = require('fs');
405-
const plan = fs.readFileSync('infra/plan-output.txt', 'utf8').substring(0, 65000);
408+
const plan = fs.readFileSync('mypythonproject1-infra/plan-output.txt', 'utf8').substring(0, 65000);
406409
github.rest.issues.createComment({
407410
issue_number: context.issue.number,
408411
owner: context.repo.owner, repo: context.repo.repo,
@@ -445,7 +448,7 @@ jobs:
445448
# Commitlint fails only on PRs (skipped on push)
446449
[[ "$CL" == "failure" ]] && { echo "❌ Commitlint failed"; exit 1; }
447450
448-
# Terraform plan failure blocks PRs when infra changed
451+
# Terraform plan failure blocks PRs when terraform-plan runs
449452
[[ "$TF" == "failure" ]] && { echo "❌ Terraform plan failed"; exit 1; }
450453
451454
echo "✅ All gates passed"

.github/workflows/release.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ jobs:
9595
with:
9696
ref: ${{ github.ref }}
9797

98+
- name: Checkout infra repository
99+
uses: actions/checkout@v4
100+
with:
101+
repository: ${{ github.repository_owner }}/mypythonproject1-infra
102+
path: mypythonproject1-infra
103+
98104
- name: Resolve version tag
99105
id: ver
100106
run: |
@@ -167,7 +173,7 @@ jobs:
167173
- name: Terraform apply
168174
uses: ./.github/actions/terraform/apply
169175
with:
170-
working-directory: ./infra
176+
working-directory: ./mypythonproject1-infra
171177
terraform-version: ${{ secrets.TF_VERSION }}
172178
environment: production
173179
aws-region: ${{ secrets.AWS_REGION }}
@@ -190,6 +196,12 @@ jobs:
190196
steps:
191197
- uses: actions/checkout@v4
192198

199+
- name: Checkout infra repository
200+
uses: actions/checkout@v4
201+
with:
202+
repository: ${{ github.repository_owner }}/mypythonproject1-infra
203+
path: mypythonproject1-infra
204+
193205
- name: Authenticate with AWS
194206
uses: ./.github/actions/aws-auth
195207
with:
@@ -198,7 +210,7 @@ jobs:
198210

199211
- name: Force new ECS deployment
200212
run: |
201-
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' infra/envs/prod.tfvars)
213+
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' mypythonproject1-infra/envs/prod.tfvars)
202214
CLUSTER_NAME="${PROJECT_NAME}-cluster"
203215
if [[ "${{ matrix.service }}" == "backend" ]]; then
204216
SERVICE_NAME="${PROJECT_NAME}-service"
@@ -215,7 +227,7 @@ jobs:
215227
- name: Wait for service stability
216228
timeout-minutes: 15
217229
run: |
218-
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' infra/envs/prod.tfvars)
230+
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' mypythonproject1-infra/envs/prod.tfvars)
219231
CLUSTER_NAME="${PROJECT_NAME}-cluster"
220232
if [[ "${{ matrix.service }}" == "backend" ]]; then
221233
SERVICE_NAME="${PROJECT_NAME}-service"

.github/workflows/staging.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ jobs:
100100
steps:
101101
- uses: actions/checkout@v4
102102

103+
- name: Checkout infra repository
104+
uses: actions/checkout@v4
105+
with:
106+
repository: ${{ github.repository_owner }}/mypythonproject1-infra
107+
path: mypythonproject1-infra
108+
103109
- name: Load staging environment
104110
run: grep -v '^\s*#' config/.env.staging | grep -v '^\s*$' >> "$GITHUB_ENV"
105111

@@ -119,7 +125,7 @@ jobs:
119125
- name: Terraform apply
120126
uses: ./.github/actions/terraform/apply
121127
with:
122-
working-directory: ./infra
128+
working-directory: ./mypythonproject1-infra
123129
terraform-version: ${{ env.TF_VERSION }}
124130
environment: staging
125131
aws-region: ${{ env.AWS_REGION }}
@@ -141,6 +147,12 @@ jobs:
141147
steps:
142148
- uses: actions/checkout@v4
143149

150+
- name: Checkout infra repository
151+
uses: actions/checkout@v4
152+
with:
153+
repository: ${{ github.repository_owner }}/mypythonproject1-infra
154+
path: mypythonproject1-infra
155+
144156
- name: Load staging environment
145157
run: grep -v '^\s*#' config/.env.staging | grep -v '^\s*$' >> "$GITHUB_ENV"
146158

@@ -152,7 +164,7 @@ jobs:
152164

153165
- name: Force new ECS deployment
154166
run: |
155-
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' infra/envs/staging.tfvars)
167+
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' mypythonproject1-infra/envs/staging.tfvars)
156168
CLUSTER_NAME="${PROJECT_NAME}-cluster"
157169
if [[ "${{ matrix.service }}" == "backend" ]]; then
158170
SERVICE_NAME="${PROJECT_NAME}-service"
@@ -169,7 +181,7 @@ jobs:
169181
- name: Wait for service stability
170182
timeout-minutes: 10
171183
run: |
172-
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' infra/envs/staging.tfvars)
184+
PROJECT_NAME=$(awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$2); print $2; exit}' mypythonproject1-infra/envs/staging.tfvars)
173185
CLUSTER_NAME="${PROJECT_NAME}-cluster"
174186
if [[ "${{ matrix.service }}" == "backend" ]]; then
175187
SERVICE_NAME="${PROJECT_NAME}-service"

Makefile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@ NC := \033[0m # No Color
3636
# ============================================================================
3737

3838
ENV_FILE := deploy/.env
39-
DEV_TFVARS_FILE := infra/envs/dev.tfvars
39+
INFRA_ROOT ?= ../mypythonproject1-infra
40+
DEV_TFVARS_FILE := $(INFRA_ROOT)/envs/dev.tfvars
4041

4142
-include $(ENV_FILE)
4243

4344
# Prefer tfvars as source of truth for infra variables.
4445
TFVARS_ENV := $(shell awk -F'=' '/^environment[[:space:]]*=/{gsub(/["[:space:]]/,"",$$2); print $$2; exit}' $(DEV_TFVARS_FILE) 2>/dev/null)
4546
ENV ?= $(or $(TFVARS_ENV),dev)
46-
TFVARS_FILE = infra/envs/$(ENV).tfvars
47+
TFVARS_FILE = $(INFRA_ROOT)/envs/$(ENV).tfvars
4748

4849
TFVARS_PROJECT_NAME := $(shell awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$$2); print $$2; exit}' $(TFVARS_FILE) 2>/dev/null || awk -F'=' '/^project_name[[:space:]]*=/{gsub(/["[:space:]]/,"",$$2); print $$2; exit}' $(DEV_TFVARS_FILE) 2>/dev/null)
4950
TFVARS_AWS_REGION := $(shell awk -F'=' '/^aws_region[[:space:]]*=/{gsub(/["[:space:]]/,"",$$2); print $$2; exit}' $(TFVARS_FILE) 2>/dev/null || awk -F'=' '/^aws_region[[:space:]]*=/{gsub(/["[:space:]]/,"",$$2); print $$2; exit}' $(DEV_TFVARS_FILE) 2>/dev/null)
@@ -286,19 +287,19 @@ setup-env:
286287

287288
tf-validate:
288289
@echo "$(GREEN)📋 Validating Terraform...$(NC)"
289-
@bash scripts/terraform-validate.sh
290+
@TF_ROOT=$(INFRA_ROOT) bash scripts/terraform-validate.sh
290291

291292
tf-plan:
292293
@echo "$(GREEN)📋 Planning Terraform for ENV=$(ENV)...$(NC)"
293-
@ENV=$(ENV) AWS_REGION=$(AWS_REGION) TERRAFORM_STATE_BUCKET=$(TERRAFORM_STATE_BUCKET) TERRAFORM_LOCK_TABLE=$(TERRAFORM_LOCK_TABLE) bash scripts/terraform-plan.sh
294+
@ENV=$(ENV) TF_ROOT=$(INFRA_ROOT) AWS_REGION=$(AWS_REGION) TERRAFORM_STATE_BUCKET=$(TERRAFORM_STATE_BUCKET) TERRAFORM_LOCK_TABLE=$(TERRAFORM_LOCK_TABLE) bash scripts/terraform-plan.sh
294295

295296
tf-apply:
296297
@echo "$(GREEN)🚀 Applying Terraform for ENV=$(ENV)...$(NC)"
297-
@ENV=$(ENV) AWS_REGION=$(AWS_REGION) TERRAFORM_STATE_BUCKET=$(TERRAFORM_STATE_BUCKET) TERRAFORM_LOCK_TABLE=$(TERRAFORM_LOCK_TABLE) bash scripts/terraform-apply.sh
298+
@ENV=$(ENV) TF_ROOT=$(INFRA_ROOT) AWS_REGION=$(AWS_REGION) TERRAFORM_STATE_BUCKET=$(TERRAFORM_STATE_BUCKET) TERRAFORM_LOCK_TABLE=$(TERRAFORM_LOCK_TABLE) bash scripts/terraform-apply.sh
298299

299300
tf-destroy:
300301
@echo "$(RED)⚠️ Destroying Terraform infrastructure for ENV=$(ENV)...$(NC)"
301-
@ENV=$(ENV) AWS_REGION=$(AWS_REGION) TERRAFORM_STATE_BUCKET=$(TERRAFORM_STATE_BUCKET) TERRAFORM_LOCK_TABLE=$(TERRAFORM_LOCK_TABLE) bash scripts/terraform-destroy.sh
302+
@ENV=$(ENV) TF_ROOT=$(INFRA_ROOT) AWS_REGION=$(AWS_REGION) TERRAFORM_STATE_BUCKET=$(TERRAFORM_STATE_BUCKET) TERRAFORM_LOCK_TABLE=$(TERRAFORM_LOCK_TABLE) bash scripts/terraform-destroy.sh
302303

303304
# ============================================================================
304305
# DOCKER BUILD & PUSH

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ Production-ready full-stack app with FastAPI + Angular + PostgreSQL on AWS ECS F
1818
.
1919
├── backend/ # FastAPI service + alembic + tests
2020
├── frontend/ # Angular application
21-
├── infra/ # Terraform root + modules + env tfvars
2221
├── deploy/ # docker-compose local stack
2322
├── config/ # env templates and ops guides
2423
├── docs/ # architecture / onboarding / testing docs
2524
└── .github/ # workflows and composite CI/CD actions
25+
26+
Sibling repo:
27+
../mypythonproject1-infra/ # Terraform root + modules + env tfvars
2628
```
2729

2830
## Local development
@@ -134,7 +136,7 @@ Optional inputs:
134136
GITHUB_ORG=<org> GITHUB_REPO=<repo> AWS_REGION=us-east-1 make bootstrap
135137
```
136138

137-
See `infra/README.md` for full bootstrap and IAM guidance.
139+
See `../mypythonproject1-infra/README.md` for full bootstrap and IAM guidance.
138140

139141
## Versioning
140142

0 commit comments

Comments
 (0)