Skip to content

feature: AWS Config Catalog Plugin - inherit owner/system from related ComponentΒ #468

@nabadger

Description

@nabadger

πŸ”– Feature description

We currently tag our AWS resources with backstage.io/component which successfully creates a dependencyOf relationship as the docs:

  owner:
    tag: owner # Set 'spec.owner' to the value of the 'owner' tag on the AWS resource
  component:
    tag: component # Create a 'dependencyOf' relationship based on the 'component' tag 
  system:
    value: my-system # Set 'spec.system' to a hard-coded value of 'my-system'

However, we are not tagging our AWS resources with owner or system which means that these values are not set on the generated Resource.

This results in the values being set to unknown, and also means we cannot filter on these on the UI.

Is is possible to automatically derive these from the linked component instead, since on our case, we do have system and owner set on those?

This would avoid us having to re-tag AWS resources.

🎀 Context

Whilst we could technically re-tag our AWS Resources, that's an expensive exercise for us at the moment, due the number of resources we have (and the code that control controls those resources).

✌️ Possible Implementation

I'm not sure if it's feasible to extend this with our own custom processor, which then finds all Resources and associates the system/owner based on component (i.e. could lookup the value from backstage itself).


Edit, my good friend Claude.AI suggested the following which seems simple enough (as a way that I could handle this...and not require any work on the config-catalog plugin).

import { CatalogProcessor, CatalogProcessorEmit } from '@backstage/plugin-catalog-node';
import { Entity } from '@backstage/catalog-model';

export class AwsTagEnricher implements CatalogProcessor {
  getProcessorName(): string {
    return 'AwsTagEnricher';
  }

  async preProcessEntity(
    entity: Entity,
    location: any,
    emit: CatalogProcessorEmit
  ): Promise<Entity> {
    // Only process AWS-discovered resources
    if (entity.metadata.annotations?.['amazonaws.com/arn']) {
      const componentTag = entity.metadata.tags?.find(tag => 
        tag.startsWith('component:')
      );
      
      if (componentTag) {
        const componentName = componentTag.split(':')[1];
        
        // Add system relationship based on your mapping logic
        const system = this.deriveSystemFromComponent(componentName);
        const owner = this.deriveOwnerFromComponent(componentName);
        
        entity.spec = entity.spec || {};
        entity.spec.system = system;
        entity.spec.owner = owner;
      }
    }
    
    return entity;
  }
  
  private deriveSystemFromComponent(component: string): string {
    // Implement your mapping logic here
    // Examples:
    // - Look up from a config map
    // - Parse component name pattern
    // - Query an external service
    return `system-for-${component}`;
  }
  
  private deriveOwnerFromComponent(component: string): string {
    // Similar mapping logic for owner
    return `team-for-${component}`;
  }
}```

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions