//AWS Marketplace

Tutorial 09 — List and Deploy via AWS Marketplace

> Status note.* The Helm chart at deploy/helm/buttrbase-backend-rust/ is real and committed — you can run it against an EKS cluster right now using tutorial 07. The AWS Marketplace *listing* (the container product, ECR repository, Metering Service entitlement wiring) is forward-looking: this tutorial is a packaging guide for when you take that chart to market, not a guide to a listing that exists today. Steps that require an AWS Marketplace seller account are marked *[Marketplace listing — forward-looking] so the distinction is never ambiguous.

This tutorial is one layer thin: it explains what AWS Marketplace adds on top of the chart, how to push the image to ECR so AWS can reference it, how the container product wraps the chart, and what a customer sees when they install from the Marketplace. For everything about how Helm install actually works — topology values, secrets, the /health probe — see 07-deploy-with-helm.md. That document is the substrate; this one references it, it does not repeat it.

1. Why AWS Marketplace

AWS Marketplace lets an EKS customer deploy ButtrBase directly into their own AWS account — they find the listing, subscribe, and deploy the Helm chart into their cluster. The purchase settles through their existing AWS billing account; ButtrBase never touches their payment method.

This maps exactly to the single-tenant-byoc topology: the customer owns the EKS cluster, the RDS Postgres instance, and the S3 bucket. ButtrBase's Mothership provisions the tenant record and issues the encryption keys; the customer's AWS infrastructure runs the workload. See the deployment matrix in docs/specs/federation-and-deployment-architecture.md for where single-tenant-byoc sits relative to the other topologies and why the marketplace path lands there.

| What AWS Marketplace provides | What you still own | |-------------------------------|-------------------| | Listing discoverability and subscribe flow for AWS customers | The Helm chart logic and values files | | Consolidated AWS billing (charges appear on customer's AWS invoice) | Mothership provisioning and entitlement sync | | ECR hosting and image scanning for the listed container | The container image (ghcr.io/buttrbase/buttrbase-backend-rust) | | AWS License Manager entitlement wiring (Metering Service) | The support, SLA, and upgrade path |

2. Prerequisites

  • An AWS account with billing enabled. The following services must be available in your chosen region: Amazon ECR*, **Amazon EKS**, *AWS License Manager.
  • aws CLI configured: aws configure or an active IAM role with ECR push and EKS describe permissions.
  • Docker installed and running locally.
  • An EKS cluster (1.25+) and kubectl configured against it.
  • Helm 3.12+.
  • Marketplace listing — forward-looking] An AWS Marketplace seller account. Seller onboarding is the gating step — AWS reviews the application and tax/banking information before you can submit a product. Begin at the [AWS Marketplace Management Portal and follow the seller registration flow. The review process typically takes several business days.
  • 3. Create an ECR repository and push the image

    AWS Marketplace container products must reference images in Amazon ECR (not GHCR) so AWS's validation and scanning pipelines can reach them.

    Create a private ECR repository in the region where you intend to list:

    aws ecr create-repository \
      --repository-name buttrbase/buttrbase-backend-rust \
      --region us-east-1
    

    Authenticate Docker to ECR (replace 111122223333 with your AWS account ID and us-east-1 with your region throughout):

    aws ecr get-login-password --region us-east-1 \
      | docker login --username AWS --password-stdin \
        111122223333.dkr.ecr.us-east-1.amazonaws.com
    

    Pull the pinned release image from GHCR, tag it for ECR, and push. Never list latest on Marketplace — pin a real release tag:

    docker pull ghcr.io/buttrbase/buttrbase-backend-rust:0.1.0

    docker tag \ ghcr.io/buttrbase/buttrbase-backend-rust:0.1.0 \ 111122223333.dkr.ecr.us-east-1.amazonaws.com/buttrbase/buttrbase-backend-rust:0.1.0

    docker push \ 111122223333.dkr.ecr.us-east-1.amazonaws.com/buttrbase/buttrbase-backend-rust:0.1.0

    After this step the image is accessible to AWS's scanning pipeline. ECR automatically runs Basic Scanning on push; you can also enable Enhanced Scanning (Inspector) in the ECR console if your Marketplace listing requires a clean scan report.

    4. Package the chart as an AWS Marketplace container product

    [Marketplace listing — forward-looking]

    AWS Marketplace supports a Container product delivery method. When the delivery method is set to Helm chart, the chart itself is the fulfillment artifact — AWS does not require a separate deployer image the way GCP does. The product is defined in the AWS Marketplace Management Portal and references the ECR image URI you pushed in step 3.

    | Artifact | Purpose | |----------|---------| | ECR image URI | The versioned container image AWS scans and hosts for customer deployments. | | Helm chart (as a ZIP upload or referenced chart source) | The fulfillment artifact AWS delivers to customers. This is deploy/helm/buttrbase-backend-rust/ as-is. | | Pricing dimensions | Units that drive billing via the AWS Marketplace Metering Service — for ButtrBase, the natural unit is active tenants or seats. | | EULA | End-User License Agreement attached to the product in the portal. |

    The chart at deploy/helm/buttrbase-backend-rust/ is the deliverable. Customers install it with a values overlay shaped like values-single-tenant-byoc.yaml, with their own inputs (tenant slug, region, RDS endpoint, S3 bucket) set at install time.

    5. Submit the listing

    [Marketplace listing — forward-looking]

    Submission happens entirely in the AWS Marketplace Management Portal web UI. The steps are:

    1. In the Management Portal, create a new Container product (not an AMI product or SaaS product — Container is the path for Helm-delivered EKS workloads). 2. Under Delivery options*, select *Helm chart and provide the ECR image URI from step 3 as the application image reference. 3. Upload or reference the Helm chart. The portal accepts the chart as a versioned artifact — package deploy/helm/buttrbase-backend-rust/ with helm package and upload the resulting .tgz. 4. Fill in product metadata: title, description, categories, support contacts, and the EULA. 5. Configure pricing dimensions in the Metering Service section. Define the unit (for example, active-tenants) and the per-unit price. AWS handles billing aggregation; your backend reports consumption via the AWS Marketplace Metering Service API at runtime. 6. AWS runs automated validation against the submitted container image — scanning for known CVEs and confirming the image is pullable. A failed scan blocks submission; a clean scan is required before the product reaches review. 7. Submit for AWS's review. Expect several business days for a first submission.

    Do not attempt to drive these steps from the aws CLI — the Marketplace producer workflow for container products is portal-native. There is no aws marketplace create-container-product subcommand in the standard AWS CLI.

    6. Customer install experience

    Once the listing is live, a customer's path is:

    1. Find ButtrBase* in AWS Marketplace and click *Subscribe. 2. Accept the EULA and confirm the pricing dimensions. The subscription is recorded against their AWS account. 3. AWS provides the customer with the Helm chart and the ECR image URI (the image is made available in the customer's account via a Marketplace-managed ECR endpoint). 4. The customer configures kubectl against their EKS cluster and runs Helm install with their own values overlay (see step 7 below). 5. The running pod registers its metering usage with the AWS Marketplace Metering Service — the customer's charges appear on their next AWS invoice.

    The customer works entirely within their own AWS account. Underneath, the chart is the same one from 07, with topology values matching values-single-tenant-byoc.yaml.

    7. Customer install on EKS

    This is what the customer (or an operator acting on their behalf) runs after subscribing. First, configure kubectl against the target EKS cluster:

    aws eks update-kubeconfig \
      --name CUSTOMER_CLUSTER_NAME \
      --region us-east-1
    

    Create the namespace and the three required secrets — the same layout as tutorial 07:

    kubectl create namespace buttrbase

    kubectl -n buttrbase create secret generic buttrbase-backend-rust \ --from-literal=database-url='postgres://buttrbase:…@db.internal:5432/buttrbase' \ --from-literal=secret-key="$(openssl rand -hex 32)" \ --from-literal=encryption-key="$(openssl rand -hex 32)"

    > Back up the encryption-key in AWS Secrets Manager or Parameter Store before running the install. It encrypts tenant secrets at rest; losing it means losing access to every encrypted value.

    Install from the chart with the single-tenant-byoc values overlay, setting the image to the ECR URI AWS provided at subscription time:

    helm upgrade --install buttrbase ./buttrbase-backend-rust \
      -n buttrbase \
      -f ./buttrbase-backend-rust/values-single-tenant-byoc.yaml \
      --set app.image.repository=111122223333.dkr.ecr.us-east-1.amazonaws.com/buttrbase/buttrbase-backend-rust \
      --set app.image.tag=0.1.0 \
      --set topology.tenantSlug=acme \
      --set topology.tenantRegion=us-east-1 \
      --set topology.storageBucket=acme-buttrbase \
      --set topology.publicBaseUrl=https://buttrbase.acme.example
    

    upgrade --install is idempotent: the first run installs, every later run is a rolling upgrade with no downtime.

    8. Verify the install

    Verification is identical to tutorial 07 — the chart is the same chart. Once the deployment is running, check readiness and probe the health endpoint:

    kubectl -n buttrbase rollout status deploy/buttrbase --timeout=120s
    kubectl -n buttrbase port-forward svc/buttrbase 4300:4300 &
    curl -fsS http://localhost:4300/health && echo "  ✓ healthy"
    

    Confirm the topology round-tripped:

    kubectl -n buttrbase exec deploy/buttrbase -- printenv BUTTRBASE_RUST_DEPLOYMENT_MODE
    

    → single-tenant-byoc

    If the pod is not ready, read the logs — the two dominant first-install failures are a database-url the pod's network cannot reach and an encryption-key that is not 32 bytes hex. Both appear in the first ten log lines:

    kubectl -n buttrbase logs deploy/buttrbase --tail=50
    

    Done

    You have the full AWS Marketplace packaging path: the image is in ECR, the chart is ready for the container product listing, and the customer install on EKS maps cleanly to single-tenant-byoc. From here:

  • Back to the substrate — if anything in the install behaves unexpectedly, 07-deploy-with-helm.md is the ground truth for chart behavior, values semantics, and secret layout.
  • GCP Marketplace — tutorial 08 covers the same chart packaged as a GKE Marketplace listing (Artifact Registry + deployer image path).
  • Azure Marketplace — tutorial 10 covers the Managed Application and AKS path.