DocsGet started

Deploy into your AWS account

One CloudFormation stack creates the server, a data bucket you own, and an admin credential in Secrets Manager.

You need a license keyProduction deployments on AWS require a license. Pilot licenses are free for 30–60 days: request one by email. To try Search without AWS, use the local pilot.

Before you begin

  • An AWS account and permission to create a CloudFormation stack with IAM roles, a VPC, EC2, S3 and Secrets Manager resources.
  • Your license key, a single line starting with SL1..
  • The IP range allowed to reach the API, for example your office egress address as 203.0.113.10/32.
  • Optional, for HTTPS: a domain name you control and an ACM certificate for it in the same region.

1. Launch the stack

Opens the AWS console's quick-create page in us-east-1 with the template preloaded. The template is not tied to a region; it looks up the Amazon Linux image in whichever region you use. Launch it in another region: us-east-2, us-west-2, eu-west-1. You can also switch regions in the console header before you choose Create stack. Your data bucket, certificate and license all stay in the region you pick.

Launch Stack

Fill in the parameters below, tick the box that acknowledges IAM resource creation, and choose Create stack.

Stack parameters
ParameterDefaultNotes
LicenseKeyrequiredYour SL1. license. Hidden in the console (NoEcho). A license may be bound to specific bucket names.
AllowedCidrrequiredWho may reach the API and console. There is deliberately no 0.0.0.0/0 default. Use the narrowest range that works.
InstanceTypet4g.smallAn arm64 Graviton instance type. Choose a larger type for bigger working sets or more concurrent queries.
DataBucketNameemptyLeave empty to create a new, retained bucket, or name an existing bucket in the same region that uses SSE-S3.
DomainName, CertificateArnemptySet both, or leave both empty. Both set adds an HTTPS load balancer with your ACM certificate. Both empty means the server listens on plain HTTP port 8080.
Versioncurrent releaseThe release to install. Change it to upgrade (see below).
ReleaseSha256current releaseSHA-256 of the release tarball. The instance refuses a download that does not match.

HTTP versus HTTPSWithout DomainName and CertificateArn, API keys travel over plain HTTP. That is fine for a short pilot from a single trusted IP. For anything else, set up the HTTPS load balancer.

What the stack creates

  • A small VPC with two public subnets (no NAT gateway) and a security group limited to AllowedCidr.
  • An S3 data bucket with Block Public Access, SSE-S3 encryption, versioning and a TLS-only policy. It is retained when the stack is deleted.
  • One EC2 instance (Amazon Linux 2023, arm64) with IMDSv2 required, an encrypted gp3 cache volume, and an Elastic IP. Administrative access is through SSM Session Manager. There is no SSH.
  • An instance role scoped to the data bucket, a Secrets Manager secret with a generated admin credential, and a CloudWatch log group.
  • If requested, an Application Load Balancer with an HTTPS listener.

At boot the instance downloads the release from this site over HTTPS and verifies its SHA-256 checksum against the value pinned in the template before installing.

2. Collect the outputs

When the stack reaches CREATE_COMPLETE, open its Outputs tab:

  • ApiEndpoint: the API base URL for your applications.
  • ConsoleUrl: the browser console (/_console).
  • LicenseStatusUrl: license status. It needs an API key with the monitor or admin action (see step 3).
  • AdminKeySecretConsoleUrl: opens the Secrets Manager secret that holds the bootstrap administrator API key.
  • BucketName, InstanceId, LogGroupName: your data bucket, the server, and its logs.
  • LoadBalancerDnsName (HTTPS only): point your DomainName at this with a CNAME or alias record.

Check that the server is up. /health needs no credentials:

curl -s <ApiEndpoint>/health

License status needs credentials. Use the administrator key from step 3:

curl -s -H 'Authorization: ApiKey <key_id>:<secret>' <ApiEndpoint>/_license

3. Sign in to the console

  1. Open AdminKeySecretConsoleUrl and choose Retrieve secret value. The secret holds key_id, secret and a ready-made authorization header. The key ID is filled in on first boot, so wait until the server is ready.
  2. Open ConsoleUrl and connect with that administrator credential. The console holds it only in browser memory, never in local storage or cookies.
  3. Treat the admin credential as break-glass. Use it to create the credentials you actually need, then store it away.

4. Create an API key for your application

In the console, open Roles & API keys. Create a role that grants read and write on your index pattern, such as articles*, then create an API key with that role. The key's secret is shown once, so copy it immediately.

You can do the same over HTTP:

curl -sX POST <ApiEndpoint>/_security/apikey \
  -H 'Authorization: ApiKey <admin_key_id>:<admin_secret>' \
  -H 'Content-Type: application/json' \
  -d '{"name": "my-app", "roles": ["articles-writer"]}'
# {"key_id":"…","secret":"…","authorization":"ApiKey <key_id>:<secret>", …}

5. Connect with opensearch-py

from opensearchpy import OpenSearch

client = OpenSearch(
    hosts=["<ApiEndpoint>"],
    headers={"Authorization": "ApiKey <key_id>:<secret>"},
)
print(client.info())  # distribution "opensearch", version 3.5.0

client.indices.create(index="articles", body={
    "mappings": {"properties": {
        "title": {"type": "text"},
        "body": {"type": "text"},
        "published": {"type": "date"},
    }}
})
client.index(index="articles", id="1", refresh="wait_for", body={
    "title": "Hello", "body": "Search that lives in object storage.",
    "published": "2026-09-27T00:00:00Z",
})
hits = client.search(index="articles", body={"query": {"match": {"body": "object storage"}}})
print(hits["hits"]["hits"])

Mappings are strict, so every field must be declared. Before porting existing queries, read the compatibility matrix.

Upgrade

Update the stack with the current template, and change Version and ReleaseSha256 to the new release. Its checksum is published at https://search.avanttechnologiesllc.com/releases/<Version>/. The instance installs the new release and recovers its state from the bucket.

CloudFormation starts the new instance before it terminates the old one. The two servers never both write: every partition has one fenced owner. While the old server still owns a partition, writes to the new one return 503 with Retry-After: 2, which OpenSearch clients retry. When the old instance shuts down it hands ownership over immediately. Searches keep working throughout. Genuine version conflicts are still 409.

Uninstall

Delete the stack. The data bucket is retained with all your data. Delete it yourself in the S3 console if you no longer need it. S3 storage keeps accruing charges until you do.

Troubleshooting

  • Cannot connect: confirm your current public IP is inside AllowedCidr, and that you are using port 8080 when no load balancer is configured.
  • 403 with license_…: check GET /_license with an administrator or monitor API key. See Licensing for what each state means.
  • Server logs: in the LogGroupName CloudWatch log group, or on the instance through SSM Session Manager.