Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/azure-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Deploy to Azure
on:
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
env:
AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }}
AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }}
AZURE_LOCATION: ${{ vars.AZURE_LOCATION }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install azd
uses: Azure/setup-azd@v1.0.0
- name: Log in with Azure (Federated Credentials)
run: |
azd auth login `
--client-id "$Env:AZURE_CLIENT_ID" `
--federated-credential-provider "github" `
--tenant-id "$Env:AZURE_TENANT_ID"
shell: pwsh
- name: Provision Infrastructure
run: azd provision --no-prompt
env:
AZD_INITIAL_ENVIRONMENT_CONFIG: ${{ secrets.AZD_INITIAL_ENVIRONMENT_CONFIG }}
AZURE_RESOURCE_GROUP: ${{ vars.AZURE_RESOURCE_GROUP }}
- name: Deploy Application
run: azd deploy --no-prompt
env:
AZURE_RESOURCE_GROUP: ${{ vars.AZURE_RESOURCE_GROUP }}
10 changes: 10 additions & 0 deletions azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
name: cosmos-db-nosql-rust-quickstart
metadata:
template: cosmos-db-nosql-rust-quickstart
services:
web:
project: ./src
language: js
host: containerapp
docker:
path: ./Dockerfile
context: ./
pipeline:
provider: github
hooks:
postprovision:
posix:
Expand Down
121 changes: 121 additions & 0 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ param location string
@description('Id of the principal to assign database and application roles.')
param deploymentUserPrincipalId string = ''

// serviceName is used as value for the tag (azd-service-name) azd uses to identify deployment host
param serviceName string = 'web'

var resourceToken = toLower(uniqueString(resourceGroup().id, environmentName, location))
var tags = {
'azd-env-name': environmentName
Expand Down Expand Up @@ -87,7 +90,125 @@ module cosmosDbAccount 'br/public:avm/res/document-db/database-account:0.8.1' =
}
}

module containerRegistry 'br/public:avm/res/container-registry/registry:0.5.1' = {
name: 'container-registry'
params: {
name: 'containerreg${resourceToken}'
location: location
tags: tags
acrAdminUserEnabled: false
anonymousPullEnabled: true
publicNetworkAccess: 'Enabled'
acrSku: 'Standard'
}
}

var containerRegistryRole = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'8311e382-0749-4cb8-b61a-304f252e45ec'
) // AcrPush built-in role

module registryUserAssignment 'br/public:avm/ptn/authorization/resource-role-assignment:0.1.1' = if (!empty(deploymentUserPrincipalId)) {
name: 'container-registry-role-assignment-push-user'
params: {
principalId: deploymentUserPrincipalId
resourceId: containerRegistry.outputs.resourceId
roleDefinitionId: containerRegistryRole
}
}

module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0.7.0' = {
name: 'log-analytics-workspace'
params: {
name: 'log-analytics-${resourceToken}'
location: location
tags: tags
}
}

module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.8.0' = {
name: 'container-apps-env'
params: {
name: 'container-env-${resourceToken}'
location: location
tags: tags
logAnalyticsWorkspaceResourceId: logAnalyticsWorkspace.outputs.resourceId
zoneRedundant: false
}
}

module containerAppsApp 'br/public:avm/res/app/container-app:0.9.0' = {
name: 'container-apps-app'
params: {
name: 'container-app-${resourceToken}'
environmentResourceId: containerAppsEnvironment.outputs.resourceId
location: location
tags: union(tags, { 'azd-service-name': serviceName })
ingressTargetPort: 3030
ingressExternal: true
ingressTransport: 'auto'
stickySessionsAffinity: 'sticky'
scaleMaxReplicas: 1
scaleMinReplicas: 1
corsPolicy: {
allowCredentials: true
allowedOrigins: [
'*'
]
}
managedIdentities: {
systemAssigned: false
userAssignedResourceIds: [
managedIdentity.outputs.resourceId
]
}
secrets: {
secureList: [
{
name: 'azure-cosmos-db-nosql-endpoint'
value: cosmosDbAccount.outputs.endpoint
}
{
name: 'user-assigned-managed-identity-client-id'
value: managedIdentity.outputs.clientId
}
]
}
containers: [
{
image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
name: 'web-front-end'
resources: {
cpu: '0.25'
memory: '.5Gi'
}
env: [
{
name: 'CONFIGURATION__AZURECOSMOSDB__ENDPOINT'
secretRef: 'azure-cosmos-db-nosql-endpoint'
}
{
name: 'CONFIGURATION__AZURECOSMOSDB__DATABASENAME'
value: databaseName
}
{
name: 'CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME'
value: containerName
}
{
name: 'AZURE_CLIENT_ID'
secretRef: 'user-assigned-managed-identity-client-id'
}
]
}
]
}
}

// Azure Cosmos DB for Table outputs
output CONFIGURATION__AZURECOSMOSDB__ENDPOINT string = cosmosDbAccount.outputs.endpoint
output CONFIGURATION__AZURECOSMOSDB__DATABASENAME string = databaseName
output CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME string = containerName

// Azure Container Registry outputs
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.outputs.loginServer
52 changes: 52 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!--
---
page_type: sample
name: "Quickstart: Azure Cosmos DB for NoSQL and Azure SDK for Rust"
description: This is a simple web application to illustrate common basic usage of Azure Cosmos DB for NoSQL and the Azure SDK for Rust.
urlFragment: template
languages:
- rust
- azdeveloper
products:
- azure-cosmos-db
---
-->

# Quickstart: Azure Cosmos DB for NoSQL client library for Go

This is a simple web application to illustrate common basic usage of Azure Cosmos DB for NoSQL's client library for Rust. This sample application accesses an existing account, database, and container using the [`azure_data_cosmos`](https://docs.rs/azure_data_cosmos) and [`azure_identity`](https://docs.rs/azure_identity) crates.

## Prerequisites

- [Docker](https://www.docker.com/)
- [Azure Developer CLI](https://aka.ms/azd-install)
- [Rust 1+](https://go.dev/dl/)

## Quickstart

1. Log in to Azure Developer CLI.

```bash
azd auth login
```

> [!TIP]
> This is only required once per-install.

1. Initialize this template (`cosmos-db-nosql-rust-quickstart`) using `azd init`

```bash
azd init --template cosmos-db-nosql-rust-quickstart
```

1. Ensure that **Docker** is running in your environment.

1. Use `azd up` to provision your Azure infrastructure and deploy the web application to Azure.

```bash
azd up
```

1. Observed the deployed web application

![Screenshot of the deployed web application.](assets/web.png)
3 changes: 3 additions & 0 deletions src/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
debug/
target/
Cargo.lock
7 changes: 7 additions & 0 deletions src/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM rust:1

COPY . ./

RUN cargo build --release

CMD ["./target/release/app-main"]
19 changes: 8 additions & 11 deletions src/app/cosmos.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use futures::StreamExt;
use serde_json;
use azure_data_cosmos::{CosmosClient, CosmosClientOptions, PartitionKey};
use azure_data_cosmos::{CosmosClient, PartitionKey};
use azure_identity::DefaultAzureCredential;
use crate::item::Item;

Expand All @@ -17,10 +17,7 @@ where

let credential = DefaultAzureCredential::new().unwrap();

let client_options = CosmosClientOptions::default();
let client_options = Some(client_options);

let service_client = match CosmosClient::new(&endpoint, credential, client_options) {
let client = match CosmosClient::new(&endpoint, credential, None) {
Ok(client) => client,
Err(e) => {
eprintln!("Error creating CosmosClient: {}", e);
Expand All @@ -29,10 +26,10 @@ where
};
callback("Client created".to_string());

let database_client = service_client.database_client(&database_name);
let database = client.database(&database_name);
callback(format!("Get database:\t {}", database_name));

let container_client = database_client.container_client(&container_name);
let container = database.container(&container_name);
callback(format!("Get container:\t {}", container_name));

{
Expand All @@ -47,7 +44,7 @@ where

let partition_key = PartitionKey::from(item.category.clone());

let upsert_response = container_client.upsert_item(partition_key, item, None).await;
let upsert_response = container.upsert_item(partition_key, item, None).await;

match upsert_response {
Ok(r) => {
Expand Down Expand Up @@ -80,7 +77,7 @@ where

let partition_key = PartitionKey::from(item.category.clone());

let upsert_response = container_client.upsert_item(partition_key, item, None).await;
let upsert_response = container.upsert_item(partition_key, item, None).await;

match upsert_response {
Ok(r) => {
Expand All @@ -105,7 +102,7 @@ where
let item_id = "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb";
let item_partition_key = "gear-surf-surfboards";

let read_response = container_client.read_item::<Item>(item_partition_key, item_id, None).await;
let read_response = container.read_item::<Item>(item_partition_key, item_id, None).await;

match read_response {
Ok(r) => {
Expand Down Expand Up @@ -133,7 +130,7 @@ where

let query = format!("SELECT * FROM c WHERE c.category = '{}'", item_partition_key);

let page_response = container_client.query_items::<Item>(&query, partition_key, None);
let page_response = container.query_items::<Item>(&query, partition_key, None);

callback("Run query:".to_string());
match page_response {
Expand Down