diff --git a/.gitignore b/.gitignore index 2eea525..73dd9b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.env \ No newline at end of file +.env +venv/* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..757382c --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# Sample Python Dash App with Secret Management + +## Python Configuration + +This configuration only needs to be done once. + +### Step 1: Create virtual environment + +```bash +python -m venv venv +``` + +### Step 2: Activate Virtual Environment +Open a powershell console (or terminal in VS Code) + +```bash +./venv/scripts/activate +``` + +### Step 3: Load Python Requirements + +```bash +pip install -r requirements.txt +``` + +## Secret Configuration + +This configuration only needs to be done once. + +### Load all Azure Keyvault secrets into local Powershell Vault + +The following script will copy all secrets from the DataHub Keyvault into local vault. +Once this is done, it is not necessary to connect to Azure to execute the application. The Python application can then work offline. + +A secret is required in the script to lock the local vault. The same secret will be required later to read secrets from the vault. The local vault is a better alternative to a plain text to store secrets. + +```bash +./load-secrets.ps1. +``` + + +## Running the application + +### Step 1: Activate Virtual Environment +Open a powershell console (or terminal in VS Code) + +```bash +./venv/scripts/activate +``` + +### Step 2: Configure the environment + +The following script will load into environment variables the secrets from the local vault. + +```bash +./configure-env.ps1. +``` + +### Step 3: Run the application + +```bash +./python app.py +``` \ No newline at end of file diff --git a/app.py b/app.py index 1c2b731..6ca966d 100644 --- a/app.py +++ b/app.py @@ -1,29 +1,26 @@ import dash from dash.dependencies import Input, Output, State from dash import html, dcc -from azure.identity import DefaultAzureCredential -from azure.keyvault.secrets import SecretClient import psycopg2 import pandas as pd +import os # Initialize the Dash app app = dash.Dash(__name__, requests_pathname_prefix="/webapp-DW1/", routes_pathname_prefix="/webapp-DW1/") -KEY_VAULT_URL = "https://fsdh-proj-dw1-poc-kv.vault.azure.net/" error_occur = False try: # Retrieve the secrets containing DB connection details - credential = DefaultAzureCredential() - secret_client = SecretClient(vault_url=KEY_VAULT_URL, credential=credential) # Retrieve the secrets containing DB connection details DB_NAME = "fsdh" - DB_HOST = secret_client.get_secret("datahub-psql-server").value - DB_USER = secret_client.get_secret("datahub-psql-admin").value - DB_PASS = secret_client.get_secret("datahub-psql-password").value + DB_HOST = os.getenv('DATAHUB_PSQL_SERVER') + print(f"DB_HOST is {DB_HOST}") + DB_USER = os.getenv('DATAHUB_PSQL_USER') + DB_PASS = os.getenv('DATAHUB_PSQL_PASSWORD') except Exception as e: error_occur = True print(f"An error occurred: {e} | Une erreur s'est produite: {e}") diff --git a/configure-env.ps1 b/configure-env.ps1 new file mode 100644 index 0000000..3bb909e --- /dev/null +++ b/configure-env.ps1 @@ -0,0 +1,5 @@ +$env:DATAHUB_PSQL_SERVER = Get-Secret -Name DB_HOST -AsPlainText +$env:DATAHUB_PSQL_USER = Get-Secret -Name DB_USER -AsPlainText +$env:DATAHUB_PSQL_PASSWORD = Get-Secret -Name DB_PASS -AsPlainText + +Write-Host "Configured environment variables from local vault" diff --git a/load-secrets.ps1 b/load-secrets.ps1 new file mode 100644 index 0000000..4e56d0b --- /dev/null +++ b/load-secrets.ps1 @@ -0,0 +1,40 @@ +# Install the Az module (if not already installed) +# Az Module is required to interact with Azure Key Vault +# Install Az module if not already installed +if (-not (Get-Module -Name Az -ListAvailable)) { + Install-Module -Name Az -AllowClobber -Scope CurrentUser +} +# Install the SecretManagement and SecretStore modules +# These modules are required to interact with the Secret Management module +# which will store the secrets locally. This avoids saving the secrets in a text file +if (-not (Get-Module -Name Microsoft.PowerShell.SecretStore -ListAvailable)) { + Install-Module -Name Microsoft.PowerShell.SecretStore -AllowClobber -Scope CurrentUser +} +if (-not (Get-Module -Name Microsoft.PowerShell.SecretManagement -ListAvailable)) { + Install-Module -Name Microsoft.PowerShell.SecretManagement -AllowClobber -Scope CurrentUser +} + +# Connect to Azure if not already connected +$env:AzureTenantId = "8c1a4d93-d828-4d0e-9303-fd3bd611c822" +Connect-AzAccount -Tenant $env:AzureTenantId -Subscription + +# Optional: Set the context to the specific Azure subscription +# Get-AzSubscription -SubscriptionName "Your Subscription Name" | Set-AzContext + +# Define Key Vault URL or name +$KeyVaultName = "fsdh-proj-dw1-poc-kv" + +Write-Output "Retrieving secrets from Key Vault: $KeyVaultName" +# Retrieve secrets from Key Vault +$DB_HOST = Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name "datahub-psql-server" -AsPlainText +$DB_USER = Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name "datahub-psql-admin" -AsPlainText +$DB_PASS = Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name "datahub-psql-password" -AsPlainText +#Register-SecretVault -Name MyVault -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault + +# Output the secrets (optional, for verification) +Write-Output "Saving DB_HOST: $DB_HOST to Powershell Vault" +Set-Secret -Name DB_HOST -Secret $DB_HOST -Vault MyVault +Write-Output "Saving DB_USER: $DB_USER to Powershell Vault" +Set-Secret -Name DB_USER -Secret $DB_USER -Vault MyVault +Write-Output "Saving DB_PASS: $DB_PASS to Powershell Vault" +Set-Secret -Name DB_PASS -Secret $DB_PASS -Vault MyVault diff --git a/run_app.ps1 b/run_app.ps1 new file mode 100644 index 0000000..d882396 --- /dev/null +++ b/run_app.ps1 @@ -0,0 +1,2 @@ +# Import python library requirements +pip install -r requirements.txt