Esiono/crossborder-iac
GitHub: Esiono/crossborder-iac
将墨西哥 LFPDPPP 2025 数据保护法的要求编码为 Terraform 模块和 OPA 策略,在 Azure 跨区域部署的 PR 阶段自动拦截数据驻留和跨境传输违规。
Stars: 0 | Forks: 0
# CrossBorder-IaC
🇪🇸 [阅读西班牙语版本](README.es.md)
[](https://www.terraform.io/)
[](https://www.conftest.dev/)
[](https://azure.microsoft.com/)
[](https://www.checkov.io/)
[](https://github.com/Esiono/crossborder-iac/actions)
[](LICENSE)
### 问题所在:8720亿美元市场中的自动化风险
2025 年 3 月,墨西哥全面重写了其数据保护法 (LFPDPPP),引入了最高 5 年的刑事处罚以及高达 386 万美元的罚款(针对敏感数据翻倍)。[¹](#sources) 继 2026 年 1 月的网络安全事件之后,新的执法机构正释放出采取严厉行动的信号。[²](#sources)
美墨走廊正在蓬勃发展,但这种快速增长造成了巨大且未缓解的基础设施差距:
- **规模:** 2025 年美墨商品贸易额达 8728 亿美元——世界上最大的双边贸易关系。[³](#sources) 超过 5,200 家公司在 IMMAX 近岸外包计划下运营,每天处理受监管的个人数据。[⁴](#sources)
- **基础设施差距:** 微软于 2024 年推出了 Azure Mexico Central 以实现国内数据驻留,[⁵](#sources) 但目前没有标准化的 IaC 模式来在跨区域部署中强制执行新的 LFPDPPP 合规性。
- **威胁:** 只需要一个配置错误的 Terraform 文件——一个异地复制存储账户、一个未经授权的 VNet Peering,或一个跨租户复制开关——就足以触发国际数据传输违规。
**解决方案:** 本项目将 2025 年 LFPDPPP 的要求直接编码到基础设施即代码中,确保跨境数据违规在 Pull Request 阶段被拦截,而不是在法律审计期间。
#### 来源
¹ [LFPDPPP 处罚框架](https://clym.io/regulations/mexican-privacy-law-lfpdppp) — 罚款从 100 到 320,000 UMA(约 386 万美元),针对敏感数据翻倍。刑事处罚参见[录像法](https://www.recordinglaw.com/world-laws/world-data-privacy-laws/mexico-data-privacy-laws/)。
² [录像法 — LFPDPPP 2025 指南](https://www.recordinglaw.com/world-laws/world-data-privacy-laws/mexico-data-privacy-laws/) — 截至 2026 年 5 月,2025 年法律尚未发布正式制裁,但在 2026 年 1 月网络安全事件后,早期的 SABG 诉讼程序表明该机构将进行严厉执法。
³ [USTR — 墨西哥贸易数据](https://ustr.gov/countries-regions/americas/mexico) — 2025 年美国与墨西哥的商品贸易总额达 8728 亿美元。由[美国人口普查局数据](https://www.freightwaves.com/news/us-mexico-trade-hits-new-high-of-872b-in-2025)确认。
⁴ [IMMEX 计划数据](https://hub.americanindustriesgroup.com/insights/understanding-nearshoring-benefits-manufacturing-companies-mexico/) — 大约有 5,220 家公司在 IMMEX 下运营,雇佣了约 294 万名工人。
⁵ [Azure Mexico Central](https://news.microsoft.com/es-xl/microsoft-launches-its-first-hyper-scale-cloud-datacenter-region-in-mexico/) — 微软在墨西哥的首个超大规模云区域,于 2024 年 5 月推出。
## 工作原理
三层强制策略在不同阶段拦截违规行为,确保没有任何未经验证的内容进入生产环境:
```
┌──────────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────────┐
│ Layer 1 — IaC │ → │ Layer 2 — CI │ → │ Layer 3 — Runtime │
│ Terraform modules │ │ GitHub Actions PR gate │ │ Azure Policy │
│ Variable validation │ │ OPA (Conftest) + Checkov│ │ Drift detection │
│ Catches at plan time │ │ Catches at PR merge │ │ Catches post-deploy │
│ modules/ │ │ .github/workflows/ │ │ (planned — ADR-002) │
└──────────────────────────┘ └──────────────────────────┘ └──────────────────────────┘
```
| 控制 | 强制层 | 机制 |
|---|---|---|
| 数据驻留 (Art. 35) | IaC | Terraform 变量验证 — 仅允许 mexicocentral 和 eastus2 |
| 禁止异地复制 (Art. 36) | IaC + CI | 存储账户硬编码为 LRS + OPA 规则拒绝任何其他配置 |
| 跨租户复制 (Art. 36) | IaC + CI | 在资源级别禁用 + OPA 规则验证 plan 输出 |
| 禁止 VNet Peering (Art. 36) | CI | OPA 规则完全拦截 azurerm_virtual_network_peering 资源 |
| 运行时漂移检测 | Runtime | 每个环境的 Azure Policy 分配(计划中 — 参见 [ADR-002](docs/adr/ADR-002-dual-enforcement-opa-azure-policy.md)) |
| 审计日志驻留 (Art. 35) | IaC | Log Analytics Workspace 和诊断设置与资源位于同一位置 |
## 代码中的法律要求
LFPDPPP 条款的引用直接在基础设施本身中强制执行。以下是第 35 条如何强制执行区域锁定:
```
variable "location" {
description = "Azure region where the storage account will be created."
type = string
validation {
condition = contains(["mexicocentral", "eastus2"], var.location)
error_message = "LFPDPPP Art. 35 (DOF 20 marzo 2025): storage must be deployed to mexicocentral or eastus2 only."
}
}
```
以及在任何 PR 合并之前,在 CI 中拦截异地复制的 OPA 策略:
```
deny contains msg if {
resource := input.planned_values.root_module.resources[_]
resource.type == "azurerm_storage_account"
replication := resource.values.account_replication_type
not allowed_replication_types[replication]
msg := sprintf(
"LFPDPPP Art. 36 violation: Storage account '%s' uses replication type '%s'. Only LRS is permitted.",
[resource.name, replication]
)
}
```
## 架构
```
crossborder-iac/
├── modules/
│ ├── compliant-storage/ # Storage account — LRS only, Art. 36
│ ├── compliant-keyvault/ # Key Vault — purge protection, network ACLs, tenant-locked
│ ├── compliant-network/ # VNet + subnets — no peering by design
│ └── observability-baseline/ # Log Analytics — region-local logs, Art. 35
├── environments/
│ ├── mx-central/ # Mexico Central — data_classification = "personal"
│ └── us-east2/ # East US 2 — data_classification = "non-personal"
├── policies/
│ └── storage_residency.rego # 4 OPA rules enforcing Arts. 35-36
├── tests/
│ └── fixtures/ # Terraform plan JSON for policy testing
├── scripts/
│ └── bootstrap-state-backend.sh # Idempotent state storage setup (West US 2)
├── docs/
│ └── adr/ # Architecture Decision Records
├── .github/
│ └── workflows/ # PR checks: terraform plan + OPA + Checkov
└── conftest.toml
```
## 模块
**compliant-storage** — 锁定为 LRS 复制的 Azure Storage Account。变量验证在 plan 阶段拒绝 GRS/ZRS/GZRS。禁用跨租户复制。强制执行第 36 条。
**compliant-keyvault** — 启用了清除保护、90 天软删除、拒绝公共访问的网络 ACL 以及租户级别锁定的 Azure Key Vault。机密永远不会离开授权的租户边界。
**compliant-network** — 每个区域具有非重叠地址空间的 VNet 和子网(墨西哥:10.0.0.0/16,美国:10.1.0.0/16)。设计上没有 Peering 资源 — 跨区域网络连接在架构上被禁止,而不仅仅是受策略阻挡。
**observability-baseline** — 带有诊断设置的 Log Analytics Workspace,确保审计日志与它们监控的资源位于同一区域。强制执行第 35 条关于合规证据的数据驻留。
## OPA 策略规则
所有四个规则在每次 PR 时通过 Conftest 针对 terraform plan 输出运行:
| 规则 | LFPDPPP 条款 | 拦截内容 |
|---|---|---|
| 区域白名单 | Art. 35 | mexicocentral 或 eastus2 之外的存储账户 |
| 仅限 LRS 复制 | Art. 36 | 除 LRS 之外的任何复制类型 |
| 禁用跨租户复制 | Art. 36 | 保留启用的跨租户复制 |
| 禁止 VNet Peering | Art. 36 | plan 中的任何 azurerm_virtual_network_peering 资源 |
## CI/CD Pipeline
每个 Pull Request 都会触发:
1. terraform plan — 为目标环境生成 plan JSON
2. Conftest OPA 检查 — 针对 plan 输出运行所有 Rego 策略
3. Checkov 静态分析 — 扫描 HCL 以发现安全配置错误
main 分支的分支保护要求所有检查通过。禁止直接推送。
## 架构决策记录
| ADR | 决策 | 原因 |
|---|---|---|
| [ADR-001](docs/adr/ADR-001-local-state-backend.md) | 本地 state backend | 个人 Azure 账户身份验证限制阻碍了远程 backend;bootstrap 脚本为未来的迁移准备了 state 存储 |
| [ADR-002](docs/adr/ADR-002-dual-enforcement-opa-azure-policy.md) | 双重强制:OPA + Azure Policy | OPA 在 CI 中预部署时拦截违规;Azure Policy 在运行时后部署检测漂移 |
| [ADR-003](docs/adr/ADR-003-bootstrap-script-outside-terraform.md) | 在 Terraform 之外的 bootstrap 脚本 | State backend 无法由依赖于它的 Terraform 管理 — 使用幂等 shell 脚本解决循环依赖 |
| [ADR-004](docs/adr/ADR-004-lfpdppp-2025-article-migration.md) | LFPDPPP 2025 条款迁移 | 墨西哥的彻底法律重写(DOF 2025年3月20日)重新对驻留和传输条款进行了编号;所有代码和文档中的合规性引用都已迁移,以保持法律上的准确性 |
## 前置条件
- Terraform >= 1.5
- Azure CLI(带有活动订阅的 az login)
- Conftest(用于 OPA 策略检查)
- Checkov(用于静态分析)
## 快速开始
```
git clone https://github.com/Esiono/crossborder-iac.git
cd crossborder-iac
chmod +x scripts/bootstrap-state-backend.sh
./scripts/bootstrap-state-backend.sh
cd environments/mx-central
terraform init
terraform plan -out=plan.tfplan
terraform show -json plan.tfplan > plan.json
conftest test plan.json -p ../../policies/ --namespace crossborder.storage
```
## 强制执行输出示例
这是针对 `tests/fixtures/` 中不合规固定配置运行 Conftest 的实际输出 — 一个位于错误区域且启用了 GRS 复制和跨租户复制的存储账户、嵌套在子模块中的相同错误配置,以及一个被禁止的 VNet Peering 资源:
```
$ conftest test tests/fixtures/ --policy policies/ --namespace crossborder.storage
FAIL - tests/fixtures/noncompliant_storage.json - crossborder.storage - LFPDPPP Art. 35 violation: Storage account 'bad' is in region 'westeurope'. Allowed regions: {"eastus2", "mexicocentral"}
FAIL - tests/fixtures/noncompliant_storage.json - crossborder.storage - LFPDPPP Art. 36 violation: Storage account 'bad' has cross-tenant replication enabled. This permits data transfer to foreign tenants without explicit authorization.
FAIL - tests/fixtures/noncompliant_storage.json - crossborder.storage - LFPDPPP Art. 36 violation: Storage account 'bad' uses replication type 'GRS'. Only LRS is permitted — geo-replication transfers data across borders without explicit authorization.
FAIL - tests/fixtures/noncompliant_storage_module.json - crossborder.storage - LFPDPPP Art. 35 violation: Storage account 'main' is in region 'westeurope'. Allowed regions: {"eastus2", "mexicocentral"}
FAIL - tests/fixtures/noncompliant_storage_module.json - crossborder.storage - LFPDPPP Art. 36 violation: Storage account 'main' has cross-tenant replication enabled. This permits data transfer to foreign tenants without explicit authorization.
FAIL - tests/fixtures/noncompliant_storage_module.json - crossborder.storage - LFPDPPP Art. 36 violation: Storage account 'main' uses replication type 'GRS'. Only LRS is permitted — geo-replication transfers data across borders without explicit authorization.
FAIL - tests/fixtures/noncompliant_peering.json - crossborder.storage - LFPDPPP Art. 36 violation: VNet peering resource 'mx_to_us' detected. Cross-region VNet peering creates unauthorized data paths across borders. Peering between mexicocentral and eastus2 is prohibited.
12 tests, 5 passed, 0 warnings, 7 failures, 0 exceptions
```
非零的退出代码将阻止 Pull Request — 这就是在每次 PR 中于 `compliance-mx-central` 和 `compliance-us-east2` 内运行的检查。
## 下一步计划
这是一个参考实现,而不是一个完成的平台。计划中的工作:
- **Azure Policy 作为第 3 层强制执行** — 依据 [ADR-002](docs/adr/ADR-002-dual-enforcement-opa-azure-policy.md) 进行运行时漂移检测,目前这是唯一存在于纸面上而未在 Terraform 中的防御纵深层。
- **将远程 state 迁移到 Azure Blob** — 一旦服务主体就位,即根据 [ADR-001](docs/adr/ADR-001-local-state-backend.md) 和 [ADR-003](docs/adr/ADR-003-bootstrap-script-outside-terraform.md) 替换本地 backend。
- **用于 Storage 和 Key Vault 的 Private Endpoints** — 这两种资源都已阻止公共网络访问;Private Endpoints 将为合法访问弥补由此产生的连接差距。
- **扩展针对其他资源类型的 OPA 策略** — 当前的四个规则涵盖了存储和网络;Key Vault 和 Log Analytics 的配置漂移尚未进行策略检查。
- **CI 增强** — 在 plan/OPA/Checkov pipeline 之前,将 `terraform fmt -check`、`terraform validate` 和 `tflint` 作为快速预检查。
## 作者
**Eduardo Ayala Siono** · 数据分析师 / 数据工程师
拥有 6 年以上大规模确保生产数据完整性的经验。居住在美墨边境的墨西卡利。
在研究了美国公司在墨西哥 2025 年 LFPDPPP 改革下面临的运营差距后构建了这个项目:386 万美元的罚款、刑事处罚,以及缺乏强制执行它们的标准基础设施模式。
📍 墨西卡利, MX · 美国太平洋时区 · EN/ES C2
[linkedin.com/in/eduardosiono](https://linkedin.com/in/eduardosiono)
根据 MIT 许可授权。这是一个用于作品集目的的参考实现。生产部署中的 LFPDPPP(DOF 2025年3月20日)合规要求应由法律顾问进行验证。
标签:Azure, ECS, OPA, Terraform, 合规, 数据驻留, 策略即代码, 结构化提示词, 聊天机器人安全, 靶场