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