Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements to managed identity updates #488

Merged
merged 9 commits into from
Feb 13, 2025
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A new year brings some much requested feature updates to one of our most popular AI chat repos!

- **[Managed Identity-based security](/docs/9-managed-identities.md)**. This uses Azure's underlying RBAC and removes (almost) all keys/secrets.
- `appreg_setup.ps1` helper script to **[create the App Registration for you](/docs/3-add-identity.md#entra-id-authentication-provider)** in Entra ID (if you have the permissions). Less copypasta means happier devs 🥰
- `appreg_setup.ps1` and `appreg_setup.sh` helper scripts to **[create the App Registration for you](/docs/3-add-identity.md#entra-id-authentication-provider)** in Entra ID (if you have the permissions). Less copypasta means happier devs 🥰

# Unleash the Power of Azure OpenAI

Expand Down
2 changes: 1 addition & 1 deletion azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ hooks:
postdeploy:
posix:
shell: sh
run: echo -e "\n\033[0;36mTo complete the application setup you will need to configure an identity provider\033[0m\n(see the "Production App Setup" documentation at https://github.com/microsoft/azurechat/blob/main/docs/3-add-identity.md)\n"
run: echo "\n\033[0;36mTo complete the application setup you will need to configure an identity provider\033[0m\n(see the "Production App Setup" documentation at https://github.com/microsoft/azurechat/blob/main/docs/3-add-identity.md)\n"
interactive: true
continueOnError: false
windows:
Expand Down
4 changes: 4 additions & 0 deletions docs/2-run-locally.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Clone this repository locally or fork to your GitHub account. Run all of the the

1. Change directory to the `src` folder
2. Rename/copy the file `.env.example` to `.env.local` and populate the environment variables based on the deployed resources in Azure.

> **NOTE**
> If you have used the Azure Developer CLI to deploy the Azure infrastructure required for the solution ([using the directions here](./4-deploy-to-azure.md)), you can find the values for many the required environment variables in the `.env` file the `.azure\<azd env name>` directory. This generated file will not contain any keys, however it is recommended to use managed identities as described in "Setup your local development environment" on [this page](./9-managed-identities.md).
3. Install npm packages by running `npm install`
4. Start the app by running `npm run dev`
5. Access the app on [http://localhost:3000](http://localhost:3000)
Expand Down
14 changes: 14 additions & 0 deletions docs/4-deploy-to-azure.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# ☁️ Deploy to Azure - Azure Developer CLI (azd)

To deploy the application to Azure using the Azure Developer CLI, follow the steps below. You can do this without cloning the repository, but instructions are also provided for those who have cloned the repository.

1. Download the [Azure Developer CLI](https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/overview)

2. **If you have not cloned this repo**:
1. Run `azd init -t microsoft/azurechat`
1. Run `azd up` to provision and deploy the application

2. **If you have cloned this repo**:
1. Run `azd init` from the repo root directory
1. Run `azd up` to provision and deploy the application

# ☁️ Deploy to Azure - GitHub Actions

The following steps describes how the application can be deployed to Azure App service using GitHub Actions.
Expand Down
16 changes: 12 additions & 4 deletions docs/9-managed-identities.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,23 @@ To deploy the application to Azure App Service with Managed Identities, follow t

1. **Update the Parameter**:
- Set the parameter `disableLocalAuth` to `true` in [`infra/main.bicep`](/infra/main.bicep) (or [`infra/main.json`](/infra/main.json) for ARM deployment) to use Managed Identities.
2. **Deploy as normal**:
2. **Deploy resources using azd**:
- refer to the [README](../README.md)
3. **(Optional) Setup your local development environment**:
- Run this script to grant yourself RBAC permissions on the Azure resources so you can run AzureChat locally

Run this script to grant yourself RBAC permissions on the Azure resources so you can run AzureChat locally with managed identities.

If you haven't already done so then you will need to login to Azure using the Azure CLI command `az login`
- In Powershell:
```powershell
PS> .\scripts\appreg_setup.ps1
PS> .\scripts\add_localdev_roles.ps1
```
- In Bash:
```bash
> chmod +x .\scripts\add_localdev_roles.sh
> .\scripts\add_localdev_roles.sh
```
- You can now refer to the documentation to [run Azure Chat locally](2-run-locally.md).
You can now refer to the documentation to [run Azure Chat locally](2-run-locally.md).

## Conclusion

Expand Down
223 changes: 114 additions & 109 deletions infra/resources.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,113 @@ resource appServicePlan 'Microsoft.Web/serverfarms@2020-06-01' = {
kind: 'linux'
}

var appSettingsCommon = [
{
name: 'USE_MANAGED_IDENTITIES'
value: disableLocalAuth
}

{
name: 'AZURE_KEY_VAULT_NAME'
value: keyVaultName
}
{
name: 'SCM_DO_BUILD_DURING_DEPLOYMENT'
value: 'true'
}
{
name: 'AZURE_OPENAI_API_INSTANCE_NAME'
value: openai_name
}
{
name: 'AZURE_OPENAI_API_DEPLOYMENT_NAME'
value: chatGptDeploymentName
}
{
name: 'AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME'
value: embeddingDeploymentName
}
{
name: 'AZURE_OPENAI_API_VERSION'
value: openai_api_version
}
{
name: 'AZURE_OPENAI_DALLE_API_INSTANCE_NAME'
value: openai_dalle_name
}
{
name: 'AZURE_OPENAI_DALLE_API_DEPLOYMENT_NAME'
value: dalleDeploymentName
}
{
name: 'AZURE_OPENAI_DALLE_API_VERSION'
value: dalleApiVersion
}
{
name: 'NEXTAUTH_SECRET'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::NEXTAUTH_SECRET.name})'
}
{
name: 'NEXTAUTH_URL'
value: 'https://${webapp_name}.azurewebsites.net'
}
{
name: 'AZURE_COSMOSDB_URI'
value: cosmosDbAccount.properties.documentEndpoint
}
{
name: 'AZURE_SEARCH_NAME'
value: search_name
}
{
name: 'AZURE_SEARCH_INDEX_NAME'
value: searchServiceIndexName
}
{
name: 'AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT'
value: 'https://${form_recognizer_name}.cognitiveservices.azure.com/'
}
{
name: 'AZURE_SPEECH_REGION'
value: location
}
{
name: 'AZURE_SPEECH_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_SPEECH_KEY.name})'
}
{
name: 'AZURE_STORAGE_ACCOUNT_NAME'
value: storage_name
}
]

var appSettingsWithLocalAuth = disableLocalAuth ? [] : [
{
name: 'AZURE_OPENAI_API_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_OPENAI_API_KEY.name})'
}
{
name: 'AZURE_OPENAI_DALLE_API_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_OPENAI_DALLE_API_KEY.name})'
}
{
name: 'AZURE_COSMOSDB_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_COSMOSDB_KEY.name})'
}
{
name: 'AZURE_SEARCH_API_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_SEARCH_API_KEY.name})'
}
{
name: 'AZURE_DOCUMENT_INTELLIGENCE_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_DOCUMENT_INTELLIGENCE_KEY.name})'
}
{
name: 'AZURE_STORAGE_ACCOUNT_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_STORAGE_ACCOUNT_KEY.name})'
}
]

resource webApp 'Microsoft.Web/sites@2020-06-01' = {
name: webapp_name
location: location
Expand All @@ -119,109 +226,7 @@ resource webApp 'Microsoft.Web/sites@2020-06-01' = {
appCommandLine: 'next start'
ftpsState: 'Disabled'
minTlsVersion: '1.2'
appSettings: [
{
name: 'USE_MANAGED_IDENTITIES'
value: disableLocalAuth
}

{
name: 'AZURE_KEY_VAULT_NAME'
value: keyVaultName
}
{
name: 'SCM_DO_BUILD_DURING_DEPLOYMENT'
value: 'true'
}
{
name: 'AZURE_OPENAI_API_KEY'
value: disableLocalAuth ? '' :'@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_OPENAI_API_KEY.name})'
}
{
name: 'AZURE_OPENAI_API_INSTANCE_NAME'
value: openai_name
}
{
name: 'AZURE_OPENAI_API_DEPLOYMENT_NAME'
value: chatGptDeploymentName
}
{
name: 'AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME'
value: embeddingDeploymentName
}
{
name: 'AZURE_OPENAI_API_VERSION'
value: openai_api_version
}
{
name: 'AZURE_OPENAI_DALLE_API_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_OPENAI_DALLE_API_KEY.name})'
}
{
name: 'AZURE_OPENAI_DALLE_API_INSTANCE_NAME'
value: openai_dalle_name
}
{
name: 'AZURE_OPENAI_DALLE_API_DEPLOYMENT_NAME'
value: dalleDeploymentName
}
{
name: 'AZURE_OPENAI_DALLE_API_VERSION'
value: dalleApiVersion
}
{
name: 'NEXTAUTH_SECRET'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::NEXTAUTH_SECRET.name})'
}
{
name: 'NEXTAUTH_URL'
value: 'https://${webapp_name}.azurewebsites.net'
}
{
name: 'AZURE_COSMOSDB_URI'
value: cosmosDbAccount.properties.documentEndpoint
}
{
name: 'AZURE_COSMOSDB_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_COSMOSDB_KEY.name})'
}
{
name: 'AZURE_SEARCH_API_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_SEARCH_API_KEY.name})'
}
{
name: 'AZURE_SEARCH_NAME'
value: search_name
}
{
name: 'AZURE_SEARCH_INDEX_NAME'
value: searchServiceIndexName
}
{
name: 'AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT'
value: 'https://${form_recognizer_name}.cognitiveservices.azure.com/'
}
{
name: 'AZURE_DOCUMENT_INTELLIGENCE_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_DOCUMENT_INTELLIGENCE_KEY.name})'
}
{
name: 'AZURE_SPEECH_REGION'
value: location
}
{
name: 'AZURE_SPEECH_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_SPEECH_KEY.name})'
}
{
name: 'AZURE_STORAGE_ACCOUNT_NAME'
value: storage_name
}
{
name: 'AZURE_STORAGE_ACCOUNT_KEY'
value: '@Microsoft.KeyVault(VaultName=${kv.name};SecretName=${kv::AZURE_STORAGE_ACCOUNT_KEY.name})'
}
]
appSettings: concat(appSettingsCommon, appSettingsWithLocalAuth)
}
}
identity: { type: 'SystemAssigned'}
Expand Down Expand Up @@ -282,15 +287,15 @@ resource kv 'Microsoft.KeyVault/vaults@2021-06-01-preview' = {
enabledForTemplateDeployment: false
}

resource AZURE_OPENAI_API_KEY 'secrets' = {
resource AZURE_OPENAI_API_KEY 'secrets' = if (!disableLocalAuth) {
name: 'AZURE-OPENAI-API-KEY'
properties: {
contentType: 'text/plain'
value: azureopenai.listKeys().key1
}
}

resource AZURE_OPENAI_DALLE_API_KEY 'secrets' = {
resource AZURE_OPENAI_DALLE_API_KEY 'secrets' = if (!disableLocalAuth){
name: 'AZURE-OPENAI-DALLE-API-KEY'
properties: {
contentType: 'text/plain'
Expand All @@ -306,15 +311,15 @@ resource kv 'Microsoft.KeyVault/vaults@2021-06-01-preview' = {
}
}

resource AZURE_COSMOSDB_KEY 'secrets' = {
resource AZURE_COSMOSDB_KEY 'secrets' = if (!disableLocalAuth){
name: 'AZURE-COSMOSDB-KEY'
properties: {
contentType: 'text/plain'
value: cosmosDbAccount.listKeys().secondaryMasterKey
}
}

resource AZURE_DOCUMENT_INTELLIGENCE_KEY 'secrets' = {
resource AZURE_DOCUMENT_INTELLIGENCE_KEY 'secrets' = if (!disableLocalAuth){
name: 'AZURE-DOCUMENT-INTELLIGENCE-KEY'
properties: {
contentType: 'text/plain'
Expand All @@ -330,15 +335,15 @@ resource kv 'Microsoft.KeyVault/vaults@2021-06-01-preview' = {
}
}

resource AZURE_SEARCH_API_KEY 'secrets' = {
resource AZURE_SEARCH_API_KEY 'secrets' = if (!disableLocalAuth){
name: 'AZURE-SEARCH-API-KEY'
properties: {
contentType: 'text/plain'
value: searchService.listAdminKeys().secondaryKey
}
}

resource AZURE_STORAGE_ACCOUNT_KEY 'secrets' = {
resource AZURE_STORAGE_ACCOUNT_KEY 'secrets' = if (!disableLocalAuth){
name: 'AZURE-STORAGE-ACCOUNT-KEY'
properties: {
contentType: 'text/plain'
Expand Down
Loading
Loading