Skip to content

Commit c20ba7d

Browse files
committed
Update Bicep article to use reusable content and emphasize OIDC
1 parent 1276ff5 commit c20ba7d

File tree

1 file changed

+34
-132
lines changed

1 file changed

+34
-132
lines changed

articles/azure-resource-manager/bicep/deploy-github-actions.md

Lines changed: 34 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -38,111 +38,13 @@ New-AzResourceGroup -Name exampleRG -Location westus
3838

3939
## Generate deployment credentials
4040

41-
# [Service principal](#tab/userlevel)
42-
43-
Your GitHub Actions run under an identity. Use the [az ad sp create-for-rbac](/cli/azure/ad/sp#az-ad-sp-create-for-rbac) command to create a [service principal](../../active-directory/develop/app-objects-and-service-principals.md#service-principal-object) for the identity. Grant the service principal the contributor role for the resource group created in the previous session so that the GitHub action with the identity can create resources in this resource group. It's recommended that you grant minimum required access.
44-
45-
```azurecli-interactive
46-
az ad sp create-for-rbac --name {app-name} --role contributor --scopes /subscriptions/{subscription-id}/resourceGroups/exampleRG --json-auth
47-
```
48-
49-
Replace the placeholder `{app-name}` with the name of your application. Replace `{subscription-id}` with your subscription ID.
50-
51-
The output is a JSON object with the role assignment credentials that provide access to your App Service app similar to the following output.
52-
53-
```output
54-
{
55-
"clientId": "<GUID>",
56-
"clientSecret": "<GUID>",
57-
"subscriptionId": "<GUID>",
58-
"tenantId": "<GUID>",
59-
...
60-
}
61-
```
62-
63-
Copy this JSON object for later. You'll only need the sections with the `clientId`, `clientSecret`, `subscriptionId`, and `tenantId` values. Make sure you don't have an extra comma at the end of the last line, for example, the `tenantId` line in the preceding example, or else it results in an invalid JSON file. You get an error during the deployment saying "Login failed with Error: Content isn't a valid JSON object. Double check if the 'auth-type' is correct."
64-
65-
# [Open ID Connect](#tab/openid)
66-
67-
Open ID Connect is an authentication method that uses short-lived tokens. Setting up [OpenID Connect with GitHub Actions](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) is more complex process that offers hardened security.
68-
69-
1. If you don't have an existing application, register a [new Active Directory application and service principal that can access resources](../../active-directory/develop/howto-create-service-principal-portal.md). Create the Active Directory application.
70-
71-
```azurecli-interactive
72-
az ad app create --display-name myApp
73-
```
74-
75-
This command outputs JSON with an `appId` that is your `client-id`. Save the value to use as the `AZURE_CLIENT_ID` GitHub secret later.
76-
77-
You use the `objectId` value when creating federated credentials with Graph API and reference it as the `APPLICATION-OBJECT-ID`.
78-
79-
1. Create a service principal. Replace the `$appID` with the appId from your JSON output.
80-
81-
This command generates JSON output with a different `Id` and will be used in the next step. The new `Id` is the `assignee-object-id`.
82-
83-
Copy the `appOwnerTenantId` to use as a GitHub secret for `AZURE_TENANT_ID` later.
84-
85-
```azurecli-interactive
86-
az ad sp create --id $appId
87-
```
88-
89-
1. 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, and `$assigneeObjectId` with the generated `assignee-object-id`. Learn [how to manage Azure subscriptions with the Azure CLI](/cli/azure/manage-azure-subscriptions-azure-cli).
90-
91-
```azurecli-interactive
92-
az role assignment create --role contributor --subscription $subscriptionId --assignee-object-id $assigneeObjectId --assignee-principal-type ServicePrincipal --scope /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName
93-
```
94-
95-
1. Run the following command to [create a new federated identity credential](/graph/api/application-post-federatedidentitycredentials?view=graph-rest-beta&preserve-view=true) for your active directory application.
41+
[!INCLUDE [include](~/reusable-content/github-actions/generate-deployment-credentials.md)]
9642

97-
* Replace `APPLICATION-OBJECT-ID` with the **objectId (of the app registration)** for your Active Directory application.
98-
* Set a value for `CREDENTIAL-NAME` to reference later.
99-
* Set the `subject`. The value of this is defined by GitHub depending on your workflow:
100-
* Jobs in your GitHub Actions environment: `repo:< Organization/Repository >:environment:< Name >`
101-
* 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` or `repo:n-username/ node_express:ref:refs/tags/my-tag`.
102-
* For workflows triggered by a pull request event: `repo:< Organization/Repository >:pull_request`.
103-
104-
```azurecli
105-
az rest --method POST --uri 'https://graph.microsoft.com/beta/applications/<APPLICATION-OBJECT-ID>/federatedIdentityCredentials' --body '{"name":"<CREDENTIAL-NAME>","issuer":"https://token.actions.githubusercontent.com","subject":"repo:organization/repository:ref:refs/heads/main","description":"Testing","audiences":["api://AzureADTokenExchange"]}'
106-
```
107-
108-
To learn how to create a Create an active directory application, service principal, and federated credentials in Azure portal, see [Connect GitHub and Azure](/azure/developer/github/connect-from-azure#use-the-azure-login-action-with-openid-connect).
109-
110-
---
11143
## Configure the GitHub secrets
11244

11345
# [Service principal](#tab/userlevel)
11446

115-
Create secrets for your Azure credentials, resource group, and subscriptions. You use these secrets in the [Create workflow](#create-workflow) section.
116-
117-
1. In [GitHub](https://github.com/), navigate to your repository.
118-
119-
1. Select **Settings > Secrets and variables > Actions > New repository secret**.
120-
121-
1. Paste the entire JSON output from the Azure CLI command into the secret's value field. Name the secret `AZURE_CREDENTIALS`.
122-
123-
1. Create another secret named `AZURE_RG`. Add the name of your resource group to the secret's value field (`exampleRG`).
124-
125-
1. Create another secret named `AZURE_SUBSCRIPTION`. Add your subscription ID to the secret's value field (example: `aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e`).
126-
127-
# [Open ID Connect](#tab/openid)
128-
129-
You need to provide your application's **Client ID**, **Tenant ID**, and **Subscription ID** to the 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.
130-
131-
1. Open your GitHub repository and go to **Settings**.
132-
133-
1. Select **Settings > Secrets > New secret**.
134-
135-
1. Create secrets for `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_SUBSCRIPTION_ID`. Use these values from your Active Directory application for your GitHub secrets:
136-
137-
|GitHub Secret | Active Directory Application |
138-
|---------|---------|
139-
|AZURE_CLIENT_ID | Application (client) ID |
140-
|AZURE_TENANT_ID | Directory (tenant) ID |
141-
|AZURE_SUBSCRIPTION_ID | Subscription ID |
142-
143-
1. Save each secret by selecting **Add secret**.
144-
145-
---
47+
[!INCLUDE [include](~/reusable-content/github-actions/create-secrets-with-openid.md)]
14648

14749
## Add a Bicep file
14850

@@ -200,25 +102,31 @@ To create a workflow, take the following steps:
200102
1. Rename the workflow file if you prefer a different name other than **main.yml**. For example: **deployBicepFile.yml**.
201103
1. Replace the content of the yml file with the following code:
202104

203-
# [Service principal](#tab/userlevel)
105+
# [OpenID Connect](#tab/openid)
204106

205107
```yml
206-
name: Deploy Bicep file
207108
on: [push]
109+
name: Azure ARM
110+
permissions:
111+
id-token: write
112+
contents: read
208113
jobs:
209114
build-and-deploy:
210115
runs-on: ubuntu-latest
211116
steps:
212117

213-
- name: Checkout code
214-
uses: actions/checkout@main
118+
# Checkout code
119+
- uses: actions/checkout@main
215120

216-
- name: Log into Azure
217-
uses: azure/login@v1
121+
# Log into Azure
122+
- uses: azure/login@v2
218123
with:
219-
creds: ${{ secrets.AZURE_CREDENTIALS }}
124+
client-id: ${{ secrets.AZURE_CLIENT_ID }}
125+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
126+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
220127

221-
- name: Deploy Bicep file
128+
# Deploy Bicep file
129+
- name: deploy
222130
uses: azure/arm-deploy@v1
223131
with:
224132
subscriptionId: ${{ secrets.AZURE_SUBSCRIPTION }}
@@ -228,41 +136,25 @@ To create a workflow, take the following steps:
228136
failOnStdErr: false
229137
```
230138
231-
Replace `mystore` with your own storage account name prefix.
232-
233-
> [!NOTE]
234-
> You can specify a JSON format parameters file instead in the ARM Deploy action (example: `.azuredeploy.parameters.json`).
235-
236-
The first section of the workflow file includes:
237-
238-
- **name**: The name of the workflow.
239-
- **on**: The name of the GitHub events that triggers the workflow. The workflow is triggered when there's a push event on the main branch.
240-
241-
# [OpenID Connect](#tab/openid)
139+
# [Service principal](#tab/userlevel)
242140
243141
```yml
142+
name: Deploy Bicep file
244143
on: [push]
245-
name: Azure ARM
246-
permissions:
247-
id-token: write
248-
contents: read
249144
jobs:
250145
build-and-deploy:
251146
runs-on: ubuntu-latest
252147
steps:
253148

254-
# Checkout code
255-
- uses: actions/checkout@main
149+
- name: Checkout code
150+
uses: actions/checkout@main
256151

257-
# Log into Azure
258-
- uses: azure/login@v1
152+
- name: Log into Azure
153+
uses: azure/login@v2
259154
with:
260-
client-id: ${{ secrets.AZURE_CLIENT_ID }}
261-
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
262-
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
155+
creds: ${{ secrets.AZURE_CREDENTIALS }}
263156

264-
# Deploy Bicep file
265-
- name: deploy
157+
- name: Deploy Bicep file
266158
uses: azure/arm-deploy@v1
267159
with:
268160
subscriptionId: ${{ secrets.AZURE_SUBSCRIPTION }}
@@ -272,6 +164,16 @@ To create a workflow, take the following steps:
272164
failOnStdErr: false
273165
```
274166
167+
Replace `mystore` with your own storage account name prefix.
168+
169+
> [!NOTE]
170+
> You can specify a JSON format parameters file instead in the ARM Deploy action (example: `.azuredeploy.parameters.json`).
171+
172+
The first section of the workflow file includes:
173+
174+
- **name**: The name of the workflow.
175+
- **on**: The name of the GitHub events that triggers the workflow. The workflow is triggered when there's a push event on the main branch.
176+
275177
---
276178

277179

0 commit comments

Comments
 (0)