Skip to content

Commit 049afe4

Browse files
authored
Merge pull request #23 from babbageclunk/cosmos-todo-demo
Add Cosmos DB todo-list demo app
2 parents e675cc2 + 549d2af commit 049afe4

File tree

3 files changed

+244
-0
lines changed

3 files changed

+244
-0
lines changed

cosmos-todo-list/README.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Azure Service Operator Cosmos DB demo
2+
3+
This sample is a demonstration of how to use the Azure Service Operator (ASO) to provision a Cosmos DB SQL database and container,
4+
and then deploy a web application that uses that container to store its data,
5+
by creating resources in a Kubernetes cluster.
6+
7+
## Prerequisites
8+
9+
To deploy this demo application you'll need the following:
10+
11+
1. A Kubernetes cluster (at least version 1.21) [created and
12+
running](https://kubernetes.io/docs/tutorials/kubernetes-basics/create-cluster/),
13+
and [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl) configured to talk to it. (You can check your cluster
14+
version with `kubectl version`.) This could be a local [Kind cluster](https://kind.sigs.k8s.io/docs/user/quick-start/)
15+
or an [Azure Kubernetes Service
16+
cluster](https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-deploy-cluster)
17+
running in your subscription.
18+
19+
2. An Azure subscription to create Azure resources under.
20+
21+
## Set up Azure Service Operator
22+
23+
ASO lets you manage Azure resources using Kubernetes tools.
24+
The operator is installed in your cluster and propagates changes to resources there to the Azure Resource Manager.
25+
[Read more about how ASO works](https://github.com/azure/azure-service-operator#what-is-it)
26+
27+
Follow [these
28+
instructions](https://github.com/Azure/azure-service-operator/tree/master/v2#installation) to install the ASO v2 operator in your cluster.
29+
Part of this installs
30+
the [custom resource definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) for the Azure and Cosmos DB resources
31+
we're going to create next: ResourceGroup, DatabaseAccount,
32+
SqlDatabase, and SqlDatabaseContainer.
33+
34+
35+
## Create the Cosmos DB resources
36+
37+
The YAML documents in [cosmos-sql-demo.yaml](cosmos-sql-demo.yaml) create a number of things:
38+
39+
* A Kubernetes namespace named `cosmosdb`,
40+
* An Azure resource group named `aso-cosmos-demo`,
41+
* A Cosmos DB database account,
42+
* A SQL database and
43+
* A container (equivalent to a table in the [Cosmos DB resource model](https://docs.microsoft.com/en-us/azure/cosmos-db/account-databases-containers-items))
44+
45+
Create them all by applying the file:
46+
```sh
47+
kubectl apply -f cosmos-sql-demo.yaml
48+
```
49+
50+
The operator will start creating the resource group and Cosmos DB items in Azure.
51+
You can monitor their progress with:
52+
```sh
53+
watch kubectl get -n cosmosdb resourcegroup,databaseaccount,sqldatabase,sqldatabasecontainer
54+
```
55+
You can also find the resource group in the [Azure portal](https://portal.azure.com) and watch the Cosmos DB resources being created there.
56+
57+
It could take a few minutes for the Cosmos DB resources to be provisioned.
58+
In that time you might see some `ResourceNotFound` errors, or messages indicating that the database account isn't ready, on the SQL database or container.
59+
This is OK!
60+
The operator will keep creating them once the account is available and the errors should eventually resolve themselves.
61+
62+
## Create the `cosmos-settings` secret
63+
64+
We need to provide the web application with access to the database.
65+
Once the database account is created, store the connection details into environment variables with the following commands:
66+
```sh
67+
COSMOS_DB_ACCOUNT="$(az cosmosdb show --resource-group aso-cosmos-demo --name sampledbaccount -otsv --query 'locations[0].documentEndpoint')"
68+
COSMOS_DB_KEY="$(az cosmosdb keys list --resource-group aso-cosmos-demo --name sampledbaccount -otsv --query 'primaryMasterKey')"
69+
```
70+
71+
Another option is to get the account URI and key from the [portal](https://portal.azure.com).
72+
You can find them on the Keys page of the Cosmos DB account.
73+
74+
Then create the secret the pod will use with:
75+
```sh
76+
kubectl --namespace cosmosdb create secret generic cosmos-settings \
77+
--from-literal=Account="$COSMOS_DB_ACCOUNT" \
78+
--from-literal=Key="$COSMOS_DB_KEY" \
79+
--from-literal=DatabaseName="sample-sql-db" \
80+
--from-literal=ContainerName="sample-sql-container"
81+
```
82+
83+
(Secret handling is an area we're still working on in ASO - in the future the operator should automatically get these details from Azure and create the secret itself once the database account is ready. See [#1471](https://github.com/Azure/azure-service-operator/issues/1471) for more details.)
84+
85+
## Deploy the web application
86+
87+
Now we can create the application deployment and service by running:
88+
```sh
89+
kubectl apply -f deploy-cosmos-app.yaml
90+
```
91+
92+
You can watch the state of the pod with:
93+
```sh
94+
watch kubectl get -n cosmosdb pods
95+
```
96+
97+
Once the pod's running, we need to expose the service outside the cluster so we can make requests to the todo app.
98+
There are a [number of ways](https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/) to do this in Kubernetes, but a simple option for this demonstration is using port-forwarding.
99+
Run this command to set it up:
100+
```sh
101+
kubectl port-forward -n cosmosdb service/cosmos-todo-service 8080:80
102+
```
103+
104+
Now visiting [http://localhost:8080](http://localhost:8080) in your browser will hit the Cosmos DB application.
105+
You can create todo items and mark them as complete!
106+
107+
Use the Cosmos DB account Data Explorer on the portal to expand the database and container, and you can see the todo-list items stored by the web app.
108+
109+
If you're interested in how the todo application uses the Cosmos DB API, the code is available [here](https://github.com/Azure-Samples/cosmos-dotnet-core-todo-app/tree/main/src).
110+
111+
## Clean up
112+
113+
When you're finished with the sample application you can clean all of the Kubernetes and Azure resources up by deleting the `cosmosdb` namespace in your cluster.
114+
```sh
115+
kubectl delete namespace cosmosdb
116+
```
117+
118+
Kubernetes will delete the web application pod and the operator will delete the Azure resource group and all the Cosmos DB resources.
119+
(Deleting a Cosmos DB account can take several minutes.)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: cosmosdb
5+
---
6+
apiVersion: microsoft.resources.azure.com/v1alpha1api20200601
7+
kind: ResourceGroup
8+
metadata:
9+
name: aso-cosmos-demo
10+
namespace: cosmosdb
11+
spec:
12+
location: westcentralus
13+
---
14+
apiVersion: microsoft.documentdb.azure.com/v1alpha1api20210515
15+
kind: DatabaseAccount
16+
metadata:
17+
name: sampledbaccount
18+
namespace: cosmosdb
19+
spec:
20+
location: westcentralus
21+
owner:
22+
name: aso-cosmos-demo
23+
kind: GlobalDocumentDB
24+
databaseAccountOfferType: Standard
25+
locations:
26+
- locationName: westcentralus
27+
---
28+
apiVersion: microsoft.documentdb.azure.com/v1alpha1api20210515
29+
kind: SqlDatabase
30+
metadata:
31+
name: sample-sql-db
32+
namespace: cosmosdb
33+
spec:
34+
location: westcentralus
35+
owner:
36+
name: sampledbaccount
37+
options:
38+
autoscaleSettings:
39+
maxThroughput: 4000
40+
resource:
41+
id: sample-sql-db
42+
---
43+
apiVersion: microsoft.documentdb.azure.com/v1alpha1api20210515
44+
kind: SqlDatabaseContainer
45+
metadata:
46+
name: sample-sql-container
47+
namespace: cosmosdb
48+
spec:
49+
location: westcentralus
50+
owner:
51+
name: sample-sql-db
52+
resource:
53+
id: sample-sql-container
54+
partitionKey:
55+
kind: Hash
56+
paths: ["/id"]
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
labels:
5+
app: cosmos-todo-app
6+
name: cosmos-todo-app
7+
namespace: cosmosdb
8+
spec:
9+
replicas: 1
10+
selector:
11+
matchLabels:
12+
app: cosmos-todo-app
13+
template:
14+
metadata:
15+
labels:
16+
app: cosmos-todo-app
17+
spec:
18+
containers:
19+
- name: app
20+
image: docker.io/babbageclunk/cosmos-todo-app:latest
21+
env:
22+
- name: CosmosDB__Account
23+
valueFrom:
24+
secretKeyRef:
25+
key: Account
26+
name: cosmos-settings
27+
optional: false
28+
- name: CosmosDB__Key
29+
valueFrom:
30+
secretKeyRef:
31+
key: Key
32+
name: cosmos-settings
33+
optional: false
34+
- name: CosmosDB__DatabaseName
35+
valueFrom:
36+
secretKeyRef:
37+
key: DatabaseName
38+
name: cosmos-settings
39+
optional: true
40+
- name: CosmosDB__ContainerName
41+
valueFrom:
42+
secretKeyRef:
43+
key: ContainerName
44+
name: cosmos-settings
45+
optional: true
46+
ports:
47+
- containerPort: 80
48+
name: webserver
49+
protocol: TCP
50+
resources:
51+
limits:
52+
cpu: 500m
53+
memory: 512Mi
54+
requests:
55+
cpu: 200m
56+
memory: 256Mi
57+
terminationGracePeriodSeconds: 10
58+
---
59+
apiVersion: v1
60+
kind: Service
61+
metadata:
62+
name: cosmos-todo-service
63+
namespace: cosmosdb
64+
spec:
65+
ports:
66+
- port: 80
67+
targetPort: 80
68+
selector:
69+
app: cosmos-todo-app

0 commit comments

Comments
 (0)