およびとの統合AWS MarketplaceLicense Manager 付きコンテナエニウェア製品 - AWS Marketplace

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

およびとの統合AWS MarketplaceLicense Manager 付きコンテナエニウェア製品

次の手順に従ってAWS License ManagerとAWS MarketplaceAmazon EKS Anywhere、Amazon ECS Anywhere、Amazon EC2、またはオンプレミスインフラストラクチャ用のコンテナ・エニウェア製品。

とのLicense Manager の統合についてはAWS Marketplace、使用可能なライセンスモデルも含めて、を参照してください。コンテナ製品の契約価格AWS License Manager。の詳細AWS License Manager「」を参照してくださいAWS License ManagerユーザーガイドAWS License Managerの セクションAWS CLIコマンドリファレンス

およびとの統合AWS MarketplaceLicense Manager 付きコンテナエニウェア製品

次の手順に従ってAWS Marketplaceコンテナ用エニウェア製品AWS License Manager。

IntegratingAWS MarketplaceLicense Manager 付きコンテナエニウェア製品

  1. Web ブラウザを開き、AWS Marketplace 管理ポータル にサインインします。

  2. 次の手順を実行して、コンテナ製品の製品 ID を作成します。この ID は、後の手順でライセンスチェックのためにコンテナーイメージに使用します。

    1. メニューバーから [Assets (アセット)] を展開し、[コンテナ] を選択します。

    2. 商品に購入者向けの名前を入力し、作成。この名前は後で変更できます。

    3. を書き留めますProduct ID。これは、製品価格の詳細を作成または更新するときに使用します。

      ヒント

      プロダクト ID を紛失した場合は、AWS Marketplace 管理ポータル選択してコンテナからのアセットメニュー。-コンテナページには、製品とその関連製品 ID のリストが表示されます。

  3. 最新の公開のダウンロードAWSSDK そしてそれからstallコンテナアプリケーションに入れます。お好みのインストール手順を見つけることができますAWSでの SDKAWS で構築するツール

    注記

    Amazon EKS Anywhere またはによって提供されていない Kubernetes クラスターからLicense Manager ー API オペレーションを呼び出すにはAWSでは、サポートされるAWSSDK。サポートされるリストを表示するにはAWSSDK については、サポートされるAWSSDK

  4. を作成するAWS License Managerにデプロイされたコンテナアプリケーションに認証情報を提供できるように、カスタム認証情報プロバイダを持つクライアントAWSオンプレミスでも同様です。カスタム認証情報プロバイダーの完全なソースコードについては、LicenseCredentialProviderについては、次のセクションを参照してください。

    LicenseCredentialsProviderはを拡張しますAWSオンプレミスで使用する SDK のデフォルトの認証情報プロバイダーチェーンには、LicenseManagerTokenCredentialsProvider。これにより、オンプレミス環境で License Manager の OIDC 発行の ID トークンを使用して認証情報が提供されます。のソースコードを含める必要がありますLicenseCredentialsProviderアプリケーションのクラスパスにあります。

    注記

    の拡張DefaultCredentialsProvider同じコンテナアプリケーションが上で実行されているときに認証情報を取得することを許可しますAWSオンプレミス環境で稼働している場合です。コンテナアプリケーションがデフォルトではなくカスタム認証情報プロバイダーチェーンをすでに使用している場合は、LicenseManagerTokenCredentialsProviderカスタムチェーンに。

    次のコードスニペットは、AWS License ManagerJava を使用するクライアント。

    LicenseManagerClientBuilder clientBuilder = LicenseManagerClient.builder().credentialsProvider(LicenseCredentialsProvider.create());
  5. をを呼び出しますCheckoutLicenseを使用した API オペレーションaws license-manager checkout-license製品オファリング内の各有料コンテナイメージからコマンドを実行します。これにより、購入者があなたの申請にライセンスを使用する権利があるかどうかがチェックされます。購入者が申請を受ける資格がある場合、CheckoutLicenseは成功し、要求されたエンタイトルメントとその値を返します。購入者が申請を受ける資格がない場合、CheckoutLicenseは例外をスローします。

    を呼び出すときは、次のパラメータが必要ですCheckoutLicenseAPI オペレーション

    • CheckoutType— 有効な値はPROVISIONALまたはPERPETUAL:

      • を使用するPERPETUALチェックアウトされたエンタイトルメントの数がプールから使い果たされるとき。

        例: 購入者は500GBのデータを処理する権利があります。彼らがデータを処理し続けると、量は引き出され、500 GBのプールから使い果たされます。

      • を使用するPROVISIONALフローティングライセンスエンタイトルメントで、エンタイトルメントがプールからチェックアウトされ、使用後に返却されます。

        例: ユーザーは、アプリケーション上で500人の同時ユーザーを受ける権利があります。ユーザーがログインまたはログアウトすると、ユーザーは500人のユーザーのプールに引き込まれるか、戻されます。フローティングライセンスエンタイトルメントの詳細については、「」を参照してください。License Manager を使用したフローティングライセンス資格

    • ClientToken— 大文字と小文字を区別。一意のリクエストごとにランダムな UUID を使用することをお勧めします。

    • Entitlements— チェックアウトするエンタイトルメントのリスト。

      • 機能エンタイトルメントについては、NameそしてUnitプロパティは以下の通りです。

        { "Name": "<Entitlement_Name>", "Unit": "None" }
      • カウントされたエンタイトルメントについては、Name,Unit, およびCountプロパティは以下の通りです。

        { "Name": "<Entitlement_Name>", "Unit": "<Entitlement_Unit>", "Value": <Desired_Count> }
    • KeyFingerprint— によって発行されたライセンスのキーフィンガープリントAWS Marketplaceですaws:294406891311:AWS/Marketplace:issuer-fingerprint。このキーフィンガープリントを使用すると、ライセンスが発行されたことが保証されますAWS Marketplace信頼できない実体によるものではありません。

    • ProductSKU— に生成された製品IDAWS Marketplace 管理ポータル前のステップで。

    以下のスニペットは、を使用したの呼び出しの例ですCheckoutLicenseを使用した API オペレーション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"
    注記

    ライセンスを確認するには、コンテナアプリケーションで License Manager を使用するにはアウトバウンドネットワークアクセスが必要です。オンプレミスにデプロイされたアプリケーションでは、アウトバウンドネットワークアクセスが信頼できないか、低速になる可能性があります。これらのアプリケーションには、License Manager を呼び出すときに適切な再試行を含める必要があります。詳細については、「オンプレミス展開で License Manager と統合するためのベストプラクティス」を参照してください。

  6. をを呼び出しますCheckoutLicenseの更新、アップグレード、またはキャンセルによるお客様のライセンスの変更を特定するための定期的なAPIオペレーションAWS Marketplace。ケイデンスはアプリケーションによって異なります。購入者の介入なしに変更を自動的に受け取るには、1日に1回ライセンスを確認することをお勧めします。

    オンプレミスにデプロイされたアプリケーションには、定期的にライセンスをチェックするための信頼性の低い送信ネットワークアクセスがある可能性があります。そのような場合、アプリケーションは十分な回復力のためにキャッシュされたライセンスを使用する必要があります。詳細については、「オンプレミス展開で License Manager と統合するためのベストプラクティス」を参照してください。

  7. 統合した後CheckoutLicenseコンテナアプリケーションでを呼び出し、変更を加えた新しいバージョンの Docker コンテナイメージをビルドします。

  8. License Manager API を使用してライセンスにアクセスするための設定を含むオプションの入力として Kubernetes シークレットを受け入れるように、アプリケーションの Helm チャートを更新します。設定シークレットには、License Manager によって発行された ID トークンとAWS Identity and Access Managementロールは、前に説明したカスタム認証情報プロバイダが取得するために使いますAWSコンテナアプリケーションがオンプレミスにデプロイされている場合に License Manager API を呼び出すための認証情報。また、AWS リージョンデフォルト値がの入力としてus-east-1

    コンテナアプリケーションをオンプレミスでデプロイする購入者は、AWS Marketplaceコンテナ製品の購入者体験。Kubernetes シークレット名をhelm installコマンド。設定シークレットは次の形式で構成されます。

    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. と統合されているコンテナイメージの Helm チャートのアプリケーションデプロイメントテンプレートを更新します。AWS License Managerには以下が含まれます。

    • ポッドのサービスアカウント — サービスアカウントは、Amazon EKS での Helm デプロイに必要です。コンテナイメージのサービスアカウントの IAM ロールを設定して、License Manager API オペレーションを呼び出す権限を取得するために使用されます。サービスアカウントの IAM ロールの詳細については、「」を参照してください。サービスアカウントの IAM ロール

    • オンプレミス展開のライセンスアクセス — ライセンス設定シークレットは、オンプレミス環境の Helm デプロイの License Manager API 操作を呼び出すための認証情報と適切な権限を提供するために必要です。購入者は、ライセンスシークレットを生成して Helm に提供するAWS Marketplace購入者エクスペリエンス

    次のコードスニペットは、サービスアカウント、ライセンス構成、およびイメージプルシークレットを含むサンプルデプロイメント仕様です。

    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 }}
    注記

    ライセンス設定シークレットはオプションです。購入者はオンプレミス展開にのみこの値を使用します。を使用する場合AWS展開環境では、展開仕様に License Manager 統合イメージのサービスアカウントを含める必要があります。

  10. 以下のセクションの手順を実行して、License Manager 統合をローカルおよび Amazon EKS でテストします。

    1. ライセンスマネージャー統合をローカル

    2. Amazon EKS でのLicense Manager 統合

  11. LLicense Manager の統合を正常に確認したらAWSおよびオンプレミスでは、「」の手順に従って、コンテナ製品リストを作成できます。コンテナ製品の作成

ライセンスマネージャー統合をローカル

minikube やその他の設定を使用して、ローカルで任意の Kubernetes クラスターで License Manager の統合をテストできます。Kubernetes クラスタに、License Manager API オペレーションを呼び出すためのアウトバウンドインターネットアクセスがあることを確認してください。

License Manager 統合をローカルでテストするには

  1. テスト用出品用アカウントで、希望するエンタイトルメントを持つテストライセンスを作成します。テストライセンスを設定するには、を参照してください。CreateLicenseAWS License ManagerAPI リファレンス。または、次のスクリプトを使用してテストライセンスを作成し、テスト購入者アカウントにライセンス付与を作成してライセンスを使用します。次のスクリプトでは、テスト用の出品用アカウント認証情報を使用します。

    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. 前に定義したシークレット形式を使用して、ライセンストークンと IAM ロールで Kubernetes シークレットを作成します。License ManagerCreateTokenライセンストークンを生成する API オペレーション。次に、IAM を使用しますCreateRoleアクセス権限と信頼ポリシーを持つ IAM ロールを作成する API オペレーション。次のスクリプトの例を参照してください。次のスクリプトは、テスト購入者アカウントの認証情報を使用します。

    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. 外部でホストされている Kubernetes クラスターをセットアップするAWS。これを使用して、コンテナアプリケーションがAWS License Manager以外の環境からの APIAWSまた、カスタム資格情報プロバイダーがアプリケーションにうまく統合されていること。

  4. 以前に生成したライセンストークンと IAM ロールをローカルの Kubernetes クラスターにデプロイします。

    kubectl create secret generic "awsmp-license-access-config" \ --from-literal=license_token=${TOKEN} \ --from-literal=iam_role=${ROLE_ARN}
  5. シークレット名を入力として Helm 経由でアプリケーションをデプロイし、アプリケーションが License Manager API オペレーションを呼び出してエンタイトルメントチェックを実行できることを確認します。Helm とデプロイメント仕様の変更については、のステップ 9 を参照してください。およびとの統合AWS MarketplaceLicense Manager 付きコンテナエニウェア製品

Amazon EKS でのLicense Manager 統合

Amazon EKS でLicense Manager 統合をテストすることもできます。アプリケーションが、ライセンス設定シークレットなしで License Manager API 操作を呼び出すことができることをテストします。また、サービスアカウントを使用してサービスアカウントの IAM ロール (IRSA) を設定し、関連する認証情報をアプリケーションに提供できることを確認します。

Amazon EKS でLicense Manager 統合をテストするには

  1. テスト用出品用アカウントで、希望するエンタイトルメントを持つテストライセンスを作成します。「」を参照してください。CreateLicense API リファレンスをクリックしてテストライセンスを設定するか、次のスクリプトを使用してライセンスを作成し、テスト購入者アカウントにライセンス付与を作成してライセンスを消費します。次のスクリプトでは、テスト用の出品用アカウント認証情報を使用します。

    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. 目的の設定のテスト Amazon EKS クラスターを作成するか、次のコマンドを実行してデフォルト設定を使用します。

    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. 既存のクラスターのサービスアカウントを作成し、それを IAM ロールに関連付けます。次のコマンドは、を使用した IAM ロールを作成しますAWSLicenseManagerConsumptionPolicy。次に、コマンドはそれをtest_saLicense Manager 統合イメージをデプロイする必要がある Amazon EKS クラスターのサービスアカウント。その結果、サービスアカウントは License Manager API 操作を呼び出すための適切な認証情報を取得できます。

    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. 前のコマンドで IAM ロールが関連付けられているサービスアカウントで、Helm を使用してアプリケーションをデプロイします。アプリケーションが License Manager API 操作を呼び出してエンタイトルメントチェックを実行できることを確認します。

License Manager を使用したフローティングライセンス資格

フローティングライセンスでは、ユーザーがアプリケーションにログインすると、使用可能なライセンスのプールからライセンスが引き出されます。ユーザーがログアウトすると、ライセンスは使用可能なライセンスのプールに戻されます。

フローティングライセンスの場合、アプリケーションはCheckoutLicenseリソースが使用されているときにエンタイトルメントプールからエンタイトルメントをチェックアウトする API オペレーション。の応答CheckoutLicenseAPI オペレーションには、チェックアウトの一意の識別子であるライセンス消費トークンが含まれます。ライセンス消費トークンは、チェックアウトされたエンタイトルメントに対して、ライセンスプールへのチェックインやチェックアウトの延長など、追加のアクションを実行できます。

リソースが使用されなくなると、アプリケーションはCheckInLicenseエンタイトルメントをプールにチェックインする API オペレーション。

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

たとえば、操作中にアプリケーションがクラッシュした場合など、ライセンスをプールにチェックインし直すことができない場合、資格は 60 分後に自動的にプールにチェックインされます。このため、リソースが 60 分以上使用されている場合は、エンタイトルメントをプールからチェックアウトしたままにしておくことがベストプラクティスです。これを行うには、ExtendLicenseConsumptionリソースが使用されている限り、API オペレーション。

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

オンプレミス展開で License Manager と統合するためのベストプラクティス

オンプレミス環境でのコンテナアプリケーションのデプロイでは、信頼性の低いアウトバウンドネットワークアクセスが発生する可能性があります。次のベストプラクティスを使用して、回復力を高め、インターネット接続不良によって引き起こされる潜在的な問題による購入者のサービスの中断を回避します。

  • 適切な再試行— 一時的なネットワークの問題により、アプリケーションが接続できなくなる可能性がありますAWS License Manager。エクスポネンシャルパックオフを使用して、最大 30 分間の再試行を実装します。これにより、短期間の停止やネットワークの問題を回避できます。

  • ハードリミットの回— 接続されたクラスタにデプロイされたアプリケーションは、定期的にライセンスをチェックして、アップグレードまたは更新による変更を特定できます。信頼性の低いアウトバウンドアクセスでは、アプリケーションがこれらの変更を識別できない場合があります。可能な限り、LicenLicense Manager でライセンスを確認できないことによる購入者へのサービスの中断を避ける必要があります。ライセンスが期限切れになり、ライセンスが有効かどうかを確認できない場合、アプリケーションは無料トライアルまたはオープンソースエクスペリエンスにフォールバックする可能性があります。

  • 購入者への通知— キャッシュライセンスを使用する場合、ライセンスへの変更 (更新またはアップグレードを含む) は、実行中のワークロードに自動的に反映されません。アプリケーションがキャッシュされたライセンスを更新できるように、アプリケーションへのアウトバウンドアクセスを一時的に再度許可する必要があることを顧客に通知します。たとえば、アプリケーション自体またはドキュメントを通じて顧客に通知します。同様に、より低い機能セットにフォールバックするときは、エンタイトルメントが使い果たされたか、ライセンスが期限切れになったことを顧客に通知します。その後、アップグレードするか更新するかを選択できます。

LicenseManagerCredentialsProvider-Java 実装

LicenseCredentialsProviderはを拡張しますAWSオンプレミスで使用する SDK のデフォルトの認証情報プロバイダーチェーンには、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

LicenseManagerTokenCredentialsProviderは、オンプレミス環境で License Manager OIDC 発行の ID トークンを使用して認証情報を提供します。のソースコードを含める必要がありますLicenseCredentialsProviderアプリケーションのクラスパスにあります。

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-Golang実装

LicenseCredentialsProvider

LicenseCredentialsProviderはを拡張しますAWSオンプレミスで使用する SDK のデフォルトの認証情報プロバイダーチェーンには、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

LicenseManagerTokenCredentialsProviderは、オンプレミス環境で License Manager OIDC 発行の ID トークンを使用して認証情報を提供します。のソースコードを含める必要がありますLicenseCredentialsProviderアプリケーションのクラスパスにあります。

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