You can develop Azure Functions using Rust. This repository contains a template using debugging configuration for Visual Studio Code that overrides the executable used when debugging.
- Azure Developer CLI
- Rust 1.82 or newer
- (Optional) Azure Functions CLI
- (Optional) GitHub CLI
This repository is configured to support both continuous deployment using GitHub Actions and manual deployment using azd.
To support either scenario, you can provision resources using azd
:
azd provision
The GitHub Actions workflows in .github/workflows
are defined as follows:
pr.yml
: Lints and tests pull requests before they can be merged tomain
.cd.yml
: Builds a release binary to run natively on an Azure Functions host.
We'll create two environments: "staging" and "production" to match our provisioned slot names.
- In your GitHub project settings, click Environments.
- Create an environment named "production". Set the Deployment branch and tags to
main
. I recommend you also set required reviewers accordingly. - Repeat the previous step to create an environment named "staging". You do not need to set required reviewers.
With your resources provisioned, you can set up OpenID Connect to deploy to staging and production environments:
-
Register an application to log in from GitHub Actions. You can leave the redirect URL blank.
-
Copy the application ID and assign it to the "Storage Blob Data Contributor" role e.g.,
az role assignment create --assignee "{AppId}" --role 'Storage Blob Data Reader' --scope "/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$AZURE_RESOURCE_GROUP"
Run the following to find the
AppId
if you need help:az ad sp list --show-mine --output table
-
Harden access when adding new client secrets:
- Under Managed, click on Certificates and secrets.
- Click Federated credentials.
- Click Add credential.
- Select the GitHub Actions deploying Azure resources scenario.
- Fill in the information requested including the environment name e.g., "staging" we created above.
- Name your credential to identify which environment will require it e.g., "staging".
- Click Add.
- Repeat the previous steps for the "production" environment.
-
For each environment created above, add the following environment secrets:
Variable Description AZURE_SUBSCRIPTION_ID
The subscription ID to which you registered the application above. AZURE_TENANT_ID
The tenant ID of the application. AZURE_CLIENT_ID
The client ID of the application. Alternatively, you could set these once as repository secrets if they have the same value. This example demonstrates configuration in case different environments are in different subscriptions.
-
For each environment created above, add the following environment variables:
Variable Description AZURE_FUNCTIONAPP_URL
The URL of the function app or slot. AZURE_STORAGE_CONTAINER
The name of the Storage blob container to use for the function app or slot. Using the GitHub CLI, you can set these like so:
azd env get-value AZURE_FUNCTIONAPP_URL | gh variable set --env production AZURE_FUNCTIONAPP_URL azd env get-value AZURE_STORAGE_CONTAINER | gh variable set --env production AZURE_STORAGE_CONTAINER azd env get-value AZURE_FUNCTIONAPP_STAGING_URL | gh variable set --env staging AZURE_FUNCTIONAPP_URL azd env get-value AZURE_STORAGE_STAGING_CONTAINER | gh variable set --env staging AZURE_STORAGE_CONTAINER
-
Define the following repository variable:
Variable Description AZURE_STORAGE_URL
The Storage blob endpoint URL. Using the GitHub CLI, you can set these like so:
azd env get-value AZURE_STORAGE_URL | gh variable set AZURE_STORAGE_URL
Now when you merge to main
the Azure Functions app will deploy first to your staging environment, test that the application is running and responds with the expected text, then deploys to your production environment.
You can provision resource and deploy the app with a single azd command:
azd up
If you would like to better understand the process to adapt to your situation, you can use the following steps instead:
-
Provision the function app and related resources:
azd provision
You can also deploy the
infra/main.bicep
template directly using theaz
CLI butazd
handles authentication, if necessary, as well as reading any environment variables already set from previous deployments or by the host process. -
Build a release binary for the Functions linux runtime host image:
cargo build --release --target x86_64-unknown-linux-musl
-
Package required files for a custom host. This command may vary depending on what zip application you use:
zip deploy.zip host.json hello/function.json target/x86_64-unknown-linux-musl/release/handler
-
Publish the
deploy.zip
created in the previous step using the resource group name and function app name used when provisioning:eval $(azd env get-values) # or source from .env file for environment under .azure/ az storage blob upload --blob-endpoint "$AZURE_STORAGE_URL" --container-name "$AZURE_STORAGE_CONTAINER" --auth-mode login --file deploy.zip --overwrite
-
You can now test that the function was successfully deployed:
curl $AZURE_FUNCTIONAPP_URL/api/hello
To delete resources created by azd
, run:
azd down