Skip to main content

SES

Protocol: Query (XML) — POST http://localhost:4566/ with Action= parameter SES supports sending plain text and raw emails, identity verification, and DKIM attributes — with 14 operations total.
ActionDescription
SendEmailSend a formatted email
SendRawEmailSend a raw MIME email
VerifyEmailIdentityVerify an email address
VerifyDomainIdentityVerify a domain
ListIdentitiesList all verified identities
GetIdentityVerificationAttributesGet verification status for identities
DeleteIdentityRemove a verified identity
GetIdentityDkimAttributesGet DKIM attributes for an identity
SetIdentityDkimEnabledEnable or disable DKIM for an identity
GetSendQuotaGet sending quota details
GetSendStatisticsGet sending statistics
SetIdentityNotificationTopicSet SNS topic for bounce/complaint/delivery notifications
GetIdentityNotificationAttributesGet notification settings for an identity
SetIdentityFeedbackForwardingEnabledEnable/disable feedback forwarding

Examples

export AWS_ENDPOINT=http://localhost:4566

# Verify sender identity first
aws ses verify-email-identity \
  --email-address [email protected] \
  --endpoint-url $AWS_ENDPOINT

# Send an email
aws ses send-email \
  --from [email protected] \
  --destination [email protected] \
  --message '{
    "Subject": {"Data": "Hello from Floci"},
    "Body": {
      "Text": {"Data": "This is a test email sent via Floci SES emulation."},
      "Html": {"Data": "<p>This is a <b>test email</b> sent via Floci SES emulation.</p>"}
    }
  }' \
  --endpoint-url $AWS_ENDPOINT

OpenSearch Service

Protocol: REST JSON
Endpoint: http://localhost:4566/2021-01-01/...
Credential scope: es
OpenSearch supports 24 operations for domain management, tagging, version queries, and instance type queries.

Implementation Modes

Domains are stored in memory and appear ACTIVE immediately. No real search capability — data-plane endpoints (/_search, /_index, etc.) are not available.This is the default mode and is sufficient for testing infrastructure code that creates, describes, and deletes OpenSearch domains.
Domain Lifecycle
OperationMethod + PathDescription
CreateDomainPOST /2021-01-01/opensearch/domainCreate a new domain
DescribeDomainGET /2021-01-01/opensearch/domain/{name}Get domain details
DescribeDomainsPOST /2021-01-01/opensearch/domain-infoBatch describe domains
DescribeDomainConfigGET /2021-01-01/opensearch/domain/{name}/configGet domain configuration
UpdateDomainConfigPOST /2021-01-01/opensearch/domain/{name}/configUpdate cluster config, EBS options, engine version
DeleteDomainDELETE /2021-01-01/opensearch/domain/{name}Delete a domain
ListDomainNamesGET /2021-01-01/domainList all domains
Tags
OperationMethod + PathDescription
AddTagsPOST /2021-01-01/tagsAdd tags to a domain by ARN
ListTagsGET /2021-01-01/tags/?arn=List tags for a domain
RemoveTagsPOST /2021-01-01/tags-removalRemove tag keys from a domain
Versions & Instance Types
OperationMethod + PathDescription
ListVersionsGET /2021-01-01/opensearch/versionsList supported engine versions
GetCompatibleVersionsGET /2021-01-01/opensearch/compatibleVersionsList valid upgrade paths
ListInstanceTypeDetailsGET /2021-01-01/opensearch/instanceTypeDetails/{version}List available instance types
DescribeInstanceTypeLimitsGET /2021-01-01/opensearch/instanceTypeLimits/{version}/{type}Get limits for an instance type
Stubs (SDK-compatible, no-op responses)DescribeDomainChangeProgress · DescribeDomainAutoTunes · DescribeDryRunProgress · DescribeDomainHealth · GetUpgradeHistory · GetUpgradeStatus · UpgradeDomain · CancelDomainConfigChange · StartServiceSoftwareUpdate · CancelServiceSoftwareUpdate

Configuration

floci:
  services:
    opensearch:
      enabled: true
      mode: mock                                       # mock | real
      default-image: "opensearchproject/opensearch:2"  # used only when mode=real
      proxy-base-port: 9400
      proxy-max-port: 9499
  storage:
    services:
      opensearch:
        flush-interval-ms: 5000
Environment variables:
VariableDefaultDescription
FLOCI_SERVICES_OPENSEARCH_ENABLEDtrueEnable/disable the service
FLOCI_SERVICES_OPENSEARCH_MODEmockmock or real
FLOCI_SERVICES_OPENSEARCH_DEFAULT_IMAGEopensearchproject/opensearch:2Docker image for real mode
FLOCI_SERVICES_OPENSEARCH_PROXY_BASE_PORT9400Port range start for real mode
FLOCI_SERVICES_OPENSEARCH_PROXY_MAX_PORT9499Port range end for real mode

Emulation Behavior

  • Domain name: 3–28 characters, must start with a lowercase letter, only lowercase letters, digits, and hyphens.
  • ARN format: arn:aws:es:{region}:{accountId}:domain/{domainName}
  • Processing: Always false in mock mode — domains are ACTIVE immediately.
  • Engine version default: OpenSearch_2.11
  • Cluster defaults: m5.large.search, 1 instance, EBS enabled with 10 GiB gp2 volume.

Examples

export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test

# Create a domain
aws opensearch create-domain \
  --domain-name my-search \
  --engine-version "OpenSearch_2.11" \
  --cluster-config InstanceType=m5.large.search,InstanceCount=1 \
  --ebs-options EBSEnabled=true,VolumeType=gp2,VolumeSize=10

# Describe the domain
aws opensearch describe-domain --domain-name my-search

# List all domains
aws opensearch list-domain-names

# Update cluster config
aws opensearch update-domain-config \
  --domain-name my-search \
  --cluster-config InstanceCount=3

# Add tags
aws opensearch add-tags \
  --arn arn:aws:es:us-east-1:000000000000:domain/my-search \
  --tag-list Key=env,Value=dev

# List tags
aws opensearch list-tags \
  --arn arn:aws:es:us-east-1:000000000000:domain/my-search

# Delete domain
aws opensearch delete-domain --domain-name my-search

SDK Example

OpenSearchClient os = OpenSearchClient.builder()
    .endpointOverride(URI.create("http://localhost:4566"))
    .region(Region.US_EAST_1)
    .credentialsProvider(StaticCredentialsProvider.create(
        AwsBasicCredentials.create("test", "test")))
    .build();

// Create a domain
CreateDomainResponse created = os.createDomain(req -> req
    .domainName("my-search")
    .engineVersion("OpenSearch_2.11")
    .clusterConfig(c -> c
        .instanceType(OpenSearchPartitionInstanceType.M5_LARGE_SEARCH)
        .instanceCount(1))
    .ebsOptions(e -> e
        .ebsEnabled(true)
        .volumeType(VolumeType.GP2)
        .volumeSize(10)));

System.out.println("ARN: " + created.domainStatus().arn());

// List domains
os.listDomainNames(req -> req.build())
    .domainNames()
    .forEach(d -> System.out.println(d.domainName()));

// Delete
os.deleteDomain(req -> req.domainName("my-search"));

Build docs developers (and LLMs) love