Skip to content

Formae Synchronization Issue - Resources Becoming Unmanaged #94

@CarsonRuns

Description

@CarsonRuns

Version

v0.75.2

Formae configuration

"@formae/formae.pkl"
import "../vars.pkl"

// Resource imports
import "@aws/ec2/vpc.pkl"


  myvpc = new vpc.VPC {
    label = "vpc-f1b2b189"
    tags = new Listing<formae.Tag> {}
    cidrBlock = "172.31.0.0/16"
    enableDnsHostnames = true
    enableDnsSupport = true
    instanceTenancy = "default"
    target = vars.target.res
    stack = vars.stack.res
  }

Steps to reproduce

See long narrative

Actual behavior

Managed resources become unmanaged

Expected behavior

Managed resources stay managed.

Logs/output

See snippets below.

Additional context

I brought three resources under management and I see them with the inventory command. Then a bit later I run the command again and there is only one resource under management.

AWS::EC2::VPC
AWS::EC2::VPCDHCPOptionsAssociation
AWS::EC2::VPCGatewayAttachment
Only the AWS::EC2::VPCDHCPOptionsAssociation remains under management and both of the other resources show in the list of unmanaged resources. Here is a summary from CoPilot

Formae Synchronization Issue - Resources Becoming Unmanaged

Summary

Resources that were successfully brought under management using formae apply --mode reconcile are being automatically unmarked as managed and moved back to the $unmanaged stack within 2-3 minutes. This occurs during the automatic synchronization process.

Environment

  • Formae Version: v0.75.2
  • Deployment: Containerized agent with PostgreSQL datastore
  • Target: AWS (us-west-2, sandbox profile)
  • Stack: sandbox-core
  • Affected Resources:
    • VPC: vpc-f1b2b189 (AWS::EC2::VPC)
    • VPC Gateway Attachment: IGW|vpc-f1b2b189 (AWS::EC2::VPCGatewayAttachment)
    • VPC DHCP Options Association: dopt-d3704bab|vpc-f1b2b189 (AWS::EC2::VPCDHCPOptionsAssociation)

Timeline of Events

Initial State (2025-11-24 17:53:29)

Resources discovered and in unmanaged state:

uri: formae://35w2HwH5PipP3tqUvcx95ZzDgID# | vpc-f1b2b189 | managed=f | stack=$unmanaged

Resources Brought Under Management (2025-11-25 17:26:47)

Applied forma file with formae apply --mode reconcile main.pkl:

uri: formae://35w2HwH5PipP3tqUvcx95ZzDgID# | vpc-f1b2b189 | managed=t | stack=sandbox-core

Automatic Unmanagement by Sync (2025-11-25 17:29:19)

Only 2.5 minutes later, synchronization process moved resources back to unmanaged:

uri: formae://35w2HwH5PipP3tqUvcx95ZzDgID# | vpc-f1b2b189 | managed=f | stack=$unmanaged

Database Query Results

Command History

SELECT command_id, command, state, timestamp FROM forma_commands ORDER BY timestamp DESC LIMIT 10;

         command_id          | command |   state    |         timestamp          
-----------------------------+---------+------------+----------------------------
 35yvWR6HiLOsr20GW3ijFT29Fgl | sync    | InProgress | 2025-11-25 18:25:56.632547
 35yuesUGK6qMTND07260voQpSd9 | sync    | Success    | 2025-11-25 18:18:50.915201
 35yub8ECNzVPwIimI3kA68k9 | sync    | Success    | 2025-11-25 18:18:10.497134

Sync commands running approximately every 5-7 minutes

Resource Version History

SELECT uri, label, managed, stack, valid_from FROM resources 
WHERE uri = 'formae://35w2HwH5PipP3tqUvcx95ZzDgID#' ORDER BY valid_from DESC LIMIT 5;

formae://35w2HwH5PipP3tqUvcx95ZzDgID# | vpc-f1b2b189 | f | $unmanaged   | 2025-11-25 17:29:19.238004
formae://35w2HwH5PipP3tqUvcx95ZzDgID# | vpc-f1b2b189 | t | sandbox-core | 2025-11-25 17:26:47.495555
formae://35w2HwH5PipP3tqUvcx95ZzDgID# | vpc-f1b2b189 | f | $unmanaged   | 2025-11-24 17:53:29.04208

Root Cause Analysis

Property Comparison

Compared the resource properties between managed and unmanaged states:

Unmanaged State (from AWS sync):

{
  "VpcId": "vpc-f1b2b189",
  "Tags": [
    {"Key": "FormaeStackLabel", "Value": "sandbox-core"},
    {"Key": "FormaeResourceLabel", "Value": "vpc-f1b2b189"}
  ],
  "CidrBlock": "172.31.0.0/16",
  "InstanceTenancy": "default",
  "EnableDnsSupport": true,
  "EnableDnsHostnames": true
}

Managed State (from forma definition):

{
  "Tags": [
    {"Key": "FormaeStackLabel", "Value": "sandbox-core"},
    {"Key": "FormaeResourceLabel", "Value": "vpc-f1b2b189"}
  ],
  "CidrBlock": "172.31.0.0/16",
  "InstanceTenancy": "default",
  "EnableDnsSupport": true,
  "EnableDnsHostnames": true
}

Key Difference: The unmanaged state includes "VpcId": "vpc-f1b2b189" while the managed state does not.

Forma File Definition

myvpc = new vpc.VPC {
  label = "vpc-f1b2b189"
  tags = new Listing<formae.Tag> {}
  cidrBlock = "172.31.0.0/16"
  enableDnsHostnames = true
  enableDnsSupport = true
  instanceTenancy = "default"
  target = vars.target.res
  stack = vars.stack.res
}

Problem Statement

The synchronization process is detecting drift because:

  1. The forma file definition does not include the VpcId property (correctly omitted as it's an AWS-assigned read-only identifier)
  2. When sync queries AWS CloudControl API, it receives the resource with the VpcId property included
  3. Sync compares the forma definition against the AWS state and treats the presence of VpcId as a difference
  4. This triggers the resource to be unmarked as managed and moved back to $unmanaged stack

Configuration

Agent Configuration (formae.conf.pkl):

synchronization {
  enabled = true
  interval = 5.min
}

Expected Behavior

Resources should remain managed after formae apply --mode reconcile unless there are actual configuration drift in user-modifiable properties. Read-only/computed properties like VpcId should be ignored during drift detection.

Actual Behavior

Resources are automatically unmarked as managed every time synchronization runs, making it impossible to maintain managed state for these resources.

Questions for Support

  1. Should read-only properties (like VpcId) be ignored during synchronization drift detection?
  2. Is it expected behavior to require all AWS-returned properties (including read-only ones) in forma definitions?
  3. Is there a configuration option to exclude certain properties from drift detection?
  4. Could this be related to the CloudControl API returning additional metadata that shouldn't trigger drift?

Workaround Attempted

None yet - awaiting guidance on whether to:

  • Add vpcId property to forma definitions
  • Disable synchronization (not ideal for production)
  • Use a different mode or configuration setting

Additional Context

  • Agent logs show successful startup and PostgreSQL connectivity
  • Discovery is working correctly and finding resources
  • The issue is reproducible across all three affected resources
  • Same behavior occurs after agent restart with fresh container

Impact

Medium - Partial functionality affected

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions