rohandeb2/github_actions_project
GitHub: rohandeb2/github_actions_project
一个生产级银行 REST API 示例项目,演示如何通过六阶段 CI/CD 流水线将 Spring Boot 应用安全地部署到 AWS EKS 并支持蓝绿部署与自动回滚。
Stars: 0 | Forks: 0
# 🏦 BankApp — 生产级银行 REST API
## 📋 目录
- [概述](#overview)
- [架构](#architecture)
- [技术栈](#tech-stack)
- [CI/CD Pipeline](#cicd-pipeline)
- [安全扫描](#security-scanning)
- [基础设施 (Terraform)](#infrastructure-terraform)
- [快速开始](#getting-started)
- [API 参考](#api-reference)
- [环境变量与 Secrets](#environment-variables--secrets)
- [项目结构](#project-structure)
## 概述
BankApp 是一个用于核心银行业务(如账户创建、存款和资金转账)的生产级 REST API。它基于 **Spring Boot 3.2** 构建,后端使用 **PostgreSQL**,并通过完全自动化的 GitHub Actions pipeline 部署在 **AWS EKS** 上。
每次向 `main` 分支推送代码都会触发一个包含 6 个阶段的 pipeline,涵盖代码质量检查、6 项并行安全扫描、Docker 镜像构建、预发布环境部署、生产环境蓝绿部署,以及失败时的自动回滚。
## 架构
```
Internet
│
▼
[ ALB / Ingress ]
│
▼
[ EKS — Spring Boot Pods ]
│ │
▼ ▼
[ RDS PostgreSQL ] [ ElastiCache (optional) ]
Multi-AZ Session Store
Private Subnet Private Subnet
```
**关键设计决策:**
- EC2 节点和 RDS 仅在**私有子网**中运行——数据库不对外公开暴露
- 每个**可用区 (AZ) 配备一个 NAT Gateway**,以实现高可用性的出站流量
- EKS secrets 使用**客户管理的 KMS 密钥**进行静态加密
- 所有工作节点强制使用 IMDSv2(防止基于 SSRF 的凭证盗用)
- RDS 启用了**删除保护**和**7 天自动备份**
## 技术栈
| 层级 | 技术 |
|---|---|
| 应用程序 | Java 21, Spring Boot 3.2, Spring Security, Spring Data JPA |
| 数据库 | PostgreSQL 16 (RDS Multi-AZ) |
| 容器 | Docker (多阶段构建, distroless 运行时) |
| 编排 | AWS EKS (Kubernetes 1.29) |
| 基础设施 | Terraform 1.6+, AWS VPC / EKS / RDS |
| CI/CD | GitHub Actions |
| 安全扫描 | Semgrep, SonarQube, Trivy, OWASP, TFLint, Checkov |
| 监控 | Spring Actuator, Prometheus (Micrometer), CloudWatch |
| API 文档 | SpringDoc OpenAPI / Swagger UI |
## CI/CD Pipeline
每次向 `main` 分支推送代码都会按顺序执行所有 6 个阶段。Pull request 仅执行第 1 和第 2 阶段。
```
Push to main
│
▼
┌─────────────────────────────────┐
│ Stage 1 — Code Quality │
│ Unit tests · Integration tests │
│ JaCoCo coverage gate (≥ 70%) │
└────────────────┬────────────────┘
│
▼
┌─────────────────────────────────┐
│ Stage 2 — Security Scanning │ ← 6 scanners run in parallel
│ Semgrep · SonarQube · Trivy │
│ OWASP · TFLint · Checkov │
└────────────────┬────────────────┘
│ (Security Gate must pass)
▼
┌─────────────────────────────────┐
│ Stage 3 — Docker Build & Push │
│ Multi-stage build · SBOM │
│ Image signed · Trivy image scan│
└────────────────┬────────────────┘
│
▼
┌─────────────────────────────────┐
│ Stage 4 — Deploy Staging │
│ Docker Compose deploy │
│ Smoke test (actuator/health) │
└────────────────┬────────────────┘
│
▼
┌─────────────────────────────────┐
│ Stage 5 — Deploy Production │ ← Manual approval gate
│ Blue-Green deploy │
│ Production smoke test │
│ Update LAST_STABLE_SHA │
└────────────────┬────────────────┘
│ (on failure)
▼
┌─────────────────────────────────┐
│ Stage 6 — Auto Rollback │
│ Restore last stable image │
│ Rollback smoke test │
└─────────────────────────────────┘
│
▼
📧 Email notification
sent to both recipients
on every outcome
```
### 回滚策略
- 在每次部署到生产环境之前,当前稳定的 SHA 会保存为 `LAST_STABLE_SHA`
- 如果预发布或生产环境的冒烟测试失败,第 6 阶段将自动触发并重新部署最后稳定的镜像
- 也可以随时通过 `workflow_dispatch` 触发**手动强制回滚**
## 安全扫描
所有 6 个扫描器都会在测试通过后并行运行。如果任何扫描器报告失败,**安全门**将阻止构建。
| 扫描器 | 检查内容 |
|---|---|
| **Semgrep** | Java SAST — OWASP Top 10、SQL 注入、代码中的 secrets |
| **SonarQube** | 代码质量门、测试覆盖率、代码异味、安全热点 |
| **Trivy** | 文件系统和 Docker 镜像 CVE 扫描 (CRITICAL / HIGH) |
| **OWASP Dependency Check** | Maven 依赖项中的已知 CVE (CVSS ≥ 7 构建失败) |
| **TFLint** | Terraform linting — 命名约定、弃用的语法 |
| **Checkov** | Terraform 和 Dockerfile IaC 策略检查 |
所有扫描器结果都会以 SARIF 格式上传,并显示在 **GitHub Security → Code Scanning** 标签页中。
## 基础设施 (Terraform)
基础设施以代码形式定义在 `terraform/` 目录下,并被组织成可重用的模块。
```
terraform/
├── main.tf # Root module — wires VPC, EKS, RDS, SGs
├── variables.tf # All input variables with descriptions
├── versions.tf # Provider versions + S3 backend config
├── environments/
│ └── prod/
│ └── terraform.tfvars
└── modules/
├── vpc/ # VPC, subnets, NAT gateways, flow logs
├── eks/ # EKS cluster, node group, KMS, add-ons
├── rds/ # RDS PostgreSQL, parameter group, monitoring
└── security-groups/ # EKS and RDS security groups
```
**部署基础设施:**
```
cd terraform
export TF_VAR_db_username=
export TF_VAR_db_password=
terraform init
terraform plan -var-file=environments/prod/terraform.tfvars
terraform apply -var-file=environments/prod/terraform.tfvars
```
## 快速开始
### 前置条件
- Docker & Docker Compose
- Java 21(用于本地开发)
- Maven 3.9+
### 本地运行
```
# 克隆 repository
git clone https://github.com//bankapp.git
cd bankapp
# 启动 app + PostgreSQL + pgAdmin
docker compose up -d
# App: http://localhost:8080
# Swagger: http://localhost:8080/swagger-ui.html
# Actuator: http://localhost:8080/actuator/health
# pgAdmin: http://localhost:5050 (admin@bank.com / admin)
```
### 运行测试
```
# 运行所有 tests 并生成 coverage report
mvn verify -Dspring.profiles.active=test
# Coverage report 生成于:
# target/site/jacoco/index.html
```
### 本地运行 SonarQube
```
# 启动 SonarQube
docker compose -f docker-compose.sonar.yml up -d
# 访问: http://localhost:9000 (admin / admin)
# 运行 analysis
mvn sonar:sonar \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=
```
## API 参考
Base URL: `http://localhost:8080/api/v1`
完整的交互式文档可在 `/swagger-ui.html` 获取。
| 方法 | Endpoint | 描述 |
|---|---|---|
| `POST` | `/accounts` | 创建新的银行账户 |
| `GET` | `/accounts` | 列出所有账户 |
| `GET` | `/accounts/{accountNumber}` | 根据账号获取账户 |
| `POST` | `/accounts/{accountNumber}/deposit` | 存入资金 |
| `POST` | `/accounts/transfer` | 在账户间转移资金 |
| `GET` | `/accounts/{accountNumber}/transactions` | 获取交易记录 |
| `GET` | `/accounts/health` | 服务健康检查 |
**示例 — 创建账户:**
```
curl -X POST http://localhost:8080/api/v1/accounts \
-H "Content-Type: application/json" \
-d '{
"ownerName": "John Doe",
"email": "john@example.com",
"type": "SAVINGS",
"balance": 1000.00
}'
```
**示例 — 转移资金:**
```
curl -X POST http://localhost:8080/api/v1/accounts/transfer \
-H "Content-Type: application/json" \
-d '{
"fromAccountNumber": "ACC1234567890",
"toAccountNumber": "ACC0987654321",
"amount": "500.00",
"description": "Rent payment"
}'
```
## 环境变量与 Secrets
### GitHub Secrets (Settings → Secrets → Actions)
| Secret | 描述 |
|---|---|
| `DOCKERHUB_USERNAME` | Docker Hub 用户名 |
| `DOCKERHUB_TOKEN` | Docker Hub 访问令牌 |
| `SONAR_TOKEN` | SonarCloud 用户令牌 |
| `NVD_API_KEY` | NVD API 密钥(加速 OWASP 扫描) |
| `SEMGREP_APP_TOKEN` | Semgrep 令牌(可选) |
| `MAIL_USERNAME` | 用于发送 pipeline 通知的 Gmail 地址 |
| `MAIL_PASSWORD` | Gmail 应用密码 |
| `GH_PAT` | GitHub PAT (repo scope) — 用于更新 `LAST_STABLE_SHA` |
### GitHub Variables (Settings → Secrets → Variables)
| 变量 | 描述 |
|---|---|
| `SONAR_HOST_URL` | SonarQube 服务器 URL |
| `LAST_STABLE_SHA` | 由 pipeline 自动管理 — 使用任意有效的 commit SHA 进行初始化 |
### 应用程序环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
| `DB_HOST` | `localhost` | PostgreSQL 主机 |
| `DB_PORT` | `5432` | PostgreSQL 端口 |
| `DB_NAME` | `bankdb` | 数据库名称 |
| `DB_USER` | `bankuser` | 数据库用户名 |
| `DB_PASSWORD` | `bankpass` | 数据库密码 |
| `SERVER_PORT` | `8080` | 应用程序端口 |
| `APP_ENV` | `local` | 环境标签 |
## 项目结构
```
bankapp/
├── .github/
│ └── workflows/
│ └── ci-cd.yaml # Full 6-stage pipeline
├── src/
│ ├── main/java/com/bank/
│ │ ├── BankApplication.java
│ │ ├── config/ # Security & OpenAPI config
│ │ ├── controller/ # REST controllers
│ │ ├── model/ # JPA entities (Account, Transaction)
│ │ ├── repository/ # Spring Data repositories
│ │ ├── service/ # Business logic
│ │ └── exception/ # Global exception handling
│ └── test/java/com/bank/
│ ├── AccountServiceTest.java # Unit tests (Mockito)
│ └── AccountControllerIntegrationTest.java # Integration tests
├── terraform/ # AWS infrastructure as code
│ ├── modules/
│ │ ├── vpc/
│ │ ├── eks/
│ │ ├── rds/
│ │ └── security-groups/
│ └── environments/prod/
├── Dockerfile # Multi-stage build (deps → builder → runtime)
├── docker-compose.yml # Local dev stack
├── docker-compose.sonar.yml # Local SonarQube stack
└── pom.xml # Maven dependencies
```
## 📧 通知
pipeline 在每次运行(成功、失败或回滚)时都会向配置的收件人发送 HTML 电子邮件报告。报告包含每个阶段的结果、部署的镜像 SHA 以及指向 pipeline 运行记录的直接链接。
## 📄 许可证
本项目用于 DevOps 培训和演示目的。
标签:AWS EKS, ECS, Spring Boot, Terraform, 域名枚举, 子域名突变, 测试用例, 自定义请求头, 请求拦截, 银行API