Skip to content

feat(cloudformation): add stack sets, tree/logs/watch, and backend management [EXPERIMENTAL] - #3001

Draft
Erik Osterman (Cloud Posse) (osterman) wants to merge 7 commits into
osterman/cfn-phase2-changesets-drift-outputsfrom
osterman/cfn-phase3-stacksets-observability
Draft

feat(cloudformation): add stack sets, tree/logs/watch, and backend management [EXPERIMENTAL]#3001
Erik Osterman (Cloud Posse) (osterman) wants to merge 7 commits into
osterman/cfn-phase2-changesets-drift-outputsfrom
osterman/cfn-phase3-stacksets-observability

Conversation

@osterman

@osterman Erik Osterman (Cloud Posse) (osterman) commented Aug 26, 2026

Copy link
Copy Markdown
Member

what

  • Phase 3 of the native aws/cloudformation component type: multi-account/multi-region StackSets
    (stackset create/update/delete/instances), the nested-stack dependency tree view, and
    observability verbs (logs, watch).
  • Raises coverage to 94.9%.
  • Documents the Phase 3 stack sets and observability verbs.

why

  • StackSets and cross-account/region orchestration are a core CloudFormation capability with no
    Terraform/Helmfile equivalent in Atmos today; this phase brings that capability natively instead
    of requiring users to shell out to the AWS CLI. logs/watch give the same live-progress
    feedback during apply that Terraform's own streaming output provides.

references

  • Builds on cfn-phase2-changesets-drift-outputs in this stack.
  • Part of a 6-PR stack; see cfn-phase4-migration-graduation for the final layer and blog post.

@atmos-pro

atmos-pro Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Tip

Atmos Pro  

No affected stacks workflow was detected for this pull request.
If this is expected, no action is needed.
Learn More. Ask AI.

@github-actions github-actions Bot added the size/l Large size PR label Aug 26, 2026
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@osterman Erik Osterman (Cloud Posse) (osterman) added the no-release Do not create a new release (wait for additional code changes) label Aug 26, 2026
@osterman Erik Osterman (Cloud Posse) (osterman) changed the title osterman/cfn phase3 stacksets observability feat(cloudformation): add stack sets, tree/logs/watch, and backend management [EXPERIMENTAL] Aug 26, 2026
@osterman
Erik Osterman (Cloud Posse) (osterman) force-pushed the osterman/cfn-phase3-stacksets-observability branch from 74f5a3b to f0df545 Compare August 27, 2026 11:28
@osterman
Erik Osterman (Cloud Posse) (osterman) force-pushed the osterman/cfn-phase3-stacksets-observability branch from f0df545 to e882672 Compare August 27, 2026 11:39
@osterman
Erik Osterman (Cloud Posse) (osterman) force-pushed the osterman/cfn-phase3-stacksets-observability branch from e882672 to ef7704b Compare August 27, 2026 11:44
@osterman
Erik Osterman (Cloud Posse) (osterman) force-pushed the osterman/cfn-phase3-stacksets-observability branch from 1bc62d1 to d2fe2dd Compare August 27, 2026 15:43
@osterman
Erik Osterman (Cloud Posse) (osterman) force-pushed the osterman/cfn-phase3-stacksets-observability branch from d2fe2dd to 09b0c42 Compare August 27, 2026 16:00
@osterman
Erik Osterman (Cloud Posse) (osterman) force-pushed the osterman/cfn-phase3-stacksets-observability branch from b06a8f2 to e8df700 Compare August 27, 2026 17:32
@github-actions github-actions Bot added size/xl Extra large size PR and removed size/l Large size PR labels Aug 27, 2026
- atmos aws cloudformation stackset create/update/delete/instances:
  multi-account/multi-region deployment via a new `kind: aws/stackset`
  provision target (accounts/regions/permission_model/administration_role_arn/
  execution_role_name — extends the same ProvisionTarget struct aws/s3
  packaging already uses, no new abstraction). create also creates initial
  stack instances when accounts/regions are configured; delete removes every
  stack instance before the StackSet itself, per AWS's own ordering
  requirement; all three mutating verbs poll DescribeStackSetOperation to a
  terminal status.
- atmos aws cloudformation tree: nested-stack dependency tree, walking
  AWS::CloudFormation::Stack resources via ListStackResources (depth-bounded
  at 10).
- atmos aws cloudformation logs [--chart]: combined chronological event log
  across a stack and its nested stacks; --chart groups by resource instead.
- atmos aws cloudformation watch: attaches to a stack's in-progress (or
  already-terminal) operation and streams events — the same polling loop
  apply/delete already use internally, exposed as its own verb for attaching
  to an operation started outside Atmos.

Verified live against Floci: stackset create/instances correctly reach a real
CreateStackSet/ListStackInstances API call (proving target resolution and
dispatch are correct) but Floci itself doesn't implement StackSets at all
(malformed CreateStackSet response, "Action ListStackInstances is not
supported") — a confirmed emulator limitation, same category as Phase 2's
drift/get-policy gaps, not an Atmos bug. tree/logs/watch all verified working
end-to-end against a real deployed stack.

Also fixed a pre-existing gap in GetAvailableCommands() (used by
pkg/composition/executor.go to validate verbs, not just documentation): fmt
was missing from Phase 2's own addition, silently blocking it from
composition execution.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pkg/component/aws/cloudformation dropped to 75.7% after stackset.go/
observability.go added with no tests of their own; now 94.9%, above the
93.7% Phase 2 baseline. No production code changes — every gap closed
through the existing MockCloudFormationClient (already regenerated for this
commit's SDK methods) and this package's established seams.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…erbs

CLI docs for stackset create/update/delete/instances, tree, logs (incl.
--chart), and watch. Documents the new kind: aws/stackset provision-target
shape (accounts/regions/permission_model/administration_role_arn/
execution_role_name) in the stack-manifest component reference, alongside
the existing aws/s3 and git delivery targets.

Notes two behaviors that would otherwise read as inconsistent: stackset
delete/instances take no --target (they act on the StackSet named by the
component's stack_name directly, unlike create/update); and a
kind: aws/stackset target is not reachable via apply --target — it's
exclusively consumed by the stackset verb group, since the generic delivery
path in provision.go only special-cases aws/s3 and git.

No atmos.yaml-level config changes — Phase 3 added stack-manifest-level
provision.targets fields and CLI verbs only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every error in stackset.go (CreateStackSet, UpdateStackSet, DeleteStackSet,
CreateStackInstances, DeleteStackInstances, ListStackInstances,
DescribeStackSetOperation) was wrapped in ErrAwsCloudFormationChangeSetFailed,
despite StackSets being a completely separate CloudFormation API surface
from changesets. Added ErrAwsCloudFormationStackSetFailed and swapped it in
throughout. Also fixed listAllStackResources (tree/logs) wrapping a plain
ListStackResources failure in the same changeset sentinel — swapped to
ErrAwsCloudFormationAPICallFailed. Found via CodeRabbit review.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ns, guard nil operation

- renderStackTree only manually branch-rendered one level of children, then
  recursed into grandchildren via a bare renderStackTree call — printing
  every grandchild+ line without its own branch glyph/continuation prefix.
  Split into a properly self-recursive renderStackTreeChildren so every
  depth renders consistently.
- toStringSlice (accounts:/regions: on a `kind: aws/stackset` provision
  target) only handled a YAML list; a single scalar string (a natural
  shorthand for a one-account/one-region target) silently produced nil,
  which meant runStackSetCreate skipped creating any stack instances at
  all. Now accepts both.
- pollStackSetOperation would nil-pointer-dereference if
  DescribeStackSetOperation ever returned a response with no
  StackSetOperation; now returns an error instead.
- Documented that `stackset delete`/`instances` act directly on stack_name
  and never resolve a `kind: aws/stackset` provision target, unlike
  `create`/`update` — the doc previously implied the whole verb group
  resolves the target the same way.

Found via CodeRabbit review. The "--stack required" doc findings on
tree.mdx/watch.mdx/stackset/instances.mdx/stackset/update.mdx are the same
false positive already dismissed on phase2: --affected/--all correctly
omit --stack since they operate across stacks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This branch's own docs add logs/stackset(+create/delete/instances/update)/
tree/watch (8 verbs) on top of Phase 2's changeset/drift/fmt/get/list/
source docs, none of which had casts recorded on this branch's own tip —
each PR in this stack is validated against its own branch, not the final
merged result. Recorded the full cumulative 35-verb set (Phase 1 + 2 + 3).

atmos --chdir=demo/casts casts generate screengrabs cli --filter=cloudformation

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-release Do not create a new release (wait for additional code changes) size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant