From 635f1f777d8b23b6c0ee21396a963bffef69fc4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 30 Jul 2025 07:26:32 +0000 Subject: [PATCH 1/3] Initial plan From 2a5918607334bac1634f4a2f50e9824ec6b5b846 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 30 Jul 2025 07:34:16 +0000 Subject: [PATCH 2/3] Fix LICENSE file, GitHub workflow naming, and README.md structure Co-authored-by: anfibiacreativa <4014025+anfibiacreativa@users.noreply.github.com> --- .../{azure-dev.yaml => azure-dev.yml} | 0 LICENSE | 21 +++++++++++++++++++ README.md | 16 +++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) rename .github/workflows/{azure-dev.yaml => azure-dev.yml} (100%) create mode 100644 LICENSE diff --git a/.github/workflows/azure-dev.yaml b/.github/workflows/azure-dev.yml similarity index 100% rename from .github/workflows/azure-dev.yaml rename to .github/workflows/azure-dev.yml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..631a2b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE \ No newline at end of file diff --git a/README.md b/README.md index 0415ca5..8ae866d 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,26 @@ This project provides the following features: ![Screenshot of chat app with question about climbing gear](docs/images/screenshot_chat.png) -## Architecture diagram +## Architecture The deployed app uses a user-assigned managed identity to authenticate to Azure services, and stores logs in Log Analytics. ![Architecture diagram: Azure Container Apps, Azure Container Registry, Managed Identity, Azure OpenAI, Azure Database for PostgreSQL](docs/images/azure_architecture.png) +## Prerequisites + +To use this template, you'll need: + +* [Azure Developer CLI (azd)](https://aka.ms/install-azd) +* [Node.js 18+](https://nodejs.org/download/) +* [Python 3.10+](https://www.python.org/downloads/) +* [PostgreSQL 14+](https://www.postgresql.org/download/) (for local development) +* [pgvector](https://github.com/pgvector/pgvector) (PostgreSQL extension) +* [Docker Desktop](https://www.docker.com/products/docker-desktop/) +* [Git](https://git-scm.com/downloads) + +An Azure subscription is required for deployment. + ## Getting started You have a few options for getting started with this template. From 65d58c19b003271dcfaa78f7d5aed2e8ca4abfe1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 30 Jul 2025 07:54:54 +0000 Subject: [PATCH 3/3] Fix Bicep metadata with requiredResources properties for Template Doctor compliance Co-authored-by: anfibiacreativa <4014025+anfibiacreativa@users.noreply.github.com> --- infra/backend-dashboard.bicep | 10 ++++++- infra/core/ai/ai-foundry.bicep | 16 +++++++++++ infra/core/ai/cognitiveservices.bicep | 10 ++++++- .../database/postgresql/flexibleserver.bicep | 16 +++++++++++ infra/core/host/container-app-upsert.bicep | 10 ++++++- infra/core/host/container-app.bicep | 10 ++++++- .../host/container-apps-environment.bicep | 10 ++++++- infra/core/host/container-apps.bicep | 13 ++++++++- infra/core/host/container-registry.bicep | 13 ++++++++- infra/core/monitor/applicationinsights.bicep | 10 ++++++- infra/core/monitor/loganalytics.bicep | 10 ++++++- infra/core/monitor/monitoring.bicep | 13 ++++++++- infra/core/security/registry-access.bicep | 10 ++++++- infra/core/security/role.bicep | 10 ++++++- infra/main.bicep | 28 +++++++++++++++---- infra/web.bicep | 13 +++++++++ 16 files changed, 185 insertions(+), 17 deletions(-) diff --git a/infra/backend-dashboard.bicep b/infra/backend-dashboard.bicep index 62af08e..adea33c 100644 --- a/infra/backend-dashboard.bicep +++ b/infra/backend-dashboard.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates a dashboard for an Application Insights instance.' + + +@metadata({ + description: 'Creates a dashboard for an Application Insights instance.' + requiredResources: [ + 'Microsoft.Portal/dashboards' + ] +}) + param name string param applicationInsightsName string param location string = resourceGroup().location diff --git a/infra/core/ai/ai-foundry.bicep b/infra/core/ai/ai-foundry.bicep index cc787a7..ab458a6 100644 --- a/infra/core/ai/ai-foundry.bicep +++ b/infra/core/ai/ai-foundry.bicep @@ -1,3 +1,19 @@ + + + +@metadata({ + description: 'Creates an Azure AI Foundry resource with projects and connections.' + requiredResources: [ + + 'Microsoft.CognitiveServices/accounts' + 'Microsoft.CognitiveServices/accounts/projects' + 'Microsoft.Storage/storageAccounts' + 'Microsoft.CognitiveServices/accounts/connections' + 'Microsoft.Authorization/roleAssignments' + + ] +}) + @minLength(1) @description('Primary location for all resources') param location string diff --git a/infra/core/ai/cognitiveservices.bicep b/infra/core/ai/cognitiveservices.bicep index 7776a4e..a049eb9 100644 --- a/infra/core/ai/cognitiveservices.bicep +++ b/infra/core/ai/cognitiveservices.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates an Azure Cognitive Services instance.' + + +@metadata({ + description: 'Creates an Azure Cognitive Services instance.' + requiredResources: [ + 'Microsoft.CognitiveServices/accounts' + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/database/postgresql/flexibleserver.bicep b/infra/core/database/postgresql/flexibleserver.bicep index 2b35250..1a3e34b 100644 --- a/infra/core/database/postgresql/flexibleserver.bicep +++ b/infra/core/database/postgresql/flexibleserver.bicep @@ -1,3 +1,19 @@ + + + +@metadata({ + description: 'Creates an Azure Database for PostgreSQL Flexible Server.' + requiredResources: [ + + 'Microsoft.DBforPostgreSQL/flexibleServers' + 'Microsoft.DBforPostgreSQL/flexibleServers/databases' + 'Microsoft.DBforPostgreSQL/flexibleServers/firewallRules' + 'Microsoft.DBforPostgreSQL/flexibleServers/administrators' + 'Microsoft.DBforPostgreSQL/flexibleServers/configurations' + + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/host/container-app-upsert.bicep b/infra/core/host/container-app-upsert.bicep index 3577d41..4b2e0e4 100644 --- a/infra/core/host/container-app-upsert.bicep +++ b/infra/core/host/container-app-upsert.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates or updates an existing Azure Container App.' + + +@metadata({ + description: 'Creates or updates an existing Azure Container App.' + requiredResources: [ + 'Microsoft.App/containerApps' + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/host/container-app.bicep b/infra/core/host/container-app.bicep index 225d068..d5ef688 100644 --- a/infra/core/host/container-app.bicep +++ b/infra/core/host/container-app.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates a container app in an Azure Container App environment.' + + +@metadata({ + description: 'Creates a container app in an Azure Container App environment.' + requiredResources: [ + 'Microsoft.App/containerApps' + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/host/container-apps-environment.bicep b/infra/core/host/container-apps-environment.bicep index 20f4632..a75f9eb 100644 --- a/infra/core/host/container-apps-environment.bicep +++ b/infra/core/host/container-apps-environment.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates an Azure Container Apps environment.' + + +@metadata({ + description: 'Creates an Azure Container Apps environment.' + requiredResources: [ + 'Microsoft.App/managedEnvironments' + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/host/container-apps.bicep b/infra/core/host/container-apps.bicep index 74db9bd..1ec06c0 100644 --- a/infra/core/host/container-apps.bicep +++ b/infra/core/host/container-apps.bicep @@ -1,4 +1,15 @@ -metadata description = 'Creates an Azure Container Registry and an Azure Container Apps environment.' + + +@metadata({ + description: 'Creates an Azure Container Registry and an Azure Container Apps environment.' + requiredResources: [ + + 'Microsoft.ContainerRegistry/registries' + 'Microsoft.App/managedEnvironments' + + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/host/container-registry.bicep b/infra/core/host/container-registry.bicep index d14731c..43c46fd 100644 --- a/infra/core/host/container-registry.bicep +++ b/infra/core/host/container-registry.bicep @@ -1,4 +1,15 @@ -metadata description = 'Creates an Azure Container Registry.' + + +@metadata({ + description: 'Creates an Azure Container Registry.' + requiredResources: [ + + 'Microsoft.ContainerRegistry/registries' + 'Microsoft.Insights/diagnosticSettings' + + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/monitor/applicationinsights.bicep b/infra/core/monitor/applicationinsights.bicep index dd91a40..692abc6 100644 --- a/infra/core/monitor/applicationinsights.bicep +++ b/infra/core/monitor/applicationinsights.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates an Application Insights instance based on an existing Log Analytics workspace.' + + +@metadata({ + description: 'Creates an Application Insights instance based on an existing Log Analytics workspace.' + requiredResources: [ + 'Microsoft.Insights/components' + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/monitor/loganalytics.bicep b/infra/core/monitor/loganalytics.bicep index 33f9dc2..b677539 100644 --- a/infra/core/monitor/loganalytics.bicep +++ b/infra/core/monitor/loganalytics.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates a Log Analytics workspace.' + + +@metadata({ + description: 'Creates a Log Analytics workspace.' + requiredResources: [ + 'Microsoft.OperationalInsights/workspaces' + ] +}) + param name string param location string = resourceGroup().location param tags object = {} diff --git a/infra/core/monitor/monitoring.bicep b/infra/core/monitor/monitoring.bicep index a12c083..4a186d3 100644 --- a/infra/core/monitor/monitoring.bicep +++ b/infra/core/monitor/monitoring.bicep @@ -1,4 +1,15 @@ -metadata description = 'Creates an Application Insights instance and a Log Analytics workspace.' + + +@metadata({ + description: 'Creates an Application Insights instance and a Log Analytics workspace.' + requiredResources: [ + + 'Microsoft.OperationalInsights/workspaces' + 'Microsoft.Insights/components' + + ] +}) + param logAnalyticsName string param applicationInsightsName string param location string = resourceGroup().location diff --git a/infra/core/security/registry-access.bicep b/infra/core/security/registry-access.bicep index fc66837..c4e583f 100644 --- a/infra/core/security/registry-access.bicep +++ b/infra/core/security/registry-access.bicep @@ -1,4 +1,12 @@ -metadata description = 'Assigns ACR Pull permissions to access an Azure Container Registry.' + + +@metadata({ + description: 'Assigns ACR Pull permissions to access an Azure Container Registry.' + requiredResources: [ + 'Microsoft.Authorization/roleAssignments' + ] +}) + param containerRegistryName string param principalId string diff --git a/infra/core/security/role.bicep b/infra/core/security/role.bicep index 0b30cfd..a52fc80 100644 --- a/infra/core/security/role.bicep +++ b/infra/core/security/role.bicep @@ -1,4 +1,12 @@ -metadata description = 'Creates a role assignment for a service principal.' + + +@metadata({ + description: 'Creates a role assignment for a service principal.' + requiredResources: [ + 'Microsoft.Authorization/roleAssignments' + ] +}) + param principalId string @allowed([ diff --git a/infra/main.bicep b/infra/main.bicep index 6fc222f..73ea07e 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -1,5 +1,27 @@ targetScope = 'subscription' + + + + +@metadata({ + description: 'Main deployment template for RAG PostgreSQL OpenAI application infrastructure.' + requiredResources: [ + + 'Microsoft.Resources/resourceGroups' + 'Microsoft.CognitiveServices/accounts' + 'Microsoft.DBforPostgreSQL/flexibleServers' + 'Microsoft.ContainerRegistry/registries' + 'Microsoft.App/managedEnvironments' + 'Microsoft.App/containerApps' + 'Microsoft.OperationalInsights/workspaces' + 'Microsoft.Insights/components' + 'Microsoft.ManagedIdentity/userAssignedIdentities' + 'Microsoft.Authorization/roleAssignments' + + ] +}) + @minLength(1) @maxLength(64) @description('Name which is used to generate a short unique hash for each resource') @@ -43,11 +65,7 @@ param principalId string = '' 'westus' 'westus3' ]) -@metadata({ - azd: { - type: 'location' - } -}) + param openAILocation string @description('Name of the OpenAI resource group. If not specified, the resource group name will be generated.') diff --git a/infra/web.bicep b/infra/web.bicep index 6419b38..1d37e9a 100644 --- a/infra/web.bicep +++ b/infra/web.bicep @@ -1,3 +1,16 @@ + + + +@metadata({ + description: 'Creates a web container app with managed identity.' + requiredResources: [ + + 'Microsoft.ManagedIdentity/userAssignedIdentities' + 'Microsoft.App/containerApps' + + ] +}) + param name string param location string = resourceGroup().location param tags object = {}