Azure Key Vault in JavaScript Applications

GETHUB 
A simple NodeJS Server:

const http = require('http');

const PORT = process.env.PORT || 3000;

async function startServer() {
    const server = http.createServer((req, res) => {
         res.writeHead(200, { "Content-Type": "text/plain" });
         res.end("Hello, world!");
    });

    server.listen(PORT, () => {
         console.log(`Server is running on port ${PORT}`);
    });
}

startServer();

Navigate to localhost:3000 gives "Hello world!"

Dockerfile

FROM node:alpine

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 3000

ENV PORT=3000

CMD ["node", "server.js"]

Create Docker Image

c:\azure-keyvault-demo> docker build -f Dockerfile -t keyvault-demo:v1 .

This image should be created in Docker Desktop

Run Docker Image

c:\azure-keyvault-demo> docker run -d -p 3000 keyvault-demo:v1

Time to get hands dirty on Azure

  1. Create a resource group
  2. Create a Container Registry
Now it's time to push the image onto this Registry. This is what I created
  • Resource Group: my-keyvault-test-rg
  • Container Registry Name: keyvaultregistry.azurecr.io
Navigate back to command prompt
  • az login (Login to Azure)
  • az acr login --name keyvaultregistry (Login to the container registry)
  • az acr update --name keyvaultregistry --admin-enabled true (Enable admin mode)

Build and push docker image to ACR

docker build -f Dockerfile -t keyvault-demo:v1 .

Tag the image into the Container Registry

docker tag keyvault-demo:v1 keyvaultregistry.azurecr.io/keyvault-demo:v1

Push the image to the Container Registry

docker push keyvaultregistry.azurecr.io/keyvault-demo:v1

Back to Azure Portal

Time to create Container Apps.

Create a container app. Do not forget to enable ingress


Output:


AZURE KEYVAULT
Update the container app's identity

And when you are deploying a new revision make sure you select "System assigned managed identity"

Create a keyvault.
I created a a keyvault called "mykeyvaultdemotest



Key vault URL: https://mykeyvaultdemotest.vault.azure.net/

Update this URL as an ENV variable inside the container


Deploy this new revision after updating the code (Docker build, tag, push)
const http = require('http');
const { DefaultAzureCredential } = require('@azure/identity');
const { SecretClient } = require('@azure/keyvault-secrets');

const PORT = process.env.PORT || 3000;
const keyVaultUrl = process.env.KEYVAULT_URL || "https://mykeyvalutdemotest.vault.azure.net/" ; // e.g., "https://<your-key-vault-name>.vault.azure.net/"

// Define a simple array to return in the response
const simpleArray = ['apple', 'banana', 'cherry'];

// Initialize the secret client only if the Key Vault URL is provided
let secretClient;
if (keyVaultUrl) {
    const credential = new DefaultAzureCredential();
    secretClient = new SecretClient(keyVaultUrl, credential);
}

async function getSecretValue(secretName) {
    if (!secretClient) {
        // If no Key Vault URL is configured, return null or a default value.
        return null;
    }
    try {
         const secret = await secretClient.getSecret(secretName);
         return secret.value;
    } catch (error) {
         console.error('Error fetching secret: ', error);
         return null;
    }
}

async function startServer() {
    const server = http.createServer(async (req, res) => {
         if (req.url === '/' && req.method === 'GET') {
             // Retrieve secret value from Azure Key Vault
             const secretValue = await getSecretValue('mysecretapikeyName');

             const responseData = JSON.stringify({
                 message: "Hello, world!",
                 simpleArray,
                 keyVaultSecret: secretValue
             });

             console.log("RESPONSE DATA: >>", responseData)

             res.writeHead(200, { "Content-Type": "application/json" });
             res.end(responseData);
         } else {
             res.writeHead(404, { "Content-Type": "text/plain" });
             res.end('Not Found');
         }
    });

    server.listen(PORT, () => {
         console.log(`Server is running on port ${PORT}`);
    });
}

startServer();





















Comments

Popular posts from this blog

Inside the JavaScript Memory Box: Visualizing Variables, References, and Copies

React & State Management: All Concepts

React: Communication between components