title | description | ms.topic | ms.date | ms.reviewer | ms.custom | author | ms.author |
---|---|---|---|---|---|---|---|
Configure CI/CD with GitHub Actions |
Learn how to deploy your code to Azure App Service from a CI/CD pipeline with GitHub Actions. Customize the build tasks and execute complex deployments. |
article |
01/16/2024 |
ushan |
github-actions-azure, devx-track-azurecli |
cephalin |
cephalin |
Get started with GitHub Actions to automate your workflow and deploy to Azure App Service from GitHub.
- An Azure account with an active subscription. Create an account for free.
- A GitHub account. If you don't have one, sign up for free.
GitHub Actions deployment is integrated into the default app creation wizard. You just need to set Continuous deployment to Enable in the Deployment tab, and configure the organization, repository, and branch you want.
:::image type="content" source="media/deploy-github-actions/create-wizard-deployment.png" alt-text="A screenshot showing how to enable GitHub Actions deployment in the App Service create wizard.":::
When you enable continuous deployment, the app creation wizard automatically picks the authentication method based on the basic authentication selection and configures your app and your GitHub repository accordingly:
Basic authentication selection | Authentication method |
---|---|
Disable | User-assigned identity (OpenID Connect) (recommended) |
Enable | Basic authentication |
Note
If you receive an error when creating your app saying that your Azure account doesn't have certain permissions, it may not have the required permissions to create and configure the user-assigned identity. For an alternative, see Set up GitHub Actions deployment from the Deployment Center.
For an existing app, you can get started quickly with GitHub Actions by using the App Service Deployment Center. This turn-key method automatically generates a GitHub Actions workflow file based on your application stack and commits it to your GitHub repository.
The Deployment Center also lets you easily configure the more secure OpenID Connect authentication with the user-assigned identity option.
If your Azure account has the needed permissions, you can select to create a user-assigned identity. Otherwise, you can select an existing user-assigned managed identity in the Identity dropdown. You can work with your Azure administrator to create a user-assigned managed identity with the Website Contributor role.
For more information, see Continuous deployment to Azure App Service.
You can also deploy a workflow without using the Deployment Center. In that case you need to perform 3 steps:
- Generate deployment credentials
- Configure the GitHub secret
- Add the workflow file to your GitHub repository
The recommended way to authenticate with Azure App Services for GitHub Actions is with OpenID Connect. This is an authentication method that uses short-lived tokens. Setting up OpenID Connect with GitHub Actions is more complex but offers hardened security.
Alternatively, you can authenticate with a User-assigned Managed Identity, a service principal, or a publish profile.
The below runs you through the steps for creating an active directory application, service principal, and federated credentials using Azure CLI statements. To learn how to create an active directory application, service principal, and federated credentials in Azure portal, see Connect GitHub and Azure.
-
If you don't have an existing application, register a new Active Directory application and service principal that can access resources. Create the Active Directory application.
az ad app create --display-name myApp
This command outputs a JSON with an
appId
that is yourclient-id
. Save the value to use as theAZURE_CLIENT_ID
GitHub secret later.You'll use the
objectId
value when creating federated credentials with Graph API and reference it as theAPPLICATION-OBJECT-ID
. -
Create a service principal. Replace the
$appID
with the appId from your JSON output.This command generates JSON output with a different
objectId
and will be used in the next step. The newobjectId
is theassignee-object-id
.Copy the
appOwnerTenantId
to use as a GitHub secret forAZURE_TENANT_ID
later.az ad sp create --id $appId
-
Create a new role assignment by subscription and object. By default, the role assignment is tied to your default subscription. Replace
$subscriptionId
with your subscription ID,$resourceGroupName
with your resource group name,$webappName
with your web app name, and$assigneeObjectId
with the generatedid
. Learn how to manage Azure subscriptions with the Azure CLI.az role assignment create --role contributor --subscription $subscriptionId --assignee-object-id $assigneeObjectId --scope /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Web/sites/$webappName --assignee-principal-type ServicePrincipal
-
Run the following command to create a new federated identity credential for your active directory application.
- Replace
APPLICATION-OBJECT-ID
with the appId (generated while creating app) for your Active Directory application. - Set a value for
CREDENTIAL-NAME
to reference later. - Set the
subject
. Its value is defined by GitHub depending on your workflow:- Jobs in your GitHub Actions environment:
repo:< Organization/Repository >:environment:< Name >
- For Jobs not tied to an environment, include the ref path for branch/tag based on the ref path used for triggering the workflow:
repo:< Organization/Repository >:ref:< ref path>
. For example,repo:n-username/ node_express:ref:refs/heads/my-branch
orrepo:n-username/ node_express:ref:refs/tags/my-tag
. - For workflows triggered by a pull request event:
repo:< Organization/Repository >:pull_request
.
- Jobs in your GitHub Actions environment:
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:organization/repository:ref:refs/heads/main", "description": "Testing", "audiences": [ "api://AzureADTokenExchange" ] }
- Replace
Note
Publish profile requires basic authentication to be enabled.
A publish profile is an app-level credential. Set up your publish profile as a GitHub secret.
-
Go to your app service in the Azure portal.
-
On the Overview page, select Get Publish profile.
-
Save the downloaded file. You'll use the contents of the file to create a GitHub secret.
Note
As of October 2020, Linux web apps needs the app setting WEBSITE_WEBDEPLOY_USE_SCM
set to true
before downloading the publish profile. This requirement will be removed in the future.
You can create a service principal with the az ad sp create-for-rbac command in the Azure CLI. Run this command with Azure Cloud Shell in the Azure portal or by selecting the Try it button.
az ad sp create-for-rbac --name "myApp" --role contributor \
--scopes /subscriptions/<subscription-id>/resourceGroups/<group-name>/providers/Microsoft.Web/sites/<app-name> \
--json-auth
In the previous example, replace the placeholders with your subscription ID, resource group name, and app name. The output is a JSON object with the role assignment credentials that provide access to your App Service app similar to the following JSON snippet. Copy this JSON object for later.
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
Important
It is always a good practice to grant minimum access. The scope in the previous example is limited to the specific App Service app and not the entire resource group.
You need to provide your application's Client ID, Tenant ID and Subscription ID to the Azure/login action. These values can either be provided directly in the workflow or can be stored in GitHub secrets and referenced in your workflow. Saving the values as GitHub secrets is the more secure option.
-
Open your GitHub repository and go to Settings > Security > Secrets and variables > Actions > New repository secret.
-
Create secrets for
AZURE_CLIENT_ID
,AZURE_TENANT_ID
, andAZURE_SUBSCRIPTION_ID
. Use these values from your Active Directory application for your GitHub secrets:GitHub Secret Active Directory Application AZURE_CLIENT_ID Application (client) ID AZURE_TENANT_ID Directory (tenant) ID AZURE_SUBSCRIPTION_ID Subscription ID -
Save each secret by selecting Add secret.
In GitHub, browse your repository. Select Settings > Security > Secrets and variables > Actions > New repository secret.
To use app-level credentials, paste the contents of the downloaded publish profile file into the secret's value field. Name the secret AZURE_WEBAPP_PUBLISH_PROFILE
.
When you configure the GitHub workflow file later, you use the AZURE_WEBAPP_PUBLISH_PROFILE
in the deploy Azure Web App action. For example:
- uses: azure/webapps-deploy@v2
with:
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
In GitHub, browse your repository. Select Settings > Security > Secrets and variables > Actions > New repository secret.
To use user-level credentials, paste the entire JSON output from the Azure CLI command into the secret's value field. Name the secret AZURE_CREDENTIALS
.
When you configure the GitHub workflow file later, you use the secret for the input creds
of the Azure/login. For example:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
A workflow is defined by a YAML (.yml) file in the /.github/workflows/
path in your GitHub repository. This definition contains the various steps and parameters that make up the workflow.
At a minimum, the workflow file would have the following distinct steps:
- Authenticate with App Service using the GitHub secret you created.
- Build the web app.
- Deploy the web app.
To deploy your code to an App Service app, you use the azure/webapps-deploy@v3 action. The action requires the name of your web app in app-name
and, depending on your language stack, the path of a *.zip, *.war, *.jar, or folder to deploy in package
. For a complete list of possible inputs for the azure/webapps-deploy@v3
action, see the action.yml definition.
The following examples show the part of the workflow that builds the web app, in different supported languages.
[!INCLUDE deploy-github-actions-openid-connect]
[!INCLUDE deploy-github-actions-publish-profile]
[!INCLUDE deploy-github-actions-service-principal]
- How do I deploy a WAR file through Maven plugin and OpenID Connect
- How do I deploy a WAR file through Az CLI and OpenID Connect
- How do I deploy to a Container
- How do I update the Tomcat configuration after deployment
In case you configured your Java Tomcat project with the Maven plugin, you can also deploy to Azure App Service through this plugin. If you use the Azure CLI GitHub action it will make use of your Azure login credentials.
- name: Azure CLI script file
uses: azure/cli@v2
with:
inlineScript: |
mvn package azure-webapp:deploy
More information on the Maven plugin and how to use and configure it can be found in the Maven plugin wiki for Azure App Service.
If you use prefer the Azure CLI to deploy to App Service, you can use the GitHub Action for CLI.
- name: Azure CLI script
uses: azure/cli@v2
with:
inlineScript: |
az webapp deploy --src-path '${{ github.workspace }}/target/yourpackage.war' --name ${{ env.AZURE_WEBAPP_NAME }} --resource-group ${{ env.RESOURCE_GROUP }} --async true --type war
More information on the GitHub Action for CLI and how to use and configure it can be found in the Azure CLI GitHub action. More information on the az webapp deploy command, how to use and the parameter details can be found in the az webapp deploy documentation.
With the Azure Web Deploy action, you can automate your workflow to deploy custom containers to App Service using GitHub Actions. Detailed information on the steps to deploy using GitHub Actions, can be found in the Deploy to a Container.
In case you would like to update any of your web apps settings after deployment, you can use the App Service Settings action.
- uses: azure/appservice-settings@v1
with:
app-name: 'my-app'
slot-name: 'staging' # Optional and needed only if the settings have to be configured on the specific deployment slot
app-settings-json: '[{ "name": "CATALINA_OPTS", "value": "-Dfoo=bar" }]'
connection-strings-json: '${{ secrets.CONNECTION_STRINGS }}'
general-settings-json: '{"alwaysOn": "false", "webSocketsEnabled": "true"}' #'General configuration settings as Key Value pairs'
id: settings
More information on this action and how to use and configure it can be found in the App Service Settings repository.
Check out references on Azure GitHub Actions and workflows: