你可以用 GitHub Actions 工作流程自動建置並部署函式程式碼到 Azure,方法是使用 Azure/functions-action.
要使用 GitHub Actions 部署,請完成以下三個關鍵步驟:
- 在 Azure 建立一個由使用者指派的管理身份,並使用一個聯邦憑證,信任你的 GitHub 倉庫,並在你的函式應用程式中將其指定為網站貢獻者角色。
- 在 GitHub 中將身份的客戶端 ID、租戶 ID 和訂閱 ID 作為倉庫秘密加入。
- 在你的資料庫中加入一個工作流程 YAML 檔案,該檔案使用
azure/login OpenID Connect(OIDC)來認證,然後呼叫 Azure/functions-action 部署。
當你使用 Azure 入口網站啟用 GitHub Actions 時,Functions 會自動執行這些任務,無論是在你的 Azure 訂閱還是 GitHub 儲存庫中。
Create a workflow configuration for Azure Functions
你維護一個 YAML 檔案(.yml),定義你倉庫路徑中的 /.github/workflows/ 工作流程設定。 此定義包含組成工作流程的動作和參數,其專屬於函式的開發語言。
請使用文章頂端的選擇器選擇一種建立工作流程檔案的方法:
| 方法 |
最適合用於 |
OIDC 支援 |
|
工作流程範本 |
完全控制:複製一個 OIDC 準備好的範本並自訂 |
需要設定 |
|
Azure portal |
最簡單的設定:入口網站可以幫你建立身份、憑證和工作流程檔案 |
為您設定 |
|
GitHub 市集 |
GitHub-first:從 GitHub 內建的市場範本開始 |
需要設定與範本修改 |
驗證概觀
GitHub Actions 必須透過 Azure 進行驗證才能部署你的程式碼。 本文使用 OpenID Connect(OIDC),這是推薦的認證方法。 OIDC 利用聯邦憑證在你的 GitHub 倉庫與 Microsoft Entra 中使用者指派的管理身份之間建立信任關係。 GitHub 中不會儲存任何秘密。
OIDC 認證範例
以下內嵌範例展示了所有工作流程範本中核心的 OIDC 認證與部署模式:
permissions:
id-token: write
contents: read
steps:
- name: 'Login via OIDC'
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: 'Deploy to Azure Functions'
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
GitHub Actions OIDC 認證考量
- OIDC 使用 工作負載身份聯盟 ,僅支援使用者指派的受管理身份。
- 當你在 Azure 入口網站啟用基於 GitHub Actions 的部署時,預設會使用 OIDC 認證。
- 在 OIDC 中,受管理身份的客戶端 ID、租戶 ID 和訂閱 ID 會被儲存為 GitHub 倉庫的秘密。
- 使用 Azure 角色基礎存取控制(Azure RBAC),限制只存取部署所需的 Azure 資源。
先決條件
-
Azure CLI,在本地開發時。 你也可以在 Azure Cloud Shell 中使用 Azure CLI。
建立一個管理身份以部署 GitHub Actions
OpenID Connect(OIDC)是 GitHub Actions 部署至 Azure Functions 的推薦認證方法。 使用 OIDC,你可以在 Azure 中設定使用者指派的管理身份,並與你的 GitHub 倉庫建立信任關係。 該工作流程可以直接用 Azure 認證,而不會將憑證存為秘密。
使用 az identity create 命令來建立使用者指派的受控識別 (即受管理的身分識別):
az identity create --name myGitHubDeployIdentity --resource-group <RESOURCE_GROUP> \
--query "{clientId: clientId, tenantId: tenantId}" -o table
將 <RESOURCE_GROUP> 以您的資源群組名稱取代。
從輸出中注意 clientId 和 tenantId 值。 另外,請提供你的訂閱 ID:
az account show --query "{subId: id}" -o table
你之後在 GitHub 新增憑證時,需要這三個值。
使用 az 角色 assignment create 指令將角色指派 Website Contributor 到管理身份,並針對你的函式應用程式設範圍:
IDENTITY_PRINCIPAL=$(az identity show --name myGitHubDeployIdentity --resource-group <RESOURCE_GROUP> --query 'principalId' -o tsv)
FUNCTION_APP_ID=$(az functionapp show --name <APP_NAME> --resource-group <RESOURCE_GROUP> --query 'id' -o tsv)
az role assignment create --assignee $IDENTITY_PRINCIPAL --role "Website Contributor" --scope $FUNCTION_APP_ID
分別用你的應用程式名稱和資源群組來取代 <APP_NAME> 和 <RESOURCE_GROUP> 。
使用 az identity federated-credential create 指令,建立一個信任你 GitHub 倉庫中代幣的聯邦憑證:
az identity federated-credential create \
--identity-name myGitHubDeployIdentity \
--resource-group <RESOURCE_GROUP> \
--name github-deploy-credential \
--issuer https://token.actions.githubusercontent.com \
--subject repo:<GITHUB_ORG>/<REPO_NAME>:ref:refs/heads/<BRANCH_NAME> \
--audiences api://AzureADTokenExchange
以您自己的值取代 <RESOURCE_GROUP>、<GITHUB_ORG>、<REPO_NAME> 和 <BRANCH_NAME>。 主體必須與觸發你工作流程的分支相符。
(可選)如果你是從 Azure Container Registry 部署容器,也請將該角色指派acrpull給受管理身份:
IDENTITY_PRINCIPAL=$(az identity show --name myGitHubDeployIdentity --resource-group <RESOURCE_GROUP> --query 'principalId' -o tsv)
az role assignment create --assignee $IDENTITY_PRINCIPAL --role acrpull \
--scope /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.ContainerRegistry/registries/<REGISTRY_NAME>
用你的數值替換 <SUBSCRIPTION_ID>、<RESOURCE_GROUP> 和 <REGISTRY_NAME>。
將憑證加入 GitHub
使用你 建立管理身份時複製的值。
在GitHub,進入你的儲存庫。
前往 設定>秘密與變數>動作。
在 Secrets 標籤中,選擇 「New repository secret」。
創造以下各項秘密:
| Name |
價值 |
AZURE_CLIENT_ID |
管理身份的概念clientId |
AZURE_TENANT_ID |
管理身份的概念tenantId |
AZURE_SUBSCRIPTION_ID |
包含你功能應用程式的訂閱 ID |
從私有登錄檔部署容器時,你也需要特定的登錄檔秘密。 欲了解更多資訊,請參閱 Docker 登入動作。
從範本建立工作流程
手動建立工作流程設定的最佳方式是從正式支援的範本開始。
請選擇 Windows 或 Linux,以確保你取得的是正確的作業系統範本。
部署至 Windows 會使用 runs-on: windows-latest。 容器化部署需要 Linux。
部署至 Linux 會使用 runs-on: ubuntu-latest。 容器化部署時使用 Linux。
請使用來自 Azure Functions 動作庫的語言專用 OIDC 工作流程範本。 將完整檔案內容複製到你儲存庫中一個新命名 .github/workflows/deploy-function-app.yml 的檔案:
name: Build and deploy .NET project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # Set this to your function app name on Azure
AZURE_FUNCTIONAPP_PROJECT_PATH: '.' # Set this to the path to your function app project, defaults to the repository root. The deploy action will package the contents of this path.
DOTNET_VERSION: '10.0.x' # Set this to the .NET version of your project
BUILD_ARTIFACT_NAME: 'released-package' # Set this according to your team's naming convention
jobs:
build:
runs-on: windows-latest # Assumes your target function app is Windows-based
permissions:
id-token: write # Required for OIDC
contents: read # Required for actions/checkout
defaults:
run:
shell: bash
working-directory: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
- name: 'Set up .NET version: ${{ env.DOTNET_VERSION }}'
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
# Perform additional steps such as running tests, if needed
- name: 'Build and prepare .NET project for deployment'
run: dotnet publish --configuration Release --output ./output
- name: Upload artifact for the deployment job
uses: actions/upload-artifact@v7
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/output
include-hidden-files: true # Required for .NET projects
deploy:
runs-on: windows-latest # Assumes your target function app is Windows-based
needs: build
permissions:
id-token: write # Required for OIDC
steps:
- name: 'Download artifact from build job'
uses: actions/download-artifact@v8
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
name: Build and deploy .NET project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # Set this to your function app name on Azure
AZURE_FUNCTIONAPP_PROJECT_PATH: '.' # Set this to the path to your function app project, defaults to the repository root. The deploy action will package the contents of this path.
DOTNET_VERSION: '10.0.x' # Set this to the .NET version of your project
BUILD_ARTIFACT_NAME: 'released-package' # Set this according to your team's naming convention
jobs:
build:
runs-on: ubuntu-latest # Assumes your target function app is Linux-based
permissions:
id-token: write # Required for OIDC
contents: read # Required for actions/checkout
defaults:
run:
shell: bash
working-directory: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
- name: 'Set up .NET version: ${{ env.DOTNET_VERSION }}'
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
# Perform additional steps such as running tests, if needed
- name: 'Build and prepare .NET project for deployment'
run: dotnet publish --configuration Release --output ./output
- name: Upload artifact for the deployment job
uses: actions/upload-artifact@v7
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/output
include-hidden-files: true # Required for .NET projects
deploy:
runs-on: ubuntu-latest # Assumes your target function app is Linux-based
needs: build
permissions:
id-token: write # Required for OIDC
steps:
- name: 'Download artifact from build job'
uses: actions/download-artifact@v8
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
name: Build and deploy Java project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # set this to your function app name on Azure. Ensure that `functionAppName` in your pom.xml file matches.
POM_XML_DIRECTORY: '.' # set this to the directory which contains the pom.xml file. The deploy action will package the contents of this path.
JAVA_VERSION: '21' # set this to the Java version of your project
BUILD_ARTIFACT_NAME: 'released-package' # Set this according to your team's naming convention
jobs:
build:
runs-on: windows-latest # Assumes your target function app is Windows-based
permissions:
id-token: write # Required to fetch an OIDC token to authenticate with the job
contents: read # Required for actions/checkout
defaults:
run:
shell: bash
working-directory: ${{ env.POM_XML_DIRECTORY }}
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
- name: 'Set up Java version: ${{ env.JAVA_VERSION }}'
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'microsoft'
- name: 'Build project with Maven'
run: mvn clean package -DfunctionAppName=${{ env.AZURE_FUNCTIONAPP_NAME }}
# Perform additional steps such as running tests, if needed
- name: 'Upload artifact for the deployment job'
uses: actions/upload-artifact@v7
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ${{ env.POM_XML_DIRECTORY }}/target/azure-functions/${{ env.AZURE_FUNCTIONAPP_NAME }}
deploy:
runs-on: windows-latest # Assumes your target function app is Windows-based
needs: build
permissions:
id-token: write # Required to fetch an OIDC token to authenticate with the job
steps:
- name: 'Download artifact from build job'
uses: actions/download-artifact@v8
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: '${{ env.POM_XML_DIRECTORY }}/downloaded-artifact'
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.POM_XML_DIRECTORY }}/downloaded-artifact'
respect-pom-xml: false # Set to `true` if the build artifact path is ${{ env.POM_XML_DIRECTORY }}
name: Build and deploy Java project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # set this to your function app name on Azure. Ensure that `functionAppName` in your pom.xml file matches.
POM_XML_DIRECTORY: '.' # set this to the directory which contains the pom.xml file. The deploy action will package the contents of this path.
JAVA_VERSION: '21' # set this to the Java version of your project
BUILD_ARTIFACT_NAME: 'released-package' # Set this according to your team's naming convention
jobs:
build:
runs-on: ubuntu-latest # Assumes your target function app is Linux-based
permissions:
id-token: write # Required to fetch an OIDC token to authenticate with the job
contents: read # Required for actions/checkout
defaults:
run:
shell: bash
working-directory: ${{ env.POM_XML_DIRECTORY }}
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
- name: 'Set up Java version: ${{ env.JAVA_VERSION }}'
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'microsoft'
- name: 'Build project with Maven'
run: mvn clean package -DfunctionAppName=${{ env.AZURE_FUNCTIONAPP_NAME }}
# Perform additional steps such as running tests, if needed
- name: 'Upload artifact for the deployment job'
uses: actions/upload-artifact@v7
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ${{ env.POM_XML_DIRECTORY }}/target/azure-functions/${{ env.AZURE_FUNCTIONAPP_NAME }}
deploy:
runs-on: ubuntu-latest # Assumes your target function app is Linux-based
needs: build
permissions:
id-token: write # Required to fetch an OIDC token to authenticate with the job
steps:
- name: 'Download artifact from build job'
uses: actions/download-artifact@v8
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: '${{ env.POM_XML_DIRECTORY }}/downloaded-artifact'
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.POM_XML_DIRECTORY }}/downloaded-artifact'
respect-pom-xml: false # Set to `true` if the build artifact path is ${{ env.POM_XML_DIRECTORY }}
name: Build and deploy Node.js project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # Set this to your function app name on Azure
AZURE_FUNCTIONAPP_PROJECT_PATH: '.' # Set this to the path to your function app project, defaults to the repository root. The deploy action will package the contents of this path.
NODE_VERSION: '22' # Set this to the Node version of your project
BUILD_ARTIFACT_NAME: 'released-package' # Set this according to your team's naming convention
jobs:
build:
runs-on: windows-latest # Assumes your target function app is Windows-based
permissions:
id-token: write # Required for OIDC
contents: read # Required for actions/checkout
defaults:
run:
shell: bash
working-directory: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
- name: 'Set up Node version: ${{ env.NODE_VERSION }}'
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: 'Install project dependencies'
run: npm install # Use `npm ci` if you have a package-lock.json file and want to ensure a clean install
- name: 'Build project'
run: npm run build --if-present
- name: 'Run tests'
run: npm run test --if-present
- name: 'Prune development dependencies'
run: npm prune --production
- name: 'Upload artifact for the deployment job'
uses: actions/upload-artifact@v7
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
deploy:
runs-on: windows-latest # Assumes your target function app is Windows-based
needs: build
permissions:
id-token: write # Required for OIDC
steps:
- name: 'Download artifact from build job'
uses: actions/download-artifact@v8
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
name: Build and deploy Node.js project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # Set this to your function app name on Azure
AZURE_FUNCTIONAPP_PROJECT_PATH: '.' # Set this to the path to your function app project, defaults to the repository root. The deploy action will package the contents of this path.
NODE_VERSION: '22' # Set this to the Node version of your project
BUILD_ARTIFACT_NAME: 'released-package' # Set this according to your team's naming convention
jobs:
build:
runs-on: ubuntu-latest # Assumes your target function app is Linux-based
permissions:
id-token: write # Required for OIDC
contents: read # Required for actions/checkout
defaults:
run:
shell: bash
working-directory: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
- name: 'Set up Node version: ${{ env.NODE_VERSION }}'
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: 'Install project dependencies'
run: npm install # Use `npm ci` if you have a package-lock.json file and want to ensure a clean install
- name: 'Build project'
run: npm run build --if-present
- name: 'Run tests'
run: npm run test --if-present
- name: 'Prune development dependencies'
run: npm prune --production
- name: 'Upload artifact for the deployment job'
uses: actions/upload-artifact@v7
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
deploy:
runs-on: ubuntu-latest # Assumes your target function app is Linux-based
needs: build
permissions:
id-token: write # Required for OIDC
steps:
- name: 'Download artifact from build job'
uses: actions/download-artifact@v8
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
Windows 不支援 Python 函式。 請改為選擇 Linux。
name: Build and deploy Python project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # Set this to your function app name on Azure
AZURE_FUNCTIONAPP_PROJECT_PATH: '.' # Set this to the path to your function app project, defaults to the repository root. The deploy action will package the contents of this path.
PYTHON_VERSION: '3.13.x' # Set this to the Python version of your project
BUILD_ARTIFACT_NAME: 'released-package' # Set this according to your team's naming convention
jobs:
build:
runs-on: ubuntu-latest # Python function apps are Linux-based
permissions:
id-token: write # Required for OIDC
contents: read # Required for actions/checkout
defaults:
run:
shell: bash
working-directory: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
- name: 'Set up Python version: ${{ env.PYTHON_VERSION }}'
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: 'Install project dependencies'
run: pip install -r requirements.txt --target ".python_packages/lib/site-packages" # Ensure requirements.txt contains all dependencies
# Perform additional steps such as running tests, if needed
- name: 'Upload artifact for the deployment job'
uses: actions/upload-artifact@v7
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
deploy:
runs-on: ubuntu-latest # Python function apps are Linux-based
needs: build
permissions:
id-token: write # Required for OIDC
steps:
- name: 'Download artifact from build job'
uses: actions/download-artifact@v8
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/downloaded-artifact'
name: Deploy PowerShell project to Azure Function App using OIDC
on:
push:
branches: [ main ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: 'APP_NAME' # Set this to your function app name on Azure
AZURE_FUNCTIONAPP_PROJECT_PATH: '.' # Set this to the path to your function app project, defaults to the repository root. The deploy action will package the contents of this path.
jobs:
# PowerShell projects do not require a build step
deploy:
runs-on: windows-latest # For PowerShell projects, the OS of the runner does not affect deployment. You may use either ubuntu-latest or windows-latest.
permissions:
id-token: write # Required for OIDC
contents: read # Required for actions/checkout
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
# Perform additional steps such as running tests, if needed
- name: 'Log in to Azure with AZ CLI'
uses: azure/login@v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Run the Azure Functions action'
uses: Azure/functions-action@v1
id: deploy-to-function-app
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}
Linux 不支援 PowerShell 函式。 選擇 Windows 吧。
Windows 不支援容器部署。 請改為選擇 Linux。
# Action Requires
# 1. Setup the AZURE_CREDENTIALS secrets in your GitHub Repository
name: Linux_Container_Workflow
on:
push:
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
environment: dev
steps:
- name: 'Checkout GitHub Action'
uses: actions/checkout@v3
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Docker Login'
uses: azure/docker-login@v1
with:
login-server: contoso.azurecr.io
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: 'Compose Customized Docker Image'
shell: bash
run: |
# If your function app project is not located in your repository's root
# Please change the path to your directory for docker build
docker build . -t REGISTRY/NAMESPACE/IMAGE:TAG
docker push REGISTRY/NAMESPACE/IMAGE:TAG
- name: 'Run Azure Functions Container Action'
uses: Azure/functions-container-action@v1
id: fa
with:
app-name: PLEASE_REPLACE_THIS_WITH_YOUR_FUNCTION_APP_NAME
image: REGISTRY/NAMESPACE/IMAGE:TAG
#- name: 'use the published functionapp url in upcoming steps'
# run: |
# echo "${{ steps.fa.outputs.app-url }}"
- name: Azure logout
run: |
az logout
在使用此 YAML 檔案前,請先完成以下步驟:
- 根據你的容器登錄檔,更新 、
REGISTRYNAMESPACEIMAGE 、 和 的數值。TAG
- 在動作
docker/login-action 中更新容器儲存庫的憑證。
在範本中更新 env: 專案變數。 每個範本都需要 AZURE_FUNCTIONAPP_NAME。 其他變數則取決於你的語言:
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
Your function app name in Azure |
DOTNET_VERSION |
是的 |
你的專案的 .NET 版本(例如,10.0.x) |
AZURE_FUNCTIONAPP_PROJECT_PATH |
否 |
你的專案資料夾路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
你在 Azure 裡的函式應用程式名稱。 必須在 pom.xml中匹配 functionAppName 。 |
JAVA_VERSION |
是的 |
你專案的 Java 版本(例如,21) |
POM_XML_DIRECTORY |
否 |
包含 pom.xml的目錄路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
Your function app name in Azure |
NODE_VERSION |
是的 |
你專案的 Node.js 版本(例如, 22) |
AZURE_FUNCTIONAPP_PROJECT_PATH |
否 |
你的專案資料夾路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
Your function app name in Azure |
PYTHON_VERSION |
是的 |
你專案的 Python 版本(例如,3.13.x) |
AZURE_FUNCTIONAPP_PROJECT_PATH |
否 |
你的專案資料夾路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
Your function app name in Azure |
AZURE_FUNCTIONAPP_PROJECT_PATH |
否 |
你的專案資料夾路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
Your function app name in Azure |
REGISTRY |
是的 |
你的容器登錄登錄伺服器(例如, contoso.azurecr.io) |
NAMESPACE |
是的 |
你登錄檔中的命名空間/儲存庫 |
IMAGE |
是的 |
容器影像名稱 |
TAG |
是的 |
圖片標籤(例如, ${{ github.sha }}) |
OIDC 範本已經包含 azure/login OIDC 認證的步驟。 確認 、 secrets.AZURE_CLIENT_ID和 secrets.AZURE_TENANT_ID 參考資料是否secrets.AZURE_SUBSCRIPTION_ID與你建立的儲存庫秘密相符。
在存放庫的 /.github/workflows/ 路徑中新增這個 YAML 檔案。
在入口網站中建立工作流程設定
當你用入口網站啟用 GitHub Actions 時,Functions 會自動處理所有設定。 你不需要手動建立管理身份、設定憑證或撰寫工作流程檔案。 功能會幫你執行以下任務:
在你的 Azure 訂閱中:
- 建立一個由使用者指派的管理身份,並在你的函式應用程式中指派其為 網站貢獻者角色 。
- 為 GitHub OIDC 認證的管理身份新增一個聯邦憑證。
在您的 GitHub 倉庫中:
- 新增客戶端 ID、訂閱 ID 和租戶 ID 值作為 GitHub Actions 秘密。
- 根據你的應用程式堆疊建立工作流程檔案並提交給
.github/workflows。
函數應用程式建立期間
你可以在 Azure 入口網站建立函式時,透過部署標籤快速開始使用 GitHub Actions。 若要在建立新函式應用程式時,新增 GitHub Actions 工作流程:
在 Azure 入口網站,選擇 Create Function App流程中的 Deployment。
如果你希望每次程式碼更新能觸發將程式碼推送到 Azure 入口網站,請啟用Continuous Deployment。
在 GitHub 設定中,選擇授權以連結你的 GitHub 帳號。 請用擁有寫入權限的 GitHub 帳號登入你的儲存庫。
輸入你的 GitHub 組織、資料庫和分支。
可選擇 預覽檔案 ,查看工作流程檔案在生成並加入儲存庫前的樣貌。
完成函數應用程式的設定。 你的GitHub倉庫現在包含一個新的工作流程檔案,格式為 /.github/workflows/。
針對現有的函數應用程式
要將 GitHub Actions 工作流程加入現有函式應用程式:
在 Azure 入口網站進入你的函式應用程式,選擇部署>部署中心。
選擇持續部署(CI/CD)。 針對 [來源],選取 [GitHub]。 如果你沒有看到預設訊息「用 GitHub Actions 建構」,請選擇「變更提供者」,再選擇「GitHub Actions」,再選擇「確定」。
如果你還沒授權 GitHub 存取,請選擇授權。 請提供您的GitHub憑證,並選擇登入。 若要授權不同的GitHub帳號,請選擇變更帳號並以另一個帳號登入。
選擇你的 GitHub Organization、Repository,以及 Branch。 要使用 GitHub Actions 部署,您必須擁有該倉庫的寫入權限。
在 工作流程選項中,選擇 新增工作流程。 此選項會建立一個新的工作流程檔案。/.github/workflows/ 若要使用現有工作流程,請選擇 「可用工作流程 」並選擇您的工作流程檔案。
在驗證設定中,選擇使用者指派身份以使用 OpenID Connect(OIDC),這是推薦的,因為它不需要你在 GitHub 中儲存秘密。 選擇您的訂閱及 (新) 建議的身份名稱。 建立一個新的使用者指派管理身份,並授予 網站貢獻 者角色的存取權。 如果您使用現有身份,必須先授權其存取網站 貢獻者 角色。
重要事項
當你選擇 Basic 認證時,包含共享秘密的發佈設定檔會儲存在 GitHub Secrets。 你也必須 啟用 SCM 基本認證,這會降低應用程式的安全性。
選取預覽檔案,以看到在.github/workflows/中,新增至 GitHub 存放庫的工作流程檔案。
選取 [儲存] 以將工作流程檔案新增至存放庫。 選擇 「日誌 」標籤以查看目前及過去部署的狀態。
建立工作流程組態檔
你可以直接從 GitHub 倉庫從 Azure Functions 範本建立 GitHub Actions 工作流程設定檔。
在GitHub,進入你的儲存庫。
選取 [動作],然後選取 [新增工作流程]。
搜尋函式。
在顯示的 Microsoft Azure 撰寫的函式應用程式工作流程中,找到符合你程式碼語言的,然後選擇配置。
在新建立的 YAML 檔案中,將 env.AZURE_FUNCTIONAPP_NAME 參數更新為 Azure 中函式應用程式資源的名稱。 你可能還需要更新設定應用程式所用語言版本的參數,例如 DOTNET_VERSION C# 或 PYTHON_VERSION Python 應用程式。
預設範本可能會使用發佈設定檔認證,而非推薦的 OIDC。 要切換到 OIDC 並符合入口網站行為,請做出以下調整:
從 中移除 publish-profile、 scm-do-build-during-deployment、 enable-oryx-build 和 參數。Azure/functions-action
如果有設定 environment ,請從工作中移除,因為聯邦憑證主體必須與分支觸發器相符。
在步驟azure/login前加一個Azure/functions-action步驟:
- name: 'Login via OIDC'
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: 'Run Azure Functions Action'
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
為工作新增以下權限:
permissions:
id-token: write
contents: read
確認新工作流程檔案已以適當名稱儲存, /.github/workflows/ 並選擇 提交變更。
Azure Functions 動作
Azure Functions動作(Azure/functions-action)定義了你的程式碼如何發佈到Azure中現有函式應用程式,或是應用程式中的特定欄位。
參數
下表描述了由 Azure/functions-action以下方式支援的輸入參數:
| 參數 |
Description |
|
app-name |
(必修)你在 Azure 中功能應用程式的名稱。 |
|
套件 |
(必修)你計畫出版的路徑。 預設值: . (倉庫中所有檔案)。 |
|
遠端建置 |
設定為 true 在部署到 Flex Consumption 應用程式時啟用 Kudu 的建置動作。 羚羊流派必執行;也不要同時設定 SCM-do-build-during deployment 或 enable-oryx-build。 預設值:false。 |
|
SCM-DO-部署期間建置 |
允許 Kudu 站點執行部署前的操作,例如 遠端建置。 設定為 true 讓 Kudu 在部署時建置你的專案。 預設值:false。 如需詳細資訊,請參閱 SCM_DO_BUILD_DURING_DEPLOYMENT。 |
|
可建奧瑞克斯建置 |
允許 Kudu 透過使用 Oryx 來解決專案相依性。 將此和 scm-do-build-during deployment 都設為 true 使用 Oryx 而非工作流程。 預設值:false。 僅限 Linux。 |
|
slot-name |
部署時 段 。 預設:生產槽。 |
|
publish-profile |
包含發行設定檔的 GitHub 祕密名稱。 使用推薦的 OIDC 認證時不需要。 |
|
斯庫 |
在使用 Flex Consumption 方案使用 flexconsumption 驗證時設定為 。 使用 OIDC 認證或其他主機方案則不需要。 |
|
尊重-POM-XML |
(僅Java)設定為 以true從 pom.xml衍生部署工件。 當 true,將 package 設為 .。 預設值:false。 |
|
尊重函數忽略 |
設定為 true 以尊重你的 .funcignore 檔案並排除列出的路徑。 預設值:false。 |
下表顯示每個主機計畫所支援的參數:
| 參數 |
彈性使用量 |
彈性進階版 |
專用 |
使用量 |
|
app-name |
必要 |
必要 |
必要 |
必要 |
|
套件 |
必要 |
必要 |
必要 |
必要 |
|
遠端建置 |
Optional |
— |
— |
— |
|
SCM-DO-部署期間建置 |
— |
Optional |
Optional |
Optional |
|
可建奧瑞克斯建置 |
— |
可選(Linux) |
可選(Linux) |
可選(Linux) |
|
slot-name |
不支援 |
Optional |
Optional |
Optional |
|
publish-profile |
不建議使用 |
不建議使用 |
不建議使用 |
不建議使用 |
|
斯庫 |
僅發布個人資料 |
— |
— |
— |
|
尊重-POM-XML |
可選(Java) |
可選(Java) |
可選(Java) |
可選(Java) |
|
尊重函數忽略 |
Optional |
Optional |
Optional |
Optional |
部署方法
當你使用 GitHub Actions 時,部署方式取決於你的主機計畫:
* 在使用量方案中在 Linux 上執行應用程式的能力計劃即將淘汰。 欲了解更多資訊,請參閱 Azure Functions 消費方案託管。
如需詳細資訊,請參閱 Azure Functions 中的部署技術。
後續步驟