Learn LocalStack - Secrets Manager & SSM Parameter Store
Episode 11 of 23

Learn LocalStack - Secrets Manager & SSM Parameter Store

Managing secrets and configuration centrally with AWS Secrets Manager and SSM Parameter Store: storing secrets and parameters, reading them from Lambda and ECS, plus rotation, tagging, and permission scenarios.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In episode 10 we defined the entire infrastructure as code. But infrastructure without configuration is like a car without keys: database URLs, API keys, passwords, and SMTP credentials have to go somewhere. Hardcoding them in code or environment variables is practical, but leaks through git history and logs. AWS answers with two centralized services: Secrets Manager for high-value secrets and SSM Parameter Store for general configuration.

In this episode you'll store and read secrets and parameters in LocalStack, connect them to Lambda and ECS, and test rotation and permission scenarios without a real AWS account.

Secrets Manager vs Parameter Store

Both services look similar, but they were created for different needs:

AspectSecrets ManagerParameter Store
PurposeHigh-value secretsGeneral configuration
Automatic rotationYes (via Lambda)No
VersioningStage-based (AWSCURRENT)Versions, but simpler
Maximum size64 KB4,096 (Standard) / 8,192 (Advanced) characters
PricePer secret + per callFree (Standard)

In the emulator, pricing rules don't apply — both are free and unlimited. What matters is getting used to choosing the right tool: store passwords, API keys, and tokens in Secrets Manager; store configuration values like log level or endpoint in Parameter Store.

Storing & Reading Secrets

Creating Your First Secret

The Secrets Manager API is very simple. Create a secret with --secret-string, then read its value:

Simpan dan baca secret
awslocal secretsmanager create-secret \
  --name db/password --secret-string 'P@ssw0rd!'
awslocal secretsmanager get-secret-value \
  --secret-id db/password

LocalStack stores that value in emulator state and returns it exactly like real AWS. To see the full JSON payload, pipe the output through jq:

Ekstrak nilai secret dengan jq
awslocal secretsmanager get-secret-value \
  --secret-id db/password | jq -r '.SecretString'

Secret Versioning

Secrets have versions. When the value changes, the old version moves to the AWSPREVIOUS stage and the new version becomes AWSCURRENT:

Update secret dan lihat staging
awslocal secretsmanager put-secret-value \
  --secret-id db/password --secret-string 'P@ssw0rd!2'
awslocal secretsmanager get-secret-value \
  --secret-id db/password --version-stage AWSPREVIOUS

This pattern enables fast rollback: applications always read AWSCURRENT, and teams can compare old versions without keeping manual duplicates.

Parameter Store

Parameter Tiers & SecureString

SSM Parameter Store has three types: String, StringList, and SecureString (KMS-encrypted). Parameters also have tiers: Standard (free, 4,096 characters) and Advanced (paid, 8,192 characters):

Put dan get parameter
awslocal ssm put-parameter \
  --name /app/prod/LOG_LEVEL --value debug --type String
awslocal ssm put-parameter \
  --name /app/prod/DB_PASSWORD --value 'secret-value' --type SecureString
awslocal ssm get-parameter --name /app/prod/DB_PASSWORD --with-decryption

Without --with-decryption, a SecureString value appears encrypted. LocalStack uses the default KMS key alias/aws/ssm for this — just like AWS.

Reading Many Parameters at Once

Naming parameters with a hierarchical path unlocks the get-parameters-by-path feature — fetch an entire service's configuration in a single call:

Ambil semua parameter di satu path
awslocal ssm get-parameters-by-path \
  --path /app/prod --recursive

Integration with Lambda & ECS

A secret is only useful if applications can read it. In LocalStack, Lambda code reads secrets exactly as in production — just point the SDK at the emulator endpoint:

PythonLambda membaca secret
import boto3
 
def handler(event, context):
    client = boto3.client(
        "secretsmanager",
        region_name="us-east-1",
        endpoint_url="http://localhost:4566",
        aws_access_key_id="test",
        aws_secret_access_key="test",
    )
    secret = client.get_secret_value(SecretId="db/password")
    return {"password": secret["SecretString"]}

For ECS, secret values are referenced directly in the task definition via the secrets property pointing to an ARN — the container runtime pulls them itself. The same pattern applies in production, so behavior never drifts.

Rotation Mock

Real rotation on AWS uses a Lambda that writes a new value to the secret. LocalStack emulates the rotate-secret API: the call is accepted and completes, but without running a real rotation Lambda:

Picu rotasi (mock)
awslocal secretsmanager rotate-secret \
  --secret-id db/password

Note

Rotation in LocalStack is a mock — enough to test code that calls the rotation API, but not to verify the rotation Lambda logic itself. Test rotation logic in CI with real test secrets.

Tagging

Plenty of secrets and parameters need organization. Both services support tagging for audit and cost allocation:

Tag secret dan parameter
awslocal secretsmanager tag-resource \
  --secret-id db/password --tags 'Key=env,Value=prod'
awslocal secretsmanager list-tags-for-resource \
  --secret-id db/password

For SSM, use ssm add-tags-to-resource with --resource-type "Parameter" and the parameter ARN as --resource-id.

Permission Scenarios in the Emulator

On real AWS, access to secrets is governed by IAM policies. In LocalStack, IAM evaluation is much looser: Deny permissions are generally ignored and almost every call succeeds as long as the ARN format is correct. That means:

  • Tests that depend on permission denial must still be verified on real AWS or through dedicated integration.
  • Use the emulator to test successful flows and request formats, not to test access control.
  • Separate credentials between environments (dev/test) from the start so they don't carry into production.

Closing

Summary of this episode:

  • Secrets Manager for high-value secrets: create-secret, put-secret-value, and the AWSCURRENT/AWSPREVIOUS version staging.
  • Parameter Store for configuration: String, SecureString, and path hierarchies with get-parameters-by-path.
  • Lambda code reads secrets via boto3 with endpoint_url pointing to http://localhost:4566.
  • Rotation is a mock; use CI with test secrets to verify real rotation logic.
  • Tagging is fully supported; IAM evaluation in the emulator is looser than real AWS.

Your configuration and secrets are now centralized. But there's a silent problem: restarting LocalStack wipes all the state you've built. In episode 12 we rescue that hard work with persistence and Cloud Pods — state that survives restarts and can be shared across your team. See you there!

Learn LocalStack - Secrets Manager & SSM Parameter Store | Learn LocalStack