Skip to content

AWS plugin discovery scope excludes EKS::Cluster/Nodegroup, blocking recovery from partial-create bookkeeping failures #690

Description

@mmassenzio

Summary

When a formae apply --mode reconcile create partially fails due to a
transient plugin/API error on the Formae side (Cloud Control GetResource
polling timeout), AWS can finish creating the resource successfully while
Formae never records it as managed. For certain resource types (observed:
AWS::EKS::Nodegroup), there is then no supported recovery path back
into Formae's state — not even through the documented
discovery → extract → adopt workflow — because those resource types are
outside the AWS plugin's discovery scan scope.

Environment

  • formae: 0.88.0
  • AWS plugin: 0.1.16
  • Resource type: AWS::EKS::Nodegroup (also affects AWS::EKS::Cluster)

Steps to reproduce

  1. formae apply --mode reconcile a stack containing an AWS::EKS::Cluster
    with 3 AWS::EKS::Nodegroup resources.
  2. Introduce (or wait for) a transient Cloud Control GetResource failure
    while polling create status for one or more node groups (in our case: a
    TLS handshake timeout against AWS Cloud Control). Agent logs:
    Plugin operator is missing in action after the timeout.
  3. AWS finishes creating the node group(s) successfully in the background.
    Formae's command terminates Failed and marks those specific resources
    as failed creates; they are never added to Formae's managed inventory.
  4. Confirm directly against AWS: the node group(s) are ACTIVE and healthy.
  5. Confirm against Formae: list_resources/inventory resources for that
    stack shows only the node group(s) that finished polling before the
    timeout. The others are absent entirely (not listed as managed, not
    listed as unmanaged).
  6. Trigger discovery explicitly (force_discover / wait for the scheduled
    scan). Query managed:false type:AWS::EKS::Nodegroup (or
    type:AWS::EKS::Cluster): zero results, even though the resources
    are live in the account discovery is configured against.

Root cause (as far as we can tell from the outside)

get_agent_stats shows the AWS plugin's discovery configuration includes an
explicit DiscoveryFilters allow-list:

AWS::EC2::Instance, AWS::EC2::SecurityGroup, AWS::EC2::NetworkInterface,
AWS::EC2::LaunchTemplate, AWS::AutoScaling::AutoScalingGroup,
AWS::EC2::VPCEndpoint, AWS::EC2::RouteTable, AWS::EC2::Subnet,
AWS::EC2::Volume, AWS::EFS::FileSystem, AWS::EFS::MountTarget,
AWS::IAM::Role, AWS::IAM::InstanceProfile,
AWS::ElasticLoadBalancingV2::LoadBalancer,
AWS::ElasticLoadBalancingV2::TargetGroup, AWS::Logs::LogGroup

AWS::EKS::Cluster and AWS::EKS::Nodegroup are not on this list, so the
plugin's List implementation for discovery never surfaces them as
candidates, regardless of how many times discovery runs. This looks like it
was scoped for the "catch out-of-band/foreign resources typically created
by autoscaling or consoles" use case, not for "recover a resource this same
plugin just created but failed to persist."

Impact

This directly undermines the tool's stated core differentiator ("formae
automatically discovers and update resources ... keeps the infrastructure
code automatically in sync with reality") for exactly the failure mode
where it matters most: a partially-successful apply. Once this happens for
an EKS cluster/node group, the operator is left with:

  • no way to adopt the orphaned resource back into Formae state through any
    documented workflow, and
  • a formae apply --mode reconcile of the original forma that will very
    likely attempt to re-create a resource with a name that already exists in
    AWS (untested exact error, but the resource identifier is a name that
    must be unique per cluster), rather than detecting and adopting it.

Suggested fixes (any of these would help)

  1. Add AWS::EKS::Cluster and AWS::EKS::Nodegroup (and likely other
    "day-0 declared, not typically out-of-band" resource types) to the AWS
    plugin's default discovery filter, so partial-create bookkeeping
    failures are always recoverable via the existing discovery/adopt flow.
  2. Harden the Cloud Control polling path so a transient
    network/TLS error while checking create status doesn't mark an
    in-flight create Failed outright — e.g. retry/backoff before giving up,
    or re-verify actual cloud state via a fresh GetResource/describe call
    before recording failure.
  3. Provide an explicit "resync/repair a specific failed resource" command
    or MCP tool that re-checks cloud reality for a named failed resource
    from a specific command, independent of the discovery scan scope, and
    offers to adopt it if found.

Happy to share more detail (agent logs, command IDs) if useful — trimmed
account-specific identifiers here since this is a public repo.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions