Updated: How to use .env files with the Azure SDK for Java

Exactly, one month ago, to the day, I wrote a post about how to use .env files with Java and Azure SDKs. The gist of the problem was that the package we use to read the .env files didn’t write those values to System.getenv or System.properties, so you had to do that manually with something like this:

OLD

static void loadEnvironmentProperties() {
    Dotenv ENVIRONMENT = Dotenv.load();
    ENVIRONMENT.entries().forEach(entry -> System.setProperty(entry.getKey(), entry.getValue()));
}

Well, I’m super happy to let you know that Carmine DiMascio, the java-dotenv package creator and maintainer, just implemented a feature that will tell java-dotenv to also write the values from .env to System.properties - which are read by the Azure SDKs.

So instead of the above you just need to call systemProperties() when you load the .env file, like so:

NEW

Dotenv.configure().systemProperties().load();

Here’s how to get everything setup. I’m going to assume that you already have a Java project - but you can find all of the source code for this simple sample here: https://github.com/jongio/azsdkjavaenv

1. Add .env file to project

Create .env file in your project and add the following settings:

AZURE_CLIENT_ID=
AZURE_CLIENT_SECRET=
AZURE_TENANT_ID=

These are the service principal settings that you get from calling az ad sp create-for-rbac --role Contributor to create a service principal - which will be used by DefaultAzureCredential. Make sure the service principal has the appropriate policy set to create a key. You can find those commands here: Authorizing an application to use a key or secret

You can use this command to assign the right policy to your service principal.

az keyvault set-policy -n KEY_VAULT_NAME --spn AZURE_CLIENT_ID --secret-permissions get list set delete --key-permissions create decrypt delete encrypt get list unwrapKey wrapKey update

2. Add java-dotenv Package

This package is used to read the .env file.

Make sure you add version 5.2.0

<dependency>
    <groupId>io.github.cdimascio</groupId>
    <artifactId>java-dotenv</artifactId>
    <version>5.2.0</version>
</dependency>

3. Add java-dotnet import

import io.github.cdimascio.dotenv.Dotenv;

4. Add code to load .env

Notice that we are now calling systemProperties(), which is the new method that will load the .env values into the Java System properties.

Dotenv.configure().systemProperties().load();
System.out.print(System.getProperty("AZURE_CLIENT_ID"));

When you run the above code, it should print the value that you have for AZURE_CLIENT_ID in your .env file.

5. Add Azure SDK Packages

Now that we have java-dotenv set, let’s get it working with the Azure SDKs. We’ll new up a DefaultAzureCredential, pass that to KeyClient, and create a key.

Add these to pom.xml

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-security-keyvault-keys</artifactId>
    <version>4.1.3</version>
</dependency>

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-identity</artifactId>
    <version>1.0.6</version>
</dependency>

You can find all the Azure SDK for Java releases here: https://aka.ms/azsdk/java

6. Add Azure SDK imports

Add imports to your Java code file.

import com.azure.identity.DefaultAzureCredential;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.security.keyvault.keys.KeyClientBuilder;
import com.azure.security.keyvault.keys.models.KeyType;
import com.azure.security.keyvault.keys.models.*;
import com.azure.security.keyvault.keys.KeyClient;

7. Create Key Vault

To run the sample, you are going to need to create an Azure Key Vault. You can do so with the Azure CLI az keyvault create or Azure Portal.

Add the following to your .env file and replace the URL with your Key Vault uri.

AZURE_KEYVAULT_URL=https://jongkv.vault.azure.net/

8. Add Azure SDK Code

We’ll first new up a DefaultAzureCredentail object, which under the covers will new up an EnvironmentCredential object, which will read the AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID values from System.properties which were written to by the java-dotenv package.

We then new up a KeyClient, and then create a key.

// Build new DAC, which will read from System.Properties
DefaultAzureCredential cred = new DefaultAzureCredentialBuilder().build();

// Use DAC when constructing a Key Vault client.
KeyClient keyClient = new KeyClientBuilder().vaultUrl(System.getProperty("AZURE_KEYVAULT_URL")).credential(cred)
        .buildClient();

KeyVaultKey key = keyClient.createKey("key1", KeyType.RSA);

System.out.printf("Key created. Name %s Id %s", key.getName(), key.getId());

And that’s how you get it all working together. Good stuff and much easier now that we have the systemProperties method.

You can find all the code here: https://github.com/jongio/azsdkjavaenv

Jon