| name | kcc-direct-service-generated-id |
| description | Standards and rules for implementing KCC direct controllers for GCP resources that ONLY support service-generated IDs. |
KCC Direct Service-Generated Resource IDs
This skill outlines the mandatory implementation requirements for direct KCC resources whose unique identifiers (IDs) are exclusively assigned/generated by the Google Cloud Platform (GCP) service itself (i.e., resources that ONLY support service-generated IDs).
Note: Resources that support both user-specified and service-generated IDs (or have alternative selection mechanisms) should be handled differently and are not covered by this skill.
For such resources, the Kubernetes configuration uses spec.resourceID to specify a service-generated ID (if acquiring or targeting a pre-existing resource), but can also leave it empty to request that KCC let the GCP service assign an ID.
The 4 Rules for Service-Generated Resource IDs
When implementing or migrating direct controllers for resources that use service-assigned or service-generated identifiers, you must strictly follow these four architectural rules:
Rule 1: Identity Construction (getIdentityFromSpec)
- Retrieve the resource ID using
GetServiceGeneratedResourceID(obj) (or common.ValueOf(obj.Spec.ResourceID)).
- MUST NEVER fall back to using
metadata.name as a default resource ID.
- If
spec.resourceID is empty or unset, the parsed specIdentity.<ResourceID> MUST be set to "".
Rule 2: Find() Pre-Check Guard
Rule 3: Create() Request Payload
- The
Create() implementation MUST NEVER set the desiredpb.Name (or equivalent identifier field) in the GCP request payload before calling the GCP Create API. The identifier must be left empty so that the GCP service knows to generate it.
Rule 4: Identity Comparison in GetIdentity()
When status.externalRef is present during reconciliation:
- If
GetServiceGeneratedResourceID(obj) == "" (Empty):
- Do NOT compare
specIdentity.<ResourceID> ("") against statusIdentity.<ResourceID> (e.g., "12345").
- Verify that immutable parent fields (such as
Project and Location) match.
- Return
statusIdentity (which carries the server-assigned ID).
- If
GetServiceGeneratedResourceID(obj) != "" (Non-Empty):
specIdentity MUST equal statusIdentity (i.e. specIdentity.<ResourceID> == statusIdentity.<ResourceID>).
- If
specIdentity.<ResourceID> != statusIdentity.<ResourceID>, return an error:
cannot change resource identity (old=%q, new=%q)
Coding Reference Example
Below is a reference example demonstrating how these rules are mapped into typical direct controller adapter Go code.
package service
import (
"context"
"fmt"
"github.com/GoogleCloudPlatform/k8s-config-connector/apis/common"
)
func GetServiceGeneratedResourceID(obj *krm.MyResource) string {
return common.ValueOf(obj.Spec.ResourceID)
}
func (a *Adapter) Find(ctx context.Context) (bool, error) {
if a.id.<ResourceID> == "" {
return false, nil
}
return true, nil
}
func (a *Adapter) Create(ctx context.Context, desired *krm.MyResource) error {
return nil
}
func GetIdentity(ctx context.Context, obj *krm.MyResource, statusIdentity *Identity) (*Identity, error) {
specID := GetServiceGeneratedResourceID(obj)
if specID == "" {
statusIdentity,
}
specID != statusIdentity.<ResourceID> {
, fmt.Errorf(, statusIdentity.<ResourceID>, specID)
}
specIdentity,
}