Integrazione di un prodotto Marketplace AWS for Containers Anywhere con License Manager - Marketplace AWS

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Integrazione di un prodotto Marketplace AWS for Containers Anywhere con License Manager

Segui queste istruzioni per effettuare l'integrazione AWS License Manager con un prodotto Marketplace AWS for Containers Anywhere per Amazon EKS ECS Anywhere, Amazon AnywhereEC2, Amazon o un'infrastruttura locale.

Per informazioni generali sull'integrazione di License Manager con Marketplace AWS, inclusi i modelli di licenza disponibili, vederePrezzi contrattuali per i prodotti Container con AWS License Manager. Per ulteriori informazioni in merito AWS License Manager, consulta la Guida per AWS License Manager l'utente e la AWS License Managersezione del AWS CLI Command Reference.

Integrazione di un prodotto Marketplace AWS for Containers Anywhere con License Manager

Utilizza le seguenti istruzioni per integrare il tuo prodotto Marketplace AWS for Containers Anywhere con AWS License Manager.

Per integrare il prodotto Marketplace AWS for Containers Anywhere con License Manager
  1. Apri un browser Web e accedi a Portale di gestione Marketplace AWS.

  2. Crea un ID prodotto per il tuo prodotto contenitore eseguendo i seguenti passaggi. Utilizzerai questo ID nell'immagine del contenitore per i controlli della licenza in una fase successiva.

    1. Dalla barra dei menu, espandi Risorse e scegli Contenitore.

    2. Inserisci un nome rivolto ai clienti per il tuo prodotto e scegli Crea. Puoi modificare questo nome in un secondo momento.

    3. Prendi nota dell'ID del prodotto. Lo utilizzerai per creare o aggiornare i dettagli dei prezzi del prodotto.

      Suggerimento

      Se perdi l'ID del prodotto, puoi trovarlo nel menu Risorse Portale di gestione Marketplace AWS scegliendo Contenitore. La pagina Contenitori mostra un elenco dei tuoi prodotti con il prodotto associatoIDs.

  3. Scarica la versione pubblica più recente AWS SDK e installala nell'applicazione contenitore. Puoi trovare le istruzioni di installazione preferite AWS SDK in Tools to Build on AWS.

    Nota

    Per richiamare le API operazioni del License Manager da Amazon EKS Anywhere o da un cluster Kubernetes non fornito da AWS, devi utilizzare un server supportato. AWS SDK Per visualizzare un elenco di quelli supportati AWS SDKs, consulta Using a supported. AWS SDK

  4. Crea un AWS License Manager client con un provider di credenziali personalizzato in modo che possa fornire credenziali all'applicazione contenitore distribuita sia in locale che in AWS locale. Per il codice sorgente completo per un provider di credenziali personalizzatoLicenseCredentialProvider, consulta le seguenti sezioni:

    LicenseCredentialsProviderestende la catena AWS SDK di provider di credenziali predefinita per l'uso in locale aggiungendo. LicenseManagerTokenCredentialsProvider Ciò fornisce le credenziali utilizzando token di identità OIDC emessi da License Manager in ambienti locali. È necessario includere il codice sorgente di LicenseCredentialsProvider nel classpath dell'applicazione.

    Nota

    L'estensione DefaultCredentialsProvider consente alla stessa applicazione contenitore di ottenere le credenziali durante l'esecuzione in un ambiente locale AWS e durante l'esecuzione in un ambiente locale. Se l'applicazione contenitore utilizza già una catena di fornitori di credenziali personalizzata anziché quella predefinita, può anche essere estesa aggiungendola LicenseManagerTokenCredentialsProvider alla catena personalizzata.

    Il seguente frammento di codice è un esempio di creazione di un AWS License Manager client utilizzando Java.

    LicenseManagerClientBuilder clientBuilder = LicenseManagerClient.builder().credentialsProvider(LicenseCredentialsProvider.create());
  5. Chiama l'CheckoutLicenseAPIoperazione utilizzando il aws license-manager checkout-license comando contenuto in ogni immagine di contenitore a pagamento nella tua offerta di prodotti. Ciò verifica che l'acquirente sia autorizzato a utilizzare una licenza per l'applicazione. Se l'acquirente ha diritto alla richiesta, CheckoutLicense ci riesce e restituisce i diritti richiesti e i relativi valori. Se l'acquirente non ha diritto alla richiesta, CheckoutLicense genera un'eccezione.

    I seguenti parametri sono necessari per richiamare l'CheckoutLicenseAPIoperazione:

    • CheckoutType— I valori validi sono PROVISIONAL oPERPETUAL:

      • Da utilizzare PERPETUAL quando la quantità di diritti prelevati dal pool sarà esaurita.

        Esempio: l'acquirente ha il diritto di elaborare 500 GB di dati. Man mano che continuano a elaborare i dati, la quantità viene prelevata ed esaurita dal pool di 500 GB.

      • PROVISIONALUtilizzatelo per le licenze flottanti, in cui le autorizzazioni vengono estratte dal pool e restituite dopo l'uso.

        Esempio: l'utente ha diritto a 500 utenti simultanei sull'applicazione. Quando gli utenti accedono o si disconnettono, gli utenti vengono estratti o restituiti al pool di 500 utenti. Per ulteriori informazioni sui diritti di licenza fluttuanti, consulta. Diritti di licenza fluttuanti con License Manager

    • ClientToken— Un identificatore univoco con distinzione tra maiuscole e minuscole. Si consiglia di utilizzare un codice casuale UUID per ogni richiesta univoca.

    • Entitlements— Un elenco di diritti da verificare.

      • Per i diritti relativi alle funzionalità, fornite le proprietà Name and Unit come segue.

        { "Name": "<Entitlement_Name>", "Unit": "None" }
      • Per i diritti conteggiati, fornite le proprietà NameUnit, e Count come segue.

        { "Name": "<Entitlement_Name>", "Unit": "<Entitlement_Unit>", "Value": <Desired_Count> }
    • KeyFingerprint— L'impronta digitale chiave per le licenze rilasciate da è. Marketplace AWS aws:294406891311:AWS/Marketplace:issuer-fingerprint L'utilizzo di questa chiave digitale garantisce che la licenza sia rilasciata da Marketplace AWS e non da un'entità inaffidabile.

    • ProductSKU— L'ID del prodotto generato Portale di gestione Marketplace AWS nei passaggi precedenti.

    Il frammento seguente è un esempio di chiamata che utilizza l'CheckoutLicenseAPIoperazione utilizzando. AWS CLI

    aws license-manager checkout-license \ --product-sku "2205b290-19e6-4c76-9eea-377d6bf71a47" \ --checkout-type "PROVISIONAL" \ --client-token "79464194dca9429698cc774587a603a1" \ --entitlements "Name=AWS::Marketplace::Usage/Drawdown/DataConsumption, Value=10, Unit=Gigabytes" \ --key-fingerprint "aws:294406891311:AWS/Marketplace:issuer-fingerprint"
    Nota

    Per controllare le licenze, le applicazioni container richiedono l'accesso alla rete in uscita per utilizzare License Manager. Le applicazioni distribuite in locale potrebbero presentare un accesso alla rete in uscita inaffidabile o lento. Queste applicazioni devono includere tentativi adeguati quando si chiama License Manager. Per ulteriori informazioni, consulta Le migliori pratiche per l'integrazione con License Manager per le distribuzioni locali.

  6. Chiamate l'ufficio CheckoutLicense API operativo a cadenza regolare per identificare eventuali modifiche alle licenze dei clienti dovute a rinnovi, upgrade o cancellazioni effettuate il. Marketplace AWS La cadenza dipende dall'applicazione. Ti consigliamo di controllare le licenze una volta al giorno per rilevare automaticamente le modifiche senza l'intervento dell'acquirente.

    Un'applicazione distribuita in locale potrebbe avere un accesso inaffidabile alla rete in uscita per controllare le licenze con cadenza regolare. In questi casi, l'applicazione deve utilizzare licenze memorizzate nella cache per una resilienza sufficiente. Per ulteriori informazioni, consulta Le migliori pratiche per l'integrazione con License Manager per le distribuzioni locali.

  7. Dopo aver integrato la CheckoutLicense chiamata con l'applicazione contenitore, crea una nuova versione dell'immagine del contenitore Docker con le modifiche.

  8. Aggiorna la tabella Helm dell'applicazione per accettare un segreto Kubernetes come input opzionale che contiene la configurazione per accedere alle licenze tramite License Manager. APIs Il segreto di configurazione conterrà un token di identità rilasciato da License Manager e un AWS Identity and Access Management ruolo che verrà utilizzato dal provider di credenziali personalizzate descritto in precedenza per ottenere AWS le credenziali per chiamare License Manager APIs quando l'applicazione contenitore viene distribuita in locale. Inoltre, aggiungi Regione AWS come input con un valore predefinito di. us-east-1

    Gli acquirenti che implementano l'applicazione container in locale possono creare il segreto di Kubernetes attraverso l'esperienza Marketplace AWS dell'acquirente per i prodotti container. Fornisci il nome segreto di Kubernetes come input per il comando. helm install Il segreto di configurazione è configurato nel seguente formato.

    apiVersion: v1 kind: Secret metadata: name: aws-marketplace-license-config type: Opaque stringData: license_token: <token_value> // License Manager issued JWT token iam_role: <role_arn> // AWS Identity and Access Management role to assume with license token
  9. Aggiorna il modello di distribuzione dell'applicazione nel grafico Helm per le immagini dei contenitori integrate con AWS License Manager per includere quanto segue:

    • Account di servizio per pod: l'account di servizio è necessario per le distribuzioni Helm su Amazon. EKS Viene utilizzato per ottenere le autorizzazioni per chiamare le API operazioni di License Manager impostando IAM i ruoli per l'account di servizio sull'immagine del contenitore. Per ulteriori informazioni sui IAM ruoli per gli account di servizio, vedi IAMruoli per gli account di servizio.

    • Accesso alla licenza per le distribuzioni locali: il segreto di configurazione della licenza è necessario per fornire le credenziali e le autorizzazioni appropriate per chiamare le API operazioni di License Manager per le distribuzioni Helm in ambienti locali. Gli acquirenti genereranno e forniranno il segreto della licenza a Helm in base all'esperienza dell'acquirente. Marketplace AWS

    Il seguente frammento di codice è un esempio di specifica di distribuzione con l'account del servizio, la configurazione della licenza e l'image pull secret.

    apiVersion: apps/v1 kind: Deployment metadata: name: example-app spec: replicas: 1 selector: matchLabels: app: example-app template: metadata: labels: app: example-app spec: // Service account for pod serviceAccountName: {{ .Values.serviceAccountName }} containers: - name: example-app image: example-app ports: - containerPort: 8001 // Add the following conditional attributes {{ - if .Values.awsmp.licenseConfigSecretName }} //Mount the license volume to the container image volumeMounts: - name: awsmp-product-license mountPath: "/var/run/secrets/product-license" //Add following environment variable to container for credential provider env: - name: AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE value: "/var/run/secrets/product-license/license_token" - name: AWS_ROLE_ARN valueFrom: secretKeyRef: name: {{ .Values.aws.licenseConfigSecretName }} key: iam_role //Mount the license secret as a volume to the pod volumes: - name: awsmp-product-license secret: secretName: {{ .Values.aws.licenseConfigSecretName }} optional: true {{ - end }}
    Nota

    Il segreto di configurazione della licenza è facoltativo. Gli acquirenti utilizzano il valore solo per le distribuzioni locali. Per le AWS distribuzioni, le specifiche di distribuzione devono includere un account di servizio per le immagini integrate di License Manager.

  10. Verifica l'integrazione del License Manager localmente e su Amazon EKS eseguendo i passaggi nelle seguenti sezioni:

    1. Test dell'integrazione con License Manager a livello locale

    2. Test dell'integrazione di License Manager su Amazon EKS

  11. Dopo aver verificato con successo l'integrazione di License Manager AWS sia in locale che in locale, puoi creare la tua lista di prodotti container seguendo la procedura riportata di seguito. Creazione di un prodotto contenitore

Test dell'integrazione con License Manager a livello locale

Puoi utilizzare minikube o qualsiasi altra configurazione per testare l'integrazione del License Manager su qualsiasi cluster Kubernetes a livello locale. Assicurati che il cluster Kubernetes disponga dell'accesso a Internet in uscita per chiamare le operazioni di License Manager. API

Per testare localmente un'integrazione di License Manager
  1. Crea una licenza di prova in un account venditore di prova con i diritti desiderati. Per configurare una licenza di prova, vedi CreateLicensenella Guida di riferimento.AWS License Manager API In alternativa, utilizza lo script seguente per creare una licenza di prova e quindi creare una concessione di licenza a un account acquirente di prova per utilizzare la licenza. Lo script seguente utilizza le credenziali dell'account venditore di prova.

    read -p 'AWS Account for test buyer: ' TEST_BUYER_ACCOUNT_ID read -p 'License entitlements: ' ENTITLEMENTS # TEST_SELLER_ACCOUNT_ID="109876543210" # ENTITLEMENTS="{\"Name\": \"ByData\",\"MaxCount\": 1000,\"Overage\":true,\"Unit\": \"Gigabits\",\"AllowCheckIn\": true}" # Create License NOW=$(date +"%Y-%m-%dT00:00:00+00:00") PRODUCT_NAME="My awesome product" PRODUCT_SKU="c97b7825-44c4-4f42-b025-12baa4c171e0" LICENSE_BENEFICIARY=" arn:aws:iam::$TEST_BUYER_ACCOUNT_ID:root " LICENSE_ISSUER_NAME="test-seller" LICENSE_NAME="test-seller-license" CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367" CONSUMPTION_TTL=180 CONSUMPTION_RENEW_TYPE="None" HOME_REGION="us-east-1" LICENSE_ARN=$(aws license-manager create-license --license-name "$LICENSE_NAME" --product-name "$PRODUCT_NAME" --product-sku "$PRODUCT_SKU" --issuer Name="$LICENSE_ISSUER_NAME" --home-region "$HOME_REGION" --validity Begin="$NOW" --entitlements "$ENTITLEMENTS" --beneficiary "$LICENSE_BENEFICIARY" --consumption-configuration RenewType="$CONSUMPTION_RENEW_TYPE",ProvisionalConfiguration={MaxTimeToLiveInMinutes=$CONSUMPTION_TTL} --client-token "$CLIENT_TOKEN" | jq -r ".LicenseArn" ) echo "License arn: $LICENSE_ARN" # Create Grant GRANT_TOKEN="e9a14140-4fca-4219-8230-57511a6ea6" GRANT_NAME="test-grant" GRANT_ARN=$(aws license-manager create-grant --grant-name "$GRANT_NAME" --license-arn "$LICENSE_ARN" --principals "$LICENSE_BENEFICIARY" --home-region "$HOME_REGION" --client-token "$GRANT_TOKEN" --allowed-operations "CheckoutLicense" "CheckInLicense" "ExtendConsumptionLicense" "CreateToken" | jq -r ".GrantArn") echo "Grant arn: $GRANT_ARN"
  2. Crea un segreto Kubernetes con il token di licenza e il IAM ruolo utilizzando il formato segreto definito in precedenza. Utilizzare l'CreateTokenAPIoperazione License Manager per generare un token di licenza. Quindi, utilizza l'IAMCreateRoleAPIoperazione per creare un IAM ruolo con autorizzazioni e una politica di fiducia. Vedi l'esempio nello script seguente. Lo script seguente utilizza le credenziali dell'account acquirente di prova.

    read -p 'AWS Account for test license: ' TEST_ACCOUNT_ID read -p 'License Arn' LICENSE_ARN # Create IAM Role ROLE_NAME="AWSLicenseManagerConsumptionTestRole" ROLE_DESCRIPTION="Role to test AWS License Manager integration on-prem" ROLE_POLICY_ARN="arn:aws:iam::aws:policy/service-role/AWSLicenseManagerConsumptionPolicy" ROLE_TRUST_POLICY="{\"Version\": \"2012-10-17\",\"Statement\": [{ \"Effect\":\"Allow\", \"Principal\": { \"Federated\": \"openid-license-manager.amazonaws.com\" }, \"Action\": \"sts:AssumeRoleWithWebIdentity\",\"Condition\": { \"ForAnyValue:StringLike\": { \"openid-license-manager.amazonaws.com:amr\": \"aws:license-manager:token-issuer-account-id:${TEST_ACCOUNT_ID}\" }}}]}" ROLE_SESSION_DURATION=3600 ROLE_ARN=$(aws iam create-role --role-name "$ROLE_NAME" --description "$ROLE_DESCRIPTION" --assume-role-policy-document "$ROLE_TRUST_POLICY" --max-session-duration $ROLE_SESSION_DURATION | jq ".Role" | jq -r ".Arn") aws iam attach-role-policy --role-name "$ROLE_NAME" --policy-arn "$ROLE_POLICY_ARN" echo "Role arn: $ROLE_ARN" # Create Token CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367" TOKEN=$(aws license-manager create-token --license-arn $LICENSE_ARN --role-arns $ROLE_ARN --client-token $CLIENT_TOKEN | jq '.Token') echo "License access token: $TOKEN"c
  3. Configura qualsiasi cluster Kubernetes ospitato all'esterno. AWS Usalo per verificare che le applicazioni container possano connettersi AWS License Manager API da ambienti diversi AWS e che il provider di credenziali personalizzate sia ben integrato nell'applicazione.

  4. Distribuisci il token di licenza e il IAM ruolo generati in precedenza nel cluster Kubernetes locale.

    kubectl create secret generic "awsmp-license-access-config" \ --from-literal=license_token=${TOKEN} \ --from-literal=iam_role=${ROLE_ARN}
  5. Implementa l'applicazione tramite Helm inserendo il nome segreto e verifica che l'applicazione possa richiamare le API operazioni del License Manager per eseguire i controlli di autorizzazione. Per le modifiche a Helm e alle specifiche di distribuzione, consulta la Fase 9 del Integrazione di un prodotto Marketplace AWS for Containers Anywhere con License Manager

Test dell'integrazione di License Manager su Amazon EKS

Puoi anche testare l'integrazione del License Manager su AmazonEKS. Verifica che l'applicazione possa richiamare le API operazioni di License Manager senza il segreto di configurazione della licenza. Assicuratevi inoltre che l'account di servizio possa essere utilizzato per configurare IAM i ruoli per gli account di servizio (IRSA) e fornire le credenziali pertinenti all'applicazione.

Per testare un'integrazione di License Manager su Amazon EKS
  1. Crea una licenza di prova in un account venditore di prova con i diritti desiderati. Consulta il CreateLicense APIriferimento per configurare la tua licenza di prova o usa lo script seguente per crearne una e concedere la licenza a un account acquirente di prova per utilizzare la licenza. Lo script seguente utilizza le credenziali dell'account venditore di prova.

    read -p 'AWS Account for test buyer: ' TEST_BUYER_ACCOUNT_ID read -p 'License entitlements: ' ENTITLEMENTS # TEST_SELLER_ACCOUNT_ID="109876543210" # ENTITLEMENTS="{\"Name\": \"ByData\",\"MaxCount\": 1000,\"Overage\": true,\"Unit\": \"Gigabits\",\"AllowCheckIn\": true}" # Create License NOW=$(date +"%Y-%m-%dT00:00:00+00:00") PRODUCT_NAME="My awesome product" PRODUCT_SKU="c97b7825-44c4-4f42-b025-12baa4c171e0" LICENSE_BENEFICIARY=" arn:aws:iam::$TEST_BUYER_ACCOUNT_ID:root " LICENSE_ISSUER_NAME="test-seller" LICENSE_NAME="test-seller-license" CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367" CONSUMPTION_TTL=180 CONSUMPTION_RENEW_TYPE="None" HOME_REGION="us-east-1" LICENSE_ARN=$(aws license-manager create-license --license-name "$LICENSE_NAME" --product-name "$PRODUCT_NAME" --product-sku "$PRODUCT_SKU" --issuer Name="$LICENSE_ISSUER_NAME" --home-region "$HOME_REGION" --validity Begin="$NOW" --entitlements "$ENTITLEMENTS" --beneficiary "$LICENSE_BENEFICIARY" --consumption-configuration RenewType="$CONSUMPTION_RENEW_TYPE",ProvisionalConfiguration={MaxTimeToLiveInMinutes=$CONSUMPTION_TTL} --client-token "$CLIENT_TOKEN" | jq -r ".LicenseArn" ) echo "License arn: $LICENSE_ARN" # Create Grant GRANT_TOKEN="e9a14140-4fca-4219-8230-57511a6ea6" GRANT_NAME="test-grant" GRANT_ARN=$(aws license-manager create-grant --grant-name "$GRANT_NAME" --license-arn "$LICENSE_ARN" --principals "$LICENSE_BENEFICIARY" --home-region "$HOME_REGION" --client-token "$GRANT_TOKEN" --allowed-operations "CheckoutLicense" "CheckInLicense" "ExtendConsumptionLicense" "CreateToken" | jq -r ".GrantArn") echo "Grant arn: $GRANT_ARN"
  2. Crea un EKS cluster Amazon di prova delle configurazioni desiderate o esegui i seguenti comandi per utilizzare una configurazione predefinita.

    aws ec2 create-key-pair --region us-west-2 --key-name eks-key-pair
    eksctl create cluster \ --name awsmp-eks-test-example \ --region us-west-2 \ --with-oidc \ --ssh-access \ --ssh-public-key eks-key-pair
  3. Crea un account di servizio per un cluster esistente e associalo a un IAM ruolo. Il comando seguente crea un IAM ruolo conAWSLicenseManagerConsumptionPolicy. Quindi, il comando lo collega all'account di test_sa servizio del EKS cluster Amazon in cui devono essere distribuite le immagini integrate di License Manager. Di conseguenza, l'account del servizio può ottenere le credenziali appropriate per chiamare le API operazioni di License Manager.

    eksctl create iamserviceaccount \ --name test_sa \ --namespace test_namespace \ --cluster awsmp-eks-test-example \ --attach-policy-arn "arn:aws:iam::aws:policy/service-role/AWSLicenseManagerConsumptionPolicy" \ --approve \ --override-existing-serviceaccounts
  4. Distribuisci l'applicazione tramite Helm nell'account di servizio a cui il IAM ruolo è associato dal comando precedente. Verificare che l'applicazione sia in grado di richiamare API le operazioni di License Manager per eseguire i controlli delle autorizzazioni.

Diritti di licenza fluttuanti con License Manager

Con le licenze fluttuanti, quando gli utenti accedono all'applicazione, viene estratta una licenza dal pool di licenze disponibili. Quando gli utenti si disconnettono, le licenze vengono aggiunte nuovamente al pool di licenze disponibili.

Per le licenze flottanti, l'applicazione utilizza l'CheckoutLicenseAPIoperazione per estrarre le autorizzazioni dal pool di autorizzazioni quando la risorsa viene utilizzata. La risposta dell'CheckoutLicenseAPIoperazione include un token di utilizzo della licenza che è un identificatore univoco per il checkout. Il token di utilizzo delle licenze può eseguire azioni aggiuntive sui diritti di accesso sottoposti a check-out, ad esempio archiviarli nuovamente nel pool di licenze o estendere il check-out.

Quando la risorsa non è più in uso, l'applicazione utilizza l'CheckInLicenseAPIoperazione per ricontrollare l'autorizzazione nel pool.

aws license-manager check-in-license \ --license-consumption-token "f1603b3c1f574b7284db84a9e771ee12"

Se il ripristino di una licenza nel pool non riesce, ad esempio, se l'applicazione si blocca durante l'operazione, l'autorizzazione viene ricontrollata automaticamente nel pool dopo 60 minuti. Per questo motivo, se la risorsa viene utilizzata per più di 60 minuti, è consigliabile mantenere l'autorizzazione selezionata dal pool. A tale scopo, utilizzate l'ExtendLicenseConsumptionAPIoperazione fintanto che la risorsa viene utilizzata.

aws license-manager extend-license-consumption \ --license-consumption-token "f1603b3c1f574b7284db84a9e771ee12"

Le migliori pratiche per l'integrazione con License Manager per le distribuzioni locali

Le implementazioni di applicazioni container in un ambiente locale potrebbero comportare un accesso inaffidabile alla rete in uscita. Utilizza le seguenti best practice per aggiungere resilienza ed evitare interruzioni del servizio agli acquirenti a causa di potenziali problemi causati da una scarsa connettività Internet:

  • Riprova adeguata: problemi transitori di rete possono impedire la connessione dell'applicazione. AWS License Manager Implementa nuovi tentativi per un massimo di 30 minuti, con backoff esponenziale. Questo può aiutare a evitare interruzioni a breve termine o problemi di rete.

  • Evita i limiti rigidi: le applicazioni distribuite in cluster connessi possono controllare regolarmente le licenze per identificare eventuali modifiche dovute ad aggiornamenti o rinnovi. Con un accesso in uscita inaffidabile, l'applicazione potrebbe non essere in grado di identificare tali modifiche. Ove possibile, l'applicazione dovrebbe evitare interruzioni del servizio agli acquirenti dovute all'impossibilità di controllare le licenze tramite License Manager. Le applicazioni possono ricorrere a una versione di prova gratuita o open source alla scadenza della licenza e non possono verificare se una licenza è valida.

  • Informa i clienti: quando si utilizza una licenza memorizzata nella cache, eventuali modifiche alla licenza (inclusi rinnovi o aggiornamenti) non si riflettono automaticamente sul carico di lavoro in esecuzione. Informa i tuoi clienti (che devono consentire nuovamente e temporaneamente l'accesso in uscita all'applicazione) in modo che l'applicazione possa aggiornare la licenza memorizzata nella cache. Ad esempio, informate i clienti tramite l'applicazione stessa o tramite la relativa documentazione. Analogamente, quando ricorri a una serie inferiore di funzionalità, comunica ai clienti che i loro diritti sono esauriti o che la licenza è scaduta. Quindi, possono scegliere di eseguire l'aggiornamento o il rinnovo.

LicenseManagerCredentialsProvider- Implementazione Java

LicenseCredentialsProviderestende la catena AWS SDK di provider di credenziali predefinita per l'uso locale aggiungendo. LicenseManagerTokenCredentialsProvider

LicenseCredentialsProvider

package com.amazon.awsmp.license; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain; import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; import software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider; import software.amazon.awssdk.utils.SdkAutoCloseable; public class LicenseCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable { private static final LicenseCredentialsProvider CREDENTIALS_PROVIDER = new LicenseCredentialsProvider(); private final LazyAwsCredentialsProvider providerChain; private LicenseCredentialsProvider() { this.providerChain = createChain(); } public static LicenseCredentialsProvider create() { return CREDENTIALS_PROVIDER; } @Override public AwsCredentials resolveCredentials() { return this.providerChain.resolveCredentials(); } @Override public void close() { this.providerChain.close(); } private LazyAwsCredentialsProvider createChain() { return LazyAwsCredentialsProvider.create(() -> { AwsCredentialsProvider[] credentialsProviders = new AwsCredentialsProvider[]{ DefaultCredentialsProvider.create(), LicenseManagerTokenCredentialsProvider.create()}; return AwsCredentialsProviderChain.builder().reuseLastProviderEnabled(true) .credentialsProviders(credentialsProviders).build(); }); } }

LicenseManagerTokenCredentialsProvider

LicenseManagerTokenCredentialsProviderfornisce le credenziali utilizzando token di identità OIDC emessi da License Manager in ambienti locali. È necessario includere il codice sorgente di LicenseCredentialsProvider nel percorso di classe dell'applicazione.

package com.amazon.awsmp.license; import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.core.SdkSystemSetting; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; import software.amazon.awssdk.core.retry.RetryPolicyContext; import software.amazon.awssdk.core.retry.conditions.OrRetryCondition; import software.amazon.awssdk.core.retry.conditions.RetryCondition; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain; import software.amazon.awssdk.services.licensemanager.LicenseManagerClient; import software.amazon.awssdk.services.licensemanager.model.GetAccessTokenRequest; import software.amazon.awssdk.services.licensemanager.model.GetAccessTokenResponse; import software.amazon.awssdk.services.sts.StsClient; import software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithWebIdentityCredentialsProvider; import software.amazon.awssdk.services.sts.model.AssumeRoleWithWebIdentityRequest; import software.amazon.awssdk.services.sts.model.IdpCommunicationErrorException; import software.amazon.awssdk.utils.IoUtils; import software.amazon.awssdk.utils.SdkAutoCloseable; import software.amazon.awssdk.utils.StringUtils; import software.amazon.awssdk.utils.SystemSetting; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; import java.util.function.Supplier; public class LicenseManagerTokenCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable { private final StsAssumeRoleWithWebIdentityCredentialsProvider credentialsProvider; private final RuntimeException loadException; private Path licenseAccessTokenFile; private String roleArn; private String roleSessionName; private StsClient stsClient; private LicenseManagerClient lmClient; public static LicenseManagerTokenCredentialsProvider create() { return new Builder().build(); } @Override public AwsCredentials resolveCredentials() { if (this.loadException != null) { throw this.loadException; } return this.credentialsProvider.resolveCredentials(); } @Override public void close() { IoUtils.closeQuietly(this.credentialsProvider, null); IoUtils.closeQuietly(this.stsClient, null); IoUtils.closeIfCloseable(this.lmClient, null); } private LicenseManagerTokenCredentialsProvider(Builder builder) { StsAssumeRoleWithWebIdentityCredentialsProvider credentialsProvider = null; RuntimeException loadException = null; try { this.licenseAccessTokenFile = Paths.get(StringUtils.trim(LicenseSystemSetting.AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE.getStringValueOrThrow())); this.roleArn = SdkSystemSetting.AWS_ROLE_ARN.getStringValueOrThrow(); this.roleSessionName = SdkSystemSetting.AWS_ROLE_SESSION_NAME.getStringValue().orElse("aws-sdk-java-" + System.currentTimeMillis()); this.stsClient = builder.stsClient != null ? builder.stsClient : StsClientFactory.create(); this.lmClient = builder.lmClient != null ? builder.lmClient : LicenseManagerClientFactory.create(); AssumeRoleWithWebIdentityRequest request = AssumeRoleWithWebIdentityRequest.builder() .roleArn(this.roleArn).roleSessionName(this.roleSessionName).build(); Supplier<AssumeRoleWithWebIdentityRequest> supplier = new AssumeRoleRequestSupplier(request, this.licenseAccessTokenFile, this.lmClient); credentialsProvider = StsAssumeRoleWithWebIdentityCredentialsProvider.builder() .stsClient(this.stsClient).refreshRequest(supplier).build(); } catch (RuntimeException ex) { loadException = ex; } this.credentialsProvider = credentialsProvider; this.loadException = loadException; } public static final class Builder { private Path licenseAccessTokenFile; private String roleArn; private String roleSessionName; private StsClient stsClient; private LicenseManagerClient lmClient; public LicenseManagerTokenCredentialsProvider build() { return new LicenseManagerTokenCredentialsProvider(this); } public LicenseManagerTokenCredentialsProvider.Builder licenseAccessTokenFile(Path licenseAccessTokenFile) { this.licenseAccessTokenFile = licenseAccessTokenFile; return this; } public LicenseManagerTokenCredentialsProvider.Builder roleArn(String roleArn) { this.roleArn = roleArn; return this; } public LicenseManagerTokenCredentialsProvider.Builder roleSessionName(String roleSessionName) { this.roleSessionName = roleSessionName; return this; } public LicenseManagerTokenCredentialsProvider.Builder stsClient(StsClient stsClient) { this.stsClient = stsClient; return this; } public LicenseManagerTokenCredentialsProvider.Builder lmClient(LicenseManagerClient lmClient) { this.lmClient = lmClient; return this; } } private static final class AssumeRoleRequestSupplier implements Supplier { private final LicenseManagerClient lmClient; private final AssumeRoleWithWebIdentityRequest request; private final Path webIdentityRefreshTokenFile; AssumeRoleRequestSupplier(final AssumeRoleWithWebIdentityRequest request, final Path webIdentityRefreshTokenFile, final LicenseManagerClient lmClient) { this.lmClient = lmClient; this.request = request; this.webIdentityRefreshTokenFile = webIdentityRefreshTokenFile; } public AssumeRoleWithWebIdentityRequest get() { return this.request.toBuilder() .webIdentityToken(getIdentityToken()) .build(); } private String getIdentityToken() { return refreshIdToken(readRefreshToken(this.webIdentityRefreshTokenFile)); } private String readRefreshToken(Path file) { try (InputStream webIdentityRefreshTokenStream = Files.newInputStream(file)) { return IoUtils.toUtf8String(webIdentityRefreshTokenStream); } catch (IOException e) { throw new UncheckedIOException(e); } } private String refreshIdToken(String licenseRefreshToken) { final GetAccessTokenRequest request = GetAccessTokenRequest.builder() .token(licenseRefreshToken) .build(); GetAccessTokenResponse response = this.lmClient.getAccessToken(request); return response.accessToken(); } } private static final class LicenseManagerClientFactory { private static final Duration DEFAULT_API_TIMEOUT = Duration.ofSeconds(30); private static final Duration DEFAULT_API_ATTEMPT_TIMEOUT = Duration.ofSeconds(10); public static LicenseManagerClient create() { return getLicenseManagerClient(); } private static LicenseManagerClient getLicenseManagerClient() { ClientOverrideConfiguration configuration = ClientOverrideConfiguration.builder() .apiCallTimeout(DEFAULT_API_TIMEOUT) .apiCallAttemptTimeout(DEFAULT_API_ATTEMPT_TIMEOUT) .build(); LicenseManagerClient client = LicenseManagerClient.builder() .region(configureLicenseManagerRegion()) .credentialsProvider(AnonymousCredentialsProvider.create()) .overrideConfiguration(configuration).build(); return client; } private static Region configureLicenseManagerRegion() { Region defaultRegion = Region.US_EAST_1; Region region; try { region = (new DefaultAwsRegionProviderChain()).getRegion(); } catch (RuntimeException ex) { region = defaultRegion; } return region; } } private static final class StsClientFactory { private static final Duration DEFAULT_API_TIMEOUT = Duration.ofSeconds(30); private static final Duration DEFAULT_API_ATTEMPT_TIMEOUT = Duration.ofSeconds(10); public static StsClient create() { return getStsClient(); } private static StsClient getStsClient() { OrRetryCondition retryCondition = OrRetryCondition.create(new StsRetryCondition(), RetryCondition.defaultRetryCondition()); ClientOverrideConfiguration configuration = ClientOverrideConfiguration.builder() .apiCallTimeout(DEFAULT_API_TIMEOUT) .apiCallAttemptTimeout(DEFAULT_API_ATTEMPT_TIMEOUT) .retryPolicy(r -> r.retryCondition(retryCondition)) .build(); return StsClient.builder() .region(configureStsRegion()) .credentialsProvider(AnonymousCredentialsProvider.create()) .overrideConfiguration(configuration).build(); } private static Region configureStsRegion() { Region defaultRegion = Region.US_EAST_1; Region stsRegion; try { stsRegion = (new DefaultAwsRegionProviderChain()).getRegion(); } catch (RuntimeException ex) { stsRegion = defaultRegion; } return stsRegion; } private static final class StsRetryCondition implements RetryCondition { public boolean shouldRetry(RetryPolicyContext context) { return context.exception() instanceof IdpCommunicationErrorException; } } } private enum LicenseSystemSetting implements SystemSetting { AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE("aws.webIdentityRefreshTokenFile"); private String systemProperty; private String defaultValue = null; LicenseSystemSetting(String systemProperty) { this.systemProperty = systemProperty; } @Override public String property() { return this.systemProperty; } @Override public String environmentVariable() { return this.name(); } @Override public String defaultValue() { return this.defaultValue; } } }

LicenseManagerCredentialsProvider- implementazione Golang

LicenseCredentialsProvider

LicenseCredentialsProviderestende la catena AWS SDK di provider di credenziali predefinita per l'uso locale aggiungendo. LicenseManagerTokenCredentialsProvider

package lib import ( "context" "fmt" "sync" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" ) // LicenseCredentialsProvider is the custom credential provider that can retrieve valid temporary aws credentials type LicenseCredentialsProvider struct { fallBackProvider aws.CredentialsProvider mux sync.RWMutex licenseCredentials aws.Credentials err error } // NewLicenseCredentialsProvider method will create a LicenseCredentialProvider Object which contains valid temporary aws credentials func NewLicenseCredentialsProvider() (*LicenseCredentialsProvider, error) { licenseCredentialProvider := &LicenseCredentialsProvider{} fallBackProvider, err := createCredentialProvider() if err != nil { return licenseCredentialProvider, fmt.Errorf("failed to create LicenseCredentialsProvider, %w", err) } licenseCredentialProvider.fallBackProvider = fallBackProvider return licenseCredentialProvider, nil } // Retrieve method will retrieve temporary aws credentials from the credential provider func (l *LicenseCredentialsProvider) Retrieve(ctx context.Context) (aws.Credentials, error) { l.mux.RLock() defer l.mux.RUnlock() l.licenseCredentials, l.err = l.fallBackProvider.Retrieve(ctx) return l.licenseCredentials, l.err } func createCredentialProvider() (aws.CredentialsProvider, error) { // LoadDefaultConfig will examine all "default" credential providers ctx := context.TODO() cfg, err := config.LoadDefaultConfig(ctx) if err != nil { return nil, fmt.Errorf("failed to create FallBackProvider, %w", err) } var useFallbackProvider bool if cfg.Credentials != nil { if _, err := cfg.Credentials.Retrieve(ctx); err != nil { // If the "default" credentials provider cannot retrieve credentials, enable fallback to customCredentialsProvider. useFallbackProvider = true } } else { useFallbackProvider = true } if useFallbackProvider { customProvider, err := newLicenseManagerTokenCredentialsProvider() if err != nil { return cfg.Credentials, fmt.Errorf("failed to create fallBackProvider, %w", err) } // wrap up customProvider with CredentialsCache to enable caching cfg.Credentials = aws.NewCredentialsCache(customProvider) } return cfg.Credentials, nil }

LicenseManagerTokenCredentialsProvider

LicenseManagerTokenCredentialsProviderfornisce le credenziali utilizzando token di identità OIDC emessi da License Manager in ambienti locali. È necessario includere il codice sorgente di LicenseCredentialsProvider nel percorso di classe dell'applicazione.

package lib import ( "context" "fmt" "io/ioutil" "os" "sync" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/sts" ) const awsRefreshTokenFilePathEnvVar = "AWS_LICENSE_ACCESS_FILE" // licenseManagerTokenCredentialsProvider defines and contains StsAssumeRoleWithWebIdentityProvider type licenseManagerTokenCredentialsProvider struct { stsCredentialProvider *stsAssumeRoleWithWebIdentityProvider mux sync.RWMutex licenseCredentials aws.Credentials err error } // Retrieve method will retrieve credentials from credential provider. // Make this method public to make this provider satisfies CredentialProvider interface func (a *licenseManagerTokenCredentialsProvider) Retrieve(ctx context.Context) (aws.Credentials, error) { a.mux.RLock() defer a.mux.RUnlock() a.licenseCredentials, a.err = a.stsCredentialProvider.Retrieve(ctx) return a.licenseCredentials, a.err } // newLicenseManagerTokenCredentialsProvider will create and return a LicenseManagerTokenCredentialsProvider Object which wraps up stsAssumeRoleWithWebIdentityProvider func newLicenseManagerTokenCredentialsProvider() (*licenseManagerTokenCredentialsProvider, error) { // 1. Retrieve variables From yaml environment envConfig, err := config.NewEnvConfig() if err != nil { return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err) } roleArn := envConfig.RoleARN var roleSessionName string if envConfig.RoleSessionName == "" { roleSessionName = fmt.Sprintf("aws-sdk-go-v2-%v", time.Now().UnixNano()) } else { roleSessionName = envConfig.RoleSessionName } tokenFilePath := os.Getenv(awsRefreshTokenFilePathEnvVar) b, err := ioutil.ReadFile(tokenFilePath) if err != nil { return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err) } refreshToken := aws.String(string(b)) // 2. Create stsClient cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err) } stsClient := sts.NewFromConfig(cfg, func(o *sts.Options) { o.Region = configureStsClientRegion(cfg.Region) o.Credentials = aws.AnonymousCredentials{} }) // 3. Configure StsAssumeRoleWithWebIdentityProvider stsCredentialProvider := newStsAssumeRoleWithWebIdentityProvider(stsClient, roleArn, roleSessionName, refreshToken) // 4. Build and return return &licenseManagerTokenCredentialsProvider{ stsCredentialProvider: stsCredentialProvider, }, nil } func configureStsClientRegion(configRegion string) string { defaultRegion := "us-east-1" if configRegion == "" { return defaultRegion } else { return configRegion } }