使用 GitHub Actions 部署到 Azure 基础结构
本指南介绍如何使用 CI/CD 和基础结构即代码 (IaC) 以自动且可重复的方式通过 GitHub Actions 部署到 Azure。
本文属于体系结构概述且提供了一个结构化解决方案,它可用于在 Azure 上设计可缩放、安全、可复原且高度可用的应用程序。 若要查看云体系结构和解决方案创意的更多真实示例,请浏览 Azure 体系结构。
将 IaC 和自动化用于部署的好处
可通过多种方式部署到 Azure,包括 Azure 门户、CLI、API 等。 对于本指南,我们将使用 IaC 和 CI/CD 自动化。 此方法的优点包括:
声明性:在代码中定义基础结构和部署流程时,可使用标准软件开发生命周期对其进行版本控制和查看。 IaC 还有助于防止配置中出现任何偏移。
一致性:遵循 IaC 流程可确保整个组织按照标准、完善的方法来部署包含最佳做法的基础结构,同时该基础结构还经过了强化以满足安全需求。 对中心模板所做的任何改进均可在整个组织中轻松应用。
安全性:云运营或安全团队可强化和批准集中管理的模板,从而满足内部标准。
自助服务:团队可使用集中管理的模板来部署自己的基础结构。
提高工作效率:通过使用标准模板,团队可快速预配新环境,而无需担心所有实现细节。
可在 Azure 体系结构中心内的可重复基础结构下找到更多信息,或在 DevOps 资源中心找到基础结构即代码的定义。
体系结构
数据流
- 创建新分支并签入所需的 IaC 代码修改。
- 准备好将更改合并到环境后,在 GitHub 中创建拉取请求 (PR)。
- GitHub Actions 工作流随即触发以确保代码格式正确、内部一致并生成安全的基础结构。 此外,Terraform Plan 或 Bicep what-if 分析也会运行,从而生成将在 Azure 环境中出现的更改的预览。
- 经过相应审查后,可将 PR 合并到主分支中。
- 另一个 GitHub Actions 工作流将从主分支触发,并使用 IaC 提供程序执行这些更改。
- (仅限 Terraform)此外,还应运行定期计划的 GitHub Action 工作流以查找环境中的所有配置偏移,并在检测到更改时创建新问题。
先决条件
使用 Bicep
创建 GitHub 环境
工作流利用 GitHub 环境和密钥来存储 Azure 标识信息,并为部署设置审批流程。 按照这些说明创建一个名为
production
的环境。 在production
环境中,设置保护规则,并添加需要对生产部署进行签核所需的所有审批者。 还可将环境限制为主分支。 可在此处找到详细说明。设置 Azure Identity:
需要一个 Azure Active Directory 应用程序,且该应用程序有权在 Azure 订阅中进行部署。 创建单个应用程序,并在 Azure 订阅中为其授予相应的读/写权限。 接下来,设置联合凭据,以允许 GitHub 通过 OpenID Connect (OIDC) 来利用标识。 有关详细说明,请查看 Azure 文档。 需添加三个联合凭据:
- 将“实体类型”设为
Environment
并使用production
环境名称。 - 将“实体类型”设为
Pull Request
。 - 将“实体类型”设为
Branch
并使用main
分支名称。
- 将“实体类型”设为
添加 GitHub 密钥
注意
虽然有关 Azure 标识的任何数据都不含任何密钥或凭据,但我们仍使用 GitHub 密钥作为一种简易方法来参数化每个环境的标识信息。
使用 Azure Identity 在存储库上创建以下密钥:
AZURE_CLIENT_ID
:Azure 中应用注册的应用(客户端)ID。AZURE_TENANT_ID
:在其中定义应用注册的 Azure Active Directory 的租户 ID。AZURE_SUBSCRIPTION_ID
:在其中定义应用注册的订阅 ID。
可在此处找到将密钥添加到存储库的相关说明。
使用 Terraform
配置 Terraform 状态位置
Terraform 利用状态文件来存储有关托管基础结构的当前状态和相关配置的信息。 此文件需在工作流的不同运行之间持久保存。 建议的方法是在 Azure 存储帐户或类似的远程后端中存储此文件。 通常,此存储会手动或通过单独的工作流进行预配。 Terraform 后端块需使用所选存储位置进行更新(请参阅此处以获取文档)。
创建 GitHub 环境
工作流利用 GitHub 环境和密钥来存储 Azure 标识信息,并为部署设置审批流程。 按照这些说明创建一个名为
production
的环境。 在production
环境中,设置保护规则,并添加需要对生产部署进行签核所需的所有审批者。 还可将环境限制为主分支。 可在此处找到详细说明。设置 Azure Identity:
需要一个 Azure Active Directory 应用程序,且该应用程序有权在 Azure 订阅中进行部署。 为
read-only
和read/write
帐户创建单独的应用程序,并在 Azure 订阅中为其授予相应的权限。 此外,这两个角色还至少需要存储帐户(步骤 1 中 Terraform 状态的存储位置)的Reader and Data Access
权限。 接下来,设置联合凭据,以允许 GitHub 通过 OpenID Connect (OIDC) 来利用标识。 有关详细说明,请查看 Azure 文档。对于
read/write
标识,请创建一个联合凭据,如下所示:- 将
Entity Type
设为Environment
并使用production
环境名称。
对于
read-only
标识,请创建两个联合凭据,如下所示:- 将
Entity Type
设置为Pull Request
。 - 将
Entity Type
设为Branch
并使用main
分支名称。
- 将
添加 GitHub 密钥
注意
虽然有关 Azure 标识的任何数据都不含任何密钥或凭据,但我们仍使用 GitHub 密钥作为一种简易方法来参数化每个环境的标识信息。
使用
read-only
标识在存储库上创建以下密钥:AZURE_CLIENT_ID
:Azure 中应用注册的应用(客户端)ID。AZURE_TENANT_ID
:在其中定义应用注册的 Azure Active Directory 的租户 ID。AZURE_SUBSCRIPTION_ID
:在其中定义应用注册的订阅 ID。
可在此处找到将密钥添加到存储库的相关说明。
使用
read-write
标识在production
环境中创建另一密钥:AZURE_CLIENT_ID
:Azure 中应用注册的应用(客户端)ID。
可在此处找到将密钥添加到环境的相关说明。 当需要提升的读/写权限时,环境密钥将在执行部署步骤时将存储库密钥覆盖到
production
环境。
使用 GitHub 操作进行部署
使用 Bicep
参考体系结构包含两个主要工作流:
-
此工作流在每个提交上运行,且由针对基础结构代码的一组单元测试组成。 它会运行 bicep build 从而将 bicep 编译为 ARM 模板。 此操作可确保没有格式错误。 接下来,它会执行 validate 以确保模板可供部署。 最后,它会运行 checkov(一种适用于 IaC 的开源静态代码分析工具)以检测安全性和合规性问题。 如果存储库正在使用 GitHub Advanced Security (GHAS),结果将上传到 GitHub。
-
此工作流会在针对主分支的每个拉取请求和每个提交上运行。 此工作流的 what-if 阶段可通过运行 what-if 来了解 IaC 更改对 Azure 环境的影响。 然后,会将此报告附加到 PR,以便轻松查看。 当工作流被主分支的某一推送触发时,部署阶段将在 what-if 分析之后运行。 此阶段将在手动评审签核后将模板部署到 Azure。
使用 Terraform
参考体系结构包含三个主要工作流:
-
此工作流在每个提交上运行,且由针对基础结构代码的一组单元测试组成。 它会运行 terraform fmt 以确保代码正确贴合并遵循 terraform 最佳做法。 接下来,它会执行 terraform validate,以确保代码语法正确且内部一致。 最后,它会运行 checkov(一种适用于 IaC 的开源静态代码分析工具)以检测安全性和合规性问题。 如果存储库正在使用 GitHub Advanced Security (GHAS),结果将上传到 GitHub。
-
此工作流会在针对主分支的每个拉取请求和每个提交上运行。 此工作流的计划阶段可通过运行 terraform plan 来了解 IaC 更改对 Azure 环境的影响。 然后,会将此报告附加到 PR,以便轻松查看。 当工作流由主分支的某一推送触发时,应用阶段将在计划阶段后运行。 如果环境有任何挂起的更改,此阶段将采用计划文档,并在手动评审签核后应用这些更改。
-
此工作流会定期运行,以扫描环境是否存在于 Terraform 外部执行的配置偏移或更改。 如果检测到偏移,则会出现 GitHub 问题,以提醒项目的维护人员。