Skip to content
cloudemu
Services

§ Documentation

Parameter Store

In-memory SSM Parameter Store with versions, labels, hierarchies, and Run Command, driven with the real AWS SDK

aws SSM Parameter Store

Emulates AWS Systems Manager Parameter Store — the hierarchical config store your app reads settings and secrets out of at startup instead of baking them into the image. You put named parameters (String, StringList, SecureString), read them back by name, version, or label, fetch a whole path prefix at once, and walk a parameter's version history. Everything lives in memory, so a test run starts from an empty store and leaves nothing behind.

Reach for it whenever your code loads config from /app/prod/..., resolves a SecureString credential, or pins a specific parameter version or label — so you can exercise those paths without a real SSM account or network. Because the SDK-compat server speaks the real wire protocol, your production config-loading code runs unchanged against it. Parameter Store is an AWS-only service; there is no Azure or GCP equivalent in cloudemu.

ProviderServiceSDK-compatDriver
AWSSSM Parameter Store✓ Liveaws.SSM

Drive it with the real SDK#

Run cloudemu as a server and point your existing production code at it — the same client, with only the endpoint redirected. The handler matches the AmazonSSM. X-Amz-Target prefix (AWS JSON 1.1), so a real aws-sdk-go-v2/service/ssm client with a custom endpoint works unchanged. Start it with cloudemu serve (or docker run --rm -p 4566:4566 ghcr.io/stackshy/cloudemu), which serves the AWS API on http://localhost:4566:

cloudemu serve   # AWS API on http://localhost:4566

Then point the SSM client at that endpoint and write and read a parameter:

import (
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/service/ssm"
    "github.com/aws/aws-sdk-go-v2/service/ssm/types"
)

client := ssm.NewFromConfig(cfg, func(o *ssm.Options) {
    o.BaseEndpoint = aws.String("http://localhost:4566")
})

client.PutParameter(ctx, &ssm.PutParameterInput{
    Name:  aws.String("/app/prod/db-url"),
    Value: aws.String("postgres://db:5432/app"),
    Type:  types.ParameterTypeString,
})

out, _ := client.GetParameter(ctx, &ssm.GetParameterInput{
    Name: aws.String("/app/prod/db-url"),
})
// out.Parameter.Value == "postgres://db:5432/app"

In-process (Go unit tests)#

For Go unit tests written inside cloudemu-aware code, stand the same wire server up in-process with httptest.NewServer and point the client at ts.URL. The Drivers you pass name exactly the drivers this service needs:

import (
    "github.com/stackshy/cloudemu/v2"
    awsserver "github.com/stackshy/cloudemu/v2/server/aws"
)

cloud := cloudemu.NewAWS()
ts := httptest.NewServer(awsserver.New(awsserver.Drivers{SSM: cloud.SSM}))
defer ts.Close()
// point the same ssm client at ts.URL instead of the running endpoint

Call the driver directly#

When you don't need to drive a real SDK — for example in cloudemu-only setup code — skip the HTTP hop and call the driver. The same operations, minus the client boilerplate:

import ssmdriver "github.com/stackshy/cloudemu/v2/services/parameterstore/driver"

aws.SSM.PutParameter(ctx, ssmdriver.PutConfig{
    Name:  "/app/prod/db-url",
    Value: "postgres://db:5432/app",
    Type:  ssmdriver.TypeString,
})

param, _ := aws.SSM.GetParameter(ctx, "/app/prod/db-url", false)

PutParameter's config carries the type (String / StringList / SecureString), an Overwrite flag (a second put to an existing name without it is rejected, as on the real service), and an optional Tier. GetParameter's withDecryption argument mirrors the SDK flag — cloudemu stores SecureString values as-is (there is no real KMS integration), so decryption is a no-op that returns the stored value.

Read many parameters, or a whole path#

GetParameters resolves a batch by name in one call, returning the found parameters and the invalid names separately, and GetParametersByPath fetches every parameter under a hierarchy prefix — the call an app makes to load its entire config namespace at boot:

found, invalid, _ := aws.SSM.GetParameters(ctx,
    []string{"/app/prod/db-url", "/app/prod/missing"}, false)
// found has db-url; invalid == ["/app/prod/missing"]

all, _ := aws.SSM.GetParametersByPath(ctx, ssmdriver.GetByPathInput{
    Path:      "/app/prod/",
    Recursive: true,
})

Versions and labels#

Every overwrite creates a new version rather than replacing in place, so you can read history and pin a specific version or a moving label — the mechanism config rollouts lean on:

// Each Overwrite put bumps the version
aws.SSM.PutParameter(ctx, ssmdriver.PutConfig{
    Name: "/app/prod/db-url", Value: "postgres://new:5432/app",
    Type: ssmdriver.TypeString, Overwrite: true,
})

history, _ := aws.SSM.GetParameterHistory(ctx, "/app/prod/db-url") // oldest first

// Attach a label to a version (0 = latest), then address it as name:label
aws.SSM.LabelParameterVersion(ctx, "/app/prod/db-url", 0, []string{"prod"})
param, _ := aws.SSM.GetParameter(ctx, "/app/prod/db-url:prod", false)

Behavior & fidelity#

BehaviorWhat happens
Versioned, not destructiveEach Overwrite put appends a version, and GetParameterHistory returns every version oldest-first.
Addressable by version or labelA name resolves as name:3 (version) or name:prod (label); a missing one returns ParameterVersionNotFound, distinct from ParameterNotFound.
HierarchiesGetParametersByPath walks a /-delimited prefix (optionally recursive), matching how Parameter Store namespaces config trees.
Public parametersReads under /aws/service/ (Amazon Linux, EKS-optimized, Ubuntu/Debian/Bottlerocket AMI aliases) resolve synthetic values, so AMI-by-alias lookups work without a real account.
TagsParameters can be tagged, and their tags listed or removed, the same way the real service exposes it.
Run Command (optional)An optional send-and-poll surface, discovered by type assertion; targeting a nonexistent instance returns InvalidInstanceId, but nothing executes — invocations report success with empty output, exercising orchestration rather than the script.

SDK-compat — Live#

Real ssm clients drive it end-to-end. See SDK-Compat for the full operation list.

On this page

On this page