06 - CI/CD (Flex Consumption)¶
Automate build, test, and deployment using GitHub Actions and Maven so every change ships through the same pipeline.
Prerequisites¶
| Tool | Version | Purpose |
|---|---|---|
| JDK | 17+ | Compile and run Java functions locally |
| Maven | 3.6+ | Build and package Java artifacts |
| Azure Functions Core Tools | v4 | Start local host and publish artifacts |
| Azure CLI | 2.61+ | Provision Azure resources and inspect app state |
| GitHub repository | — | Source code hosting with Actions enabled |
Flex Consumption plan basics
Flex Consumption (FC1) keeps serverless economics while adding VNet integration, configurable instance memory (512 MB to 4096 MB), and per-function scaling. Microsoft recommends it for many new apps.
What You'll Build¶
You will configure a GitHub Actions pipeline that builds and deploys a Java Function App to Flex Consumption, then verify the release with a smoke test and workflow run evidence.
Infrastructure Context
Plan: Flex Consumption (FC1) | Network: VNet integration supported
GitHub Actions deploys to the Flex Consumption function app using a publish profile and the Azure/functions-action.
flowchart LR
GH["GitHub Actions"] -->|"publish profile\n+ staging dir"| FA[Function App\nFlex Consumption FC1]
DEV["Developer"] -->|"git push"| GH
style GH fill:#24292e,color:#fff
style FA fill:#0078d4,color:#fff flowchart LR
A[Push to main] --> B[GitHub Actions]
B --> C[Maven build and test]
C --> D[Publish from staging dir]
D --> E[Smoke test] Steps¶
Step 1 - Get the publish profile¶
Download the publish profile for use in GitHub Actions:
az functionapp deployment list-publishing-profiles \
--name "$APP_NAME" \
--resource-group "$RG" \
--xml
Step 2 - Store deployment secrets in GitHub¶
Add repository secrets:
AZURE_FUNCTIONAPP_PUBLISH_PROFILE— paste the XML from Step 1AZURE_FUNCTIONAPP_NAME— your function app name (e.g.,func-jflex-04100144)
Step 3 - Create workflow file¶
Save the following as .github/workflows/deploy-java-flex.yml:
name: deploy-java-function-flex
on:
push:
branches: [ main ]
paths:
- 'apps/java/**'
env:
JAVA_VERSION: '17'
AZURE_FUNCTIONAPP_NAME: ${{ secrets.AZURE_FUNCTIONAPP_NAME }}
POM_XML_DIRECTORY: 'apps/java'
POM_FUNCTIONAPP_NAME: 'azure-functions-java-guide'
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ env.JAVA_VERSION }}
- name: Build with Maven
run: mvn --batch-mode clean package
working-directory: ${{ env.POM_XML_DIRECTORY }}
- name: Deploy to Azure Functions
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: '${{ env.POM_XML_DIRECTORY }}/target/azure-functions/${{ env.POM_FUNCTIONAPP_NAME }}'
publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}
Deploy from staging directory, not project root
The package path must point to the Maven staging directory (target/azure-functions/<appName>/) where function.json files are generated. Deploying from the project root will result in 0 functions being indexed.
Step 4 - Add post-deployment smoke test¶
Add a smoke test step after deployment:
- name: Smoke test
run: |
sleep 30
HTTP_STATUS=$(curl --silent --output /dev/null --write-out "%{http_code}" \
"https://${{ env.AZURE_FUNCTIONAPP_NAME }}.azurewebsites.net/api/health")
if [ "$HTTP_STATUS" -ne 200 ]; then
echo "Smoke test failed with status $HTTP_STATUS"
exit 1
fi
echo "Smoke test passed with status $HTTP_STATUS"
Step 5 - Validate the release¶
# Check function app last modified time
az functionapp show \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "lastModifiedTimeUtc" \
--output tsv
# Test health endpoint
curl --request GET "https://$APP_NAME.azurewebsites.net/api/health"
# Test hello endpoint
curl --request GET "https://$APP_NAME.azurewebsites.net/api/hello/CICD"
Use GitHub Actions run history as the deployment timeline of record (Actions tab → workflow runs → latest commit SHA), and compare it with lastModifiedTimeUtc to confirm release timing.
No log streaming on Flex Consumption
Flex Consumption does not support Kudu/SCM, so az functionapp log tail and az webapp log tail may not be available.
Alternatives for viewing logs:
- Application Insights queries:
az monitor app-insights query --app $APP_NAME --resource-group $RG --analytics-query "traces | take 20" - Azure Portal: Navigate to Function App → Monitor → Log stream
- Live Metrics: Application Insights → Live Metrics (real-time)
Verification¶
Maven build output:
Health endpoint response after deployment:
Hello endpoint response:
Next Steps¶
See Also¶
- Tutorial Overview & Plan Chooser
- Java Language Guide
- Platform: Hosting Plans
- Operations: Deployment
- Recipes Index