Introduction
Azure Active Directory (Azure AD) provides identity services that applications use for authentication and authorization. A crucial aspect of deploying applications in Azure involves managing identities that are used to authenticate to resources. Two prominent identity types in Azure are System-Assigned Managed Identity and User-Assigned Managed Identity. This article explores these two identity types, their differences, and real-world application examples.
1. System-Assigned Managed Identity
Definition and Characteristics
- Automated Management: System-assigned managed identities are automatically managed by Azure. When the resource (like a VM or function app) is deleted, Azure automatically cleans up the credentials.
- Tied to Service Instance: The lifecycle of a system-assigned identity is directly tied to the Azure service instance that it’s enabled on. If the instance is deleted, the identity is automatically deleted.
Use Case: Automating Database Backups with Azure Functions
Consider a scenario where an Azure Function is set up to automate backups of a PostgreSQL database. The function needs to authenticate to the database securely without storing credentials in code.
- Secure Authentication: The function is assigned a system-assigned managed identity, which is granted the necessary permissions on the PostgreSQL database.
- Credential-Free Code: The code doesn’t contain any credentials, as it uses the managed identity to authenticate to the database.
In this example, let’s create an Azure Function that uses a system-assigned managed identity to authenticate to an Azure PostgreSQL database and perform a simple query.
Prerequisites:
- An Azure PostgreSQL database with the necessary tables/data.
- An Azure Function App with a system-assigned managed identity enabled.
- The managed identity is granted necessary permissions on the PostgreSQL database.
Steps:
- Enable Managed Identity:
- Navigate to your Function App in the Azure portal.
- Under the “Platform features” tab, select “Identity”.
- Under the “System assigned” tab, switch the “Status” to “On” and save.
- Assign Database Permissions:
- Navigate to your PostgreSQL database in the Azure portal.
- Under “Connection security”, add the managed identity (using the Function App’s name) and assign necessary permissions.
- Develop the Azure Function:
Below is a simplified Python code snippet for an Azure Function that uses a system-assigned managed identity to connect to a PostgreSQL database:
import logging import azure.functions as func import psycopg2 from azure.identity import DefaultAzureCredential from azure.keyvault.secrets import SecretClient from azure.core.exceptions import AzureError def main(req: func.HttpRequest) -> func.HttpResponse: logging.info('Python HTTP trigger function processed a request.') # Azure Key Vault URL where DB credentials are stored KEY_VAULT_URI = "https://[your-keyvault-name].vault.azure.net" # Get credentials from Azure Key Vault using Managed Identity try: credential = DefaultAzureCredential() client = SecretClient(vault_url=KEY_VAULT_URI, credential=credential) db_user = client.get_secret("[DB-USER-SECRET-NAME]").value db_password = client.get_secret("[DB-PASSWORD-SECRET-NAME]").value except AzureError as e: return func.HttpResponse(f"Error retrieving secrets: {str(e)}", status_code=400) # Connect to PostgreSQL using credentials try: connection = psycopg2.connect( host="[DB-HOST]", database="[DB-NAME]", user=db_user, password=db_password ) cursor = connection.cursor() # Execute a simple query cursor.execute("SELECT * FROM [YOUR-TABLE-NAME] LIMIT 5;") records = cursor.fetchall() logging.info(f"Records: {records}") return func.HttpResponse(f"Data: {records}", status_code=200) except Exception as e: return func.HttpResponse(f"Database connection error: {str(e)}", status_code=500) finally: if connection: cursor.close() connection.close()
in c# :
Prerequisites:
- Azure Functions development setup (Visual Studio, Azure Functions Core Tools, etc.)
- Azure PostgreSQL database and Azure Key Vault configured as per the previous example.
using System.IO; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Npgsql; using Azure.Security.KeyVault.Secrets; using Azure.Identity; public static class PostgresFunction { [FunctionName("QueryPostgres")] public static IActionResult Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); string keyVaultUrl = "https://[your-keyvault-name].vault.azure.net"; string dbName = "[DB-NAME]"; string dbHost = "[DB-HOST]"; string tableName = "[YOUR-TABLE-NAME]"; SecretClient secretClient = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential()); string dbUser = secretClient.GetSecret("[DB-USER-SECRET-NAME]").Value.Value; string dbPassword = secretClient.GetSecret("[DB-PASSWORD-SECRET-NAME]").Value.Value; string connectionString = $"Host={dbHost};Username={dbUser};Password={dbPassword};Database={dbName}"; try { using (var connection = new NpgsqlConnection(connectionString)) { connection.Open(); using (var cmd = new NpgsqlCommand($"SELECT * FROM {tableName} LIMIT 5;", connection)) using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { log.LogInformation($"Read from table {tableName}: {reader.GetString(0)}"); } } } return new OkResult(); } catch (Exception ex) { log.LogError($"Failed to query PostgreSQL: {ex.Message}"); return new StatusCodeResult(StatusCodes.Status500InternalServerError); } } }
Explanation:
- Retrieve Secrets: The function uses the
DefaultAzureCredential
andSecretClient
from Azure SDK to authenticate with Azure Key Vault using the system-assigned managed identity and retrieve the database credentials. - Database Connection: The function connects to the PostgreSQL database using the
NpgsqlConnection
from the Npgsql library and performs a query.
Notes:
- Ensure to replace placeholder values (like
[your-keyvault-name]
,[DB-USER-SECRET-NAME]
, etc.) with actual values relevant to your Azure setup. - Make sure to manage dependencies properly. For this code, you need to add the
Azure.Security.KeyVault.Secrets
,Azure.Identity
, andNpgsql
NuGet packages to your Azure Functions project. - Always adhere to best practices for managing identities and secrets in production environments.
This example demonstrated a basic use case and should be adapted according to specific application requirements and best practices.
2. User-Assigned Managed Identity
Definition and Characteristics
- Explicit Creation and Management: User-assigned managed identities are created as standalone Azure resources. An administrator must manually delete a user-assigned identity when it’s no longer needed.
- Reusable: Unlike system-assigned identities, user-assigned identities can be used by multiple resources simultaneously.
Use Case: Managing Access to Multiple Resources
Imagine a scenario where multiple Azure VMs need access to several databases and storage accounts for a data processing pipeline.
- Centralized Identity: A user-assigned managed identity is created and granted the necessary permissions on all required resources (databases, storage accounts, etc.).
- Shared Across VMs: All VMs are assigned the user-assigned managed identity, allowing them to authenticate to the resources securely without each VM needing a separate identity.
Comparative Analysis
- Lifecycle Management: System-assigned identities are simpler to manage with respect to the lifecycle since they are automatically deleted when the associated resource is deleted.
- User-assigned identities require manual cleanup.
- Flexibility: User-assigned identities offer more flexibility as they can be shared across multiple resources and can persist independently of these resources.
- Use-Case Suitability: System-assigned identities might be more suitable for scenarios where resources need isolated identities and are provisioned and de-provisioned frequently. User-assigned identities might be preferable for scenarios requiring centralized identity management across multiple resources.
Conclusion
Choosing between system-assigned and user-assigned managed identities in Azure depends on the specific requirements of your use case. System-assigned identities offer automated lifecycle management and simplicity, whereas user-assigned identities provide flexibility and centralized management. By understanding the characteristics and practical applications of each, developers and administrators can implement secure, efficient, and manageable identity solutions in Azure.
Comments 1