1. Implicit Authentication for AI Services with Azure MSI


    Managed Service Identity (MSI) provides Azure services with an automatically managed identity within Azure Active Directory. You can use this identity to authenticate to any service that supports Azure AD authentication, without needing to embed credentials in your code.

    When you enable MSI for an Azure service like an Azure Function or Azure Virtual Machine, Azure creates a service principal for the instance in Azure AD and injects the necessary credentials at runtime, allowing your application to authenticate and obtain tokens to access other Azure services like Azure Storage, Azure SQL Database, and more.

    Using MSI is a best practice for secure, scoped access to Azure services because credentials do not need to be managed in your code or configurations.

    In Pulumi, you can enable MSI on Azure Resources by configuring the identity property with SystemAssigned or UserAssigned type. A SystemAssigned identity is tied to the lifecycle of the resource and is deleted if the resource is deleted. A UserAssigned identity can be shared across multiple resources and has its own lifecycle.

    For example, you might want to use MSI to authenticate calls to Azure Cognitive Services from an Azure Function, ensuring that the code running in the Function has the necessary permissions, and that these credentials are safely managed by Azure.

    Here's a Pulumi program that demonstrates how to create an Azure Function with a SystemAssigned Managed Service Identity (MSI) and grants it permission to access an Azure Cognitive Services account:

    import pulumi import pulumi_azure_native as azure_native # Create an Azure Resource Group resource_group = azure_native.resources.ResourceGroup("resource_group") # Create an Azure Cognitive Services account cognitive_services_account = azure_native.cognitiveservices.Account("cognitiveServicesAccount", resource_group_name=resource_group.name, kind="TextAnalytics", sku=azure_native.cognitiveservices.SkuArgs( name="S0", ), location="West US", ) # Create an Azure App Service Plan app_service_plan = azure_native.web.AppServicePlan("appServicePlan", resource_group_name=resource_group.name, sku=azure_native.web.SkuDescriptionArgs( name="B1", tier="Basic", ), location=resource_group.location, ) # Create an Azure Function App with SystemAssigned Managed Identity function_app = azure_native.web.WebApp("functionApp", resource_group_name=resource_group.name, server_farm_id=app_service_plan.id, location=resource_group.location, identity=azure_native.web.ManagedServiceIdentityArgs( type="SystemAssigned", ), # Additional properties like site_config etc. should be configured as needed ) # Provide the Azure Function MSI the role assignment to access the Cognitive Services account role_assignment = azure_native.authorization.RoleAssignment("roleAssignment", scope=cognitive_services_account.id, role_definition_id=pulumi.Output.concat("/subscriptions/", pulumi.get_project(), "/providers/Microsoft.Authorization/roleDefinitions/", azure_native.authorization.RoleDefinitionId.CONTRIBUTOR), principal_id=function_app.identity.apply(lambda identity: identity.principal_id if identity else ''), ) # Output the principal ID of the function app pulumi.export("function_app_principal_id", function_app.identity.apply(lambda identity: identity.principal_id if identity else '')) # Output the properties necessary to use the cognitive services account pulumi.export("cognitive_services_account_key", cognitive_services_account.keys.apply(lambda k: k.keys[0].value if k.keys else '')) pulumi.export("cognitive_services_account_endpoint", cognitive_services_account.endpoint)

    In this program:

    • We first create an Azure Resource Group to hold our resources.
    • Next, we set up a Cognitive Services account with the kind TextAnalytics, showing how easily you can create different kinds of resources just by changing parameters.
    • We then set up an App Service Plan to act as a hosting environment for the Azure Function.
    • The Azure Function App is then created with a SystemAssigned managed identity, which means that Azure will automatically create a service principal for this Function App.
    • A Role Assignment is created to grant the Function App's managed identity the Contributor role on the Cognitive Services account, giving the Function App the permissions it needs to access the Cognitive Services.
    • Finally, we export the principal ID of the function app, along with the Cognitive Services account's key and endpoint. This makes it possible to use these values in other parts of your Pulumi program, or reference them via the Pulumi CLI after deployment.

    To use this program, adjust the location to your preferred Azure location and potentially change the role definition to a less privileged one if needed for your scenario. Ensure your Pulumi and Azure CLI are correctly configured to deploy this to your Azure subscription.