你可以用 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 儲存庫中。
建立 Azure Functions 的工作流程設定
你維護一個 YAML 檔案(.yml),定義你倉庫路徑中的 /.github/workflows/ 工作流程設定。 此定義包含組成工作流程的動作和參數,其專屬於函式的開發語言。
請使用文章頂端的選擇器選擇一種建立工作流程檔案的方法:
| 方法 |
最適合用於 |
OIDC 支援 |
|
工作流程範本 |
完全控制:複製一個 OIDC 準備好的範本並自訂 |
需要設定 |
|
Azure portal |
最簡單的設定:入口網站可以幫你建立身份、憑證和工作流程檔案 |
已為您設定完成 |
|
GitHub 市集 |
以 GitHub 為先:從 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 role 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 檔案前,請先完成以下步驟:
- 根據您的容器登錄,更新
REGISTRY、NAMESPACE、IMAGE 和 TAG 的值。
- 在動作
docker/login-action 中更新容器儲存庫的憑證。
在範本中更新 env: 專案變數。 每個範本都需要 AZURE_FUNCTIONAPP_NAME。 其他變數則取決於你的語言:
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
您在 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 |
是的 |
您在 Azure 中的函式應用程式名稱 |
NODE_VERSION |
是的 |
你專案的 Node.js 版本(例如, 22) |
AZURE_FUNCTIONAPP_PROJECT_PATH |
否 |
你的專案資料夾路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
您在 Azure 中的函式應用程式名稱 |
PYTHON_VERSION |
是的 |
你專案的 Python 版本(例如,3.13.x) |
AZURE_FUNCTIONAPP_PROJECT_PATH |
否 |
你的專案資料夾路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
您在 Azure 中的函式應用程式名稱 |
AZURE_FUNCTIONAPP_PROJECT_PATH |
否 |
你的專案資料夾路徑。 預設值: . (儲存庫根) |
| Variable |
必要 |
Description |
AZURE_FUNCTIONAPP_NAME |
是的 |
您在 Azure 中的函式應用程式名稱 |
REGISTRY |
是的 |
你的容器登錄登錄伺服器(例如, contoso.azurecr.io) |
NAMESPACE |
是的 |
你登錄檔中的命名空間/儲存庫 |
IMAGE |
是的 |
容器影像名稱 |
TAG |
是的 |
圖片標籤(例如, ${{ github.sha }}) |
OIDC 範本已包含使用 OIDC 驗證的 azure/login 步驟。 確認 、 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 並符合入口網站行為,請做出以下調整:
從 Azure/functions-action 中移除 publish-profile、scm-do-build-during-deployment 和 enable-oryx-build 參數。
如果作業中有設定 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 方案時要求遠端建置。 遠端版本總是用 Oryx。 也不要設定 scm-do-build-during-deployment 或 enable-oryx-build。 預設值:false。 |
|
SCM-DO-部署期間建置 |
允許 Kudu 站點執行部署前的操作,例如 遠端建置。 設定為 true 讓 Kudu 在部署時建置你的專案。 預設值:false。 如需詳細資訊,請參閱 SCM_DO_BUILD_DURING_DEPLOYMENT。 |
|
啟用 Oryx 建置 |
允許 Kudu 透過使用 Oryx 來解決專案相依性。 將此項和 scm-do-build-during-deployment 都設為 true,以使用 Oryx 而非工作流程。 預設值:false。 僅限 Linux。 |
|
slot-name |
要部署到的 部署位置。 預設:實際執行插槽。 |
|
發佈-設定檔 |
包含發行設定檔的 GitHub 祕密名稱。 使用推薦的 OIDC 認證時不需要。 |
|
斯庫 |
在 Flex Consumption 方案中使用 publish-profile 進行驗證時,請設為 flexconsumption。 使用 OIDC 認證或其他主機方案則不需要。 |
|
respect-pom-xml |
(僅限 Java)將其設為 true,即可從 pom.xml 衍生部署成品。 當 true,將 package 設為 .。 預設值:false。 |
|
respect-funcignore |
設定為 true 以尊重你的 .funcignore 檔案並排除列出的路徑。 預設值:false。 |
下表顯示每個主機計畫所支援的參數:
| 參數 |
彈性使用量 |
彈性進階版 |
專用 |
使用量 |
|
app-name |
必要 |
必要 |
必要 |
必要 |
|
套件 |
必要 |
必要 |
必要 |
必要 |
|
遠端建置 |
Optional |
— |
— |
— |
|
SCM-DO-部署期間建置 |
— |
Optional |
Optional |
Optional |
|
啟用 Oryx 建置 |
— |
可選(Linux) |
可選(Linux) |
可選(Linux) |
|
slot-name |
不支援 |
Optional |
Optional |
Optional |
|
發佈-設定檔 |
不建議使用 |
不建議使用 |
不建議使用 |
不建議使用 |
|
斯庫 |
僅限發佈-設定檔 |
— |
— |
— |
|
respect-pom-xml |
可選(Java) |
可選(Java) |
可選(Java) |
可選(Java) |
|
respect-funcignore |
Optional |
Optional |
Optional |
Optional |
部署方法
當你使用 GitHub Actions 時,部署方式取決於你的主機計畫:
* 在使用量方案中在 Linux 上執行應用程式的能力計劃即將淘汰。 欲了解更多資訊,請參閱 Azure Functions 消費方案託管。
如需詳細資訊,請參閱 Azure Functions 中的部署技術。
後續步驟