-
Notifications
You must be signed in to change notification settings - Fork 132
Description
Summary
When using --skip-consumers flag combined with default_lookup_tags.consumers to reference existing consumers for consumer-scoped plugin creation, deck is creating consumers instead of creating plugins.
This issue appears related to #532 which reported similar behavior.
Expected Behavior
When running deck gateway diff with:
--skip-consumersflagdefault_lookup_tags.consumersconfigured to reference existing consumers by tag- A plugin scoped to both a consumer and service
The output should show:
creating plugin rate-limiting-advanced for service my-service and consumer my-consumer-username
Summary:
Created: 1
Actual Behavior
With --skip-consumers, deck outputs:
creating consumer my-consumer-username
creating consumer another-consumer
Summary:
Created: 2
The plugin is NOT created. Instead, consumers are being created even though --skip-consumers should prevent consumer operations.
Steps to Reproduce
1. Ensure a consumer exists in Kong with a specific tag
Consumer in Konnect:
- Username:
my-consumer-username - Tags:
["MyConsumerTag"]
2. Create a deck state file
deck-test-minimal.json:
{
"_format_version": "3.0",
"services": [{
"name": "my-service",
"host": "example.com",
"port": 443,
"protocol": "https",
"path": "/api",
"tags": ["my-service"]
}],
"plugins": [{
"name": "rate-limiting-advanced",
"consumer": "my-consumer-username",
"service": "my-service",
"config": {
"limit": [30000],
"window_size": [60],
"strategy": "local",
"window_type": "fixed",
"namespace": "my-namespace"
},
"tags": ["my-service"]
}],
"_konnect": {
"control_plane_name": "my-control-plane"
},
"_info": {
"select_tags": ["my-service"],
"default_lookup_tags": {
"consumers": ["MyConsumerTag"]
}
}
}3. Run deck diff WITH --skip-consumers
deck gateway diff --konnect-addr https://eu.api.konghq.com \
--konnect-token "$TOKEN" \
--skip-ca-certificates \
--skip-consumers \
deck-test-minimal.jsonOutput (INCORRECT):
It is creating all the consumers again with the same tags (Why????)
creating consumer my-consumer-username
creating consumer another-consumer
Summary:
Created: 2
4. Run deck diff WITHOUT --skip-consumers
deck gateway diff --konnect-addr https://eu.api.konghq.com \
--konnect-token "$TOKEN" \
--skip-ca-certificates \
deck-test-minimal.jsonOutput (CORRECT):
creating plugin rate-limiting-advanced for service my-service and consumer my-consumer-username
Summary:
Created: 1
Suspected Root Cause
After investigating the deck source code, we believe the issue is in cmd/common.go — specifically the order of operations between --skip-consumers processing and default_lookup_tags loading.
Code Location 1: SkipConsumers filter (runs FIRST)
// https://github.com/Kong/deck/blob/main/cmd/common.go ~lines 160-165
if dumpConfig.SkipConsumers {
targetContent.Consumers = []file.FConsumer{} // Clears consumers
targetContent.ConsumerGroups = []file.FConsumerGroupObject{}
targetContent.Plugins = RemoveConsumerPlugins(targetContent.Plugins) // ← Removes consumer-scoped plugins!
}Code Location 2: Lookup tag processing (runs AFTER)
// https://github.com/Kong/deck/blob/main/cmd/common.go ~lines 323-339
if dumpConfig.LookUpSelectorTagsConsumers != nil {
consumersGlobal, err := dump.GetAllConsumers(ctx, kongClient,
dumpConfig.LookUpSelectorTagsConsumers)
// ... unconditionally appends to targetContent.Consumers
}The Problem
--skip-consumersexecutes first and callsRemoveConsumerPlugins(), which strips our consumer-scoped plugin from the target statedefault_lookup_tagsexecutes after and loads consumers into the state for foreign key resolution- Result: The consumer-scoped plugin is removed, but the looked-up consumers are added to the managed state
- During reconciliation, deck sees these consumers as "new" and plans to create them, while the plugin is never created
Expected Behavior
I think Consumers loaded via default_lookup_tags should be treated as reference-only entities for foreign key resolution, they should NOT be added to the managed sync state. Additionally, RemoveConsumerPlugins() should not remove plugins that reference consumers loaded via default_lookup_tags, since those consumers are not being "managed" by this sync operation.
Use Case
We're building tooling that generates deck configuration files for API gateway management. Our use case involves:
- Service-level rate limiting global rate limits applied to all traffic for a service
- Consumer-service rate limiting per-consumer rate limit overrides for specific services
For consumer-service rate limiting:
- Consumers already exist in Kong (managed separately by another team/process)
- We use
default_lookup_tags.consumersto reference them by tag for foreign key resolution - We create
rate-limiting-advancedplugins scoped to bothconsumerandservice - We use
--skip-consumersbecause we do NOT want to manage consumer lifecycle
This pattern should allow us to create consumer-scoped plugins while leaving the consumers themselves untouched.
Questions
- Is
--skip-consumersintentionally removing consumer-scoped plugins viaRemoveConsumerPlugins()? If so, this conflicts with thedefault_lookup_tagsuse case. - Should consumers loaded via
default_lookup_tagsbe excluded from the--skip-consumersfilter since they're meant for reference only? - Why are lookup-tag consumers being shown as "creating" when
--skip-consumersis set?
Related Issues
- deck sync creates consumers even with --skip-consumers #532 —
deck synccreates consumers even with--skip-consumers