diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml deleted file mode 100644 index a372650..0000000 --- a/.github/workflows/validate.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Validate Node.js solution -on: - workflow_dispatch: - pull_request: -jobs: - validate-nodejs: - name: Validate Node.js solution - runs-on: ubuntu-latest - container: node:22 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Check Node.js version - run: node --version - - name: Check NPM version - run: npm --version - - name: Install NPM packages (Javascript) - run: npm install - working-directory: ./src/js - - name: Install NPM packages (Typescript) - run: npm install - working-directory: ./src/ts \ No newline at end of file diff --git a/infra/abbreviations.json b/infra/abbreviations.json index d009e2c..81c842b 100644 --- a/infra/abbreviations.json +++ b/infra/abbreviations.json @@ -1,6 +1,8 @@ -{ +{ + "logAnalyticsWorkspace": "log-analytics", "containerRegistry": "containerreg", "containerAppsEnv": "container-env", "containerAppsApp": "container-app", - "cosmosDbAccount": "cosmos-db-nosql" + "cosmosDbAccount": "cosmos-db-nosql", + "userAssignedIdentity": "managed-identity" } \ No newline at end of file diff --git a/infra/app/data.bicep b/infra/app/data.bicep deleted file mode 100644 index 98f5839..0000000 --- a/infra/app/data.bicep +++ /dev/null @@ -1,50 +0,0 @@ -metadata description = 'Create database account resources.' - -param databaseAccountName string -param tags object = {} - -var database = { - name: 'cosmicworks' // Based on AdventureWorksLT data set -} - -var containers = [ - { - name: 'products' // Set of products - partitionKeyPaths: [ - '/category' // Partition on the product category - ] - autoscale: true // Scale at the container level - throughput: 1000 // Enable autoscale with a minimum of 100 RUs and a maximum of 1,000 RUs - } -] - -module cosmosDbDatabase '../core/database/cosmos-db/nosql/database.bicep' = { - name: 'cosmos-db-database-${database.name}' - params: { - name: database.name - parentAccountName: databaseAccountName - tags: tags - setThroughput: false - } -} - -module cosmosDbContainers '../core/database/cosmos-db/nosql/container.bicep' = [for (container, _) in containers: { - name: 'cosmos-db-container-${container.name}' - params: { - name: container.name - parentAccountName: databaseAccountName - parentDatabaseName: cosmosDbDatabase.outputs.name - tags: tags - setThroughput: true - autoscale: container.autoscale - throughput: container.throughput - partitionKeyPaths: container.partitionKeyPaths - } -}] - -output database object = { - name: cosmosDbDatabase.outputs.name -} -output containers array = [for (_, index) in containers: { - name: cosmosDbContainers[index].outputs.name -}] diff --git a/infra/app/database.bicep b/infra/app/database.bicep index 1ae24ea..afc3eac 100644 --- a/infra/app/database.bicep +++ b/infra/app/database.bicep @@ -4,14 +4,69 @@ param accountName string param location string = resourceGroup().location param tags object = {} -module cosmosDbAccount '../core/database/cosmos-db/nosql/account.bicep' = { +@description('Id of the service principals to assign database and application roles.') +param appPrincipalId string + +@description('Id of the user principals to assign database and application roles.') +param userPrincipalId string = '' + +var database = { + name: 'cosmicworks' // Based on AdventureWorksLT data set +} + +var containers = [ + { + name: 'products' // Set of products + partitionKeyPaths: [ + '/category' // Partition on the product category + ] + autoscale: true // Scale at the container level + throughput: 1000 // Enable autoscale with a minimum of 100 RUs and a maximum of 1,000 RUs + } +] + +module cosmosDbAccount 'br/public:avm/res/document-db/database-account:0.6.1' = { name: 'cosmos-db-account' params: { name: accountName location: location tags: tags + disableKeyBasedMetadataWriteAccess: true + disableLocalAuth: true + sqlRoleDefinitions: [ + { + name: 'nosql-data-plane-contributor' + dataAction: [ + 'Microsoft.DocumentDB/databaseAccounts/readMetadata' // Read account metadata + 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*' // Create items + 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*' // Manage items + ] + } + ] + sqlRoleAssignmentsPrincipalIds: union( + [ + appPrincipalId + ], + !empty(userPrincipalId) + ? [ + userPrincipalId + ] + : [] + ) + sqlDatabases: [ + { + name: database.name + containers: [ + for container in containers: { + name: container.name + paths: container.partitionKeyPaths + autoscaleSettingsMaxThroughput: container.throughput + } + ] + } + ] } } +output name string = cosmosDbAccount.outputs.name output endpoint string = cosmosDbAccount.outputs.endpoint -output accountName string = cosmosDbAccount.outputs.name diff --git a/infra/app/environment.bicep b/infra/app/environment.bicep deleted file mode 100644 index bcd3a51..0000000 --- a/infra/app/environment.bicep +++ /dev/null @@ -1,16 +0,0 @@ -metadata description = 'Create web application environment resources.' - -param envName string -param location string = resourceGroup().location -param tags object = {} - -module containerAppsEnvironment '../core/host/container-apps/environments/managed.bicep' = { - name: 'container-apps-env' - params: { - name: envName - location: location - tags: tags - } -} - -output name string = containerAppsEnvironment.outputs.name diff --git a/infra/app/identity.bicep b/infra/app/identity.bicep new file mode 100644 index 0000000..14ddd91 --- /dev/null +++ b/infra/app/identity.bicep @@ -0,0 +1,19 @@ +metadata description = 'Create identity resources.' + +param identityName string +param location string = resourceGroup().location +param tags object = {} + +module userAssignedIdentity 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.0' = { + name: 'user-assigned-identity' + params: { + name: identityName + location: location + tags: tags + } +} + +output name string = userAssignedIdentity.outputs.name +output resourceId string = userAssignedIdentity.outputs.resourceId +output principalId string = userAssignedIdentity.outputs.principalId +output clientId string = userAssignedIdentity.outputs.clientId diff --git a/infra/app/registry.bicep b/infra/app/registry.bicep index c54d023..2243bb9 100644 --- a/infra/app/registry.bicep +++ b/infra/app/registry.bicep @@ -4,18 +4,33 @@ param registryName string param location string = resourceGroup().location param tags object = {} -module containerRegistry '../core/host/container-registry/registry.bicep' = { +@description('Id of the user principals to assign database and application roles.') +param userPrincipalId string = '' + +module containerRegistry 'br/public:avm/res/container-registry/registry:0.5.1' = { name: 'container-registry' params: { name: registryName location: location tags: tags - adminUserEnabled: false + acrAdminUserEnabled: false anonymousPullEnabled: true - publicNetworkAccessEnabled: true - skuName: 'Standard' + publicNetworkAccess: 'Enabled' + acrSku: 'Standard' + } +} + +module registryUserAssignment 'br/public:avm/ptn/authorization/resource-role-assignment:0.1.1' = if (!empty(userPrincipalId)) { + name: 'container-registry-role-assignment-push-user' + params: { + principalId: userPrincipalId + resourceId: containerRegistry.outputs.resourceId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '8311e382-0749-4cb8-b61a-304f252e45ec' // AcrPush built-in role + ) } } -output endpoint string = containerRegistry.outputs.endpoint output name string = containerRegistry.outputs.name +output endpoint string = containerRegistry.outputs.loginServer diff --git a/infra/app/security.bicep b/infra/app/security.bicep deleted file mode 100644 index 6e60f25..0000000 --- a/infra/app/security.bicep +++ /dev/null @@ -1,59 +0,0 @@ -metadata description = 'Create role assignment and definition resources.' - -param databaseAccountName string - -@description('Id of the service principals to assign database and application roles.') -param appPrincipalIds string[] = [] - -@description('Id of the user principals to assign database and application roles.') -param userPrincipalId string = '' - -resource database 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = { - name: databaseAccountName -} - -module nosqlDefinition '../core/database/cosmos-db/nosql/role/definition.bicep' = { - name: 'nosql-role-definition' - params: { - targetAccountName: database.name // Existing account - definitionName: 'Write to Azure Cosmos DB for NoSQL data plane' // Custom role name - permissionsDataActions: [ - 'Microsoft.DocumentDB/databaseAccounts/readMetadata' // Read account metadata - 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*' // Create items - 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*' // Manage items - ] - } -} - -module nosqlAppAssignments '../core/database/cosmos-db/nosql/role/assignment.bicep' = [for (appPrincipalId, index) in appPrincipalIds: { - name: 'nosql-role-assignment-app-${index}' - params: { - targetAccountName: database.name // Existing account - roleDefinitionId: nosqlDefinition.outputs.id // New role definition - principalId: appPrincipalId // Principal to assign role - } -}] - -module nosqlUserAssignment '../core/database/cosmos-db/nosql/role/assignment.bicep' = if (!empty(userPrincipalId)) { - name: 'nosql-role-assignment-user' - params: { - targetAccountName: database.name // Existing account - roleDefinitionId: nosqlDefinition.outputs.id // New role definition - principalId: userPrincipalId ?? '' // Principal to assign role - } -} - -module registryUserAssignment '../core/security/role/assignment.bicep' = if (!empty(userPrincipalId)) { - name: 'container-registry-role-assignment-push-user' - params: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec') // AcrPush built-in role - principalId: userPrincipalId // Principal to assign role - principalType: 'User' // Current deployment user - } -} - -output roleDefinitions object = { - nosql: nosqlDefinition.outputs.id -} - -output roleAssignments array = !empty(userPrincipalId) ? [ nosqlUserAssignment.outputs.id, registryUserAssignment.outputs.id ] : [] diff --git a/infra/app/web.bicep b/infra/app/web.bicep index 1f3de99..3025d0d 100644 --- a/infra/app/web.bicep +++ b/infra/app/web.bicep @@ -1,43 +1,146 @@ -metadata description = 'Create web application host resources.' +metadata description = 'Create web application resources.' -param appName string -param serviceTag string +param workspaceName string +param envName string +param jsAppName string +param tsAppName string +param jsServiceTag string +param tsServiceTag string param location string = resourceGroup().location param tags object = {} -@description('Name of the environment where the application will be hosted.') -param envName string - -@description('Endpoint for Azure Cosmos DB for NoSQL account.') +@description('Endpoint for Azure Cosmos DB for Table account.') param databaseAccountEndpoint string -module containerAppsApp '../core/host/container-apps/app.bicep' = { - name: 'container-apps-app-${appName}' +@description('Client ID of the service principal to assign database and application roles.') +param appClientId string + +@description('Resource ID of the service principal to assign database and application roles.') +param appResourceId string + +module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0.7.0' = { + name: 'log-analytics-workspace' + params: { + name: workspaceName + location: location + tags: tags + } +} + +module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.8.0' = { + name: 'container-apps-env' params: { - name: appName - parentEnvironmentName: envName + name: envName location: location - tags: union(tags, { - 'azd-service-name': serviceTag - }) - transport: 'http' - secrets: [ + tags: tags + logAnalyticsWorkspaceResourceId: logAnalyticsWorkspace.outputs.resourceId + zoneRedundant: false + } +} + +module containerAppsJsApp 'br/public:avm/res/app/container-app:0.9.0' = { + name: 'container-apps-app-js' + params: { + name: jsAppName + environmentResourceId: containerAppsEnvironment.outputs.resourceId + location: location + tags: union(tags, { 'azd-service-name': jsServiceTag }) + ingressTargetPort: 3000 + ingressExternal: true + ingressTransport: 'auto' + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: [ + appResourceId + ] + } + secrets: { + secureList: [ + { + name: 'azure-cosmos-db-nosql-endpoint' + value: databaseAccountEndpoint + } + { + name: 'user-assigned-managed-identity-client-id' + value: appClientId + } + ] + } + containers: [ { - name: 'azure-cosmos-db-nosql-endpoint' // Create a uniquely-named secret - value: databaseAccountEndpoint // NoSQL database account endpoint + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + name: 'web-front-end' + resources: { + cpu: '0.25' + memory: '0.5Gi' + } + env: [ + { + name: 'AZURE_COSMOS_DB_NOSQL_ENDPOINT' + secretRef: 'azure-cosmos-db-nosql-endpoint' + } + { + name: 'AZURE_CLIENT_ID' + secretRef: 'user-assigned-managed-identity-client-id' + } + ] } ] - environmentVariables: [ + } +} +module containerAppsTsApp 'br/public:avm/res/app/container-app:0.9.0' = { + name: 'container-apps-app-ts' + params: { + name: tsAppName + environmentResourceId: containerAppsEnvironment.outputs.resourceId + location: location + tags: union(tags, { 'azd-service-name': tsServiceTag }) + ingressTargetPort: 3000 + ingressExternal: true + ingressTransport: 'auto' + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: [ + appResourceId + ] + } + secrets: { + secureList: [ + { + name: 'azure-cosmos-db-nosql-endpoint' + value: databaseAccountEndpoint + } + { + name: 'user-assigned-managed-identity-client-id' + value: appClientId + } + ] + } + containers: [ { - name: 'AZURE_COSMOS_DB_NOSQL_ENDPOINT' // Name of the environment variable referenced in the application - secretRef: 'azure-cosmos-db-nosql-endpoint' // Reference to secret + image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' + name: 'web-front-end' + resources: { + cpu: '0.25' + memory: '0.5Gi' + } + env: [ + { + name: 'AZURE_COSMOS_DB_NOSQL_ENDPOINT' + secretRef: 'azure-cosmos-db-nosql-endpoint' + } + { + name: 'AZURE_CLIENT_ID' + secretRef: 'user-assigned-managed-identity-client-id' + } + ] } ] - targetPort: 3000 - enableSystemAssignedManagedIdentity: true } } -output name string = containerAppsApp.outputs.name -output endpoint string = containerAppsApp.outputs.endpoint -output systemAssignedManagedIdentityPrincipalId string = containerAppsApp.outputs.systemAssignedManagedIdentityPrincipalId +output jsEndpoint string = 'https://${containerAppsJsApp.outputs.fqdn}' +output tsEndpoint string = 'https://${containerAppsTsApp.outputs.fqdn}' +output envName string = containerAppsJsApp.outputs.name +output jsSystemAssignedManagedIdentityPrincipalId string = containerAppsJsApp.outputs.systemAssignedMIPrincipalId +output tsSystemAssignedManagedIdentityPrincipalId string = containerAppsTsApp.outputs.systemAssignedMIPrincipalId diff --git a/infra/core/ai/cognitive-services/account.bicep b/infra/core/ai/cognitive-services/account.bicep deleted file mode 100644 index 2eebe9a..0000000 --- a/infra/core/ai/cognitive-services/account.bicep +++ /dev/null @@ -1,35 +0,0 @@ -metadata description = 'Creates an Azure Cognitive Services account.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@allowed([ 'OpenAI', 'ComputerVision', 'TextTranslation', 'CognitiveServices' ]) -@description('Sets the kind of account.') -param kind string - -@allowed([ - 'S0' -]) -@description('SKU for the account. Defaults to "S0".') -param sku string = 'S0' - -@description('Enables access from public networks. Defaults to true.') -param enablePublicNetworkAccess bool = true - -resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = { - name: name - location: location - tags: tags - kind: kind - sku: { - name: sku - } - properties: { - customSubDomainName: name - publicNetworkAccess: enablePublicNetworkAccess ? 'Enabled' : 'Disabled' - } -} - -output endpoint string = account.properties.endpoint -output name string = account.name diff --git a/infra/core/ai/cognitive-services/deployment.bicep b/infra/core/ai/cognitive-services/deployment.bicep deleted file mode 100644 index 2cb4947..0000000 --- a/infra/core/ai/cognitive-services/deployment.bicep +++ /dev/null @@ -1,43 +0,0 @@ -metadata description = 'Creates an Azure Cognitive Services deployment.' - -param name string - -@description('Name of the parent Azure Cognitive Services account.') -param parentAccountName string - -@description('Name of the SKU for the deployment. Defaults to "Standard".') -param skuName string = 'Standard' - -@description('Capacity of the SKU for the deployment. Defaults to 100.') -param skuCapacity int = 100 - -@description('Name of the model to use in the deployment.') -param modelName string - -@description('Format of the model to use in the deployment.') -param modelFormat string - -@description('Version of the model to use in the deployment.') -param modelVersion string - -resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' existing = { - name: parentAccountName -} - -resource deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01' = { - parent: account - name: name - sku: { - name: skuName - capacity: skuCapacity - } - properties: { - model: { - name: modelName - format: modelFormat - version: modelVersion - } - } -} - -output name string = account.name diff --git a/infra/core/database/cosmos-db/account.bicep b/infra/core/database/cosmos-db/account.bicep deleted file mode 100644 index aba6d99..0000000 --- a/infra/core/database/cosmos-db/account.bicep +++ /dev/null @@ -1,53 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB account.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@allowed([ 'GlobalDocumentDB', 'MongoDB', 'Parse' ]) -@description('Sets the kind of account.') -param kind string - -@description('Enables serverless for this account. Defaults to false.') -param enableServerless bool = false - -@description('Disables key-based authentication. Defaults to false.') -param disableKeyBasedAuth bool = false - -@description('List of capabilities for the account. Defaults to an empty array.') -param capabilities object[] = [] - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' = { - name: name - location: location - tags: tags - kind: kind - properties: { - consistencyPolicy: { - defaultConsistencyLevel: 'Session' - } - databaseAccountOfferType: 'Standard' - locations: [ - { - locationName: location - failoverPriority: 0 - isZoneRedundant: false - } - ] - enableAutomaticFailover: false - enableMultipleWriteLocations: false - apiProperties: (kind == 'MongoDB') ? { - serverVersion: '4.2' - } : {} - disableLocalAuth: disableKeyBasedAuth - capabilities: union(capabilities, - (enableServerless) ? [ - { - name: 'EnableServerless' - } - ] : [] - ) - } -} - -output name string = account.name diff --git a/infra/core/database/cosmos-db/nosql/account.bicep b/infra/core/database/cosmos-db/nosql/account.bicep deleted file mode 100644 index bb21159..0000000 --- a/infra/core/database/cosmos-db/nosql/account.bicep +++ /dev/null @@ -1,26 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for NoSQL account.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@description('Enables serverless for this account. Defaults to false.') -param enableServerless bool = false - -@description('Disables key-based authentication. Defaults to true.') -param disableKeyBasedAuth bool = true - -module account '../account.bicep' = { - name: 'cosmos-db-nosql-account' - params: { - name: name - location: location - tags: tags - kind: 'GlobalDocumentDB' - enableServerless: enableServerless - disableKeyBasedAuth: disableKeyBasedAuth - } -} - -output endpoint string = 'https://${account.outputs.name}.documents.azure.com:443/' -output name string = account.outputs.name diff --git a/infra/core/database/cosmos-db/nosql/container.bicep b/infra/core/database/cosmos-db/nosql/container.bicep deleted file mode 100644 index 9544013..0000000 --- a/infra/core/database/cosmos-db/nosql/container.bicep +++ /dev/null @@ -1,59 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for NoSQL container.' - -param name string -param tags object = {} - -@description('Name of the parent Azure Cosmos DB account.') -param parentAccountName string - -@description('Name of the parent Azure Cosmos DB database.') -param parentDatabaseName string - -@description('Enables throughput setting at this resource level. Defaults to true.') -param setThroughput bool = true - -@description('Enables autoscale. If setThroughput is enabled, defaults to false.') -param autoscale bool = false - -@description('The amount of throughput set. If setThroughput is enabled, defaults to 400.') -param throughput int = 400 - -@description('List of hierarhical partition key paths. Defaults to an array that only contains /id.') -param partitionKeyPaths string[] = [ - '/id' -] - -var options = setThroughput ? autoscale ? { - autoscaleSettings: { - maxThroughput: throughput - } -} : { - throughput: throughput -} : {} - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = { - name: parentAccountName -} - -resource database 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2024-05-15' existing = { - name: parentDatabaseName - parent: account -} - -resource container 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2024-05-15' = { - name: name - parent: database - tags: tags - properties: { - options: options - resource: { - id: name - partitionKey: { - paths: partitionKeyPaths - kind: 'Hash' - } - } - } -} - -output name string = container.name diff --git a/infra/core/database/cosmos-db/nosql/database.bicep b/infra/core/database/cosmos-db/nosql/database.bicep deleted file mode 100644 index 36b67dc..0000000 --- a/infra/core/database/cosmos-db/nosql/database.bicep +++ /dev/null @@ -1,42 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for NoSQL database.' - -param name string -param tags object = {} - -@description('Name of the parent Azure Cosmos DB account.') -param parentAccountName string - -@description('Enables throughput setting at this resource level. Defaults to false.') -param setThroughput bool = false - -@description('Enables autoscale. If setThroughput is enabled, defaults to false.') -param autoscale bool = false - -@description('The amount of throughput set. If setThroughput is enabled, defaults to 400.') -param throughput int = 400 - -var options = setThroughput ? autoscale ? { - autoscaleSettings: { - maxThroughput: throughput - } -} : { - throughput: throughput -} : {} - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = { - name: parentAccountName -} - -resource database 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2024-05-15' = { - name: name - parent: account - tags: tags - properties: { - options: options - resource: { - id: name - } - } -} - -output name string = database.name diff --git a/infra/core/database/cosmos-db/nosql/role/assignment.bicep b/infra/core/database/cosmos-db/nosql/role/assignment.bicep deleted file mode 100644 index 3e70217..0000000 --- a/infra/core/database/cosmos-db/nosql/role/assignment.bicep +++ /dev/null @@ -1,29 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for NoSQL role assignment.' - -@description('Name of the target Azure Cosmos DB account.') -param targetAccountName string - -@description('Id of the role definition to assign to the targeted principal and account.') -param roleDefinitionId string - -@description('Id of the principal to assign the role definition for the account.') -param principalId string - -@description('Scope of the role assignment. Defaults to the account.') -param scope string = '/' - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = { - name: targetAccountName -} - -resource assignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2024-05-15' = { - name: guid(roleDefinitionId, principalId, account.id) - parent: account - properties: { - principalId: principalId - roleDefinitionId: roleDefinitionId - scope: '${account.id}${scope}' - } -} - -output id string = assignment.id diff --git a/infra/core/database/cosmos-db/nosql/role/definition.bicep b/infra/core/database/cosmos-db/nosql/role/definition.bicep deleted file mode 100644 index ae220e6..0000000 --- a/infra/core/database/cosmos-db/nosql/role/definition.bicep +++ /dev/null @@ -1,37 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for NoSQL role definition.' - -@description('Name of the target Azure Cosmos DB account.') -param targetAccountName string - -@description('Name of the role definiton.') -param definitionName string - -@description('An array of data actions that are allowed. Defaults to an empty array.') -param permissionsDataActions string[] = [] - -@description('An array of data actions that are denied. Defaults to an empty array.') -param permissionsNonDataActions string[] = [] - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = { - name: targetAccountName -} - -resource definition 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2024-05-15' = { - name: guid('nosql-role-definition', account.id) - parent: account - properties: { - assignableScopes: [ - account.id - ] - permissions: [ - { - dataActions: permissionsDataActions - notDataActions: permissionsNonDataActions - } - ] - roleName: definitionName - type: 'CustomRole' - } -} - -output id string = definition.id diff --git a/infra/core/database/cosmos-db/table/account.bicep b/infra/core/database/cosmos-db/table/account.bicep deleted file mode 100644 index bc02a11..0000000 --- a/infra/core/database/cosmos-db/table/account.bicep +++ /dev/null @@ -1,31 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for Table account.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@description('Enables serverless for this account. Defaults to false.') -param enableServerless bool = false - -@description('Disables key-based authentication. Defaults to true.') -param disableKeyBasedAuth bool = true - -module account '../account.bicep' = { - name: 'cosmos-db-table-account' - params: { - name: name - location: location - tags: tags - kind: 'GlobalDocumentDB' - enableServerless: enableServerless - disableKeyBasedAuth: disableKeyBasedAuth - capabilities: [ - { - name: 'EnableTable' - } - ] - } -} - -output endpoint string = 'https://${account.outputs.name}.table.cosmos.azure.com:443/' -output name string = account.outputs.name diff --git a/infra/core/database/cosmos-db/table/role/assignment.bicep b/infra/core/database/cosmos-db/table/role/assignment.bicep deleted file mode 100644 index ca6b9ca..0000000 --- a/infra/core/database/cosmos-db/table/role/assignment.bicep +++ /dev/null @@ -1,29 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for Table role assignment.' - -@description('Name of the target Azure Cosmos DB account.') -param targetAccountName string - -@description('Id of the role definition to assign to the targeted principal and account.') -param roleDefinitionId string - -@description('Id of the principal to assign the role definition for the account.') -param principalId string - -@description('Scope of the role assignment. Defaults to the account.') -param scope string = '/' - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = { - name: targetAccountName -} - -resource assignment 'Microsoft.DocumentDB/databaseAccounts/tableRoleAssignments@2024-05-15' = { - name: guid(roleDefinitionId, principalId, account.id) - parent: account - properties: { - principalId: principalId - roleDefinitionId: roleDefinitionId - scope: '${account.id}${scope}' - } -} - -output id string = assignment.id diff --git a/infra/core/database/cosmos-db/table/role/definition.bicep b/infra/core/database/cosmos-db/table/role/definition.bicep deleted file mode 100644 index 362e954..0000000 --- a/infra/core/database/cosmos-db/table/role/definition.bicep +++ /dev/null @@ -1,37 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for Table role definition.' - -@description('Name of the target Azure Cosmos DB account.') -param targetAccountName string - -@description('Name of the role definiton.') -param definitionName string - -@description('An array of data actions that are allowed. Defaults to an empty array.') -param permissionsDataActions string[] = [] - -@description('An array of data actions that are denied. Defaults to an empty array.') -param permissionsNonDataActions string[] = [] - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = { - name: targetAccountName -} - -resource definition 'Microsoft.DocumentDB/databaseAccounts/tableRoleDefinitions@2024-05-15' = { - name: guid('table-role-definition', account.id) - parent: account - properties: { - assignableScopes: [ - account.id - ] - permissions: [ - { - dataActions: permissionsDataActions - notDataActions: permissionsNonDataActions - } - ] - roleName: definitionName - type: 'CustomRole' - } -} - -output id string = definition.id diff --git a/infra/core/database/cosmos-db/table/table.bicep b/infra/core/database/cosmos-db/table/table.bicep deleted file mode 100644 index df23234..0000000 --- a/infra/core/database/cosmos-db/table/table.bicep +++ /dev/null @@ -1,42 +0,0 @@ -metadata description = 'Create an Azure Cosmos DB for Table table.' - -param name string -param tags object = {} - -@description('Name of the parent Azure Cosmos DB account.') -param parentAccountName string - -@description('Enables throughput setting at this resource level. Defaults to false.') -param setThroughput bool = false - -@description('Enables autoscale. If setThroughput is enabled, defaults to false.') -param autoscale bool = false - -@description('The amount of throughput set. If setThroughput is enabled, defaults to 400.') -param throughput int = 400 - -var options = setThroughput ? autoscale ? { - autoscaleSettings: { - maxThroughput: throughput - } -} : { - throughput: throughput -} : {} - -resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = { - name: parentAccountName -} - -resource table 'Microsoft.DocumentDB/databaseAccounts/tables@2024-05-15' = { - name: name - parent: account - tags: tags - properties: { - options: options - resource: { - id: name - } - } -} - -output name string = table.name diff --git a/infra/core/host/app-service/config.bicep b/infra/core/host/app-service/config.bicep deleted file mode 100644 index 93beaa9..0000000 --- a/infra/core/host/app-service/config.bicep +++ /dev/null @@ -1,18 +0,0 @@ -metadata description = 'Creates an Azure App Service configuration for a site.' - -@description('Name of the parent App Service site for the configuration.') -param parentSiteName string - -@secure() -param appSettings object = {} - -resource site 'Microsoft.Web/sites@2022-09-01' existing = { - name: parentSiteName -} - -resource config 'Microsoft.Web/sites/config@2022-09-01' = { - name: 'appsettings' - parent: site - kind: 'string' - properties: appSettings -} diff --git a/infra/core/host/app-service/plan.bicep b/infra/core/host/app-service/plan.bicep deleted file mode 100644 index 98cefbb..0000000 --- a/infra/core/host/app-service/plan.bicep +++ /dev/null @@ -1,32 +0,0 @@ -metadata description = 'Creates an Azure App Service plan.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@allowed([ - 'linux' -]) -@description('OS type of the plan. Defaults to "linux".') -param kind string = 'linux' - -@allowed([ - 'F1' -]) -@description('SKU for the plan. Defaults to "F1".') -param sku string = 'F1' - -resource plan 'Microsoft.Web/serverfarms@2022-09-01' = { - name: name - location: location - tags: tags - sku: { - name: sku - } - kind: kind - properties: { - reserved: kind == 'linux' ? true : null - } -} - -output name string = plan.name diff --git a/infra/core/host/app-service/site.bicep b/infra/core/host/app-service/site.bicep deleted file mode 100644 index 741bbec..0000000 --- a/infra/core/host/app-service/site.bicep +++ /dev/null @@ -1,68 +0,0 @@ -metadata description = 'Creates an Azure App Service site.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@description('Name of the parent plan for the site.') -param parentPlanName string - -@allowed([ - 'dotnet' - 'dotnetcore' - 'dotnet-isolated' - 'node' - 'python' - 'java' - 'powershell' - 'custom' -]) -@description('Runtime to use for the site.') -param runtimeName string - -@description('Version of the runtime to use for the site.') -param runtimeVersion string - -@description('The OS kind of the site. Defaults to "app, linux"') -param kind string = 'app,linux' - -@description('If the site should be always on. Defaults to true.') -param alwaysOn bool = true - -@description('Allowed origins for client-side CORS request on the site.') -param allowedCorsOrigins string[] = [] - -@description('Enable system-assigned managed identity. Defaults to false.') -param enableSystemAssignedManagedIdentity bool = false - -var linuxFxVersion = '${runtimeName}|${runtimeVersion}' - -resource plan 'Microsoft.Web/serverfarms@2022-09-01' existing = { - name: parentPlanName -} - -resource site 'Microsoft.Web/sites@2022-09-01' = { - name: name - location: location - tags: tags - kind: kind - identity: enableSystemAssignedManagedIdentity ? { - type: 'SystemAssigned' - } : null - properties: { - serverFarmId: plan.id - siteConfig: { - linuxFxVersion: linuxFxVersion - alwaysOn: alwaysOn - minTlsVersion: '1.2' - cors: { - allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedCorsOrigins) - } - } - httpsOnly: true - } -} - -output endpoint string = 'https://${site.properties.defaultHostName}' -output name string = site.name -output managedIdentityPrincipalId string = enableSystemAssignedManagedIdentity ? site.identity.principalId : '' diff --git a/infra/core/host/container-apps/app.bicep b/infra/core/host/container-apps/app.bicep deleted file mode 100644 index 7a5e805..0000000 --- a/infra/core/host/container-apps/app.bicep +++ /dev/null @@ -1,132 +0,0 @@ -metadata description = 'Creates an Azure Container Apps app.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@description('Name of the parent environment for the app.') -param parentEnvironmentName string - -@description('Specifies the docker container image to deploy.') -param containerImage string = 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' - -@description('Specifies the container port.') -param targetPort int = 80 - -@description('Number of CPU cores the container can use. Can have a maximum of two decimals.') -param cpuCores string = '0.25' - -@description('Amount of memory (in gibibytes, GiB) allocated to the container up to 4GiB. Can have a maximum of two decimals. Ratio with CPU cores must be equal to 2.') -param memorySize string = '0.5Gi' - -@description('Minimum number of replicas that will be deployed.') -@minValue(1) -@maxValue(25) -param minReplicas int = 1 - -@description('Maximum number of replicas that will be deployed.') -@minValue(1) -param maxReplicas int = 1 - -type envVar = { - name: string - secretRef: string? - value: string? -} - -@description('The environment variables for the container.') -param environmentVariables envVar[] = [] - -type secret = { - name: string - identity: string? - keyVaultUrl: string? - value: string? -} - -@description('The secrets required for the container') -param secrets secret[] = [] - -@description('Specifies if the resource ingress is exposed externally.') -param externalAccess bool = true - -@description('Specifies if Ingress is enabled for the container app.') -param ingressEnabled bool = true - -@description('Allowed CORS origins.') -param allowedOrigins string[] = [] - -type registry = { - server: string - identity: string? - username: string? - passwordSecretRef: string? -} - -@description('List of registries. Defaults to an empty list.') -param registries registry[] = [] - -@description('Enable system-assigned managed identity. Defaults to false.') -param enableSystemAssignedManagedIdentity bool = false - -@description('List of user-assigned managed identities. Defaults to an empty array.') -param userAssignedManagedIdentityIds string[] = [] - -@allowed([ - 'auto' - 'http' - 'http2' - 'tcp' -]) -@description('Transport protocol. Defaults to "auto".') -param transport string = 'auto' - -resource environment 'Microsoft.App/managedEnvironments@2023-05-01' existing = { - name: parentEnvironmentName -} - -resource app 'Microsoft.App/containerApps@2023-05-01' = { - name: name - location: location - tags: tags - identity: { - type: enableSystemAssignedManagedIdentity ? !empty(userAssignedManagedIdentityIds) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned' : !empty(userAssignedManagedIdentityIds) ? 'UserAssigned' : 'None' - userAssignedIdentities: !empty(userAssignedManagedIdentityIds) ? toObject(userAssignedManagedIdentityIds, uaid => uaid, uaid => {}) : null - } - properties: { - environmentId: environment.id - configuration: { - ingress: ingressEnabled ? { - external: externalAccess - targetPort: targetPort - transport: transport - corsPolicy: { - allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins) - } - } : null - secrets: secrets - registries: !empty(registries) ? registries : null - } - template: { - containers: [ - { - image: containerImage - name: name - resources: { - cpu: json(cpuCores) - memory: memorySize - } - env: environmentVariables - } - ] - scale: { - minReplicas: minReplicas - maxReplicas: maxReplicas - } - } - } -} - -output endpoint string = ingressEnabled ? 'https://${app.properties.configuration.ingress.fqdn}' : '' -output name string = app.name -output systemAssignedManagedIdentityPrincipalId string = enableSystemAssignedManagedIdentity ? app.identity.principalId : '' diff --git a/infra/core/host/container-apps/environments/managed.bicep b/infra/core/host/container-apps/environments/managed.bicep deleted file mode 100644 index d997160..0000000 --- a/infra/core/host/container-apps/environments/managed.bicep +++ /dev/null @@ -1,14 +0,0 @@ -metadata description = 'Creates an Azure Container Apps managed environment.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -resource environment 'Microsoft.App/managedEnvironments@2023-05-01' = { - name: name - location: location - tags: tags - properties: {} -} - -output name string = environment.name diff --git a/infra/core/host/container-registry/registry.bicep b/infra/core/host/container-registry/registry.bicep deleted file mode 100644 index 3e78c08..0000000 --- a/infra/core/host/container-registry/registry.bicep +++ /dev/null @@ -1,39 +0,0 @@ -metadata description = 'Creates an Azure Container Registry registry.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -@description('Whether admin user is enabled. Defaults to false.') -param adminUserEnabled bool = false - -@description('Whether anonymous pull is enabled. Defaults to false.') -param anonymousPullEnabled bool = false - -@description('Enables public network access. Defaults to false.') -param publicNetworkAccessEnabled bool = false - -@allowed([ - 'Basic' - 'Standard' - 'Premium' -]) -@description('Name of the SKU. Defaults to "Standard".') -param skuName string = 'Standard' - -resource registry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = { - name: name - location: location - tags: tags - sku: { - name: skuName - } - properties: { - adminUserEnabled: adminUserEnabled - anonymousPullEnabled: anonymousPullEnabled - publicNetworkAccess: publicNetworkAccessEnabled ? 'Enabled' : 'Disabled' - } -} - -output endpoint string = registry.properties.loginServer -output name string = registry.name diff --git a/infra/core/security/identity/user-assigned.bicep b/infra/core/security/identity/user-assigned.bicep deleted file mode 100644 index 0583ab8..0000000 --- a/infra/core/security/identity/user-assigned.bicep +++ /dev/null @@ -1,17 +0,0 @@ -metadata description = 'Creates a Microsoft Entra user-assigned identity.' - -param name string -param location string = resourceGroup().location -param tags object = {} - -resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: name - location: location - tags: tags -} - -output name string = identity.name -output resourceId string = identity.id -output principalId string = identity.properties.principalId -output clientId string = identity.properties.clientId -output tenantId string = identity.properties.tenantId diff --git a/infra/core/security/role/assignment.bicep b/infra/core/security/role/assignment.bicep deleted file mode 100644 index 2362f41..0000000 --- a/infra/core/security/role/assignment.bicep +++ /dev/null @@ -1,30 +0,0 @@ -metadata description = 'Creates a role-based access control assignment.' - -@description('Id of the role definition to assign to the targeted principal and account.') -param roleDefinitionId string - -@description('Id of the principal to assign the role definition for the account.') -param principalId string - -@allowed([ - 'Device' - 'ForeignGroup' - 'Group' - 'ServicePrincipal' - 'User' - 'None' -]) -@description('Type of principal associated with the principal Id.') -param principalType string - -resource assignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(subscription().id, resourceGroup().id, principalId, roleDefinitionId) - scope: resourceGroup() - properties: { - principalId: principalId - roleDefinitionId: roleDefinitionId - principalType: principalType != 'None' ? principalType : null - } -} - -output id string = assignment.id diff --git a/infra/core/security/role/definition.bicep b/infra/core/security/role/definition.bicep deleted file mode 100644 index 5903357..0000000 --- a/infra/core/security/role/definition.bicep +++ /dev/null @@ -1,42 +0,0 @@ -metadata description = 'Creates a role-based access control role definition.' - -@description('Name of the role definiton.') -param definitionName string - -@description('Description for the role definition.') -param definitionDescription string - -@description('Array of control-plane actions allowed for the role definition.') -param actions string[] = [] - -@description('Array of control-plane actions disallowed for the role definition.') -param notActions string[] = [] - -@description('Array of data-plane actions allowed for the role definition.') -param dataActions string[] = [] - -@description('Array of data-plane actions disallowed for the role definition.') -param notDataActions string[] = [] - -resource definition 'Microsoft.Authorization/roleDefinitions@2022-04-01' = { - name: guid(subscription().id, resourceGroup().id) - scope: resourceGroup() - properties: { - roleName: definitionName - description: definitionDescription - type: 'CustomRole' - permissions: [ - { - actions: actions - notActions: notActions - dataActions: dataActions - notDataActions: notDataActions - } - ] - assignableScopes: [ - resourceGroup().id - ] - } -} - -output id string = definition.id diff --git a/infra/main.bicep b/infra/main.bicep index 29fbe43..1367034 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -13,6 +13,7 @@ param location string param principalId string = '' // Optional parameters +param logWorkspaceName string = '' param cosmosDbAccountName string = '' param containerRegistryName string = '' param containerAppsEnvName string = '' @@ -36,22 +37,25 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { tags: tags } -module database 'app/database.bicep' = { - name: 'database' +module identity 'app/identity.bicep' = { + name: 'identity' scope: resourceGroup params: { - accountName: !empty(cosmosDbAccountName) ? cosmosDbAccountName : '${abbreviations.cosmosDbAccount}-${resourceToken}' + identityName: '${abbreviations.userAssignedIdentity}-${resourceToken}' location: location tags: tags } } -module data 'app/data.bicep' = { - name: 'data' +module database 'app/database.bicep' = { + name: 'database' scope: resourceGroup params: { - databaseAccountName: database.outputs.accountName + accountName: !empty(cosmosDbAccountName) ? cosmosDbAccountName : '${abbreviations.cosmosDbAccount}-${resourceToken}' + location: location tags: tags + appPrincipalId: identity.outputs.principalId + userPrincipalId: !empty(principalId) ? principalId : null } } @@ -59,76 +63,38 @@ module registry 'app/registry.bicep' = { name: 'registry' scope: resourceGroup params: { - registryName: !empty(containerRegistryName) - ? containerRegistryName - : '${abbreviations.containerRegistry}${resourceToken}' + registryName: !empty(containerRegistryName) ? containerRegistryName : '${abbreviations.containerRegistry}${resourceToken}' location: location tags: tags } } -module environment 'app/environment.bicep' = { - name: 'environment' +module web 'app/web.bicep' = { + name: 'web' scope: resourceGroup params: { + workspaceName: !empty(logWorkspaceName) ? logWorkspaceName : '${abbreviations.logAnalyticsWorkspace}-${resourceToken}' envName: !empty(containerAppsEnvName) ? containerAppsEnvName : '${abbreviations.containerAppsEnv}-${resourceToken}' + jsAppName: !empty(containerAppsJavaScriptAppName) ? containerAppsJavaScriptAppName : '${abbreviations.containerAppsApp}-js-${resourceToken}' + tsAppName: !empty(containerAppsTypeScriptAppName) ? containerAppsTypeScriptAppName : '${abbreviations.containerAppsApp}-ts-${resourceToken}' location: location tags: tags - } -} - -module jsweb 'app/web.bicep' = { - name: javaScriptServiceName - scope: resourceGroup - params: { - appName: !empty(containerAppsJavaScriptAppName) ? containerAppsJavaScriptAppName : '${abbreviations.containerAppsApp}-js-${resourceToken}' - envName: environment.outputs.name - databaseAccountEndpoint: database.outputs.endpoint - location: location - tags: tags - serviceTag: javaScriptServiceName - } -} - -module tsweb 'app/web.bicep' = { - name: typeScriptServiceName - scope: resourceGroup - params: { - appName: !empty(containerAppsTypeScriptAppName) ? containerAppsTypeScriptAppName : '${abbreviations.containerAppsApp}-ts-${resourceToken}' - envName: environment.outputs.name + jsServiceTag: javaScriptServiceName + tsServiceTag: typeScriptServiceName + appResourceId: identity.outputs.resourceId + appClientId: identity.outputs.clientId databaseAccountEndpoint: database.outputs.endpoint - location: location - tags: tags - serviceTag: typeScriptServiceName - } -} - -module security 'app/security.bicep' = { - name: 'security' - scope: resourceGroup - params: { - databaseAccountName: database.outputs.accountName - appPrincipalIds: [ - jsweb.outputs.systemAssignedManagedIdentityPrincipalId - tsweb.outputs.systemAssignedManagedIdentityPrincipalId - ] - userPrincipalId: !empty(principalId) ? principalId : null } } // Database outputs output AZURE_COSMOS_DB_NOSQL_ENDPOINT string = database.outputs.endpoint -output AZURE_COSMOS_DB_NOSQL_DATABASE_NAME string = data.outputs.database.name -output AZURE_COSMOS_DB_NOSQL_CONTAINER_NAMES array = map(data.outputs.containers, c => c.name) // Container outputs output AZURE_CONTAINER_REGISTRY_ENDPOINT string = registry.outputs.endpoint output AZURE_CONTAINER_REGISTRY_NAME string = registry.outputs.name // Application outputs -output AZURE_CONTAINER_ENVIRONMENT_NAME string = environment.outputs.name -output AZURE_CONTAINER_APP_JS_ENDPOINT string = jsweb.outputs.endpoint -output AZURE_CONTAINER_APP_TS_ENDPOINT string = tsweb.outputs.endpoint - -// Security outputs -output AZURE_NOSQL_ROLE_DEFINITION_ID string = security.outputs.roleDefinitions.nosql +output AZURE_CONTAINER_APP_JS_ENDPOINT string = web.outputs.jsEndpoint +output AZURE_CONTAINER_APP_TS_ENDPOINT string = web.outputs.tsEndpoint +output AZURE_CONTAINER_ENVIRONMENT_NAME string = web.outputs.envName diff --git a/src/js/cosmos.js b/src/js/cosmos.js index 963d96b..7efcaa1 100644 --- a/src/js/cosmos.js +++ b/src/js/cosmos.js @@ -2,10 +2,10 @@ import { DefaultAzureCredential } from '@azure/identity'; import { CosmosClient } from '@azure/cosmos'; export async function start(emit) { + // const endpoint = process.env.AZURE_COSMOS_DB_NOSQL_ENDPOINT; console.log(`ENDPOINT: ${endpoint}`); - // const credential = new DefaultAzureCredential(); const client = new CosmosClient({ @@ -15,18 +15,15 @@ export async function start(emit) { // emit('Current Status:\tStarting...') - // const database = client.database('cosmicworks'); - // + emit(`Get database:\t${database.id}`); - // const container = database.container('products'); - // + emit(`Get container:\t${container.id}`); { - // var item = { 'id': '70b63682-b93a-4c77-aad2-65501347265f', 'category': 'gear-surf-surfboards', @@ -37,7 +34,7 @@ export async function start(emit) { }; var response = await container.items.upsert(item); - // + if (response.statusCode == 200 || response.statusCode == 201) { emit(`Upserted item:\t${JSON.stringify(response.resource)}`); } @@ -62,13 +59,12 @@ export async function start(emit) { } { - // var id = '70b63682-b93a-4c77-aad2-65501347265f'; var partitionKey = 'gear-surf-surfboards'; var response = await container.item(id, partitionKey).read(); var read_item = response.resource; - // + emit(`Read item id:\t${read_item.id}`); emit(`Read item:\t${JSON.stringify(read_item)}`); emit(`Status code:\t${response.statusCode}`); @@ -76,7 +72,6 @@ export async function start(emit) { } { - // const querySpec = { query: 'SELECT * FROM products p WHERE p.category = @category', parameters: [ @@ -91,7 +86,7 @@ export async function start(emit) { for (var item of response.resources) { } - // + for (var item of response.resources) { emit(`Found item:\t${item.name}\t${item.id}`); } diff --git a/src/ts/cosmos.ts b/src/ts/cosmos.ts index 0296b85..f877fb5 100644 --- a/src/ts/cosmos.ts +++ b/src/ts/cosmos.ts @@ -20,13 +20,14 @@ export class DataClient { await this.queryItems(emit, container); - emit('Current Status:\tEnding...'); + emit('Current Status:\tFinalizing...'); } - async createClient(emit: Emit, endpoint: string = process.env.AZURE_COSMOS_DB_NOSQL_ENDPOINT!): Promise { + async createClient(emit: Emit): Promise { + // + const endpoint: string = process.env.AZURE_COSMOS_DB_NOSQL_ENDPOINT! console.log(`ENDPOINT: ${endpoint}`); - // const credential = new DefaultAzureCredential(); const client = new CosmosClient({ @@ -39,21 +40,18 @@ export class DataClient { } async createContainer(emit: Emit, client: CosmosClient): Promise { - // const database: Database = client.database('cosmicworks'); - // + emit(`Get database:\t${database.id}`); - // const container: Container = database.container('products'); - // + emit(`Get container:\t${container.id}`); return container; } async createItemVerbose(emit: Emit, container: Container) { - // var item: Product = { 'id': '70b63682-b93a-4c77-aad2-65501347265f', 'category': 'gear-surf-surfboards', @@ -64,7 +62,7 @@ export class DataClient { }; var response: ItemResponse = await container.items.upsert(item); - // + if (response.statusCode == 200 || response.statusCode == 201) { emit(`Upserted item:\t${JSON.stringify(response.resource)}`); } @@ -87,13 +85,12 @@ export class DataClient { } async readItem(emit: Emit, container: Container) { - // var id = '70b63682-b93a-4c77-aad2-65501347265f'; var partitionKey = 'gear-surf-surfboards'; var response: ItemResponse = await container.item(id, partitionKey).read(); var read_item: Product = response.resource!; - // + emit(`Read item id:\t${read_item?.id}`); emit(`Read item:\t${JSON.stringify(read_item)}`); emit(`Status code:\t${response.statusCode}`); @@ -101,7 +98,6 @@ export class DataClient { } async queryItems(emit: Emit, container: Container) { - // const querySpec: SqlQuerySpec = { query: 'SELECT * FROM products p WHERE p.category = @category', parameters: [ @@ -116,10 +112,10 @@ export class DataClient { for (var item of response.resources) { } - // + for (var item of response.resources) { emit(`Found item:\t${item.name}\t${item.id}`); } emit(`Request charge:\t${response.requestCharge}`); } -} \ No newline at end of file +}