Skip to content

Read AWS SSM Parameter Store

Configuration in AWS Systems Manager Parameter Store becomes a config layer through the sibling module config-aws-ssm, so a consumer who needs it takes it — and the AWS SDK — and one who does not pays nothing.

go get gitlab.com/phpboyscout/go/config-aws-ssm

You build and configure the SSM client — region, credentials, endpoint all stay yours — and hand it in. The adapter takes a path prefix that scopes and is stripped from the parameter names:

import (
    awscfg "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/ssm"
    "gitlab.com/phpboyscout/go/config"
    configawsssm "gitlab.com/phpboyscout/go/config-aws-ssm"
)

awsCfg, _ := awscfg.LoadDefaultConfig(ctx)
client := ssm.NewFromConfig(awsCfg)

store, err := config.NewStore(ctx,
    config.WithFiles(fsys, "/etc/app.yaml"),                        // YAML defaults
    config.WithBackend(configawsssm.FromClient(client, "/app/")),   // SSM outranks them
)

Parameter names are /-separated paths, so /app/server/port under prefix /app/ reads as server.port — taking part in precedence, per-key merge and provenance exactly as a file does.

store.View().GetInt("server.port") // 8080, from SSM

Value types

  • String — a scalar string; the View's typed accessors coerce it, and a JSON/YAML document value decodes into a subtree when you pass a codec: configawsssm.FromClient(client, "/app/", configawsssm.WithValueCodec(configjson.Codec{})).
  • StringList — read as a []string leaf.
  • SecureString — read decrypted (the adapter passes WithDecryption), and when a prefix contains one the whole layer reports Sensitive: the core then refuses to write any of its keys into a non-sensitive layer, so a decrypted secret cannot leak into a plain file.

Read-only, and how writes behave

SSM's PutParameter overwrites unconditionally — there is no compare-and-swap to satisfy the conflict trap the toolkit turns on, so config-aws-ssm is read-only. A write to a key it defines routes to the writable layer beneath and is reported shadowed (or, for a SecureString key, refused as a leak) — never silently applied to SSM. Write support is a tracked follow-on; until then, provision parameters through your existing IaC.

Watching

The adapter joins hot-reload by polling GetParametersByPath (NativeWatch: false) — SSM has no change feed. The default interval is conservative because of SSM's API rate limits; WithPollInterval overrides it.

What it costs

The config graph plus the AWS SDK for Go v2's SSM client (service/ssm and the SDK core — five modules, asserted by an allowlist test). You build the client, so its config/credentials packages are yours, not the adapter's. The testcontainers/LocalStack integration suite is test-only.