Stacks & SSM Wiring
An Axis application is a set of independently deployable CDK stacks. Every value that crosses a stack boundary — a table ARN, a user-pool ID, an API stage ARN — travels through SSM Parameter Store, never through CloudFormation exports. This one rule is what keeps stacks independently deployable, substitutable, and safe to evolve.
The stack topology
Section titled “The stack topology”The full-breadth starters compose up to seven stacks; leaner starters and composer selections use a subset. Producers write SSM parameters; consumers read them:
flowchart TD
subgraph DataStack["DataStack"]
dynamo["DynamoDB tables"]
sqs["SQS queues (DLQ by default)"]
sns["SNS topics"]
storage["KMS · S3 · Secrets"]
events["EventBridge"]
end
subgraph CognitoStack["CognitoStack"]
pool["User pool + client"]
end
subgraph ApiStack["ApiStack / HttpApiStack / GraphqlStack"]
api["API + route/resolver Lambdas"]
end
subgraph WorkerStack["WorkerStack"]
workers["Worker + cron Lambdas"]
end
subgraph SecurityStack["SecurityStack"]
waf["WAF WebACL"]
ses["SES identity"]
end
subgraph ObservabilityStack["ObservabilityStack"]
obs["Alarms · alert topic · dashboard"]
end
subgraph BudgetStack["BudgetStack (opt-in)"]
budget["AWS Budget + alerts"]
end
DataStack -. "ssm:dynamodb/‹table›/tableArn" .-> ApiStack
DataStack -. "ssm:sqs/‹queue›/queueArn" .-> WorkerStack
DataStack -. "ssm:sqs/‹queue›/dlqArn" .-> ObservabilityStack
CognitoStack -. "ssm:cognito/userPoolId" .-> ApiStack
ApiStack -. "ssm:api/restApiStageArn" .-> SecurityStack
Dashed edges are SSM reads — the same picture axs visualize draws for your own project from its config.
The parameter contract
Section titled “The parameter contract”Parameters are namespaced /{appName}/{stageName}/{service}/{baseName}/{field}:
/my-api/dev/dynamodb/main/tableArn/my-api/dev/cognito/userPoolId/my-api/dev/api/restApiStageArn/my-api/dev/appsync/main/apiArnThe ParameterRegistry in @axis-tech-co/axis-core provides the read/write surface (put, putMany, get, getMany, getVersioned), and the framework stacks use it consistently — a DataStack writes its resources’ identifiers as it creates them; an ApiStack imports the Cognito pool by reading cognito/userPoolId.
Two hard rules ride along:
- ARNs, names, URLs, and IDs only — never secret material. A Secrets Manager secret publishes its ARN to SSM; the value is resolved at runtime through the Secrets Manager API and IAM grants. Writing a secret value into a String parameter would expose it in plaintext in the parameter store and in synthesized templates.
CfnOutputis for humans only. Stacks still emit outputs like the API URL for console copy-paste — but never withexportName. An export is the thing this whole design exists to avoid.
Why not CloudFormation exports
Section titled “Why not CloudFormation exports”CloudFormation exports look simpler but carry a fatal coupling: once another stack references an export, the producer cannot rename it, change its type, or delete it without first removing every consumer. That means lock-step deployments and cascading failures — the opposite of independent stack evolution. With SSM:
- Stacks deploy and destroy independently. No deployment-order constraints imposed by the reference mechanism.
- Renaming a key is a one-line consumer update, not a multi-stack unwind.
- Parameters survive stack destruction in prod (retained), which makes rollbacks safer.
- Whole stacks become substitutable. Because consumers only know SSM paths, you can replace an entire Axis stack with your own custom stack that writes the same paths — the substitution mechanism the composer makes first-class.
The costs are small and accepted: SSM lookups during synthesis, and a slightly more verbose two-step import in consumers (read the identifier, construct the resource reference from it).
Extending with your own stacks
Section titled “Extending with your own stacks”When you add a raw-CDK stack beside the framework’s (every starter’s STRUCTURE.md shows the pattern), follow the same discipline: read producers’ SSM parameters instead of passing construct handles across stacks, and publish your own outputs under the same /{app}/{stage}/… namespace so other stacks — and axs visualize — can see them.
© 2026 Axis Tech. Powered by axis-tech.co.