你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在 Azure 存储中使用 GitHub Actions 工作流以部署静态网站
使用工作流将静态站点部署到 Azure 存储帐户以开始使用 GitHub Actions。 设置 GitHub Actions 工作流后,当更改站点代码时,站点会从 GitHub 自动部署到 Azure。
注意
如果你使用的是 Azure Static Web Apps,则无需手动设置 GitHub Actions 工作流。
Azure Static Web Apps 会自动为你创建 GitHub Actions 工作流。
先决条件
Azure 订阅和 GitHub 帐户。
备注
通常使用内容分发网络 (CDN) 来降低全球用户的延迟,并减少存储帐户的事务数。 将静态内容部署到基于云的存储服务可以降低对可能非常昂贵的计算实例的需求。 有关详细信息,请参阅“静态内容托管模式”。
生成部署凭据
在 Azure CLI 中使用 az ad sp create-for-rbac 命令创建服务主体。 请使用 Azure 门户中的 Azure Cloud Shell 或选择“试用”按钮运行此命令。
az ad sp create-for-rbac --name "myML" --role contributor \
--scopes /subscriptions/<subscription-id>/resourceGroups/<group-name> \
--json-auth
参数 --json-auth
在 Azure CLI 版本 >= 2.51.0 中可用。 此版本之前的版本使用 --sdk-auth
,带有弃用警告。
在上面的示例中,请将占位符替换为你的订阅 ID、资源组名称和应用名称。 输出是一个 JSON 对象,包含的角色分配凭据可提供对应用服务应用的访问权限,如下所示。 复制此 JSON 对象供以后使用。
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
OpenID Connect 是一种使用短期令牌的身份验证方法。 使用 GitHub Actions 设置 OpenID Connect 的过程会更复杂,能提供更强的安全性。
如果当前没有应用程序,请注册一个新的可访问资源的 Microsoft Entra 应用程序和服务主体。
az ad app create --display-name myApp
此命令将输出 JSON,其中 appId
为你的 client-id
。 objectId
是 APPLICATION-OBJECT-ID
,它将用于通过图形 API 调用创建联合凭据。 保存该值,稍后将其用作 AZURE_CLIENT_ID
GitHub 机密。
创建服务主体。 将 $appID
替换为 JSON 输出中的 appId。 此命令使用不同的 objectId
生成 JSON 输出,将在下一步中使用。 新的 objectId
是 assignee-object-id
。
此命令使用不同的 objectId
生成 JSON 输出,将在下一步中使用。 新的 objectId
是 assignee-object-id
。
复制 appOwnerTenantId
以在稍后用作 AZURE_TENANT_ID
的 GitHub 机密。
az ad sp create --id $appId
按订阅和对象创建新的角色分配。 默认情况下,角色分配将绑定到默认订阅。 将 $subscriptionId
替换为你的订阅 ID,将 $resourceGroupName
替换为你的资源组名称,将 $assigneeObjectId
替换为生成的 assignee-object-id
(新创建的服务主体对象 ID)。
az role assignment create --role contributor --subscription $subscriptionId --assignee-object-id $assigneeObjectId --assignee-principal-type ServicePrincipal --scope /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName
运行以下命令,为 Microsoft Entra 应用程序创建新的联合标识凭据。
- 将
APPLICATION-OBJECT-ID
替换为 Microsoft Entra 应用程序的 objectId(在创建应用时生成)。
- 为
CREDENTIAL-NAME
设置一个值供以后引用。
- 设置
subject
。 此项的值由 GitHub 根据工作流定义:
- GitHub Actions 环境中的作业:
repo:< Organization/Repository >:environment:< Name >
- 对于未绑定到环境的作业,请根据用于触发工作流的 ref 路径包括分支/标记的 ref 路径:
repo:< Organization/Repository >:ref:< ref path>
。 例如 repo:n-username/ node_express:ref:refs/heads/my-branch
或 repo:n-username/ node_express:ref:refs/tags/my-tag
。
- 对于由拉取请求事件触发的工作流:
repo:< Organization/Repository >:pull_request
。
az ad app federated-credential create --id <APPLICATION-OBJECT-ID> --parameters credential.json
("credential.json" contains the following content)
{
"name": "<CREDENTIAL-NAME>",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:octo-org/octo-repo:environment:Production",
"description": "Testing",
"audiences": [
"api://AzureADTokenExchange"
]
}
在 GitHub 中,转到存储库。
转到导航菜单中的“设置”。
选择“安全性”>“机密和变量”>“操作”。
选择“新建存储库机密”。
将 Azure CLI 命令的整个 JSON 输出粘贴到机密的值字段中。 为机密指定名称 AZURE_CREDENTIALS
。
选择“添加机密”。
需要向登录操作提供应用程序的“客户端 ID”、“租户 ID”和“订阅 ID”。 这些值可直接在工作流中提供,或可存储在 GitHub 机密中并在工作流中引用。 将这些值保存为 GitHub 机密是更安全的选择。
在 GitHub 中,转到存储库。
选择“安全性”>“机密和变量”>“操作”。
选择“新建存储库机密”。
为 AZURE_CLIENT_ID
、AZURE_TENANT_ID
和 AZURE_SUBSCRIPTION_ID
创建机密。 将 Microsoft Entra 应用程序中的这些值用于 GitHub 机密:
GitHub 机密 |
Microsoft Entra 应用程序 |
AZURE_CLIENT_ID |
应用程序(客户端)ID |
AZURE_TENANT_ID |
目录(租户)ID |
AZURE_SUBSCRIPTION_ID |
订阅 ID |
通过选择“添加机密”来保存每个机密。
添加工作流
转到 GitHub 存储库的“操作”。
选择“自己设置工作流”。
删除工作流文件 on:
部分后面的所有内容。 例如,剩下的工作流可能如下所示。
name: CI
on:
push:
branches: [ main ]
将工作流重命名为 Blob storage website CI
,并添加签出和登录操作。 这些操作将签出你的站点代码,并使用之前创建的 AZURE_CREDENTIALS
GitHub 机密向 Azure 进行身份验证。
name: Blob storage website CI
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
利用 Azure CLI 操作将代码上传到 blob 存储,并清除 CDN 终结点。 对于 az storage blob upload-batch
,将占位符替换为存储帐户的名称。 脚本将上传到 $web
容器。 对于 az cdn endpoint purge
,将占位符替换为 CDN 配置文件名称、CDN 终结点名称和资源组。 若要加快 CDN 清除的速度,可以将 --no-wait
选项添加到 az cdn endpoint purge
。 若要增强安全性,还可以在存储帐户密钥中添加 --account-key
选项。
- name: Upload to blob storage
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --auth-mode key -d '$web' -s .
- name: Purge CDN endpoint
uses: azure/CLI@v1
with:
inlineScript: |
az cdn endpoint purge --content-paths "/*" --profile-name "CDN_PROFILE_NAME" --name "CDN_ENDPOINT" --resource-group "RESOURCE_GROUP"
通过添加注销 Azure 的操作来完成工作流。 下面是已完成的工作流。 文件将显示在存储库的 .github/workflows
文件夹中。
name: Blob storage website CI
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Upload to blob storage
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --auth-mode key -d '$web' -s .
- name: Purge CDN endpoint
uses: azure/CLI@v1
with:
inlineScript: |
az cdn endpoint purge --content-paths "/*" --profile-name "CDN_PROFILE_NAME" --name "CDN_ENDPOINT" --resource-group "RESOURCE_GROUP"
# Azure logout
- name: logout
run: |
az logout
if: always()
转到 GitHub 存储库的“操作”。
选择“自己设置工作流”。
删除工作流文件 on:
部分后面的所有内容。 例如,剩下的工作流可能如下所示。
name: CI with OpenID Connect
on:
push:
branches: [ main ]
添加权限部分。
name: CI with OpenID Connect
on:
push:
branches: [ main ]
permissions:
id-token: write
contents: read
添加签出和登录操作。 这些操作将签出你的站点代码,并使用之前创建的 GitHub 机密向 Azure 进行身份验证。
name: CI with OpenID Connect
on:
push:
branches: [ main ]
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
利用 Azure CLI 操作将代码上传到 blob 存储,并清除 CDN 终结点。 对于 az storage blob upload-batch
,将占位符替换为存储帐户的名称。 脚本将上传到 $web
容器。 对于 az cdn endpoint purge
,将占位符替换为 CDN 配置文件名称、CDN 终结点名称和资源组。 若要加快 CDN 清除的速度,可以将 --no-wait
选项添加到 az cdn endpoint purge
。 若要增强安全性,还可以在存储帐户密钥中添加 --account-key
选项。
- name: Upload to blob storage
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --auth-mode key -d '$web' -s .
- name: Purge CDN endpoint
uses: azure/CLI@v1
with:
inlineScript: |
az cdn endpoint purge --content-paths "/*" --profile-name "CDN_PROFILE_NAME" --name "CDN_ENDPOINT" --resource-group "RESOURCE_GROUP"
通过添加注销 Azure 的操作来完成工作流。 下面是已完成的工作流。 文件将显示在存储库的 .github/workflows
文件夹中。
name: CI with OpenID Connect
on:
push:
branches: [ main ]
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Upload to blob storage
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --auth-mode key -d '$web' -s .
- name: Purge CDN endpoint
uses: azure/CLI@v1
with:
inlineScript: |
az cdn endpoint purge --content-paths "/*" --profile-name "CDN_PROFILE_NAME" --name "CDN_ENDPOINT" --resource-group "RESOURCE_GROUP"
# Azure logout
- name: logout
run: |
az logout
if: always()
查看部署
转到 GitHub 存储库的“操作”。
打开第一个结果,查看工作流运行的详细日志。
清理资源
如果不再需要静态网站和 GitHub 存储库,请删除资源组和 GitHub 存储库,以清理部署的资源。
后续步骤