kylon-cloud-dev/terraform-azure-modules
GitHub: kylon-cloud-dev/terraform-azure-modules
该项目提供版本化的 Azure Terraform 可复用模块,并结合 GitHub Actions OIDC 与 HashiCorp Vault 实现了动态短期凭证签发的安全 DevOps 流水线。
Stars: 0 | Forks: 0
# 结合 HCP Terraform 与 Vault OIDC 的 Terraform Azure 模块库
## 项目概述
本项目展示了一个用于 Azure 基础设施的可复用 Terraform 模块库。
它包含针对 Azure 虚拟网络 (Azure Virtual Network)、Azure 容器注册表 (Azure Container Registry) 和 Azure Kubernetes Service 的版本化 Terraform 模块。这些模块已通过 GitHub Actions 验证,并发布到了 HCP Terraform 私有注册表。
该项目还演示了使用 HashiCorp Vault、GitHub Actions OIDC 和 Azure 动态凭证的安全 DevSecOps 凭证模式。GitHub Actions 不再将长期的 Azure 凭证直接存储在 GitHub 仓库的 secrets 中,而是使用 OIDC 向 Vault 进行身份验证,并由 Vault 在运行时签发短期的 Azure 凭证。
本项目旨在展示在 Terraform 模块设计、HCP Terraform、GitHub Actions、HashiCorp Vault、Azure 身份、动态凭证以及云安全故障排除方面的实践经验。
## 业务问题
云团队通常会在多个项目中重复使用相同的 Terraform 模式。如果没有可复用的模块,每个团队在配置网络、容器注册表和 Kubernetes 集群时可能会有所不同。
这可能会导致:
* 基础设施标准不一致
* Terraform 代码重复
* 安全审查更加困难
* 模块手动发布
* 长期凭证存储在 CI/CD 系统中
本项目通过创建可复用的 Azure 模块、通过 CI 验证它们、将其发布到私有 Terraform 注册表,并演示通过 Vault 安全获取凭证,从而解决了这个问题。
## 工具和技术
| 类别 | 工具 |
| --- | --- |
| 云服务商 | Microsoft Azure |
| 基础设施即代码 | Terraform |
| 模块注册表 | HCP Terraform 私有注册表 |
| 密钥管理 | HashiCorp Vault Dedicated |
| CI/CD | GitHub Actions |
| 身份与访问管理 | GitHub Actions OIDC, Microsoft Entra ID, Azure RBAC |
| Azure 服务 | Virtual Network, Azure Container Registry, Azure Kubernetes Service |
| CLI 工具 | Azure CLI, Terraform CLI, curl, jq |
## 架构
```
Developer Push to GitHub
|
v
GitHub Repository
|
v
GitHub Actions Validation
|
v
Terraform Module Library
|
+--> VNet Module
+--> ACR Module
+--> AKS Module
|
v
HCP Terraform Private Registry
```
Vault 和 GitHub Actions OIDC 流程:
```
GitHub Actions Workflow
|
v
GitHub OIDC Token
|
v
Vault JWT Auth Method
|
v
Vault Policy
|
v
Vault Azure Secrets Engine
|
v
Short-Lived Azure Credentials
```
## 仓库结构
```
terraform-azure-modules/
├── .github/
│ └── workflows/
│ ├── validate.yml
│ ├── publish.yml
│ └── vault-oidc-test.yml
├── examples/
│ └── complete/
├── modules/
│ ├── vnet/
│ ├── acr/
│ └── aks/
├── screenshots/
├── vault-infra/
├── .gitignore
├── README.md
└── troubleshooting.md
```
## Terraform 模块
### 1. VNet 模块
VNet 模块用于创建一个 Azure 虚拟网络 (Azure Virtual Network) 以及一个或多个子网。
源码目录:
```
modules/vnet
```
创建的资源:
* Azure 虚拟网络
* Azure 子网
* 可选的资源标签
### 2. ACR 模块
ACR 模块用于创建一个 Azure 容器注册表 (Azure Container Registry),支持配置 SKU、管理员访问设置和可选标签。
源码目录:
```
modules/acr
```
创建的资源:
* Azure 容器注册表
* 可配置的 SKU
* 可选的管理员访问设置
* 可选的资源标签
### 3. AKS 模块
AKS 模块用于创建 Azure Kubernetes Service 集群基线,包含托管标识、Azure 网络和可选的 ACR 拉取访问权限。
源码目录:
```
modules/aks
```
创建的资源:
* Azure Kubernetes Service 集群
* 系统分配的托管标识
* Azure CNI 网络
* Azure 网络策略
* 针对 Azure 容器注册表的可选 AcrPull 角色分配
## 完整示例
examples/complete 配置演示了如何将这些模块结合使用。
```
Resource Group
|
+--> Virtual Network
| |
| +--> AKS Subnet
|
+--> Azure Container Registry
|
+--> Azure Kubernetes Service
|
+--> AcrPull access to ACR
```
## HCP Terraform 私有注册表
这些模块使用基于标签的模块发布方式,发布到了 HCP Terraform 私有注册表。
| 模块 | Provider | 版本 | 源码目录 | Git 标签 |
| --- | --- | --- | --- | --- |
| vnet | azurerm | 1.0.0 | modules/vnet | vnet-v1.0.0 |
| acr | azurerm | 1.0.0 | modules/acr | acr-v1.0.0 |
| aks | azurerm | 1.0.0 | modules/aks | aks-v1.0.0 |
## GitHub Actions 工作流
| 工作流 | 用途 |
| --- | --- |
| validate.yml | 验证 Terraform 格式和模块语法。 |
| publish.yml | 用于未来自动化的手动发布工作流占位符。 |
| vault-oidc-test.yml | 测试 GitHub Actions OIDC 向 Vault 的身份验证及动态凭证签发。 |
## 已实施的安全控制
| 安全控制 | 用途 |
| --- | --- |
| 可复用的 Terraform 模块 | 跨项目标准化基础设施模式。 |
| GitHub Actions 验证 | 在接受更改之前确认模块格式和语法。 |
| HCP Terraform 私有注册表 | 从受控的注册表发布可复用模块。 |
| GitHub Actions OIDC | 避免将长期的云凭证直接存储在 GitHub secrets 中。 |
| Vault JWT 身份验证 | 允许 GitHub Actions 使用短期 OIDC token 向 Vault 进行身份验证。 |
| Vault 策略 | 限制 GitHub Actions 仅访问所需的凭证路径。 |
| Vault Azure secrets 引擎 | 在运行时签发短期 Azure 凭证。 |
| 清理流程 | 在测试后移除实验资源和敏感的本地文件。 |
## 截图与验证
### GitHub Actions 验证成功
Terraform 验证工作流已成功完成。

### HCP Terraform VNet 模块已发布

### HCP Terraform ACR 模块已发布

### HCP Terraform AKS 模块已发布

### HCP Vault 集群运行中
创建了一个 HCP Vault Dedicated 开发集群,用于测试 Vault 身份验证和 Azure 动态凭证。

### HCP Vault 集群概览

### 本地签发 Vault 动态 Azure 凭证
Vault 成功在本地签发了短期 Azure 凭证,且凭证租约在测试后被撤销。

### GitHub Actions OIDC 连接 Vault 成功
GitHub Actions 成功使用 OIDC 向 Vault 进行身份验证,并完成了 Vault 凭证工作流。

### HCP 清理验证
实验结束后,HCP 资源已被删除以避免产生不必要的费用。

## 验证结果
本项目成功演示了:
```
Terraform module validation: Passed
HCP Terraform module publishing: Completed
VNet module version: 1.0.0
ACR module version: 1.0.0
AKS module version: 1.0.0
Vault local dynamic credential test: Passed
GitHub Actions OIDC to Vault test: Passed
HCP and Azure cleanup: Completed
```
## 已执行的故障排除
在项目进行期间,我解决了几个实际的 Terraform、HCP Terraform、Vault 和 Azure 身份问题。
| 问题 | 解决方案 |
| --- | --- |
| Shell 进入了 heredoc 模式 | 正确关闭了 heredoc,并避免粘贴不完整的 shell 代码块。 |
| HCP Terraform 模块设置因缺少标签而失败 | 创建了特定于模块的版本标签,例如 vnet-v1.0.0、acr-v1.0.0 和 aks-v1.0.0。 |
| AKS 模块出现 AzureRM provider 弃用警告 | 记录了该 provider 警告,并保持模块与项目中使用的 AzureRM 配置兼容。 |
| Vault Azure secrets 引擎返回权限不足错误 | 添加了所需的 Microsoft Graph 权限和 Azure 角色分配权限。 |
| Azure/Entra 传播延迟了动态凭证的创建 | 在传播完成后重试,并调整了 CI 验证以使用现有的低权限 app registration。 |
| 敏感的 service principal secret 出现在终端输出中 | 将该凭证视为已暴露,删除/轮换了该身份,并安全地重新创建了凭证。 |
| Vault 测试后 HCP 资源仍保持活动状态 | 在验证后删除了 Vault 集群和 HashiCorp 虚拟网络 (Virtual Networks)。 |
## 学到了什么
本项目加深了我对以下方面的理解:
* 设计可复用的 Terraform 模块
* 构建多模块 Terraform 仓库结构
* 使用 GitHub Actions 验证 Terraform 模块
* 将模块发布到 HCP Terraform 私有注册表
* 为 GitHub Actions OIDC 配置 Vault JWT 身份验证
* 使用 Vault 签发短期 Azure 凭证
* 排查 Azure/Entra ID 权限和传播延迟问题
* 测试后清理 HCP、Azure、Terraform state 和本地 secret 文件
## 如何重现此项目
### 1. 克隆仓库
```
git clone https://github.com/kylon-cloud-dev/terraform-azure-modules.git
cd terraform-azure-modules
```
### 2. 在本地验证模块
```
terraform fmt -recursive modules examples
cd modules/vnet
terraform init -backend=false
terraform validate
cd ../..
cd modules/acr
terraform init -backend=false
terraform validate
cd ../..
cd modules/aks
terraform init -backend=false
terraform validate
cd ../..
cd examples/complete
terraform init -backend=false
terraform validate
cd ../..
```
### 3. 将模块发布到 HCP Terraform
创建特定于模块的标签:
```
git tag vnet-v1.0.0
git tag acr-v1.0.0
git tag aks-v1.0.0
git push origin vnet-v1.0.0 acr-v1.0.0 aks-v1.0.0
```
使用以下命令在 HCP Terraform 中发布每个模块:
```
vnet -> modules/vnet -> tag prefix vnet-
acr -> modules/acr -> tag prefix acr-
aks -> modules/aks -> tag prefix aks-
```
### 4. 配置 Vault
创建一个 HCP Vault Dedicated 开发集群,生成管理员 token,并从以下文件创建本地 terraform.tfvars 文件:
```
vault-infra/terraform.tfvars.example
```
然后应用 Vault 配置:
```
cd vault-infra
terraform init
terraform plan
terraform apply
cd ..
```
### 5. 运行 GitHub Actions OIDC 测试
添加以下 GitHub Actions secrets:
```
VAULT_ADDR
VAULT_NAMESPACE
```
然后手动运行工作流:
```
Actions -> Vault OIDC Dynamic Azure Credential Test -> Run workflow
```
## 清理
为了避免不必要的费用并降低安全风险,请在测试后移除实验资源。
本项目完成的清理工作:
* 删除了 HCP Vault Dedicated 集群
* 删除了 HashiCorp 虚拟网络 (Virtual Networks)
* 移除了 Azure 实验 app registrations 和 service principals
* 移除了本地的 Terraform 变量和 state 文件
* 取消设置了本地的 Vault 和 Azure 凭证环境变量
* 确认 Git 工作树是干净的
本地清理示例:
```
rm -f vault-infra/terraform.tfvars
rm -f vault-infra/terraform.tfstate
rm -f vault-infra/terraform.tfstate.backup
unset VAULT_TOKEN
unset VAULT_ADDR
unset VAULT_NAMESPACE
unset VAULT_SP_CLIENT_SECRET
unset SP_JSON
```
标签:Azure, DevSecOps, ECS, GitHub Actions, HashiCorp Vault, Terraform, 上游代理, 自动笔记