Search code examples
pythonazureazure-functionsazure-keyvault

Cannot Access Azure Key Vault from Python script via 'os.environ["VAULT_URL]" - Key Error: "VAULT_URL"


I am having trouble accessing my Azure Key vault from my python script (debugging before deployment), the script cannot find the environment variable "VAULT_URL" even though I have set this in my environment variables on my Function App on Azure Portal.

All I need to do is retrieve secrets and use them later in the script, I am using this code as a direct copy/paste from this link to test Key vault connection and if it will work POST DEPLOYMENT https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/keyvault/azure-keyvault-secrets/samples/hello_world.py#L37 :

app = func.FunctionApp()

@app.schedule(schedule="0 */5 * * * *", arg_name="myTimer", run_on_startup=True,
              use_monitor=False) 
def timer_trigger(myTimer: func.TimerRequest) -> None:
    if myTimer.past_due:
        logging.info('The timer is past due!')

    logging.info('Python timer trigger function executed.')

    print("hello world!")

    logging.info(os.environ)
    # Instantiate a secret client that will be used to call the service.
    # Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
    # [START create_secret_client]
    VAULT_URL = os.environ["VAULT_URL"]
    credential = DefaultAzureCredential()
    client = SecretClient(vault_url=VAULT_URL, credential=credential)
    # [END create_secret_client]

    # Let's create a secret holding bank account credentials valid for 1 year.
    # if the secret already exists in the Key Vault, then a new version of the secret is created.
    print("\n.. Create Secret")
    expires = datetime.datetime.utcnow() + datetime.timedelta(days=365)
    secret = client.set_secret("helloWorldSecretName", "helloWorldSecretValue", expires_on=expires)
    assert secret.name
    print(f"Secret with name '{secret.name}' created with value '{secret.value}'")
    print(f"Secret with name '{secret.name}' expires on '{secret.properties.expires_on}'")

    # Let's get the bank secret using its name
    print("\n.. Get a Secret by name")
    bank_secret = client.get_secret(secret.name)
    assert bank_secret.properties.expires_on
    print(f"Secret with name '{bank_secret.name}' was found with value '{bank_secret.value}'.")

    # After one year, the bank account is still active, we need to update the expiry time of the secret.
    # The update method can be used to update the expiry attribute of the secret. It cannot be used to update
    # the value of the secret.
    print("\n.. Update a Secret by name")
    expires = bank_secret.properties.expires_on + datetime.timedelta(days=365)
    updated_secret_properties = client.update_secret_properties(secret.name, expires_on=expires)
    print(f"Secret with name '{secret.name}' was updated on date '{updated_secret_properties.updated_on}'")
    print(f"Secret with name '{secret.name}' was updated to expire on '{updated_secret_properties.expires_on}'")

    # Bank forced a password update for security purposes. Let's change the value of the secret in the Key Vault.
    # To achieve this, we need to create a new version of the secret in the Key Vault. The update operation cannot
    # change the value of the secret.
    new_secret = client.set_secret(secret.name, "newSecretValue")
    print(f"Secret with name '{new_secret.name}' created with value '{new_secret.value}'")

    # The bank account was closed, need to delete its credentials from the Key Vault.
    print("\n.. Deleting Secret...")
    client.begin_delete_secret(secret.name)
    print(f"Secret with name '{secret.name}' was deleted.")

the error it gives me is as follows enter image description here

and here are my environment variables I want to access to be able to access my Key Vault both locally and after deployment

enter image description here

The error seems to surround the environment variable "VAULT_URL"

I have tried this code to retrieve secrets:

keyVaultName = "<Key-vault-name>"
        KVUri = f"https://{keyVaultName}.vault.azure.net"

        credential = DefaultAzureCredential()
        client = SecretClient(vault_url=KVUri, credential=credential)

        
        username = client.get_secret("username").value
        password = client.get_secret("password").value
        security_token = client.get_secret("security-token").value
        domain = client.get_secret("domain").value
        
        sharepoint_username = client.get_secret("sharepoint-username").value
        sharepoint_password = client.get_secret("sharepoint-password").value
        sharepoint_clientID = client.get_secret("sharepoint-clientID").value
        sharepoint_clientSecret = client.get_secret("sharepoint-clientSecret").value
        sharepoint_tenantID = client.get_secret("sharepoint-tenantID").value

Which worked locally, but when running remotely (after deployment), could not access the key vault, giving a 403 error, I have a managed instance which is assigned the role of Key Vault Administrator on my Key Vault but this did not work and so I decided it might have been something with my code that wasn't connecting to the key vault AFTER deployment

UPDATE os.environ output enter image description here

Error Message enter image description here


Solution

  • You have to use os.environ.get(), to get the values from app settings in Function App.

    Firstly created a app setting :

    enter image description here

    Below is the code which worked for me:

    import azure.functions as func
    import logging
    import os
    
    app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)
    @app.route(route="http_trigger")
    def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
        logging.info('Python HTTP trigger function processed a request.')
        rith_val=os.environ.get("Value")
        print(rith_val)
        return func.HttpResponse(f"Hello, Rithwik Bojja . The Value is {rith_val}")
    

    Output:

    enter image description here