Skip to content

Commit

Permalink
Add byoc samples in Azure Spring Cloud Samples
Browse files Browse the repository at this point in the history
  • Loading branch information
CaihuaRui committed Jun 21, 2021
1 parent 3befb6d commit c2874ed
Show file tree
Hide file tree
Showing 51 changed files with 1,161 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM node:15-alpine
ENV AZURE_KEYVAULT_URI https://<your-keyvault-name>.vault.azure.net/

COPY . /src
RUN cd /src && npm install
CMD ["node", "/src/server.js"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Access Key Vault with managed identity in a Node.js app container

This sample shows how to access Key Vault with managed identity in `Azure Spring Cloud`'s apps written in Node.js and deployed with custom container.

You need to import [ManagedIdentityCredential](https://docs.microsoft.com/en-us/javascript/api/@azure/identity/managedidentitycredential?view=azure-node-latest) and [SecretClient](https://docs.microsoft.com/en-us/javascript/api/@azure/keyvault-secrets/secretclient?view=azure-node-latest) in your code. In this sample project, you could refer to [identity.js](identity.js).

## Prerequisite

* [Docker](https://www.docker.com/products/container-runtime)
* [Nodejs](https://nodejs.org/en/)
* [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/cloud-shell/overview)
* An existing Key Vault. If you need to create a Key Vault, you can use the [Azure Portal](https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-portal) or [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)

## How to run

1. Specify the URI of your Key Vault in [Dockerfile](Dockerfile).
2. Install Azure CLI extension for Azure Spring Cloud by running below command.
```
az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl
```
3. Create an instance of Azure Spring Cloud.
```
az spring-cloud create -n <resource name> -g <resource group name>
```
4. Create an app with public domain assigned.
```
az spring-cloud app create -n <app name> -s <resource name> -g <resource group name> --is-public true
```
5. Enable system-assigned managed identity for your app and take note of the principal id from the command output.
```
az spring-cloud app identity assign -n <app name> -s <resource name> -g <resource group name>
```
6. Grant permission of Key Vault to the system-assigned managed identity.
```
az keyvault set-policy -n keyvault_name -g resource_group_of_keyvault --secret-permissions get set --object-id <principal-id-you-got-in-step5>
```
7. Deploy the app written in Node.js with your custom container.

8. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`.
```
az spring-cloud app show -n <app name> -s <resource name> -g <resource group name>
```
9. Verify sample is working. The url is fetched from previous step.
```
# Create a secret in Key Vault
curl -X PUT {url}/secrets/{secret-name}?value={value}
# Get the value of secret-name you just created before
curl {url}/secrets/{secret-name}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { SecretClient } = require("@azure/keyvault-secrets");
const { ManagedIdentityCredential } = require("@azure/identity");
const util = require('util');

const credential = new ManagedIdentityCredential()

const url = process.env.AZURE_KEYVAULT_URI;
console.log("About to connect to: ", url);
const client = new SecretClient(url, credential);

async function getSecret(name) {
console.log("About to get secret: " + name);
try {
var secret = await client.getSecret(name);
return util.format("Successfully got the value of secret %s from Key Vault %s: %s",
name, url, secret.value);
} catch (err) {
console.log(err)
return util.format("Failed to get secret %s from Key Vault %s due to %s", name,
url, err.message);
}
}

async function setSecret(name, value) {
console.log(util.format("About to set secret: (%s, %s)"), name, value);

try {
await client.setSecret(name, value);
return util.format("Successfully set secret %s in Key Vault %s", name, url);
} catch (err) {
console.log(err)
return util.format("Failed to set secret %s in Key Vault %s due to %s", name,
url, err.message);
}
}

module.exports = {getSecret, setSecret};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "byoc-managed-identity-keyvault-node-sample",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "MIT",
"dependencies": {
"@azure/identity": "^1.3.0",
"@azure/keyvault-secrets": "^4.1.0",
"express": "^4.17.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var identity = require('./identity.js')

const http = require('http')
const port = 1025

const express = require('express');
var app = express();

app.get('/secrets/:name', async (req, res) => {
try {
const result = await identity.getSecret(req.params.name).then((value) => {
res.send(value);
})
} catch (err) {
console.log(err)
}
})

app.put('/secrets/:name', async (req, res) => {
try {
const result = await identity.setSecret(req.params.name, req.query.value).then((value) => {
res.send(value);
})
} catch (err) {
console.log(err)
}
})

var server = app.listen(port, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM python:3.8

WORKDIR /code

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

CMD [ "gunicorn", "--bind", "0.0.0.0:1025", "server:app" ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Access Key Vault with managed identity in a Python app container

This sample shows how to access Key Vault with managed identity in `Azure Spring Cloud`'s apps written in Python and deployed with custom container.

You need to import [ManagedIdentityCredential](https://docs.microsoft.com/en-us/python/api/azure-identity/azure.identity.managedidentitycredential?view=azure-python) and [SecretClient](https://docs.microsoft.com/en-us/python/api/azure-keyvault-secrets/azure.keyvault.secrets.secretclient?view=azure-python) in your code. In this sample project, you could refer to [identity.py](identity.py).

## Prerequisite

* Python & [Python extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ms-python.python)
* [Docker](https://www.docker.com/products/container-runtime)
* [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/cloud-shell/overview)
* An existing Key Vault. If you need to create a Key Vault, you can use the [Azure Portal](https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-portal) or [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)

## How to run

1. Specify the URI of your Key Vault in [identityconfg.py](indentityconfig.py).
2. Install Azure CLI extension for Azure Spring Cloud by running below command.
```
az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl
```
3. Create an instance of Azure Spring Cloud.
```
az spring-cloud create -n <resource name> -g <resource group name>
```
4. Create an app with public domain assigned.
```
az spring-cloud app create -n <app name> -s <resource name> -g <resource group name> --is-public true
```
5. Enable system-assigned managed identity for your app and take note of the principal id from the command output.
```
az spring-cloud app identity assign -n <app name> -s <resource name> -g <resource group name>
```
6. Grant permission of Key Vault to the system-assigned managed identity.
```
az keyvault set-policy -n keyvault_name -g resource_group_of_keyvault --secret-permissions get set --object-id <principal-id-you-got-in-step5>
```
7. Deploy the app written in Python with your custom container.

8. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`.
```
az spring-cloud app show -n <app name> -s <resource name> -g <resource group name>
```
9. Verify sample is working. The url is fetched from previous step.
```
# Create a secret in Key Vault
curl -X PUT {url}/secrets/{secret-name}?value={value}
# Get the value of secret-name you just created before
curl {url}/secrets/{secret-name}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from azure.identity import ManagedIdentityCredential
from azure.keyvault.secrets import SecretClient
import indentityconfig as cfg

credential = ManagedIdentityCredential()
keyVaultUrl = cfg.key_vault["vault_url"]
print("About to connect to: ", keyVaultUrl)
client = SecretClient(keyVaultUrl, credential, logging_enable=True)

def getSecret(name):
try:
print("About to get secret: " + name)
secret = client.get_secret(name)
return "Successfully got the value of secret {} from Key Vault {}: {}".format(name, keyVaultUrl, secret.value)
except Exception as e:
print(e)
return "Failed to get secret {} from Key Vault {} due to {}".format(name, keyVaultUrl, e.__str__())

def setSecret(name, value):
try:
print("About to set secret: ({}, {})".format(name, value))
secret = client.set_secret(name, value)
return "Successfully got the value of secret {} from Key Vault {}: {}".format(name, keyVaultUrl, secret.value)
except Exception as e:
print(e)
return "Failed to set secret {} in Key Vault {} due to {}".format(name, keyVaultUrl, e.__str__())
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
key_vault = {
# Specify the URI of your Key Vault (e.g.: https://name.vault.azure.net/)
"vault_url": "https://<your-keyvault-name>.vault.azure.net/"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Flask==1.1.1
azure-keyvault-secrets
azure-identity
gunicorn
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from flask import Flask, request
import identity as identity

app = Flask(__name__)

@app.route("/secrets/<name>", methods = ['PUT', 'GET'])
def secret(name):
try:
if request.method == 'GET':
return identity.getSecret(name)
else :
value = request.args['value']
return identity.setSecret(name, value)
except Exception as e:
print(e)
return e.__str__()


if __name__ == "__main__":
app.run(port = 1025)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM node:15-alpine

COPY . /src
RUN cd /src && npm install
CMD ["node", "/src/server.js"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Binding your app with Azure COSMOS Mongo API

This sample shows how to run Node.js apps with Azure Cosmos DB(Mongo) in `Azure Spring Cloud` with your custom container.

### Prerequisite

* [Docker](https://www.docker.com/products/container-runtime)
* [Nodejs](https://nodejs.org/en/)
* [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) or [Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/cloud-shell/overview)

### How to run

1. Install Azure CLI extension for Azure Spring Cloud by running below command.
```
az extension add -y --source https://azureclitemp.blob.core.windows.net/spring-cloud/spring_cloud-0.1.0-py2.py3-none-any.whl
```
1. Create an instance of Azure Spring Cloud.
```
az spring-cloud create -n <resource name> -g <resource group name>
```
1. Create an app with public domain assigned.
```
az spring-cloud app create -n <app name> -s <resource name> -g <resource group name> --is-public true
```
1. Deploy the app written in Node.js with your custom container.

1. Add a binding of Azure Cosmos for this app.
```
az spring-cloud app binding cosmos add --api-type mongo --app <app name> -s <resource name> -g <resource group name> -n cosmos --resource-id <resource id of your cosmosdb account> --database-name <database name>
```
1. Restart the app.
```
az spring-cloud app restart -n <app name> -s <resource name> -g <resource group name>
```
1. Verify app is running. Instances should have status `RUNNING` and discoveryStatus `UP`.
```
az spring-cloud app show -n <app name> -s <resource name> -g <resource group name>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const mongoose = require('mongoose');

mongoose.connect(process.env.SPRING_DATA_MONGODB_URI, {useNewUrlParser: true})

mongoose.connection.on("error", function(error) {
console.log(error)
})

mongoose.connection.on("open", function() {
console.log("Connected to MongoDB database.")
})

const userSchema = new mongoose.Schema({
name: String
});
const User = mongoose.model('User', userSchema);

function all(res){
User.find(function (err, users) {
if (err) return console.error(err);
console.log(users);
res.send(users)
})
}

function add(name){
var myObj = new User({ name: name });
console.log(myObj);
myObj.save(function (err) {
if (err) return console.error(err);
});
}

module.exports = { all, add }
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "byoc-service-binding-cosmosdb-mongo-node-sample",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "MIT",
"dependencies": {
"express": "^4.17.1",
"mongoose": "^5.12.14"
}
}
Loading

0 comments on commit c2874ed

Please sign in to comment.