Configurare MicroProfile con Azure Key Vault
Questa esercitazione illustra come configurare un'applicazione MicroProfile per recuperare i segreti da Azure Key Vault utilizzando le API di MicroProfile Config . Gli sviluppatori traggono vantaggio dall'API Di configurazione MicroProfile standard aperta per il recupero e l'inserimento dei dati di configurazione nei microservizi.
Prerequisiti
- Una sottoscrizione di Azure. Se non si ha già una sottoscrizione di Azure, è possibile attivare i vantaggi del sottoscrittore MSDN o iscriversi a un account gratuito .
- Interfaccia della riga di comando di Azure per ambienti simili a Unix. Questo articolo richiede solo la variante Bash dell'interfaccia della riga di comando di Azure.
- Bash
- PowerShell
- di Visual Studio Code
Installare dell'interfaccia della riga di comando di Azure e accedere in modo interattivo con il comando az login az login per accedere ad Azure prima di usare DefaultAzureCredential
nel codice.az login
- Questo articolo richiede almeno la versione 2.61.0 dell'interfaccia della riga di comando di Azure. Se si usa Azure Cloud Shell, la versione più recente è già installata.
- Azure Cloud Shell include tutti questi prerequisiti preinstallati. Per altre informazioni, vedere Avvio rapido per Azure Cloud Shell.
- Se si eseguono i comandi in questa guida in locale (anziché usare Azure Cloud Shell), completare i passaggi seguenti:
- Preparare un computer locale con sistema operativo simile a Unix installato, ad esempio Ubuntu, macOS o Sottosistema Windows per Linux.
- Installare un'implementazione Java SE versione 17 o successiva - ad esempio, Microsoft build di OpenJDK.
- Installare Maven 3.9.8 o una versione successiva.
- Installare cURL.
Connessione di MicroProfile Config con Azure Key Vault
Diamo un'occhiata veloce alla potenza della combinazione di Azure Key Vault e della MicroProfile Config API. Ecco un frammento di codice di un campo in una classe annotata con @Inject
e @ConfigProperty
. Il name
specificato nell'annotazione è il nome del segreto da cercare in Azure Key Vault e il defaultValue
viene usato se il segreto non viene individuato. Il valore del segreto archiviato in Azure Key Vault o il valore predefinito, se tale segreto non esiste, viene inserito automaticamente nel campo in fase di esecuzione. L'inserimento di valori di proprietà in questo modo offre numerosi vantaggi. Ad esempio, non è più necessario passare valori nei costruttori e nei metodi setter e la configurazione viene esternata dal codice. Uno dei vantaggi più potenti è la presenza di set di valori separati per ambienti di sviluppo, test e produzione.
@Inject
@ConfigProperty(name = "key-name", defaultValue = "Unknown")
String keyValue;
È anche possibile accedere in modo imperativo alla configurazione di MicroProfile, come illustrato nell'esempio seguente:
public class DemoClass {
@Inject
Config config;
public void method() {
System.out.println("Hello: " + config.getValue("key-name", String.class));
}
}
Questo esempio usa l'implementazione
Questo esempio usa l'estensione Azure a bassa frizione per la libreria ConfigSource personalizzata MicroProfile Key Vault. Per altre informazioni su questa libreria, consultare la libreria README.
Ecco i passaggi necessari per eseguire questo codice nel computer locale, a partire dalla creazione di una risorsa di Azure Key Vault.
Creare una risorsa di Azure Key Vault
Usi l'Azure CLI per creare una risorsa Azure Key Vault e riempirla con due segreti. Per prima cosa, accedere ad Azure e impostare una sottoscrizione come sottoscrizione attiva corrente.
az login
az account set --subscription <subscription-id>
Creare quindi un gruppo di risorse con un nome univoco, ad esempio mp-kv-rg-ejb010424.
export RESOURCE_GROUP_NAME=mp-kv-rg-ejb010424
az group create \
--name ${RESOURCE_GROUP_NAME} \
--location eastus
A questo punto, creare una risorsa di Azure Key Vault con un nome univoco, ad esempio kobb010424, aggiungere due segreti ed esportare l'URI di Key Vault come variabile di ambiente.
export KEY_VAULT_NAME=kv-ejb010424
az keyvault create \
--resource-group "${RESOURCE_GROUP_NAME}" \
--name "${KEY_VAULT_NAME}" \
--location eastus \
--enable-rbac-authorization false
az keyvault secret set \
--vault-name "${KEY_VAULT_NAME}" \
--name secret \
--value 1234
az keyvault secret set \
--vault-name "${KEY_VAULT_NAME}" \
--name anotherSecret \
--value 5678
export AZURE_KEYVAULT_URL=$(az keyvault show \
--resource-group "${RESOURCE_GROUP_NAME}" \
--name "${KEY_VAULT_NAME}" \
--query properties.vaultUri \
--output tsv)
echo $AZURE_KEYVAULT_URL
La variabile di ambiente AZURE_KEYVAULT_URL
è necessaria per configurare la libreria in modo che funzioni con l'esempio in un secondo momento. Mantenere aperto il terminale e usarlo per l'esecuzione dell'app in locale in un secondo momento.
Questo è tutto! L'insieme di credenziali delle chiavi è ora in esecuzione in Azure con due segreti. È ora possibile clonare il repository di esempio e configurarlo per usare questa risorsa nell'app.
Iniziare a funzionare in locale
Questo esempio si basa su un'applicazione di esempio disponibile in GitHub. Passare al terminale aperto prima ed eseguire i comandi seguenti per clonare il repository ed eseguire l'app in locale:
git clone https://github.com/Azure/azure-microprofile.git
cd azure-microprofile
git checkout 1.0.0-beta.3
cd integration-tests/open-liberty-sample
mvn clean package liberty:run
Se viene visualizzato un messaggio relativo a You are in 'detached HEAD' state
, questo messaggio è sicuro da ignorare.
Nota
La libreria usa delle credenziali di Azure predefinite per l'autenticazione in Azure.
Poiché hai autenticato un account tramite il comando az login
dell'interfaccia della riga di comando di Azure in locale, DefaultAzureCredential
si autentica con quell'account per accedere ad Azure Key Vault.
Attendere che venga visualizzato un output simile a The defaultServer server is ready to run a smarter planet
. Aprire un nuovo terminale e usare i comandi seguenti per testare l'esempio:
# Get the value of secret "secret" stored in the Azure key vault. You should see 1234 in the response.
echo $(curl -s http://localhost:9080/config/value/secret -X GET)
# Get the value of secret "anotherSecret" stored in the Azure key vault. You should see 5678 in the response.
echo $(curl -s http://localhost:9080/config/value/anotherSecret -X GET)
# Get the names of secrets stored in the Azure key vault. You should see ["anotherSecret","secret"] in the response.
echo $(curl -s http://localhost:9080/config/propertyNames -X GET)
# Get the name-value paris of secrets stored in the Azure key vault. You should see {"anotherSecret":"5678","secret":"1234"} in the response.
echo $(curl -s http://localhost:9080/config/properties -X GET)
Verranno visualizzati gli output previsti descritti nei commenti. Tornare al terminale in cui è in esecuzione l'app. Per arrestare l'app, premere CTRL+C.
Esaminare l'app di esempio
Approfondiamo come funziona MicroProfile Config in generale e, in particolare, come funziona la libreria MicroProfile Key Vault Custom ConfigSource.
Dipendenza della libreria
Includere MicroProfile Key Vault Custom ConfigSource nella tua applicazione con la seguente dipendenza Maven:
<dependency>
<groupId>com.azure.microprofile</groupId>
<artifactId>azure-microprofile-config-keyvault</artifactId>
</dependency>
Connessione ad Azure Key Vault
La libreria azure-microprofile-config-keyvault
connette l'app ad Azure Key Vault senza introdurre dipendenze dirette dalle API di Azure. La libreria fornisce un'implementazione della specifica MicroProfile Config interfaccia ConfigSource che sa come leggere da Azure Key Vault. Il resto dell'implementazione di MicroProfile Config viene fornito dal runtime Open Liberty. Per un collegamento alla specifica, vedere Passaggi successivi.
La libreria definisce la proprietà di configurazione azure.keyvault.url
per associare l'applicazione a un archivio chiavi specifico. La specifica MicroProfile Config definisce "Regole di mapping delle variabili di ambiente" per il modo in cui il valore di una proprietà config, ad esempio azure.keyvault.url
, viene individuato in fase di esecuzione. Una di queste regole indica che le proprietà vengono convertite in variabili di ambiente. La proprietà azure.keyvault.url
fa sì che venga consultata la variabile di ambiente AZURE_KEYVAULT_URL
.
Classi chiave nell'app di esempio
Si esaminerà ora la risorsa REST che hanno chiamato i comandi cURL precedenti. Questa risorsa REST viene definita nella classe ConfigResource.java
nel progetto integration-tests/open-liberty-sample
.
@Path("/config")
public class ConfigResource {
@Inject
private Config config;
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/value/{name}")
public String getConfigValue(@PathParam("name") String name) {
return config.getConfigValue(name).getValue();
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/propertyNames")
public Set<String> getConfigPropertyNames() {
ConfigSource configSource = getConfigSource(AzureKeyVaultConfigSource.class.getSimpleName());
return configSource.getPropertyNames();
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/properties")
public Map<String, String> getConfigProperties() {
ConfigSource configSource = getConfigSource(AzureKeyVaultConfigSource.class.getSimpleName());
return configSource.getProperties();
}
private ConfigSource getConfigSource(String name) {
return StreamSupport.stream(config.getConfigSources().spliterator(), false)
.filter(source -> source.getName().equals(name))
.findFirst()
.orElseThrow(() -> new RuntimeException("ConfigSource not found: " + name));
}
}
Il metodo getConfigValue()
usa l'implementazione Config
inserita per recuperare un valore dalla configurazione dell'applicazione. Le ricerche di valori sull'implementazione Config
vengono eseguite tramite l'algoritmo di ricerca definito dalla specifica MicroProfile Config. La libreria azure-microprofile-config-keyvault
aggiunge Azure Key Vault come origine di configurazione.
Il metodo getConfigSource()
evita l'algoritmo di ricerca e passa direttamente al AzureKeyVaultConfigSource
per risolvere le proprietà. Questo metodo viene usato dai metodi getConfigPropertyNames()
e getConfigProperties()
.
Eseguire nelle app di Azure Container
In questa sezione containerizzi l'app, configuri un'identità gestita assegnata dall'utente per accedere ad Azure Key Vault e distribuisci l'app containerizzata su Azure Container Apps.
Tornare al terminale in cui è stata eseguita l'app in locale e usarla in questa sezione.
Configurare un Registro di Container di Azure
Si usa Azure Container Registry per containerizzare l'app e archiviare l'immagine dell'app.
Creare prima di tutto un Registro Azure Container con un nome univoco, ad esempio acrejb010424.
export ACR_NAME=acrejb010424
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACR_NAME \
--sku Basic
Attendere alcuni minuti dopo che questo comando viene restituito prima di continuare.
Containerizzare l'app
Successivamente, containerizzare l'app ed eseguire il push dell'immagine dell'app su Azure Container Registry. Assicurati di essere nel percorso dell'applicazione di esempio, ad esempio azure-microprofile/integration-tests/open-liberty-sample.
az acr build \
--registry ${ACR_NAME} \
--image open-liberty-mp-azure-keyvault:latest \
.
Verrà visualizzato l'output di compilazione che termina con un messaggio simile a Run ID: ca1 was successful after 1m28s
. Se non viene visualizzato un messaggio simile, individuare e risolvere il problema prima di continuare.
Utilizzare i comandi seguenti per recuperare le informazioni di connessione necessarie per accedere all'immagine quando si distribuisce l'app su Azure Container Apps successivamente.
export ACR_LOGIN_SERVER=$(az acr show \
--name $ACR_NAME \
--query 'loginServer' \
--output tsv)
Configurare un'identità gestita assegnata dall'utente
Come indicato in precedenza, la libreria usa delle credenziali di Azure predefinite per l'autenticazione in Azure. Quando si distribuisce l'app in App Azure Container, si imposta la variabile di ambiente AZURE_CLIENT_ID
per configurare DefaultAzureCredential per l'autenticazione come identità gestita definita dall'utente, che dispone delle autorizzazioni per accedere ad Azure Key Vault e viene assegnata in un secondo momento ad App Azure Container.
Usare prima di tutto i comandi seguenti per creare un'identità gestita assegnata dall'utente con un nome univoco, ad esempio uamiejb010424. Per altre informazioni, vedere Creare un'identità gestita assegnata dall'utente.
export USER_ASSIGNED_IDENTITY_NAME=uamiejb010424
az identity create \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${USER_ASSIGNED_IDENTITY_NAME}
Successivamente, usare i comandi seguenti per assegnare le autorizzazioni per ottenere ed elencare i segreti da Azure Key Vault. Per ulteriori informazioni, vedi Assegna i criteri di accesso.
export USER_ASSIGNED_IDENTITY_OBJECT_ID="$(az identity show \
--resource-group "${RESOURCE_GROUP_NAME}" \
--name "${USER_ASSIGNED_IDENTITY_NAME}" \
--query 'principalId' \
--output tsv)"
az keyvault set-policy --name "${KEY_VAULT_NAME}" \
--resource-group "${RESOURCE_GROUP_NAME}" \
--secret-permissions get list \
--object-id "${USER_ASSIGNED_IDENTITY_OBJECT_ID}"
L'output deve contenere il codice JSON seguente per essere considerato riuscito:
"permissions": {
"certificates": null,
"keys": null,
"secrets": [
"list",
"get"
],
"storage": null
}
Se l'output non contiene questo JSON, individuare e risolvere il problema prima di continuare.
Usare quindi i comandi seguenti per recuperare l'ID e l'ID client dell'identità gestita assegnata dall'utente in modo da poterlo assegnare alle app Azure Container in un secondo momento per accedere ad Azure Key Vault:
export USER_ASSIGNED_IDENTITY_ID="$(az identity show \
--resource-group "${RESOURCE_GROUP_NAME}" \
--name "${USER_ASSIGNED_IDENTITY_NAME}" \
--query 'id' \
--output tsv)"
export USER_ASSIGNED_IDENTITY_CLIENT_ID="$(az identity show \
--name "${USER_ASSIGNED_IDENTITY_NAME}" \
--resource-group "${RESOURCE_GROUP_NAME}" \
--query 'clientId' \
--output tsv)"
echo $USER_ASSIGNED_IDENTITY_ID
echo $USER_ASSIGNED_IDENTITY_CLIENT_ID
Distribuire l'app su Azure Container Apps
Hai containerizzato l'app e configurato un'identità gestita assegnata dall'utente per accedere ad Azure Key Vault. Ora puoi distribuire l'app containerizzata su Azure Container Apps.
Creare prima di tutto un ambiente per le app contenitore di Azure. Un ambiente in Azure Container Apps crea un perimetro sicuro intorno a un gruppo di app di contenitori. Le app contenitore distribuite nello stesso ambiente vengono distribuite nella stessa rete virtuale e scrivono i log nella stessa area di lavoro Log Analytics. Usare il comando az containerapp env create per creare un ambiente con un nome univoco, per esempio acaenvejb010424, come illustrato nell'esempio seguente.
export ACA_ENV=acaenvejb010424
az containerapp env create \
--resource-group $RESOURCE_GROUP_NAME \
--location eastus \
--name $ACA_ENV
Successivamente, usare il comando az containerapp create per creare un'istanza di Container Apps con un nome univoco, ad esempio acaappejb010424, per eseguire l'app dopo l'estrazione dell'immagine dal Container Registry, come illustrato nell'esempio seguente.
export ACA_NAME=acaappejb010424
az containerapp create \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${ACA_NAME} \
--environment ${ACA_ENV} \
--image ${ACR_LOGIN_SERVER}/open-liberty-mp-azure-keyvault:latest \
--registry-server $ACR_LOGIN_SERVER \
--registry-identity system \
--user-assigned ${USER_ASSIGNED_IDENTITY_ID} \
--env-vars \
AZURE_CLIENT_ID=${USER_ASSIGNED_IDENTITY_CLIENT_ID} \
AZURE_KEYVAULT_URL=${AZURE_KEYVAULT_URL} \
--target-port 9080 \
--ingress 'external'
Nota
Assegni l'identità gestita assegnata dall'utente all'istanza di Container Apps con il parametro --user-assigned ${USER_ASSIGNED_IDENTITY_ID}
.
L'istanza di App contenitore può accedere ad Azure Key Vault con due variabili di ambiente fornite nei parametri --env-vars AZURE_CLIENT_ID=${USER_ASSIGNED_IDENTITY_CLIENT_ID} AZURE_KEYVAULT_URL=${AZURE_KEYVAULT_URL}
. Tenere presente che la variabile di ambiente AZURE_KEYVAULT_URL
viene consultata conformemente alle regole di mapping delle variabili di ambiente definite dalla specificazione MicroProfile Config.
Recupera quindi un URL completo per accedere all'app usando il seguente comando:
export APP_URL=https://$(az containerapp show \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${ACA_NAME} \
--query properties.configuration.ingress.fqdn \
--output tsv)
Eseguire di nuovo i comandi seguenti per testare l'esempio che è in esecuzione nell'istanza di Container Apps, infine.
# Get the value of secret "secret" stored in the Azure key vault. You should see 1234 in the response.
echo $(curl -s ${APP_URL}/config/value/secret -X GET)
# Get the value of secret "anotherSecret" stored in the Azure key vault. You should see 5678 in the response.
echo $(curl -s ${APP_URL}/config/value/anotherSecret -X GET)
# Get the names of secrets stored in the Azure key vault. You should see ["anotherSecret","secret"] in the response.
echo $(curl -s ${APP_URL}/config/propertyNames -X GET)
# Get the name-value paris of secrets stored in the Azure key vault. You should see {"anotherSecret":"5678","secret":"1234"} in the response.
echo $(curl -s ${APP_URL}/config/properties -X GET)
Verranno visualizzati gli output previsti descritti nei commenti. Se non le vedi, l'app potrebbe essere ancora in fase di avvio. Attendere un po' e riprovare.
Pulire le risorse
Per evitare addebiti di Azure, è consigliabile pulire le risorse non necessarie. Quando le risorse non sono più necessarie, eseguire i comandi seguenti per pulire le risorse.
az keyvault delete \
--resource-group "${RESOURCE_GROUP_NAME}" \
--name "${KEY_VAULT_NAME}"
az keyvault purge \
--name "${KEY_VAULT_NAME}" \
--no-wait
az group delete \
--name ${RESOURCE_GROUP_NAME} \
--yes \
--no-wait
Passaggi successivi
Per altre informazioni, vedere i riferimenti seguenti: