

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Mengintegrasikan AWS Marketplace untuk Kontainer Di Mana Saja dengan License Manager
<a name="container-anywhere-license-manager-integration"></a>

Sebagai AWS Marketplace penjual, Anda dapat berintegrasi AWS License Manager dengan produk AWS Marketplace for Containers Anywhere untuk Amazon EKS Anywhere, Amazon ECS Anywhere, Amazon EC2, atau infrastruktur lokal. Bagian berikut memberikan instruksi untuk integrasi ini.

Untuk informasi umum tentang integrasi License Manager dengan AWS Marketplace, termasuk model lisensi yang tersedia, lihat[Harga kontrak untuk produk kontainer dengan AWS License Manager](container-license-manager-integration.md). Untuk informasi selengkapnya AWS License Manager, lihat [Panduan AWS License Manager Pengguna](https://docs.aws.amazon.com/license-manager/latest/userguide/license-manager.html) dan [AWS License Manager](https://docs.aws.amazon.com/cli/latest/reference/license-manager/index.html)bagian *Referensi AWS CLI Perintah*.

**Topics**
+ [Mengintegrasikan produk AWS Marketplace for Containers Anywhere dengan License Manager](#containers-anywhere-integrate-with-LM)
+ [Menguji integrasi License Manager secara lokal](#container-testing-LM-integration-locally)
+ [Menguji integrasi License Manager di Amazon EKS](#container-testing-LM-integration-EKS)
+ [Hak lisensi mengambang dengan License Manager](#container-LM-floating-license)
+ [Praktik terbaik untuk mengintegrasikan dengan License Manager untuk penerapan lokal](#container-LM-best-practices-on-prem)
+ [`LicenseManagerCredentialsProvider`- Implementasi Java](#container-license-manager-cred-provider-java)
+ [`LicenseManagerCredentialsProvider`- `Golang` implementasi](#container-license-manager-cred-provider-golang)

## Mengintegrasikan produk AWS Marketplace for Containers Anywhere dengan License Manager
<a name="containers-anywhere-integrate-with-LM"></a>

Gunakan petunjuk berikut untuk mengintegrasikan produk AWS Marketplace for Containers Anywhere Anda AWS License Manager.

**Untuk mengintegrasikan produk Containers Anywhere Anda AWS Marketplace dengan License Manager**

1. Buka browser web dan masuk ke file [Portal Manajemen AWS Marketplace](https://aws.amazon.com/marketplace/management/).

1. Buat ID produk untuk produk kontainer Anda dengan melakukan langkah-langkah berikut. Anda akan menggunakan ID ini dalam gambar kontainer Anda untuk pemeriksaan lisensi di langkah selanjutnya.

   1. Dari bilah menu, perluas **Aset**, dan pilih **Kontainer**.

   1. **Masukkan nama yang menghadap pelanggan untuk produk Anda, dan pilih Buat.** Anda dapat mengubah nama ini nanti.

   1. Catat **ID Produk**. Anda akan menggunakannya saat membuat atau memperbarui detail harga produk.
**Tip**  
Jika Anda kehilangan ID produk Anda, Anda dapat menemukannya di Portal Manajemen AWS Marketplace dengan memilih **Container** dari menu **Assets**. Halaman **Kontainer** menampilkan daftar produk Anda dengan produk terkait mereka IDs.

1. Unduh AWS SDK publik terbaru dan kemudian instal di aplikasi penampung Anda. Anda dapat menemukan petunjuk penginstalan untuk AWS SDK pilihan Anda di [Tools to Build on AWS](https://aws.amazon.com/tools/).
**catatan**  
Untuk memanggil operasi License Manager API dari Amazon EKS Anywhere atau klaster Kubernetes yang tidak disediakan oleh AWS, Anda harus menggunakan SDK yang didukung. AWS Untuk melihat daftar yang didukung AWS SDKs, lihat [Menggunakan AWS SDK yang didukung](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html).

1. Buat AWS License Manager klien dengan penyedia kredensi khusus sehingga dapat memberikan kredensil ke aplikasi kontainer yang digunakan di AWS maupun lokal. Untuk kode sumber lengkap untuk penyedia kredensi kustom`LicenseCredentialProvider`, lihat bagian berikut:
   + [`LicenseManagerCredentialsProvider`- Implementasi Java](#container-license-manager-cred-provider-java)
   + [`LicenseManagerCredentialsProvider`- `Golang` implementasi](#container-license-manager-cred-provider-golang)

    `LicenseCredentialsProvider`memperluas rantai penyedia kredensi default AWS SDK untuk penggunaan lokal dengan menambahkan. `LicenseManagerTokenCredentialsProvider` Ini memberikan kredensil dengan menggunakan License Manager OIDC mengeluarkan token identitas di lingkungan lokal. Anda harus menyertakan kode sumber untuk `LicenseCredentialsProvider` di classpath aplikasi Anda.
**catatan**  
Memperluas aplikasi kontainer `DefaultCredentialsProvider` memungkinkan aplikasi kontainer yang sama untuk mendapatkan kredensil saat berjalan AWS dan saat berjalan di lingkungan lokal. Jika aplikasi kontainer sudah menggunakan rantai penyedia kredensi kustom alih-alih default, itu juga dapat diperpanjang dengan menambahkan `LicenseManagerTokenCredentialsProvider` ke rantai kustom.

   Cuplikan kode berikut adalah contoh membuat AWS License Manager klien menggunakan Java.

   ```
   LicenseManagerClientBuilder clientBuilder = LicenseManagerClient.builder().credentialsProvider(LicenseCredentialsProvider.create());
   ```

1. Panggil operasi `CheckoutLicense` API dengan menggunakan `aws license-manager checkout-license` perintah dari setiap image container berbayar dalam penawaran produk Anda. Ini memeriksa bahwa pembeli berhak menggunakan lisensi untuk aplikasi Anda. Jika pembeli berhak atas aplikasi, `CheckoutLicense` berhasil dan mengembalikan hak yang diminta dan nilainya. Jika pembeli tidak berhak atas aplikasi, `CheckoutLicense` melempar pengecualian.

   Parameter berikut diperlukan saat memanggil operasi `CheckoutLicense` API:
   + `CheckoutType`— Nilai yang valid adalah `PROVISIONAL` atau`PERPETUAL`:
     + Gunakan `PERPETUAL` ketika jumlah hak yang diperiksa akan habis dari kolam.

       Contoh: Pembeli berhak memproses 500 GB data. Ketika mereka terus memproses data, kuantitas ditarik ke bawah dan habis dari kumpulan 500 GB.
     + Gunakan `PROVISIONAL` untuk hak lisensi mengambang di mana hak diperiksa keluar dari kumpulan dan dikembalikan setelah digunakan.

       Contoh: Pengguna berhak atas 500 pengguna simultan pada aplikasi. Saat pengguna masuk atau keluar, pengguna ditarik atau dikembalikan ke kumpulan 500 pengguna. Untuk mempelajari lebih lanjut tentang hak lisensi mengambang, lihat. [Hak lisensi mengambang dengan License Manager](#container-LM-floating-license)
   + `ClientToken`— Pengidentifikasi unik dan peka huruf besar/kecil. Sebaiknya gunakan UUID acak untuk setiap permintaan unik.
   + `Entitlements`— Daftar hak yang akan diperiksa.
     + Untuk hak fitur, berikan `Name` dan `Unit` properti sebagai berikut.

       ```
       {
         "Name": "<Entitlement_Name>",
         "Unit": "None"
       }
       ```
     + Untuk hak yang dihitung, berikan, `Name``Unit`, dan `Count` properti sebagai berikut.

       ```
       {
         "Name": "<Entitlement_Name>",
         "Unit": "<Entitlement_Unit>",
         "Value": <Desired_Count>
       }
       ```
   + `KeyFingerprint`— Sidik jari kunci untuk lisensi yang dikeluarkan oleh AWS Marketplace adalah`aws:294406891311:AWS/Marketplace:issuer-fingerprint`. Menggunakan sidik jari kunci ini memastikan bahwa lisensi dikeluarkan oleh AWS Marketplace dan bukan oleh entitas yang tidak dapat diandalkan.
   + `ProductSKU`— ID Produk yang dihasilkan Portal Manajemen AWS Marketplace pada langkah sebelumnya.

   Cuplikan berikut adalah contoh panggilan menggunakan operasi `CheckoutLicense` API menggunakan. 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"
   ```
**catatan**  
Untuk memeriksa lisensi, aplikasi kontainer memerlukan akses jaringan keluar untuk menggunakan License Manager. Aplikasi yang digunakan di lokasi mungkin mengalami akses jaringan keluar yang tidak dapat diandalkan atau lambat. Aplikasi ini harus menyertakan percobaan ulang yang memadai saat memanggil License Manager. Untuk informasi selengkapnya, lihat [Praktik terbaik untuk mengintegrasikan dengan License Manager untuk penerapan lokal](#container-LM-best-practices-on-prem).

1. Hubungi operasi `CheckoutLicense` API dengan irama reguler untuk mengidentifikasi perubahan apa pun pada lisensi pelanggan karena perpanjangan, peningkatan, atau pembatalan yang dilakukan. AWS Marketplace Irama tergantung pada aplikasi. Kami merekomendasikan untuk memeriksa lisensi sekali sehari untuk mengambil perubahan secara otomatis tanpa campur tangan pembeli.

   Aplikasi yang digunakan di lokasi mungkin memiliki akses jaringan keluar yang tidak dapat diandalkan untuk memeriksa lisensi pada irama reguler. Dalam kasus seperti itu, aplikasi harus menggunakan lisensi cache untuk ketahanan yang memadai. Untuk informasi selengkapnya, lihat [Praktik terbaik untuk mengintegrasikan dengan License Manager untuk penerapan lokal](#container-LM-best-practices-on-prem).

1. Setelah Anda mengintegrasikan `CheckoutLicense` panggilan dengan aplikasi container Anda, buat versi baru image container Docker Anda dengan perubahan.

1. Perbarui bagan Helm aplikasi Anda untuk menerima rahasia Kubernetes sebagai input opsional yang berisi konfigurasi untuk mengakses lisensi menggunakan License Manager. APIs Rahasia konfigurasi akan berisi token identitas yang dikeluarkan oleh License Manager dan AWS Identity and Access Management peran yang akan digunakan oleh penyedia kredensi kustom yang dijelaskan sebelumnya untuk mendapatkan AWS kredensil untuk memanggil License Manager APIs saat aplikasi kontainer di-deploy di lokasi. Juga, tambahkan Wilayah AWS sebagai input dengan nilai default`us-east-1`.

   Pembeli yang menerapkan aplikasi kontainer di tempat dapat membuat rahasia Kubernetes melalui pengalaman AWS Marketplace pembeli untuk produk kontainer. Berikan nama rahasia Kubernetes sebagai input ke perintah. `helm install` Rahasia konfigurasi dikonfigurasi dalam format berikut.

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

1. Perbarui template penerapan aplikasi di bagan Helm untuk gambar kontainer yang terintegrasi dengan menyertakan AWS License Manager yang berikut:
   + Akun layanan untuk pod - Akun layanan diperlukan untuk penerapan Helm di Amazon EKS. Ini digunakan untuk mendapatkan izin untuk memanggil operasi License Manager API dengan menyiapkan peran IAM untuk akun layanan pada image container. Untuk informasi selengkapnya tentang peran IAM untuk akun layanan, lihat [peran IAM untuk akun layanan](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html).
   + Akses lisensi untuk penerapan lokal — Rahasia konfigurasi lisensi diperlukan untuk menyediakan kredensil dan izin yang sesuai untuk memanggil operasi License Manager API untuk penerapan Helm di lingkungan lokal. Pembeli akan menghasilkan dan memberikan rahasia lisensi kepada Helm dari pengalaman AWS Marketplace pembeli.

   Cuplikan kode berikut adalah spesifikasi penyebaran sampel dengan akun layanan, konfigurasi lisensi, dan rahasia tarik gambar.

   ```
   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 }}
   ```
**catatan**  
Rahasia konfigurasi lisensi adalah opsional. Pembeli hanya menggunakan nilai untuk penerapan lokal. Untuk AWS penerapan, spesifikasi penyebaran harus menyertakan akun layanan untuk gambar terintegrasi License Manager.

1. Uji integrasi License Manager secara lokal dan di Amazon EKS dengan melakukan langkah-langkah di bagian berikut:

   1. [Menguji integrasi License Manager secara lokal](#container-testing-LM-integration-locally)

   1. [Menguji integrasi License Manager di Amazon EKS](#container-testing-LM-integration-EKS)

1. Setelah berhasil memverifikasi integrasi License Manager baik di dalam AWS maupun lokal, Anda dapat membuat daftar produk container dengan mengikuti langkah-langkah di dalamnya[Ikhtisar: Buat produk kontainer](container-product-getting-started.md#create-container-product).

## Menguji integrasi License Manager secara lokal
<a name="container-testing-LM-integration-locally"></a>

Anda dapat menggunakan minikube atau penyiapan lainnya untuk menguji integrasi License Manager pada klaster Kubernetes mana pun secara lokal. Pastikan bahwa klaster Kubernetes memiliki akses internet keluar untuk memanggil operasi License Manager API.

**Untuk menguji integrasi License Manager secara lokal**

1. Buat lisensi pengujian di akun penjual uji dengan hak yang diinginkan. Untuk menyiapkan lisensi pengujian, lihat [CreateLicense](https://docs.aws.amazon.com/license-manager/latest/APIReference/API_CreateLicense.html)di *Referensi AWS License Manager API*. Atau, gunakan skrip berikut untuk membuat lisensi pengujian dan kemudian buat hibah lisensi ke akun pembeli uji untuk menggunakan lisensi. Skrip berikut menggunakan kredensil akun penjual uji.

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

1. Buat rahasia Kubernetes dengan token lisensi dan peran IAM menggunakan format rahasia yang ditentukan sebelumnya. Gunakan operasi License Manager `CreateToken` API untuk menghasilkan token lisensi. Kemudian, gunakan operasi IAM `CreateRole` API untuk membuat peran IAM dengan izin dan kebijakan kepercayaan. Lihat contoh dalam skrip berikut. Skrip berikut menggunakan kredensil akun pembeli uji.

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

1. Siapkan klaster Kubernetes yang dihosting di luar. AWS Gunakan untuk menguji bahwa aplikasi kontainer dapat terhubung ke AWS License Manager API dari lingkungan selain AWS dan bahwa penyedia kredensi khusus terintegrasi dengan baik dalam aplikasi.

1. Menerapkan token lisensi dan peran IAM yang dihasilkan sebelumnya ke dalam klaster Kubernetes lokal.

   ```
   kubectl create secret generic "awsmp-license-access-config" \
   --from-literal=license_token=${TOKEN} \
   --from-literal=iam_role=${ROLE_ARN}
   ```

1. Terapkan aplikasi Anda melalui Helm dengan nama rahasia sebagai masukan dan verifikasi bahwa aplikasi dapat memanggil operasi License Manager API untuk melakukan pemeriksaan hak. Untuk perubahan spesifikasi Helm dan penerapan, lihat Langkah 9 di. [Mengintegrasikan produk AWS Marketplace for Containers Anywhere dengan License Manager](#containers-anywhere-integrate-with-LM)

## Menguji integrasi License Manager di Amazon EKS
<a name="container-testing-LM-integration-EKS"></a>

Anda juga dapat menguji integrasi License Manager di Amazon EKS. Uji untuk memastikan bahwa aplikasi dapat memanggil operasi License Manager API tanpa rahasia konfigurasi lisensi. Juga pastikan bahwa akun layanan dapat digunakan untuk mengatur Peran IAM untuk Akun Layanan (IRSA) dan memberikan kredensi yang relevan untuk aplikasi.

**Untuk menguji integrasi License Manager di Amazon EKS**

1. Buat lisensi pengujian di akun penjual uji dengan hak yang diinginkan. Lihat [referensi CreateLicense API](https://docs.aws.amazon.com/license-manager/latest/APIReference/API_CreateLicense.html) untuk menyiapkan lisensi pengujian Anda atau gunakan skrip berikut untuk membuatnya dan membuat hibah lisensi ke akun pembeli pengujian untuk menggunakan lisensi. Skrip berikut menggunakan kredensil akun penjual uji.

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

1. Buat cluster pengujian Amazon EKS dari konfigurasi yang diinginkan, atau jalankan perintah berikut untuk menggunakan konfigurasi default.

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

1. Buat akun layanan untuk klaster yang ada dan kaitkan dengan peran IAM. Perintah berikut menciptakan peran IAM dengan. `AWSLicenseManagerConsumptionPolicy` Kemudian, perintah melampirkannya ke akun `test_sa` layanan cluster Amazon EKS di mana gambar terintegrasi License Manager harus digunakan. Akibatnya, akun layanan bisa mendapatkan kredensi yang sesuai untuk memanggil operasi 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
   ```

1. Terapkan aplikasi melalui Helm di akun layanan tempat peran IAM dikaitkan dari perintah sebelumnya. Verifikasi bahwa aplikasi dapat memanggil operasi License Manager API untuk melakukan pemeriksaan hak.

## Hak lisensi mengambang dengan License Manager
<a name="container-LM-floating-license"></a>

Dengan lisensi mengambang, saat pengguna masuk ke aplikasi, lisensi diambil dari kumpulan lisensi yang tersedia. Saat pengguna keluar, lisensi ditambahkan kembali ke kumpulan lisensi yang tersedia.

Untuk lisensi mengambang, aplikasi menggunakan operasi `CheckoutLicense` API untuk memeriksa hak dari kumpulan hak saat sumber daya digunakan. Respons operasi `CheckoutLicense` API mencakup token konsumsi lisensi yang merupakan pengidentifikasi unik untuk checkout. Token konsumsi lisensi dapat melakukan tindakan tambahan pada hak yang diperiksa, seperti memeriksanya kembali ke kumpulan lisensi atau memperpanjang checkout.

Ketika sumber daya tidak lagi digunakan, aplikasi menggunakan operasi `CheckInLicense` API untuk memeriksa hak kembali ke kumpulan.

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

Jika memeriksa lisensi kembali ke pool gagal, misalnya, jika aplikasi mogok selama operasi, hak akan diperiksa kembali ke kolam secara otomatis setelah 60 menit. Karena itu, jika sumber daya digunakan lebih dari 60 menit, itu adalah praktik terbaik untuk menjaga hak diperiksa dari kolam. Untuk melakukan ini, gunakan operasi `ExtendLicenseConsumption` API selama sumber daya digunakan.

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

## Praktik terbaik untuk mengintegrasikan dengan License Manager untuk penerapan lokal
<a name="container-LM-best-practices-on-prem"></a>

Penerapan aplikasi kontainer di lingkungan lokal mungkin mengalami akses jaringan keluar yang tidak dapat diandalkan. Gunakan praktik terbaik berikut untuk menambah ketahanan guna menghindari gangguan layanan kepada pembeli karena potensi masalah yang disebabkan oleh konektivitas internet yang buruk:
+ **Coba lagi yang memadai** - Masalah jaringan sementara dapat membuat aplikasi Anda tidak terhubung. AWS License Manager Terapkan percobaan ulang hingga 30 menit, dengan mundur eksponensial. Ini dapat membantu menghindari pemadaman jangka pendek atau masalah jaringan.
+ **Hindari batas keras** — Aplikasi yang digunakan dalam cluster yang terhubung dapat secara teratur memeriksa lisensi untuk mengidentifikasi perubahan apa pun karena peningkatan atau pembaruan. Dengan akses keluar yang tidak dapat diandalkan, aplikasi mungkin tidak dapat mengidentifikasi perubahan tersebut. Bila memungkinkan, aplikasi harus menghindari gangguan layanan kepada pembeli karena ketidakmampuan untuk memeriksa lisensi melalui License Manager. Aplikasi dapat kembali pada pengalaman uji coba gratis atau sumber terbuka ketika lisensi kedaluwarsa dan mereka tidak dapat memeriksa apakah lisensi valid.
+ **Beri tahu pelanggan** — Saat menggunakan lisensi yang di-cache, setiap perubahan pada lisensi (termasuk pembaruan atau peningkatan) tidak secara otomatis tercermin pada beban kerja yang sedang berjalan. Beri tahu pelanggan Anda (bahwa mereka harus mengizinkan akses keluar ke aplikasi lagi sementara sehingga aplikasi dapat memperbarui lisensi yang di-cache. Misalnya, beri tahu pelanggan melalui aplikasi itu sendiri atau melalui dokumentasinya. Demikian pula, ketika kembali ke serangkaian fungsi yang lebih rendah, beri tahu pelanggan bahwa hak mereka habis atau lisensi kedaluwarsa. Kemudian, mereka dapat memilih untuk meningkatkan atau memperbarui.

## `LicenseManagerCredentialsProvider`- Implementasi Java
<a name="container-license-manager-cred-provider-java"></a>

`LicenseCredentialsProvider`memperluas rantai penyedia kredensi default AWS SDK untuk penggunaan lokal dengan menambahkan. `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`menyediakan kredensil dengan menggunakan License Manager OIDC mengeluarkan token identitas di lingkungan lokal. Anda harus menyertakan kode sumber untuk `LicenseCredentialsProvider` di classpath aplikasi Anda.

```
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` implementasi
<a name="container-license-manager-cred-provider-golang"></a>

**`LicenseCredentialsProvider`**

`LicenseCredentialsProvider`memperluas rantai penyedia kredensi default AWS SDK untuk penggunaan lokal dengan menambahkan. `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`menyediakan kredensil dengan menggunakan License Manager OIDC mengeluarkan token identitas di lingkungan lokal. Anda harus menyertakan kode sumber untuk `LicenseCredentialsProvider` di classpath aplikasi Anda.

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