AWS Marketplace
Automating updates to your container listings in AWS Marketplace with Catalog API
Update (October 13, 2023)
This article uses the legacy “Details” attribute in change requests, which requires additional formatting for your change details. We recommend using the alternative “DetailsDocument” attribute. It doesn’t require additional formatting and the change details don’t need to be changed. For examples of the “DetailsDocument” attribute, see Working with container-based products in the AWS Marketplace Catalog API Reference.
The Catalog API for AWS Marketplace enables you as a seller to manage your listings more seamlessly. It’s available for software packaged as single Amazon Machine Images (AMI) or containers. This post describes how to update your existing container products listed in AWS Marketplace. For information about updating single AMI products instead, see Automating updates to your Single AMI listings.
Using the Catalog API helps you automate your publishing pipelines. Until now, when you needed to add new versions of your container product to your AWS Marketplace listing, you had to manually submit those changes. Now you can integrate your release process or continuous integration/continuous delivery (CI/CD) pipelines with the Catalog API to automate this process. If you have a large catalog and update your listings frequently, using the Catalog API can help you streamline and reduce time dedicated to the update process.
In this post, I show you how to use the Catalog API to programmatically update product details, add new image repositories, add new container versions, update version details, and restrict specific versions.
Prerequisites
To walk through this post’s solution, you must have the following prerequisites.
- The product ID – To find the product ID of your product, go to the AWS Marketplace Management Portal for Server products. In your list of current server products, choose the product that you want to update using the Catalog API and copy the product ID. You can also call ListEntities with the
EntityType
set toContainerProduct
. The product ID is available only after your container product is in the limited state in AWS Marketplace. Products in the limited state are visible only to your seller AWS account and test accounts that you specify. All new products are first published into the limited state for testing before they’re made publicly available in AWS Marketplace. For more information on submitting your product, see Getting started with container products in the AWS Marketplace Seller Guide. - IAM permissions for managing products – Make sure the IAM user or role that you’re using has the proper permissions to manage your products in AWS Marketplace. You can attach either
AWSMarketplaceSellerFullAccess
orAWSMarketplaceSellerProductsFullAccess
as described in Policies and permissions for AWS Marketplace sellers in the AWS Marketplace Seller Guide. Alternatively, you can grant the user or role least privilege by granting only the permissions required to perform the API calls for the Catalog API. To view the specific IAM actions for the Catalog API, see the actions table at Actions, resources, and condition keys for AWS Marketplace Catalog in the Service Authorization Reference. Catalog API clients are available in multiple AWS SDKs. - AWS CloudShell and AWS CLI – The following walkthrough uses AWS CloudShell, a browser-based shell with the AWS Command Line Interface (AWS CLI) preinstalled in the seller AWS account. Because AWS CloudShell inherits the credentials of the user signed in to the AWS Management Console, make sure to sign in with a user that has permissions to manage your products.
- An application to convert JSON objects into JSON strings – The following walkthrough uses the command line application
jq
to convert JSON objects into JSON strings.jq
is preinstalled in AWS CloudShell, but you can also install it with many package managers. For example, you can runsudo yum install -y jq
on Amazon Linux 2 orsudo apt-get install -y jq
on Ubuntu.
Solution walkthrough
This solution has the following sections:
- A. Updating product details
- B. Checking update status
- C. Adding new image repositories
- D. Adding a new container version
- E. Getting container details
- F. Updating container version details
- G. Restricting a container version
A. Updating product details
In this first section, I show how to make changes to your product details by calling StartChangeSet with the change type UpdateInformation
.
Here is a sample product with the following details:
- Product title – My Container Product
- Short description – My container product that makes it simple to do something.
- Long description – My container product that makes it simple to do something. For some industries, it’s been reported that this solution increases productivity by 10 times.
The following image shows the product detail page for My Container Product with those short and long descriptions.
In this section, you update only the title, short description, and long description of this product. You can update other product details as well. For a full list of product details that you can change, see Working with container products in the AWS Marketplace Catalog API Reference. Any details that your request omits use the values in the latest version.
To update the product details, do the following steps in AWS CloudShell, replacing the values in italics with values specific to your product.
- Set a variable to the product ID of your product.
PRODUCT_ID="example1-abcd-1234-5ef6-7890abcdef12";
- Set a variable to a JSON object that includes the details that you want to change.
DETAILS_JSON='{ "ProductTitle": "My Container Product Updated", "ShortDescription": "My container product short description updated.", "LongDescription": "My container product long description updated." }';
- To pass this JSON object through the Catalog API, you must convert the JSON object into a JSON string so that you can nest it into another JSON object as a string. Run the following command and use
jq
to do the conversion and set the output to another variable calledDETAILS_JSON_STRING
.DETAILS_JSON_STRING="$(echo "${DETAILS_JSON}" | jq 'tostring';)";
Optionally, you can view the value of the converted JSON string by running the command
echo "${DETAILS_JSON_STRING}"
. The following is an example of that JSON object after the conversion to a JSON string with the JSON control characters properly escaped.
"{\"ProductTitle\":\"My Container Product Updated\",\"ShortDescription\":\"My container product short description updated.\",\"LongDescription\":\"My container product long description updated.\"}"
- Run the following AWS CLI command for StartChangeSet with the variables
PRODUCT_ID
andDETAILS_JSON_STRING
. UseUpdateInformation
as the change type. This starts a change set to update the product information.aws marketplace-catalog start-change-set \ --catalog "AWSMarketplace" \ --change-set '[ { "ChangeType": "UpdateInformation", "Entity": { "Identifier": "'"${PRODUCT_ID}"'", "Type": "ContainerProduct@1.0" }, "Details": '"${DETAILS_JSON_STRING}"' } ]';
After running the commands, your output should include the change set ID and the change set Amazon Resource Number (ARN). The change set ID in the following result is example123456789012abcdef.
{
"ChangeSetId": "example123456789012abcdef",
"ChangeSetArn": "arn:aws:aws-marketplace:us-east-1:123456789012:AWSMarketplace/ChangeSet/example123456789012abcdef"
}
You have now started a change set to change the title, short description, and long description of your product. Change sets take time to apply. In the next section, you check its status.
B. Checking update status
After starting a change set, you can check its status by calling DescribeChangeSet with the change set ID returned in the StartChangeSet response.
To check the status of your change set, run the following command in AWS CloudShell, but replace the value in italics with the change set ID you got in the previous section.
- Run the following AWS CLI command with your change set ID.
- Change sets take time. Depending on the change, it can take minutes or hours. Run this command in intervals until the change set succeeds or fails.
aws marketplace-catalog describe-change-set \ --catalog "AWSMarketplace" \ --change-set-id "example123456789012abcdef";
When the change set succeeds, the
Status
property in the JSON output has a value ofSUCCEEDED
. The following is an example response of a successful change set that has been edited for brevity.
{
"ChangeSetId": "example123456789012abcdef",
"ChangeSetArn": "arn:aws:aws-marketplace:us-east-1:123456789012:AWSMarketplace/ChangeSet/example123456789012abcdef",
...
"Status": "SUCCEEDED",
...
"ChangeSet": [
{
"ChangeType": "UpdateInformation",
"Entity": {
"Type": "ContainerProduct@1.0",
"Identifier": "example1-abcd-1234-5ef6-7890abcdef12"
},
"Details": "{\"ProductTitle\":\"My Container Product Updated\",\"ShortDescription\":\"My container product short description updated.\",\"LongDescription\":\"My container product long description updated.\"}",
"ErrorDetailList": []
}
]
}
Currently, there isn’t any notification for when the change set status changes. You must continuously poll this API for the status. To view all status possibilities, see ChangeSetSummaryListItem in the AWS Marketplace Catalog API Reference.
You have now successfully updated product details. In the next section, you add new image repositories.
C. Adding new image repositories
In this section, you use the same StartChangeSet call from section A but with AddRepositories
as the change type to create new image repositories for your container product.
To publish container images, all container images used in your product must be pushed to image repositories in AWS Marketplace. When you add a new version for your container product, you can push new container images to existing repositories with different image tags or create new ones. For step-by-step instructions for publishing container products, see Getting started with container products in the AWS Marketplace Seller Guide.
To add new container image repositories, do the following steps in AWS CloudShell, but replace the values in italics with values specific to your product.
- Set a variable to the product ID of your product.
PRODUCT_ID="example1-abcd-1234-5ef6-7890abcdef12";
- Set a variable to a JSON object that includes the names of the new image repositories to create. In the following example, the new image repositories are named
new-repo-1
andnew-repo-2
.DETAILS_JSON=' { "Repositories": [ { "RepositoryName": "new-repo-1", "RepositoryType": "ECR" }, { "RepositoryName": "new-repo-2", "RepositoryType": "ECR" } ] }';
The resulting full repository URIs appear as
<account-ID>.dkr.ecr.us-east-1.amazonaws.com/<seller-prefix>/<respository-name>
. The<account-ID>
is an AWS account owned and managed by AWS Marketplace, and the<seller-prefix>
is created based on the name you created for your seller account. The<repository-name>
is the repository name that you specify in this change set request. - You must convert the JSON object into a JSON string so you can nest it into another JSON object as a string. To do that, run the following command. Use
jq
again to do the conversion and set the output to another variable namedDETAILS_JSON_STRING
.DETAILS_JSON_STRING="$(echo "${DETAILS_JSON}" | jq 'tostring';)";
- Run the following AWS CLI command for StartChangeSet with the variables
PRODUCT_ID
andDETAILS_JSON_STRING
from steps C.1 and 3. UseAddRepositories
for the change type. This starts a change set to add the new image repositories.aws marketplace-catalog start-change-set \ --catalog "AWSMarketplace" \ --change-set '[ { "ChangeType": "AddRepositories", "Entity": { "Identifier": "'"${PRODUCT_ID}"'", "Type": "ContainerProduct@1.0" }, "Details": '"${DETAILS_JSON_STRING}"' } ]';
After running the command, your output should include the change set ID and the change set ARN.
{
"ChangeSetId": "example123456789012abcdef",
"ChangeSetArn": "arn:aws:aws-marketplace:us-east-1:123456789012:AWSMarketplace/ChangeSet/example123456789012abcdef"
}
To get the status of your change set, repeat the steps in section B of this walkthrough.
After the image repositories in AWS Marketplace are created for your product, you can log in your Docker client and push your container images to the repository URIs. This is similar to how you push images to Amazon ECR. For more information on pushing Docker images, see Pushing a Docker image in the Amazon ECR User Guide.
After your container images are pushed into these AWS Marketplace image repositories for your product, you can reference them in the new container version details. We do this in the next section.
D. Adding a new container version
In this section, you add a new container version by using StartChangeSet but with the change type AddDeliveryOptions
.
When you add a new container version, you are actually adding one or more delivery options inside the new container version. For container products, each container version can have up to four delivery options. A delivery option is a group of images that make up a product deployment or product configuration. It’s up to you as the seller to define different delivery options or just one. For example, you can have one delivery option that deploys a set of container images to Amazon ECS and another that deploys another set to Amazon EKS. Similarly, you can have one delivery option that deploys a set of container images for a standard configuration and another that deploys another set for a quick configuration. The following steps includes only one delivery option in the new container version that you’re adding.
To add a new container version, do the following steps in AWS CloudShell, but replace the values in italics with values specific to your product.
- Set a variable to the product ID of your product.
PRODUCT_ID="example1-abcd-1234-5ef6-7890abcdef12";
- Set a variable to a JSON object that includes the details for this new version. In the following example, the new details for my product include a version title of
3.0
, release notes calledMy new release notes
, and the repository URI where I pushed the new container image to. It also includes the title of this delivery option asStandard Configuration
, the compatible services as bothECS
andEKS
, the description, and the usage instructions.DETAILS_JSON='{ "Version": { "VersionTitle": "3.0", "ReleaseNotes": "My new release notes" }, "DeliveryOptions": [ { "DeliveryOptionTitle": "Standard Configuration", "Details": { "EcrDeliveryOptionDetails": { "ContainerImages": [ "709825985650.dkr.ecr.us-east-1.amazonaws.com/some-seller-prefix/my-product-repository:3.0" ], "CompatibleServices": [ "ECS", "EKS" ], "Description": "This deploys the standard product with extra features turned off.", "UsageInstructions": "Visit https://example.com/usage-instructions for full deployment instructions." } } } ] }';
- You must convert the JSON object into a JSON string so you can nest it into another JSON object as a string. To do that, run the following command. Use
jq
again to do the conversion and set the output to another variable calledDETAILS_JSON_STRING
.DETAILS_JSON_STRING="$(echo "${DETAILS_JSON}" | jq 'tostring';)";
- Run the following AWS CLI command for StartChangeSet with the variables
PRODUCT_ID
andDETAILS_JSON_STRING
. UseAddDeliveryOptions
for the change type. This starts a change set to add a new container version.aws marketplace-catalog start-change-set \ --catalog "AWSMarketplace" \ --change-set '[ { "ChangeType": "AddDeliveryOptions", "Entity": { "Identifier": "'"${PRODUCT_ID}"'", "Type": "ContainerProduct@1.0" }, "Details": '"${DETAILS_JSON_STRING}"' } ]';
After running the command, your output should include the change set ID and the change set ARN.
{
"ChangeSetId": "example123456789012abcdef",
"ChangeSetArn": "arn:aws:aws-marketplace:us-east-1:123456789012:AWSMarketplace/ChangeSet/example123456789012abcdef"
}
To get the status of your change set, repeat the steps in section B of this walkthrough.
Because this is a new container version, it can take a few hours to complete. During this time, AWS Marketplace scans the container images for critical vulnerabilities. If any issues are found, the status shows FAILED
, and the reason is provided. For more information, see Container product scans for security issues and Container-based product requirements in the AWS Marketplace Seller Guide.
When the change set status changes to SUCCEEDED
, your new version is immediately available.
- If your product is in the limited state and hasn’t been published publicly yet, it stays in the limited state.
- If your product is public in AWS Marketplace, this new version is available to the public. Your existing users receive an email notifying them that the new version is available, linking to the version’s release notes, and suggesting that they upgrade to the latest version. You also receive a copy of the email sent to the email of the root user of the seller AWS account.
Your new version and existing version or versions are available for buyers to select from on the configuration page of your product in AWS Marketplace. The following image shows my example product configuration page in AWS Marketplace, with two available versions, 3.0 and 2.0, and their release dates.
In section F, you will update the details of this container version. However, before you can do that, you must retrieve the delivery option ID that was created for this new container version. The next section describes how to retrieve your delivery option ID.
E. Getting container details
In this section, you retrieve the versions and container details of your product by using DescribeEntity and format it in the CLI for easier reading.
The purpose in this section is to locate a delivery option ID. One or more delivery options are created each time you add a new container version. For container products, each container version can have up to four delivery options. A delivery option is a group of images that make up a product deployment or product configuration. You use this delivery option ID in section E of this walkthrough to modify the usage instructions and in section F to restrict the delivery option of a container version.
To locate a delivery option ID, do the following steps in AWS CloudShell, but replace the values in italics with values specific to your product.
- Run the following AWS CLI command, replacing the product ID in italics with the product ID from step D.1.
aws marketplace-catalog describe-entity \ --catalog "AWSMarketplace" \ --entity-id "example1-abcd-1234-5ef6-7890abcdef12";
The actual output is long; the following example has been edited it for brevity. Even so, it’s a bit difficult to read, especially the
Details
property. TheDetails
property is a JSON string with JSON control characters, such as double quotation marks, escaped.
{
"EntityType": "ContainerProduct@1.0",
"EntityIdentifier": "example1-abcd-1234-5ef6-7890abcdef12@3",
...
"Details": "{\"Versions\":[{\"Id\":\"example2-0000-aaaa-5ef6-7890abcdef12\",\"ReleaseNotes\":\"My new release notes\",\"UpgradeInstructions\":\"N/A\",\"VersionTitle\":\"3.0\",\"CreationDate\":\"2021-03-02T00:00:00.000Z\",\"Sources\":[{\"Type\":\"DockerImages\", \"Id\":\"example3-1111-bbbb-5ef6-7890abcdef12\",..."
... - Because you need the
Details
property, run the command again, but use the--query
filter of the AWS CLI to select just theDetails
property.aws marketplace-catalog describe-entity \ --catalog "AWSMarketplace" \ --entity-id "example1-abcd-1234-5ef6-7890abcdef12" \ --query 'Details';
The following shows the
Details
property that I received after running the command in this step.
"{\"Versions\":[{\"Id\":\"example2-0000-aaaa-5ef6-7890abcdef12\",\"ReleaseNotes\":\"My new release notes\",\"UpgradeInstructions\":\"N/A\",\"VersionTitle\":\"3.0\",\"CreationDate\":\"2021-03-06T00:00:00.000Z\",\"Sources\":[{\"Type\":\"DockerImages\", \"Id\":\"example3-1111-bbbb-5ef6-7890abcdef12\",..."
Because theDetails
property is still a JSON string, you must parse and format it for readability.
- To output a pretty-formatted JSON object, use
jq
to parse the JSON string back into a JSON object. First, pipe|
theDetails
property outputted intojq
. Then, use its built-in functionfromjson
to clean it up, as shown in the following command:aws marketplace-catalog describe-entity \ --catalog "AWSMarketplace" \ --entity-id "example1-abcd-1234-5ef6-7890abcdef12" \ --query 'Details' | jq 'fromjson';
The output should now look something like the following. The example has been edited for brevity.
{
"Versions": [
{
"Id": "example2-0000-aaaa-0000-aaaaaaaaaaaa",
"ReleaseNotes": "My new release notes",
"UpgradeInstructions": "N/A",
"VersionTitle": "3.0",
"CreationDate": "2021-03-06T00:00:00.000Z",
"Sources": [
{
"Type": "DockerImages",
"Id": "example3-1111-bbbb-1111-bbbbbbbbbbbb",
...
"DeliveryOptions": [
{
"Id": "example4-2222-cccc-2222-cccccccccccc",
"Type": "ElasticContainerRegistry",
"SourceId": "example3-1111-bbbb-1111-bbbbbbbbbbbb",
"Title": "Standard Configuation",
"ShortDescription": "This deploys the standard product with extra features turned off.",
"isRecommended": false,
"Compatibility": {
"AWSServices": [
"ECS",
"EKS"
]
},
"Instructions": {
"Usage": "Visit https://example.com/usage-instructions for full deployment instructions."
},
...
Because you’re updating the container usage instruction in section F of this walkthrough, copy the delivery option ID of the version that you want to edit from this output. You can locate delivery option IDs in the JSON pathVersions[].DeliveryOptions[].Id
of theDetails
JSON. For the preceding example output,example4-2222-cccc-2222-cccccccccccc
is the ID of the delivery option that you’re updating the usage instructions to in the next section. - (Optional) You can use
jq
to do some additional filtering for you. For example, run the following AWS CLI command to find the delivery option ID or IDs for a specific version by matching a specificVersionTitle
.aws marketplace-catalog describe-entity \ --catalog "AWSMarketplace" \ --entity-id "example1-abcd-1234-5ef6-7890abcdef12" \ --query 'Details' | jq --raw-output 'fromjson'\ ' | .Versions[]'\ ' | select(.VersionTitle == "3.0")'\ ' | .DeliveryOptions[].Id';
The following is output of this additional filtering.
example4-2222-cccc-2222-cccccccccccc
F. Updating container version details
In this section, you update details of a container version using StartChangeSet but with the change type UpdateDeliveryOptions
.
In the previous section, you retrieved a delivery option ID. As a reminder, one or more delivery options are created each time you add a new container version.
To update container version details, do the following steps in AWS CloudShell, but replace the values in italics with values specific to your product.
- In AWS CloudShell, set a variable to the delivery option ID from section E.
DELIVERY_OPTION_ID="example4-2222-cccc-2222-cccccccccccc";
- Set a variable to the product ID of your product.
PRODUCT_ID="example1-abcd-1234-5ef6-7890abcdef12";
In this section, you are updating only the usage instructions of this delivery option for this container version. You can update other details as well. For a full list of product details that you can change, see Working with container products in the AWS Marketplace Catalog API Reference. Any details that your request omits use the values in the latest version.
- Set a variable to a JSON object with the new usage instructions included.
DETAILS_JSON='{ "DeliveryOptions": [ { "Id": "'"${DELIVERY_OPTION_ID}"'", "Details": { "EcrDeliveryOptionDetails": { "UsageInstructions": "Updated usage instructions" } } } ] }';
- You must convert the JSON object into a JSON string so you can nest it into another JSON object as a string. Run the following command. Use
jq
again to do the conversion and set the output to another variable calledDETAILS_JSON_STRING
.DETAILS_JSON_STRING="$(echo "${DETAILS_JSON}" | jq 'tostring';)";
- Run the following AWS CLI command for StartChangeSet with the variables
PRODUCT_ID
andDETAILS_JSON_STRING
. UseUpdateDeliveryOptions
for the change type. This starts a change set to update the details of the delivery option of the container version.aws marketplace-catalog start-change-set \ --catalog "AWSMarketplace" \ --change-set '[{ "ChangeType": "UpdateDeliveryOptions", "Entity": { "Identifier": "'"${PRODUCT_ID}"'", "Type": "ContainerProduct@1.0" }, "Details": '"${DETAILS_JSON_STRING}"' }]';
After running the command, your output should include the change set ID and the change set ARN.
{
"ChangeSetId": "example123456789012abcdef",
"ChangeSetArn": "arn:aws:aws-marketplace:us-east-1:123456789012:AWSMarketplace/ChangeSet/example123456789012abcdef"
}
To get the status of your change set, repeat the steps in section B of this walkthrough.
G. Restricting a container version
In this final section, you restrict a container version from your product. To do this, you use StartChangeSet again but with the change type RestrictDeliveryOptions
.
Restricting a container version prevents new buyers from accessing that specific version of your public product. For more information on how it affects existing users, see Publishing container products in the AWS Marketplace Seller Guide.
You can restrict a version only if the product is live in AWS Marketplace. This change type doesn’t work for products still in the limited state.
In section E of this walkthrough, you retrieved a delivery option ID. As a reminder, one or more delivery options are created each time you add a new container version. If you have more than one delivery option in the version that you’re restricting, you need to restrict all of the delivery options in that version. In other words, restricting one delivery option in a version doesn’t automatically restrict all other delivery options in that version.
To restrict one or more delivery options of a version, do the following steps in AWS CloudShell, replacing the values in italics with values specific to your product.
- Set a variable to the product ID of your product.
PRODUCT_ID="example1-abcd-1234-5ef6-7890abcdef12";
- Set a variable to the delivery option ID from section E.
DETAILS_JSON='{ "DeliveryOptionIds": [ "example4-2222-cccc-2222-cccccccccccc" ] }';
- You must convert the JSON object into a JSON string so that you can nest it into another JSON object as a string. Run the following command and use
jq
again to do the conversion and set the output to another variable calledDETAILS_JSON_STRING
.DETAILS_JSON_STRING="$(echo "${DETAILS_JSON}" | jq 'tostring';)";
- Run the following AWS CLI command for StartChangeSet with the variables
PRODUCT_ID
andDETAILS_JSON_STRING
. UseRestrictDeliveryOptions
for the change type. This starts a change set to restrict the delivery option of the container version.aws marketplace-catalog start-change-set \ --catalog "AWSMarketplace" \ --change-set '[ { "ChangeType": "RestrictDeliveryOptions", "Entity": { "Identifier": "'"${PRODUCT_ID}"'", "Type": "ContainerProduct@1.0" }, "Details": '"${DETAILS_JSON_STRING}"' } ]';
After running the command, your output should include the change set ID and the change set ARN.
{
"ChangeSetId": "example123456789012abcdef",
"ChangeSetArn": "arn:aws:aws-marketplace:us-east-1:123456789012:AWSMarketplace/ChangeSet/example123456789012abcdef"
}
To get the status of your change set, repeat the steps in section B of this walkthrough.
Conclusion and next steps
In this post, I showed how to use the Catalog API to update your container listings in AWS Marketplace. I showed how to update product details, describe the update status, add a new container version and image repository, and describe container details. I also showed how to update container version details and restrict a container version.
The Catalog API can help you automate how you manage your AMI and container products in AWS Marketplace. For more information, see Working with container-based products in the AWS Marketplace Catalog API Reference. As you integrate the Catalog API with your release process or CI/CD pipeline, keep in mind the Catalog API service limits.
You can also control who can manage your product listings using AWS Identity and Access Management (IAM). Furthermore, if you have multiple products, you can limit access to groups of products by using resource tagging. Access to your products can also be shared with other AWS accounts using AWS Resource Access Manager (AWS RAM).
To get started, see Working with container-based products.
About the author
Joseph Shih is a Senior Partner Solutions Architect focusing on AWS Marketplace and is passionate about application development, serverless technology, and DevOps. He believes that code increases productivity in every workplace, industry, and home, and his dream is to write software that changes the world and transforms lives.