Skip to content

Commit 8cbf73a

Browse files
authored
Merge pull request #232441 from alexwolfmsft/migration-guide-user-identity
Update migration doc to user-assigned identites
2 parents 76788de + caf1f9b commit 8cbf73a

10 files changed

+264
-103
lines changed
61.9 KB
Loading
35.6 KB
Loading
47.8 KB
Loading
63.3 KB
Loading

articles/storage/common/migrate-azure-credentials.md

Lines changed: 57 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,23 @@ Application requests to Azure Storage must be authenticated using either account
1919

2020
## Security risks associated with Shared Key authorization
2121

22-
The following code example demonstrates how to connect to Azure Storage using a storage account key. When you create a storage account, Azure generates access keys for that account. Many developers gravitate towards this solution because it feels familiar to options they have worked with in the past. For example, connection strings for storage accounts also use access keys as part of the string. If your application currently uses access keys, consider migrating to passwordless connections using the steps described later in this document.
22+
The following code example demonstrates how to connect to Azure Storage using a storage account key. When you create a storage account, Azure generates access keys for that account. Many developers gravitate towards this solution because it feels familiar to options they've worked with in the past. For example, connection strings for storage accounts also use access keys as part of the string. If your application currently uses access keys, consider migrating to passwordless connections using the steps described later in this document.
2323

2424
```csharp
2525
var blobServiceClient = new BlobServiceClient(
2626
new Uri("https://<storage-account-name>.blob.core.windows.net"),
2727
new StorageSharedKeyCredential("<storage-account-name>", "<your-access-key>"));
2828
```
2929

30-
Storage account keys should be used with caution. Developers must be diligent to never expose the keys in an unsecure location. Anyone who gains access to the key is able to authenticate. For example, if an account key is accidentally checked into source control, sent through an unsecure email, pasted into the wrong chat, or viewed by someone who shouldn't have permission, there's risk of a malicious user accessing the application. Instead, consider updating your application to use passwordless connections.
30+
Storage account keys should be used with caution. Developers must be diligent to never expose the keys in an unsecure location. Anyone who gains access to the key is able to authenticate. For example, if an account key is accidentally checked into source control, sent through an unsecure email, or viewed by someone who shouldn't have permission, there's risk of a malicious user accessing the application. Instead, consider updating your application to use passwordless connections.
3131

3232
## Migrate to passwordless connections
3333

3434
[!INCLUDE [migrate-to-passwordless-overview](../../../includes/passwordless/migration-guide/migrate-to-passwordless-overview.md)]
3535

3636
## Steps to migrate an app to use passwordless authentication
3737

38-
The following steps explain how to migrate an existing application to use passwordless connections instead of a key-based solution. These same migration steps should apply whether you are using access keys directly, or through connection strings.
38+
The following steps explain how to migrate an existing application to use passwordless connections instead of a key-based solution. These same migration steps should apply whether you're using access keys directly, or through connection strings.
3939

4040
### Configure roles and users for local development authentication
4141

@@ -47,7 +47,7 @@ For local development, make sure you're authenticated with the same Azure AD acc
4747

4848
[!INCLUDE [default-azure-credential-sign-in](../../../includes/passwordless/default-azure-credential-sign-in.md)]
4949

50-
Next you will need to update your code to use passwordless connections.
50+
Next you need to update your code to use passwordless connections.
5151

5252
1. To use `DefaultAzureCredential` in a .NET application, add the **Azure.Identity** NuGet package to your application.
5353

@@ -76,121 +76,52 @@ Next you will need to update your code to use passwordless connections.
7676

7777
#### Run the app locally
7878

79-
After making these code changes, run your application locally. The new configuration should pick up your local credentials, such as the Azure CLI, Visual Studio, or IntelliJ. The roles you assigned to your local dev user in Azure will allow your app to connect to the Azure service locally.
79+
After making these code changes, run your application locally. The new configuration should pick up your local credentials, such as the Azure CLI, Visual Studio, or IntelliJ. The roles you assigned to your local dev user in Azure allows your app to connect to the Azure service locally.
8080

8181
### Configure the Azure hosting environment
8282

83-
Once your application is configured to use passwordless connections and runs locally, the same code can authenticate to Azure services after it is deployed to Azure. For example, an application deployed to an Azure App Service instance that has a managed identity enabled can connect to Azure Storage.
83+
Once your application is configured to use passwordless connections and runs locally, the same code can authenticate to Azure services after it's deployed to Azure. The sections that follow explain how to configure a deployed application to connect to Azure Blob Storage using a managed identity.
8484

85-
#### Create the managed identity using the Azure portal
85+
#### Create the managed identity
8686

87-
[!INCLUDE [create-managed-identity-portal](../../../includes/passwordless/migration-guide/create-managed-identity-portal.md)]
87+
[!INCLUDE [create-managed-identity](../../../includes/passwordless/migration-guide/create-user-assigned-managed-identity.md)]
8888

89-
Alternatively, you can also enable managed identity on an Azure hosting environment using the Azure CLI.
89+
#### Associate the managed identity with your web app
9090

91-
### [Service Connector](#tab/service-connector-identity)
91+
You need to configure your web app to use the managed identity you created. Assign the identity to your app using either the Azure portal or the Azure CLI.
9292

93-
You can use Service Connector to create a connection between an Azure compute hosting environment and a target service using the Azure CLI. The CLI automatically handles creating a managed identity and assigns the proper role, as explained in the [portal instructions](#create-the-managed-identity-using-the-azure-portal).
93+
# [Azure Portal](#tab/azure-portal-associate)
9494

95-
If you're using an Azure App Service, use the `az webapp connection` command:
95+
Complete the following steps in the Azure portal to associate an identity with your app. These same steps apply to the following Azure services:
9696

97-
```azurecli
98-
az webapp connection create storage-blob \
99-
--resource-group <resource-group-name> \
100-
--name <webapp-name> \
101-
--target-resource-group <target-resource-group-name> \
102-
--account <target-storage-account-name> \
103-
--system-identity
104-
```
105-
106-
If you're using Azure Spring Apps, use `the az spring-cloud connection` command:
107-
108-
```azurecli
109-
az spring-cloud connection create storage-blob \
110-
--resource-group <resource-group-name> \
111-
--service <service-instance-name> \
112-
--app <app-name> \
113-
--deployment <deployment-name> \
114-
--target-resource-group <target-resource-group> \
115-
--account <target-storage-account-name> \
116-
--system-identity
117-
```
118-
119-
If you're using Azure Container Apps, use the `az containerapp connection` command:
120-
121-
```azurecli
122-
az containerapp connection create storage-blob \
123-
--resource-group <resource-group-name> \
124-
--name <containerapp-name> \
125-
--target-resource-group <target-resource-group-name> \
126-
--account <target-storage-account-name> \
127-
--system-identity
128-
```
129-
130-
### [Azure App Service](#tab/app-service-identity)
131-
132-
You can assign a managed identity to an Azure App Service instance with the [az webapp identity assign](/cli/azure/webapp/identity) command.
133-
134-
```azurecli
135-
az webapp identity assign \
136-
--resource-group <resource-group-name> \
137-
--name <webapp-name>
138-
```
139-
140-
### [Azure Spring Apps](#tab/spring-apps-identity)
141-
142-
You can assign a managed identity to an Azure Spring Apps instance with the [az spring app identity assign](/cli/azure/spring/app/identity) command.
143-
144-
```azurecli
145-
az spring app identity assign \
146-
--resource-group <resource-group-name> \
147-
--name <app-name> \
148-
--service <service-name>
149-
```
150-
151-
### [Azure Container Apps](#tab/container-apps-identity)
97+
* Azure Spring Apps
98+
* Azure Container Apps
99+
* Azure virtual machines
100+
* Azure Kubernetes Service.
152101

153-
You can assign a managed identity to an Azure Container Apps instance with the [az container app identity assign](/cli/azure/containerapp/identity) command.
102+
1. Navigate to the overview page of your web app.
103+
1. Select **Identity** from the left navigation.
104+
1. On the **Identity** page, switch to the **User assigned** tab.
105+
1. Select **+ Add** to open the **Add user assigned managed identity** flyout.
106+
1. Select the subscription you used previously to create the identity.
107+
1. Search for the **MigrationIdentity** by name and select it from the search results.
108+
1. Select **Add** to associate the identity with your app.
154109

155-
```azurecli
156-
az containerapp identity assign \
157-
--resource-group <resource-group-name> \
158-
--name <app-name>
159-
```
160-
161-
### [Azure virtual machines](#tab/virtual-machines-identity)
110+
:::image type="content" source="../../../articles/storage/common/media/create-user-assigned-identity-small.png" alt-text="Screenshot showing how to create a user assigned identity." lightbox="../../../articles/storage/common/media/create-user-assigned-identity.png":::
162111

163-
You can assign a managed identity to a virtual machine with the [az vm identity assign](/cli/azure/vm/identity) command.
112+
# [Azure CLI](#tab/azure-cli-associate)
164113

165-
```azurecli
166-
az vm identity assign \
167-
--resource-group <resource-group-name> \
168-
--name <virtual-machine-name>
169-
```
114+
[!INCLUDE [associate-managed-identity-cli](../../../includes/passwordless/migration-guide/associate-managed-identity-cli.md)]
170115

171-
### [Azure Kubernetes Service](#tab/aks-identity)
116+
# [Service Connector](#tab/service-connector-associate)
172117

173-
You can assign a managed identity to an Azure Kubernetes Service (AKS) instance with the [az aks update](/cli/azure/aks) command.
174-
175-
```azurecli
176-
az vm identity assign \
177-
--resource-group <resource-group-name> \
178-
--name <virtual-machine-name>
179-
```
118+
[!INCLUDE [service-connector-commands](../../../includes/passwordless/migration-guide/service-connector-commands.md)]
180119

181120
---
182121

183122
#### Assign roles to the managed identity
184123

185-
Next, you need to grant permissions to the managed identity you created to access your storage account. You can do this by assigning a role to the managed identity, just like you did with your local development user.
186-
187-
### [Service Connector](#tab/assign-role-service-connector)
188-
189-
If you connected your services using the Service Connector you do not need to complete this step. The necessary configurations were handled for you:
190-
191-
* If you selected a managed identity while creating the connection, a system-assigned managed identity was created for your app and assigned the **Storage Blob Data Contributor** role on the storage account.
192-
193-
* If you selected connection string, the connection string was added as an app environment variable.
124+
Next, you need to grant permissions to the managed identity you created to access your storage account. Grant permissions by assigning a role to the managed identity, just like you did with your local development user.
194125

195126
### [Azure portal](#tab/assign-role-azure-portal)
196127

@@ -204,15 +135,15 @@ If you connected your services using the Service Connector you do not need to co
204135

205136
1. On the **Add role assignment** screen, for the **Assign access to** option, select **Managed identity**. Then choose **+Select members**.
206137

207-
1. In the flyout, search for the managed identity you created by entering the name of your app service. Select the system assigned identity, and then choose **Select** to close the flyout menu.
138+
1. In the flyout, search for the managed identity you created by name and select it from the results. Choose **Select** to close the flyout menu.
208139

209140
:::image type="content" source="media/migration-select-identity-small.png" alt-text="Screenshot showing how to select the assigned managed identity." lightbox="media/migration-select-identity.png":::
210141

211142
1. Select **Next** a couple times until you're able to select **Review + assign** to finish the role assignment.
212143

213144
### [Azure CLI](#tab/assign-role-azure-cli)
214145

215-
To assign a role at the resource level using the Azure CLI, you first must retrieve the resource ID using the az storage account show command. You can filter the output properties using the --query parameter.
146+
To assign a role at the resource level using the Azure CLI, you first must retrieve the resource ID using the [az storage account](/cli/azure/storage/account) show command. You can filter the output properties using the `--query` parameter.
216147

217148
```azurecli
218149
az storage account show \
@@ -221,7 +152,7 @@ az storage account show \
221152
--query id
222153
```
223154

224-
Copy the output ID from the preceding command. You can then assign roles using the az role command of the Azure CLI.
155+
Copy the output ID from the preceding command. You can then assign roles using the [az role assignment](/cli/azure/role/assignment) command of the Azure CLI.
225156

226157
```azurecli
227158
az role assignment create \
@@ -230,11 +161,35 @@ az role assignment create \
230161
--scope "<your-resource-id>"
231162
```
232163

164+
### [Service Connector](#tab/assign-role-service-connector)
165+
166+
If you connected your services using Service Connector you don't need to complete this step. The necessary role configurations were handled for you when you ran the Service Connector CLI commands.
167+
233168
---
234169

170+
#### Update the application code
171+
172+
You need to configure your application code to look for the specific managed identity you created when it is deployed to Azure. In some scenarios, explicitly setting the managed identity for the app also prevents other environment identities from accidentally being detected and used automatically.
173+
174+
1. On the managed identity overview page, copy the client ID value to your clipboard.
175+
1. Update the `DefaultAzureCredential` object in the `Program.cs` file of your app to specify this managed identity client ID.
176+
177+
```csharp
178+
// TODO: Update the <your-storage-account-name> and <your-managed-identity-client-id> placeholders
179+
var blobServiceClient = new BlobServiceClient(
180+
new Uri("https://<your-storage-account-name>.blob.core.windows.net"),
181+
new DefaultAzureCredential(
182+
new DefaultAzureCredentialOptions()
183+
{
184+
ManagedIdentityClientId = "<your-managed-identity-client-id>"
185+
}));
186+
```
187+
188+
3. Redeploy your code to Azure after making this change in order for the configuration updates to be applied.
189+
235190
#### Test the app
236191

237-
After making these code changes, browse to your hosted application in the browser. Your app should be able to connect to the storage account successfully. Keep in mind that it may take several minutes for the role assignments to propagate through your Azure environment. Your application is now configured to run both locally and in a production environment without the developers having to manage secrets in the application itself.
192+
After deploying the updated code, browse to your hosted application in the browser. Your app should be able to connect to the storage account successfully. Keep in mind that it may take several minutes for the role assignments to propagate through your Azure environment. Your application is now configured to run both locally and in a production environment without the developers having to manage secrets in the application itself.
238193

239194
## Next steps
240195

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
The following steps demonstrate how to create a user-assigned managed identity for various web hosting services. The managed identity can securely connect to other Azure services using the app configurations you set up previously.
2+
3+
### [Service Connector](#tab/service-connector)
4+
5+
Some app hosting environments support Service Connector, which helps you connect Azure compute services to other backing services. Service Connector automatically configures network settings and connection information.
6+
7+
The following compute services are currently supported:
8+
9+
* Azure App Service
10+
* Azure Spring Cloud
11+
* Azure Container Apps (preview)
12+
13+
For this migration guide, you'll use App Service. The steps are similar on Azure Spring Apps and Azure Container Apps.
14+
15+
> [!NOTE]
16+
> Azure Spring Apps currently only supports Service Connector using connection strings.
17+
18+
1. On the main overview page of your App Service, select **Service Connector** from the left navigation.
19+
20+
1. Select **+ Create** from the top menu and the **Create connection** panel will open. Enter the following values:
21+
22+
* **Service type**: Choose **Service bus**.
23+
* **Subscription**: Select the subscription you would like to use.
24+
* **Connection Name**: Enter a name for your connection, such as *connector_appservice_servicebus*.
25+
* **Client type**: Leave the default value selected or choose the specific client you'd like to use.
26+
27+
Select **Next: Authentication**.
28+
29+
1. Select **User assigned managed identity**.
30+
1. Select the subscription and **MigrationIdentity** user identity you configured in the previous section.
31+
1. Select **Next: Networking**.
32+
1. Leave the default values selected, and then choose **Next: Review + Create**.
33+
1. After Azure validates your settings, select **Create**.
34+
35+
The Service Connector will automatically assign the managed identity an **Azure Service Bus Data Owner** role for the service bus you selected.
36+
37+
### [Azure portal](#tab/app-service)
38+
39+
You can assign the correct roles to your user-assigned managed identity through the storage account settings pages.
40+
41+
1. On the overview page of your storage account, select **Access control (IAM)**.
42+
1. Select **+ Add** at the top of the page and then choose **Add role assignment** from the drop down menu.
43+
1. On the **Add role assignment** page, leave the default **Assignment type** toggled and select **Next**.
44+
1. On the **Role** tab, search for *Storage Blob Data Contributor* and select the matching result. Then select **Next**.
45+
1. On the **Members** tab, make sure the following values are set:
46+
* **Selected Role**: Storage Blob Data Contributor
47+
* **Assign access to**: Select **Managed identity**.
48+
* **Members**: Select **+ Select members**.
49+
50+
In the flyout menu, make sure the following values are set:
51+
52+
* **Subscription**: Select the subscription you want to use.
53+
* **Managed identity**: Select **User-assigned managed identity**.
54+
* **Select**: Search for the **Migration Identity** you created earlier and select it from the results below the input.
55+
56+
57+
1. Choose **Select** to close the flyout.
58+
1. Select **Review and assign** at the bottom of the page.
59+
1. After Azure validates your inputs, select **Assign** to complete the workflow.
60+
61+
The correct role is assigned to the user-assigned managed identity used by your app.

0 commit comments

Comments
 (0)