Configuración de MicroProfile con Azure Key Vault
En este tutorial se muestra cómo configurar una aplicación microProfile para recuperar secretos de Azure Key Vault mediante las API de configuración de MicroProfile. Los desarrolladores se benefician de la API de configuración de MicroProfile estándar abierta para recuperar e insertar datos de configuración en sus microservicios.
Requisitos previos
- Una suscripción de Azure. Si todavía no la tiene, puede activar sus ventajas como suscriptor de MSDN o registrarse para obtener una cuenta gratis.
- CLI de Azure para entornos similares a Unix. En este artículo solo se requiere la variante bash de la CLI de Azure.
Instale la CLI de Azure e inicie sesión de forma interactiva con el comando az login para iniciar sesión en Azure antes de usar DefaultAzureCredential
en el código.az login
- Este artículo requiere al menos la versión 2.61.0 de la CLI de Azure. Si usa Azure Cloud Shell, ya está instalada la versión más reciente.
- Azure Cloud Shell tiene todos estos requisitos previos preinstalados. Para obtener más información, consulte Inicio rápido para Azure Cloud Shell.
- Si ejecuta los comandos en esta guía localmente (en lugar de usar Azure Cloud Shell), complete los pasos siguientes:
- Prepare una máquina local con un sistema operativo similar a Unix instalado (por ejemplo, Ubuntu, macOS o Subsistema de Windows para Linux).
- Instale una implementación de Java SE versión 17 o posterior (por ejemplo, microsoft build of OpenJDK).
- Instale Maven 3.9.8 o posterior.
- Instale cURL.
Conexión de la configuración de MicroProfile con Azure Key Vault
Echemos un vistazo rápido a la eficacia de combinar Azure Key Vault y la API de configuración de MicroProfile. Este es un fragmento de código de un campo de una clase anotada con @Inject
y @ConfigProperty
. El name
especificado en la anotación es el nombre del secreto que se va a buscar en Azure Key Vault y defaultValue
se usa si no se detecta el secreto. El valor secreto almacenado en Azure Key Vault o el valor predeterminado si no existe dicho secreto, se inserta automáticamente en el campo en tiempo de ejecución. La inserción de valores de propiedad de esta manera proporciona numerosas ventajas. Por ejemplo, ya no es necesario pasar valores en constructores y métodos establecedores, y la configuración se externaliza desde el código. Una de las ventajas más eficaces es tener conjuntos independientes de valores para entornos de desarrollo, pruebas y prod.
@Inject
@ConfigProperty(name = "key-name", defaultValue = "Unknown")
String keyValue;
También es posible acceder a la configuración de MicroProfile de forma imperativa, como se muestra en el ejemplo siguiente:
public class DemoClass {
@Inject
Config config;
public void method() {
System.out.println("Hello: " + config.getValue("key-name", String.class));
}
}
En este ejemplo se usa la implementación de Open Liberty de MicroProfile. Para obtener una lista completa de implementaciones compatibles, consulte Implementaciones compatibles con MicroProfile. En el ejemplo también se muestra cómo incluir en contenedores y ejecutar la aplicación en Azure.
En este ejemplo se usa la extensión de Azure de baja fricción para la biblioteca ConfigSource personalizada de MicroProfile Key Vault. Para obtener más información sobre esta biblioteca, consulte el archivo Léame de la biblioteca.
Estos son los pasos necesarios para ejecutar este código en el equipo local, empezando por la creación de un recurso de Azure Key Vault.
Creación de un recurso de Azure Key Vault
Use la CLI de Azure para crear el recurso de Azure Key Vault y rellenarlo con dos secretos.
En primer lugar, inicie sesión en Azure y establezca una suscripción para que sea la suscripción activa actual.
az login
az account set --subscription <subscription-id>
A continuación, cree un grupo de recursos con un nombre único, por ejemplo, mp-kv-rg-ejb010424.
export RESOURCE_GROUP_NAME=mp-kv-rg-ejb010424
az group create \
--name ${RESOURCE_GROUP_NAME} \
--location eastus
Ahora cree un recurso de Azure Key Vault con un nombre único (por ejemplo, kvejb010424), agregue dos secretos y exporte el URI de Key Vault como una variable de entorno.
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 variable AZURE_KEYVAULT_URL
de entorno es necesaria para configurar la biblioteca para que funcione con el ejemplo más adelante. Mantenga el terminal abierto y úselo para ejecutar la aplicación localmente más adelante.
Eso es todo. Ahora tiene Key Vault ejecutándose en Azure con dos secretos. Ahora puede clonar el repositorio de ejemplo y configurarlo para usar este recurso en la aplicación.
Preparación y ejecución local
Este ejemplo se basa en una aplicación de ejemplo disponible en GitHub. Cambie al terminal que abrió antes y ejecute los siguientes comandos para clonar el repositorio y ejecutar la aplicación localmente:
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
Si ve un mensaje sobre You are in 'detached HEAD' state
, este mensaje es seguro omitir.
Nota:
La biblioteca usa credenciales predeterminadas de Azure para autenticarse en Azure.
Puesto que ha autenticado una cuenta mediante el comando de la CLI az login
de Azure localmente, DefaultAzureCredential
se autentica con esa cuenta para acceder a Azure Key Vault.
Espere hasta que vea una salida similar a The defaultServer server is ready to run a smarter planet
. Abra un nuevo terminal y ejecute los siguientes comandos para probar el ejemplo:
# 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)
Debería ver las salidas esperadas descritas en los comentarios. Vuelva al terminal donde se ejecuta la aplicación. Presione CTRL + C para detener la aplicación.
Examen de la aplicación de ejemplo
Vamos a comprender mejor cómo funciona La configuración de MicroProfile en general y la biblioteca ConfigSource personalizada de MicroProfile Key Vault funciona en particular.
Dependencia de biblioteca
Incluya MicroProfile Key Vault Custom ConfigSource en la aplicación con la siguiente dependencia de Maven:
<dependency>
<groupId>com.azure.microprofile</groupId>
<artifactId>azure-microprofile-config-keyvault</artifactId>
</dependency>
Conexión a Azure Key Vault
La azure-microprofile-config-keyvault
biblioteca conecta la aplicación a Azure Key Vault sin introducir dependencias directas en las API de Azure. La biblioteca proporciona una implementación de la interfaz ConfigSource de especificación de MicroProfile Que sabe cómo leer desde Azure Key Vault. El tiempo de ejecución de Open Liberty proporciona el resto de la implementación de MicroProfile Config. Para obtener un vínculo a la especificación, consulte Pasos siguientes.
La biblioteca define la propiedad de configuración para enlazar la azure.keyvault.url
aplicación a un almacén de claves específico. La especificación de configuración de MicroProfile define las "Reglas de asignación de variables de entorno" para saber cómo se detecta el valor de una propiedad config, como azure.keyvault.url
, en tiempo de ejecución. Una de estas reglas indica que las propiedades se convierten en variables de entorno. La propiedad azure.keyvault.url
hace que se consulte la variable AZURE_KEYVAULT_URL
de entorno.
Clases clave en la aplicación de ejemplo
Vamos a examinar el recurso REST al que se han llamado los comandos cURL anteriores. Este recurso REST se define en la clase ConfigResource.java
del integration-tests/open-liberty-sample
proyecto.
@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));
}
}
El getConfigValue()
método usa la implementación insertada Config
para buscar un valor de los orígenes de configuración de la aplicación. Las búsquedas de valores de la Config
implementación se encuentran a través del algoritmo de búsqueda definido por la especificación de configuración de MicroProfile. La azure-microprofile-config-keyvault
biblioteca agrega Azure Key Vault como origen de configuración.
El getConfigSource()
método evita el algoritmo de búsqueda y va directamente a para AzureKeyVaultConfigSource
resolver las propiedades. Los métodos y getConfigProperties()
usan getConfigPropertyNames()
este método.
Ejecución en Azure Container Apps
En esta sección, va a incluir en contenedores la aplicación, configurar una identidad administrada asignada por el usuario para acceder a Azure Key Vault e implementar la aplicación en contenedor en Azure Container Apps.
Vuelva al terminal donde ejecutó la aplicación localmente y úsela en esta sección.
Configuración de una instancia de Azure Container Registry
Puede usar Azure Container Registry para incluir en contenedores la aplicación y almacenar la imagen de la aplicación.
En primer lugar, cree una instancia de Azure Container Registry con un nombre único, por ejemplo, acrejb010424.
export ACR_NAME=acrejb010424
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACR_NAME \
--sku Basic
Espere unos minutos después de que este comando vuelva antes de continuar.
Contenedorización de la aplicación
A continuación, intensifique la aplicación e inserte la imagen de la aplicación en Azure Container Registry. Asegúrese de que está en la ruta de acceso de la aplicación de ejemplo, por ejemplo, azure-microprofile/integration-tests/open-liberty-sample.
az acr build \
--registry ${ACR_NAME} \
--image open-liberty-mp-azure-keyvault:latest \
.
Debería ver la salida de compilación que concluye con un mensaje similar a Run ID: ca1 was successful after 1m28s
. Si no ve un mensaje similar, solucione y resuelva el problema antes de continuar.
Use los siguientes comandos para recuperar la información de conexión necesaria para acceder a la imagen al implementar la aplicación en Azure Container Apps más adelante.
export ACR_LOGIN_SERVER=$(az acr show \
--name $ACR_NAME \
--query 'loginServer' \
--output tsv)
Configuración de una identidad administrada asignada por el usuario
Como se indicó anteriormente, la biblioteca usa credenciales predeterminadas de Azure para autenticarse en Azure. Al implementar la aplicación en Azure Container Apps, establezca la variable AZURE_CLIENT_ID
de entorno para configurar DefaultAzureCredential para autenticarse como una identidad administrada definida por el usuario, que tiene permisos para acceder a Azure Key Vault y se asigna más adelante a Azure Container Apps.
En primer lugar, use los siguientes comandos para crear una identidad administrada asignada por el usuario con un nombre único, por ejemplo, uamiejb010424. Para más información, vaya a Creación de una identidad administrada asignada por el usuario.
export USER_ASSIGNED_IDENTITY_NAME=uamiejb010424
az identity create \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${USER_ASSIGNED_IDENTITY_NAME}
A continuación, use los siguientes comandos para concederle permisos para obtener y enumerar secretos de Azure Key Vault. Para obtener más información, consulte Asignación de la directiva de acceso.
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}"
La salida debe contener el siguiente JSON para que se considere correcta:
"permissions": {
"certificates": null,
"keys": null,
"secrets": [
"list",
"get"
],
"storage": null
}
Si la salida no contiene este JSON, solucione y resuelva el problema antes de continuar.
A continuación, use los siguientes comandos para recuperar el identificador y el identificador de cliente de la identidad administrada asignada por el usuario para poder asignarlo a Azure Container Apps más adelante para acceder a 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
Implementación de la aplicación en Azure Container Apps
Ha contenedorizado la aplicación y ha configurado una identidad administrada asignada por el usuario para acceder a Azure Key Vault. Ahora puede implementar la aplicación en contenedor en Azure Container Apps.
En primer lugar, cree un entorno para Azure Container Apps. Un entorno de Azure Container Apps crea un límite seguro alrededor de un grupo de aplicaciones de contenedor. Las aplicaciones de contenedor implementadas en el mismo entorno se implementan en la misma red virtual y escriben registros en la misma área de trabajo de Log Analytics. Use el comando az containerapp env create para crear un entorno con un nombre único (por ejemplo, acaenvejb010424), como se muestra en el ejemplo siguiente:
export ACA_ENV=acaenvejb010424
az containerapp env create \
--resource-group $RESOURCE_GROUP_NAME \
--location eastus \
--name $ACA_ENV
A continuación, use el comando az containerapp create para crear una instancia de Container Apps con un nombre único (por ejemplo, acaappejb010424) para ejecutar la aplicación después de extraer la imagen de Container Registry, como se muestra en el ejemplo siguiente:
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:
Asigne la identidad administrada asignada por el usuario a la instancia de Container Apps con el parámetro --user-assigned ${USER_ASSIGNED_IDENTITY_ID}
.
La instancia de Container Apps puede acceder a Azure Key Vault con dos variables de entorno proporcionadas en los parámetros --env-vars AZURE_CLIENT_ID=${USER_ASSIGNED_IDENTITY_CLIENT_ID} AZURE_KEYVAULT_URL=${AZURE_KEYVAULT_URL}
. Recuerde que se consulta la AZURE_KEYVAULT_URL
variable de entorno debido a las reglas de asignación de variables de entorno definidas por la especificación de configuración de MicroProfile.
A continuación, recupere una dirección URL completa para acceder a la aplicación mediante el siguiente comando:
export APP_URL=https://$(az containerapp show \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${ACA_NAME} \
--query properties.configuration.ingress.fqdn \
--output tsv)
Por último, vuelva a ejecutar los siguientes comandos para probar el ejemplo que se ejecuta en la instancia de Container Apps:
# 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)
Debería ver las salidas esperadas descritas en los comentarios. Si no los ve, la aplicación todavía podría iniciarse. Espere un rato e inténtelo de nuevo.
Limpieza de recursos
Para evitar los cargos de Azure, se recomienda limpiar los recursos que no sean necesarios. Cuando los recursos ya no sean necesarios, ejecute los siguientes comandos para limpiar los recursos.
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
Pasos siguientes
Puede obtener más información en estas referencias:
- Azure Container Apps
- Jakarta EE en Azure
- Extensiones de Azure para MicroProfile
- MicroProfile
- Especificación de configuración de MicroProfile
- API de configuración de MicroProfile
- Open Liberty
- Configuración del servidor Open Liberty
- Complemento de Maven para Liberty
- Imágenes de contenedor de Open Liberty