Konfigurera MicroProfile med Azure Key Vault

Den här självstudien visar hur du konfigurerar ett MicroProfile-program för att hämta hemligheter från Azure Key Vault med hjälp av MicroProfile Config-API:er. Utvecklare drar nytta av det öppna Standard MicroProfile Config-API:et för att hämta och mata in konfigurationsdata i sina mikrotjänster.

Förutsättningar

  • En Azure-prenumeration; Om du inte redan har en Azure-prenumeration kan du aktivera dina MSDN-prenumerantförmåner eller registrera dig för ett kostnadsfritt konto.
  • Azure CLI för Unix-liknande miljöer. Den här artikeln kräver endast Bash-varianten av Azure CLI.
    • Installera Azure CLI och logga in interaktivt med kommandot az login för att logga in på Azure innan du använder DefaultAzureCredential kod.
      az login
      
    • Den här artikeln kräver minst version 2.55.0 av Azure CLI. Om du använder Azure Cloud Shell är den senaste versionen redan installerad.
  • Azure Cloud Shell har alla dessa förutsättningar förinstallerade. Mer information finns i Snabbstart för Azure Cloud Shell.
  • Om du kör kommandona i den här guiden lokalt (i stället för att använda Azure Cloud Shell) utför du följande steg:
    • Förbered en lokal dator med Unix-liknande operativsystem installerat (till exempel Ubuntu, macOS eller Windows-undersystem för Linux).
    • Installera en Java SE-implementeringsversion 17 eller senare (till exempel Microsoft-version av OpenJDK).
    • Installera Maven 3.5.0 eller senare.
    • Installera cURL.

Anslut ing MicroProfile Config med Azure Key Vault

Låt oss ta en snabb titt på kraften i att kombinera Azure Key Vault och MicroProfile Config API. Här är ett kodfragment för ett fält i en klass som kommenteras med @Inject och @ConfigProperty. Den name angivna i kommentaren är namnet på hemligheten som ska sökas upp i Azure Key Vault och defaultValue används om hemligheten inte identifieras. Det hemliga värdet som lagras i Azure Key Vault, eller standardvärdet om det inte finns någon sådan hemlighet, matas automatiskt in i fältet vid körning. Att mata in egenskapsvärden på det här sättet ger många fördelar. Du behöver till exempel inte längre skicka runt värden i konstruktorer och settermetoder, och konfigurationen externaliseras från koden. En av de mest kraftfulla fördelarna är att ha separata uppsättningar med värden för utvecklings-, test- och prod-miljöer.

@Inject
@ConfigProperty(name = "key-name", defaultValue = "Unknown")
String keyValue;

Det är också möjligt att komma åt MicroProfile-konfigurationen imperativt, vilket visas i följande exempel:

public class DemoClass {
    @Inject
    Config config;

    public void method() {
        System.out.println("Hello: " + config.getValue("key-name", String.class));
    }
}

Det här exemplet använder Open Liberty-implementeringen av MicroProfile. En fullständig lista över kompatibla implementeringar finns i MicroProfile-kompatibla implementeringar. Exemplet visar också hur du containeriserar och kör programmet i Azure.

Det här exemplet använder Azure-tillägget med låg friktion för Det anpassade ConfigSource-biblioteket för MicroProfile Key Vault. Mer information om det här biblioteket finns i biblioteket README.

Här är stegen som krävs för att köra koden lokalt i datorn, vi börjar med att skapa en Azure Key Vault-resurs.

Skapa en Azure Key Vault-resurs

Du använder Azure CLI för att skapa Azure Key Vault-resursen och fylla den med två hemligheter.

Logga först in på Azure och ange att en prenumeration ska vara den aktuella aktiva prenumerationen.

az login
az account set --subscription <subscription-id>

Skapa sedan en resursgrupp med ett unikt namn, till exempel mp-kv-rg-ejb010424.

export RESOURCE_GROUP_NAME=mp-kv-rg-ejb010424
az group create \
    --name ${RESOURCE_GROUP_NAME} \
    --location eastus

Skapa nu en Azure Key Vault-resurs med ett unikt namn (till exempel kvejb010424), lägg till två hemligheter och exportera Key Vault-URI:n som en miljövariabel.

export KEY_VAULT_NAME=kv-ejb010424
az keyvault create \
    --resource-group "${RESOURCE_GROUP_NAME}" \
    --name "${KEY_VAULT_NAME}" \
    --location eastus

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

Miljövariabeln AZURE_KEYVAULT_URL krävs för att konfigurera biblioteket så att det fungerar med exemplet senare. Håll terminalen öppen och använd den för att köra appen lokalt senare.

Det var allt! Nu körs Key Vault i Azure med två hemligheter. Nu kan du klona exempelrepo och konfigurera den så att den använder den här resursen i din app.

Kom igång lokalt

Det här exemplet baseras på ett exempelprogram som är tillgängligt på GitHub. Växla till den terminal som du öppnade tidigare och kör följande kommandon för att klona lagringsplatsen och köra appen lokalt:

git clone https://github.com/Azure/azure-microprofile.git
cd azure-microprofile
git checkout 20240116
cd integration-tests/open-liberty-sample
mvn package liberty:run

Om du ser ett meddelande om You are in 'detached HEAD' stateär det här meddelandet säkert att ignorera.

Kommentar

Biblioteket använder Azure-standardautentiseringsuppgifter för att autentisera i Azure.

Eftersom du har autentiserat ett konto via Azure CLI-kommandot az login lokalt DefaultAzureCredential autentiserar du med det kontot för att få åtkomst till Azure Key Vault.

Vänta tills du ser utdata som liknar The defaultServer server is ready to run a smarter planet. Öppna en ny terminal och kör följande kommandon för att testa exemplet:

# 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)

Du bör se de förväntade utdata som beskrivs i kommentarerna. Växla tillbaka till terminalen där appen körs. Tryck på Ctrl + C för att stoppa appen.

Granska exempelappen

Låt oss få en djupare förståelse för hur MicroProfile Config fungerar i allmänhet, och microProfile Key Vault Custom ConfigSource-biblioteket fungerar i synnerhet.

Biblioteksberoende

Inkludera Anpassad ConfigSource för MicroProfile Key Vault i din app med följande Maven-beroende:

<dependency>
  <groupId>com.azure.microprofile</groupId>
  <artifactId>azure-microprofile-config-keyvault</artifactId>
</dependency>

Anslut till Azure Key Vault

Biblioteket azure-microprofile-config-keyvault ansluter din app till Azure Key Vault utan att introducera några direkta beroenden för Azure-API:er. Biblioteket tillhandahåller en implementering av ConfigSource-gränssnittet för MicroProfile ConfigSource som vet hur man läser från Azure Key Vault. Resten av implementeringen av MicroProfile Config tillhandahålls av Open Liberty-körningen. En länk till specifikationen finns i Nästa steg.

Biblioteket definierar konfigurationsegenskapen azure.keyvault.url för att binda din app till ett specifikt nyckelvalv. Specifikationen MicroProfile Config definierar "Mappningsregler för miljövariabler" för hur värdet för en konfigurationsegenskap, till exempel azure.keyvault.url, identifieras vid körning. En av dessa regler anger att egenskaper konverteras till miljövariabler. Egenskapen azure.keyvault.url gör att miljövariabeln AZURE_KEYVAULT_URL konsulteras.

Nyckelklasser i exempelappen

Nu ska vi undersöka REST-resursen som de föregående cURL-kommandona har anropat. Den här REST-resursen definieras i klassen ConfigResource.java i integration-tests/open-liberty-sample projektet.

@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));
    }
}

Metoden getConfigValue() använder den inmatade Config implementeringen för att leta upp ett värde från programkonfigurationskällorna. Alla värdesökningar i implementeringen Config hittas via sökalgoritmen som definieras av MicroProfile Config-specifikationen. Biblioteket azure-microprofile-config-keyvault lägger till Azure Key Vault som konfigurationskälla.

Metoden getConfigSource() undviker sökalgoritmen och går direkt till AzureKeyVaultConfigSource för att lösa egenskaper. Den här metoden används av getConfigPropertyNames() metoderna och getConfigProperties() .

Kör i Azure Container Apps

I det här avsnittet ska du containerisera appen, konfigurera en användartilldelad hanterad identitet för att få åtkomst till Azure Key Vault och distribuera den containerbaserade appen i Azure Container Apps.

Växla tillbaka till terminalen där du körde appen lokalt och använd den i hela det här avsnittet.

Konfigurera ett Azure Container Registry

Du använder Azure Container Registry för att containerisera appen och lagra appavbildningen.

Skapa först ett Azure Container Registry med ett unikt namn, till exempel acrejb010424.

export ACR_NAME=acrejb010424
az acr create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $ACR_NAME \
    --sku Basic \
    --admin-enabled

Vänta några minuter efter att kommandot har returnerats innan du fortsätter.

Containerisera appen

Därefter ska du containerisera appen och skicka appavbildningen till Ditt Azure Container Registry. Kontrollera att du är i sökvägen till exempelappen, till exempel azure-microprofile/integration-tests/open-liberty-sample.

az acr build \
    --registry ${ACR_NAME} \
    --image open-liberty-mp-azure-keyvault:latest \
    .

Du bör se byggutdata som avslutas med ett meddelande som liknar Run ID: ca1 was successful after 1m28s. Om du inte ser något liknande meddelande kan du felsöka och lösa problemet innan du fortsätter.

Använd följande kommandon för att hämta anslutningsinformation som krävs för att komma åt avbildningen när du distribuerar appen i Azure Container Apps senare.

export ACR_LOGIN_SERVER=$(az acr show \
    --name $ACR_NAME \
    --query 'loginServer' \
    --output tsv)
export ACR_USER_NAME=$(az acr credential show \
    --name $ACR_NAME \
    --query 'username' \
    --output tsv)
export ACR_PASSWORD=$(az acr credential show \
    --name $ACR_NAME \
    --query 'passwords[0].value' \
    --output tsv)

Konfigurera en användartilldelad hanterad identitet

Som tidigare nämnts använder biblioteket Azure-standardautentiseringsuppgifter för att autentisera i Azure. När du distribuerar appen till Azure Container Apps ställer du in miljövariabeln AZURE_CLIENT_ID för att konfigurera DefaultAzureCredential för att autentisera som en användardefinierad hanterad identitet, som har behörighet att komma åt Azure Key Vault och tilldelas till Azure Container Apps senare.

Använd först följande kommandon för att skapa en användartilldelad hanterad identitet med ett unikt namn, till exempel uamiejb010424. Mer information finns i Skapa en användartilldelad hanterad identitet.

export USER_ASSIGNED_IDENTITY_NAME=uamiejb010424
az identity create \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name ${USER_ASSIGNED_IDENTITY_NAME}

Använd sedan följande kommandon för att ge den behörighet att hämta och lista hemligheter från Azure Key Vault. Mer information finns i Tilldela åtkomstprincipen.

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}"

Utdata måste innehålla följande JSON för att anses vara lyckade:

"permissions": {
  "certificates": null,
  "keys": null,
  "secrets": [
    "list",
    "get"
  ],
  "storage": null
}

Om utdata inte innehåller den här JSON-filen felsöker du och löser problemet innan du fortsätter.

Använd sedan följande kommandon för att hämta ID:t och klient-ID:t för den användartilldelade hanterade identiteten så att du kan tilldela den till dina Azure Container Apps senare för åtkomst till 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

Distribuera appen i Azure Container Apps

Du har containeriserat appen och konfigurerat en användartilldelad hanterad identitet för åtkomst till Azure Key Vault. Nu kan du distribuera den containerbaserade appen i Azure Container Apps.

Skapa först en miljö för Azure Container Apps. En miljö i Azure Container Apps skapar en säker gräns runt en grupp med containerappar. Container Apps som distribueras till samma miljö distribueras i samma virtuella nätverk och skriver loggar till samma Log Analytics-arbetsyta. Använd kommandot az containerapp env create för att skapa en miljö med ett unikt namn (till exempel acaenvejb010424), som du ser i följande exempel:

export ACA_ENV=acaenvejb010424
az containerapp env create \
    --resource-group $RESOURCE_GROUP_NAME \
    --location eastus \
    --name $ACA_ENV

Använd sedan kommandot az containerapp create för att skapa en Container Apps-instans med ett unikt namn (till exempel acaappejb010424) för att köra appen när du har hämtat avbildningen från Container Registry, som du ser i följande exempel:

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-username $ACR_USER_NAME \
    --registry-password $ACR_PASSWORD \
    --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'

Kommentar

Du tilldelar den användartilldelade hanterade identiteten till Container Apps-instansen med parametern --user-assigned ${USER_ASSIGNED_IDENTITY_ID}.

Container Apps-instansen kan komma åt Azure Key Vault med två miljövariabler som anges i parametrarna --env-vars AZURE_CLIENT_ID=${USER_ASSIGNED_IDENTITY_CLIENT_ID} AZURE_KEYVAULT_URL=${AZURE_KEYVAULT_URL}. AZURE_KEYVAULT_URL Kom ihåg att miljövariabeln konsulteras på grund av de mappningsregler för miljövariabler som definieras av MicroProfile Config-specifikationen.

Hämta sedan en fullständigt kvalificerad URL för att komma åt appen med hjälp av följande kommando:

export APP_URL=https://$(az containerapp show \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name ${ACA_NAME} \
    --query properties.configuration.ingress.fqdn \
    --output tsv)

Kör slutligen följande kommandon igen för att testa exemplet som körs på Container Apps-instansen:

# 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)

Du bör se de förväntade utdata som beskrivs i kommentarerna. Om du inte ser dem kan appen fortfarande startas. Vänta en stund och försök igen.

Rensa resurser

För att undvika Azure-avgifter bör du rensa onödiga resurser. När resurserna inte längre behövs kör du följande kommandon för att rensa resurserna.

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

Nästa steg

Du kan lära dig mer från följande referenser: