Install AGLedger on Amazon EKS

This guide brings up a single AGLedger Server on Amazon EKS, reachable on a real hostname over TLS, using AWS-native services: an AWS Load Balancer Controller Application Load Balancer (ALB), an AWS Certificate Manager (ACM) certificate, and Amazon Aurora PostgreSQL as the database. It is the AWS companion to Install AGLedger on Kubernetes; read that first for the base model (signing key, readiness gate). Every command below is a literal transcript captured against a live Server reachable at https://agledger-aws.agledger.ai.

Validated against API v0.25.4 on 2026-05-25 (Amazon EKS 1.35, Amazon Aurora PostgreSQL 17.9, AWS Load Balancer Controller 2.x, Helm 3.20, cosign 3.0).

AWS prerequisites

1. Prepare the Amazon Aurora database

Create a dedicated database and an application role. Run this from inside the VPC (Aurora is not publicly reachable) — for example a one-off psql pod connecting as the Aurora master user.

CREATE ROLE agledger_aws_app LOGIN PASSWORD '<app-password>';
GRANT agledger_aws_app TO agledger;          -- master must be a member to set ownership
CREATE DATABASE agledger_aws OWNER agledger_aws_app;

Migration privilege. The schema migration creates a PostgreSQL event trigger (agledger_block_audit_drop, which protects the audit chain). Event triggers require superuser; on Aurora / RDS that is the rds_superuser role. A plain database-owner role is not enough — the migration fails with permission denied to create event trigger. Grant the migration role rds_superuser:

GRANT rds_superuser TO agledger_aws_app;

For least-privilege role separation (a privileged role for migrations, a restricted role for the running Server), use the chart's secrets.databaseUrlMigrate for the migration DDL and a restricted database.externalUrl for the API and worker.

The connection string uses sslmode=require. The agledger image bundles the AWS RDS / Aurora root CA at /etc/ssl/certs/rds-global-bundle.pem, so the Server validates the Aurora server certificate — set config.nodeExtraCaCerts to that path.

2. Values for the AWS path

aws-values.yaml:

image:
  digest: "sha256:489d5d215303d7920b6421f143dd6020674cbac5beef5b5326b9835dd2fa0f0b"  # 0.25.4
database:
  poolMax: 20
config:
  externalUrl: "https://agledger-aws.agledger.ai"          # the Server's signed issuer identity
  nodeExtraCaCerts: "/etc/ssl/certs/rds-global-bundle.pem"  # bundled AWS RDS / Aurora CA
ingress:
  enabled: true
  className: alb
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/healthcheck-path: /health
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-west-2:<acct>:certificate/<id>"
  hosts:
    - host: agledger-aws.agledger.ai
      paths: [{ path: /, pathType: Prefix }]
  tls: []   # TLS terminates at the ALB via the ACM cert above — no in-cluster TLS secret
networkPolicy:
  enabled: false   # see note below

NetworkPolicy on the ALB path. The chart's default NetworkPolicy admits ingress only from ingress-controller pods (ingress-nginx / traefik). With target-type: ip, the ALB sends traffic and health checks from VPC elastic network interfaces — not from a pod — so the default policy blocks the ALB and targets never go healthy. Set networkPolicy.enabled: false on the ALB path (or apply your own policy admitting the VPC CIDR on port 3000).

3. Install

Generate the vault signing key and create the platform key exactly as in Install (steps 2 and 4). Inject the Aurora URL and signing key with --set so neither is written to the values file.

$ kubectl create namespace agledger-aws
$ helm install agledger oci://registry-1.docker.io/agledger/agledger-chart \
    --version 0.25.4 --namespace agledger-aws \
    --values aws-values.yaml \
    --set database.externalUrl='postgresql://agledger_aws_app:<pw>@<aurora-endpoint>:5432/agledger_aws?sslmode=require' \
    --set secrets.vaultSigningKey=<vault-key>
NAME: agledger
STATUS: deployed
REVISION: 1
  API URL:  https://agledger-aws.agledger.ai

$ kubectl rollout status deploy/agledger-agledger-chart-api -n agledger-aws --timeout=180s
deployment "agledger-agledger-chart-api" successfully rolled out
$ kubectl get pods,jobs -n agledger-aws
pod/agledger-agledger-chart-api-...      1/1   Running
pod/agledger-agledger-chart-migrate-...  0/1   Completed
pod/agledger-agledger-chart-worker-...   1/1   Running
job.batch/agledger-agledger-chart-migrate   Complete   1/1   7s

4. Point DNS at the ALB

The Ingress provisions an ALB; read its hostname and create a DNS record for your host (CNAME, or a Route 53 alias) pointing at it.

$ kubectl get ingress -n agledger-aws
NAME                      CLASS   HOSTS                      ADDRESS
agledger-agledger-chart   alb     agledger-aws.agledger.ai   k8s-agledger-agledger-....us-west-2.elb.amazonaws.com

Wait for the ALB target to register as healthy:

$ aws elbv2 describe-target-health --target-group-arn <tg-arn> \
    --query 'TargetHealthDescriptions[].TargetHealth.State'
[ "healthy" ]

5. The readiness gate: named, TLS-terminated, signing

Reach the Server on its real hostname over HTTPS. The ALB serves the ACM certificate.

$ curl -s https://agledger-aws.agledger.ai/health
{"status":"ok","version":"0.25.4","timestamp":"..."}

$ echo | openssl s_client -connect agledger-aws.agledger.ai:443 \
    -servername agledger-aws.agledger.ai 2>/dev/null | openssl x509 -noout -subject -issuer
subject=CN = *.agledger.ai
issuer=C = US, O = Amazon, CN = Amazon RSA 2048 M04

$ curl -s -o /dev/null -w "HTTP %{http_code} -> %{redirect_url}\n" http://agledger-aws.agledger.ai/health
HTTP 301 -> https://agledger-aws.agledger.ai:443/health

The served certificate is issued by Amazon (ACM), and plain HTTP is redirected to HTTPS by the ssl-redirect annotation. Confirm the Server is signing with the key you generated — the keyId matches your vault-key fingerprint:

$ curl -s https://agledger-aws.agledger.ai/v1/verification-keys
{"data":[{"keyId":"c4ddafd6bf06f1ef","algorithm":"Ed25519","status":"active"}],"envelope":"COSE_Sign1"}

The Server is healthy, reachable on its name over an ACM-issued certificate, backed by Aurora, and signing with your key.

AWS licensing

With no license the Server runs as Developer Edition. For Enterprise via AWS Marketplace, set the Marketplace product code and grant the Server's service account access to AWS License Manager with IRSA — marketplace.productCode and marketplace.serviceAccountAnnotations in the chart values.

Air-gapped / private registries

To run from Amazon ECR instead of Docker Hub, mirror agledger/agledger:0.25.4 into ECR, set image.repository to the ECR repository and image.pullSecrets (or use the node role / IRSA for ECR pull), and pin image.digest. Verify the mirrored image against cosign.pub first.