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
- An Amazon EKS cluster (1.27+) with
kubectlandhelmconfigured against it - The AWS Load Balancer Controller installed in the cluster — it provides the
albIngressClass and provisions the ALB from the Ingress resource. (Install via its Helm chart with an IAM Role for Service Accounts / IRSA, per the AWS docs.) - An ACM certificate in the same region as the ALB, covering your hostname (here a wildcard
*.agledger.ai), statusISSUED - An Amazon Aurora PostgreSQL cluster (or Amazon RDS for PostgreSQL) reachable from the EKS node/pod security group on 5432
cosign3.0+ to verify the release (see Install step 1 — same commands)
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.