Explorar el Código

docs: Enhance ClusterExternalSecret documentation with "fan-out" approach (#6241)

Co-authored-by: Gergely Bräutigam <gergely.brautigam@sap.com>
Jaruwat Panturat hace 1 mes
padre
commit
870fcc8724

+ 37 - 0
docs/api/clusterexternalsecret.md

@@ -13,6 +13,43 @@ Below is an example of the `ClusterExternalSecret` in use.
 {% include 'full-cluster-external-secret.yaml' %}
 ```
 
+## Reducing provider calls for large namespace sets
+
+A `ClusterExternalSecret` creates one `ExternalSecret` per matched namespace,
+and **each of those `ExternalSecret`s independently polls the upstream provider** on its own `refreshInterval`. 
+This means provider API calls scale linearly with the number of matched namespaces, which can be costly or hit rate limits. 
+This is a known characteristic of the design.
+
+![Direct polling: each namespace polls the provider independently](../pictures/diagrams-ces-direct-polling.png)
+
+If your selector matches more than a handful of namespaces, the recommended pattern is to pull
+from the upstream provider **once** into a single in-cluster `Secret`, then
+use the [Kubernetes provider](../provider/kubernetes.md) to fan that
+`Secret` out via the `ClusterExternalSecret`:
+
+1. A single namespace-scoped `ExternalSecret` pulls from the upstream
+   provider and writes a `Secret` in a dedicated "source" namespace.
+2. A `ClusterSecretStore` using the Kubernetes provider points at that
+   source `Secret`.
+3. A `ClusterExternalSecret` references that `ClusterSecretStore`,
+   replicating the `Secret` into every matched namespace. Regardless of how
+   many namespaces match, the upstream provider is only called by the single
+   source `ExternalSecret` in step 1.
+
+![Fan-out pattern: only the source ExternalSecret polls the provider](../pictures/diagrams-ces-fanout-pattern.png)
+
+```yaml
+{% include 'cluster-external-secret-fanout.yaml' %}
+```
+
+The `ServiceAccount` and RBAC for the Kubernetes provider store are the same
+as described in the [Kubernetes provider docs](../provider/kubernetes.md).
+
+Direct use of `ClusterExternalSecret` against a cloud-backed store is still
+appropriate for small namespace sets or when per-namespace refresh isolation
+is intentional. This is a recommendation for minimizing provider load, not
+a deprecation of the simpler pattern shown above.
+
 ## Synchronizing corresponding ExternalSecrets
 
 Regular refreshes can be controlled using the `refreshPolicy` and

+ 170 - 0
docs/pictures/diagrams-ces-direct-polling.drawio

@@ -0,0 +1,170 @@
+<mxfile host="65bd71144e">
+    <diagram id="phmhrq9sNyguH6r90t0f" name="high-level-simple">
+        <mxGraphModel dx="510" dy="605" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+            <root>
+                <mxCell id="g-vbnRHEd7JeOrGF2uE1-0"/>
+                <mxCell id="g-vbnRHEd7JeOrGF2uE1-1" parent="g-vbnRHEd7JeOrGF2uE1-0"/>
+                <mxCell id="140" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=light-dark(#DAE8FC,#DAE8FC);strokeColor=#6c8ebf;" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="20" y="460" width="540" height="490" as="geometry"/>
+                </mxCell>
+                <mxCell id="141" value="" style="aspect=fixed;html=1;points=[];align=center;image;fontSize=12;image=img/lib/mscae/Kubernetes.svg;" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry y="440" width="50" height="48" as="geometry"/>
+                </mxCell>
+                <mxCell id="143" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="270" y="481.25" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="144" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="282" y="511.25" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="145" value="namespace-1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="312.5" y="489.25" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="149" value="" style="group;strokeColor=none;fillColor=none;container=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" connectable="0" vertex="1">
+                    <mxGeometry x="601" y="580" width="223" height="113" as="geometry"/>
+                </mxCell>
+                <mxCell id="150" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="338" y="521.75" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="151" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="270" y="578" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="152" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="282" y="608" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="153" value="namespace-2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="312.5" y="586" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="154" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="338" y="618.5" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="155" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="270" y="840" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="156" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="282" y="870" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="157" value="namespace-n" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="312.5" y="848" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="158" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="338" y="880.5" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="159" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="270" y="676" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="160" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="282" y="706" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="161" value="namespace-3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="312.5" y="684" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="162" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="338" y="716.5" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="163" value="&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;AWS / GCP / Vault / ..." style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="614" y="593" width="210" height="100" as="geometry"/>
+                </mxCell>
+                <mxCell id="164" value="&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;AWS / GCP / Vault / ..." style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="601" y="580" width="210" height="100" as="geometry"/>
+                </mxCell>
+                <mxCell id="165" value="" style="html=1;fillColor=#5184F3;strokeColor=none;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;align=center;spacingTop=-6;fontSize=11;fontStyle=1;fontColor=#999999;shape=mxgraph.gcp2.hexIcon;prIcon=key_management_service" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="601" y="600.75" width="66" height="58.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="166" value="ClusterExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="60" y="604.5" width="138.41" height="36.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="173" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=light-dark(#000000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" source="166" target="159" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="129" y="660"/>
+                            <mxPoint x="129" y="725"/>
+                        </Array>
+                        <mxPoint x="80" y="688" as="sourcePoint"/>
+                        <mxPoint x="245" y="727" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="175" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" source="166" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="129" y="890"/>
+                        </Array>
+                        <mxPoint x="120" y="810" as="sourcePoint"/>
+                        <mxPoint x="270" y="890" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="177" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=light-dark(#000000,#000000);" parent="g-vbnRHEd7JeOrGF2uE1-1" source="166" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="129" y="600"/>
+                            <mxPoint x="130" y="600"/>
+                            <mxPoint x="130" y="530"/>
+                        </Array>
+                        <mxPoint x="127.72499999999992" y="606.5" as="sourcePoint"/>
+                        <mxPoint x="270" y="530" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="178" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=light-dark(#000000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" source="166" target="151" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points"/>
+                        <mxPoint x="200" y="710" as="sourcePoint"/>
+                        <mxPoint x="262.32" y="633.5" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="179" value="" style="shape=ellipse;fillColor=#000000;strokeColor=none;html=1;sketch=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="357.5" y="780" width="10" height="10" as="geometry"/>
+                </mxCell>
+                <mxCell id="180" value="" style="shape=ellipse;fillColor=#000000;strokeColor=none;html=1;sketch=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="357.5" y="800" width="10" height="10" as="geometry"/>
+                </mxCell>
+                <mxCell id="181" value="" style="shape=ellipse;fillColor=#000000;strokeColor=none;html=1;sketch=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" vertex="1">
+                    <mxGeometry x="357.5" y="820" width="10" height="10" as="geometry"/>
+                </mxCell>
+                <mxCell id="182" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=light-dark(#CC0000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" source="150" target="164" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="480" y="533"/>
+                            <mxPoint x="480" y="630"/>
+                        </Array>
+                        <mxPoint x="550.0049999999999" y="571.5" as="sourcePoint"/>
+                        <mxPoint x="540" y="640" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="183" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=light-dark(#CC0000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" source="154" target="164" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="540" y="630"/>
+                            <mxPoint x="540" y="630"/>
+                        </Array>
+                        <mxPoint x="425" y="630" as="sourcePoint"/>
+                        <mxPoint x="591" y="727" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="184" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=light-dark(#CC0000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" source="162" target="164" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="480" y="728"/>
+                            <mxPoint x="480" y="630"/>
+                        </Array>
+                        <mxPoint x="423.83" y="731.5699999999999" as="sourcePoint"/>
+                        <mxPoint x="588.83" y="731.5699999999999" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="185" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=light-dark(#CC0000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="g-vbnRHEd7JeOrGF2uE1-1" target="164" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="480" y="892"/>
+                            <mxPoint x="480" y="630"/>
+                        </Array>
+                        <mxPoint x="423.83" y="891.5699999999999" as="sourcePoint"/>
+                        <mxPoint x="650" y="630" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="186" value="Pull &lt;font style=&quot;font-size: 9px;&quot;&gt;x&amp;nbsp;&lt;/font&gt;n" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];labelBackgroundColor=#DAE8FC;" parent="185" vertex="1" connectable="0">
+                    <mxGeometry x="0.6897" y="-2" relative="1" as="geometry">
+                        <mxPoint x="-13" y="-2" as="offset"/>
+                    </mxGeometry>
+                </mxCell>
+            </root>
+        </mxGraphModel>
+    </diagram>
+</mxfile>

BIN
docs/pictures/diagrams-ces-direct-polling.png


+ 179 - 0
docs/pictures/diagrams-ces-fanout-pattern.drawio

@@ -0,0 +1,179 @@
+<mxfile host="65bd71144e">
+    <diagram id="ces-fanout-pattern" name="ces-fanout-pattern">
+        <mxGraphModel dx="510" dy="605" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="1100" math="0" shadow="0">
+            <root>
+                <mxCell id="0"/>
+                <mxCell id="1" parent="0"/>
+                <mxCell id="200" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=light-dark(#DAE8FC,#DAE8FC);strokeColor=#6c8ebf;" parent="1" vertex="1">
+                    <mxGeometry x="30" y="440" width="810" height="520" as="geometry"/>
+                </mxCell>
+                <mxCell id="201" value="" style="aspect=fixed;html=1;points=[];align=center;image;fontSize=12;image=img/lib/mscae/Kubernetes.svg;" parent="1" vertex="1">
+                    <mxGeometry x="10" y="420" width="50" height="48" as="geometry"/>
+                </mxCell>
+                <mxCell id="210" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="554" y="521.75" width="180" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="211" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="1" vertex="1">
+                    <mxGeometry x="570.59" y="556.25" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="212" value="source namespace" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="576.5" y="529.75" width="130" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="213" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="626.59" y="566.75" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="220" value="" style="group;strokeColor=none;fillColor=none;container=0;" parent="1" connectable="0" vertex="1">
+                    <mxGeometry x="870" y="528" width="223" height="113" as="geometry"/>
+                </mxCell>
+                <mxCell id="221" value="&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;AWS / GCP / Vault / ..." style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);" parent="1" vertex="1">
+                    <mxGeometry x="883" y="541" width="210" height="100" as="geometry"/>
+                </mxCell>
+                <mxCell id="222" value="&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;AWS / GCP / Vault / ..." style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=12;fontColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);" parent="1" vertex="1">
+                    <mxGeometry x="870" y="528" width="210" height="100" as="geometry"/>
+                </mxCell>
+                <mxCell id="223" value="" style="html=1;fillColor=#5184F3;strokeColor=none;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;align=center;spacingTop=-6;fontSize=11;fontStyle=1;fontColor=#999999;shape=mxgraph.gcp2.hexIcon;prIcon=key_management_service" parent="1" vertex="1">
+                    <mxGeometry x="870" y="548.75" width="66" height="58.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="224" value="Pull x 1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#188038;fontColor=#188038;fontStyle=1;labelBackgroundColor=#DAE8FC;" parent="1" source="213" target="222" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="230" value="ClusterSecretStore&lt;br&gt;&lt;font style=&quot;font-size: 10px;&quot; color=&quot;#888888&quot;&gt;(Kubernetes provider)&lt;/font&gt;" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="539.92" y="707.5" width="210" height="40" as="geometry"/>
+                </mxCell>
+                <mxCell id="231" value="&lt;span style=&quot;background-color: rgb(218, 232, 252);&quot;&gt;fetch&lt;/span&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;strokeColor=#888888;fontColor=#000000;fontSize=10;labelBackgroundColor=none;exitPerimeter=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;" parent="1" source="211" target="230" edge="1">
+                    <mxGeometry x="0.0103" relative="1" as="geometry">
+                        <mxPoint as="offset"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="240" value="ClusterExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="60" y="604.5" width="138.41" height="36.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="250" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="270" y="481.25" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="251" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="1" vertex="1">
+                    <mxGeometry x="282" y="511.25" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="252" value="namespace-1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="312.5" y="489.25" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="253" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="338" y="521.75" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="260" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="270" y="578" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="261" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="1" vertex="1">
+                    <mxGeometry x="282" y="608" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="262" value="namespace-2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="312.5" y="586" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="263" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="338" y="618.5" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="270" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="270" y="676" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="271" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="1" vertex="1">
+                    <mxGeometry x="282" y="706" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="272" value="namespace-3" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="312.5" y="684" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="273" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="338" y="716.5" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="280" value="" style="shape=ellipse;fillColor=#000000;strokeColor=none;html=1;sketch=0;" parent="1" vertex="1">
+                    <mxGeometry x="357.5" y="780" width="10" height="10" as="geometry"/>
+                </mxCell>
+                <mxCell id="281" value="" style="shape=ellipse;fillColor=#000000;strokeColor=none;html=1;sketch=0;" parent="1" vertex="1">
+                    <mxGeometry x="357.5" y="800" width="10" height="10" as="geometry"/>
+                </mxCell>
+                <mxCell id="282" value="" style="shape=ellipse;fillColor=#000000;strokeColor=none;html=1;sketch=0;" parent="1" vertex="1">
+                    <mxGeometry x="357.5" y="820" width="10" height="10" as="geometry"/>
+                </mxCell>
+                <mxCell id="290" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=light-dark(#000000,#000000);fillColor=light-dark(#FFFFFF,#FFFFFF);fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="270" y="840" width="185" height="89.5" as="geometry"/>
+                </mxCell>
+                <mxCell id="291" value="" style="html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=light-dark(#FFFFFF,#FFFFFF);points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon;prIcon=secret" parent="1" vertex="1">
+                    <mxGeometry x="282" y="870" width="45.83" height="44" as="geometry"/>
+                </mxCell>
+                <mxCell id="292" value="namespace-n" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=2;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="312.5" y="848" width="100" height="20" as="geometry"/>
+                </mxCell>
+                <mxCell id="293" value="ExternalSecret" style="text;html=1;whiteSpace=wrap;strokeColor=light-dark(#000000,#000000);fillColor=none;align=center;verticalAlign=middle;rounded=0;fontColor=light-dark(#000000,#000000);" parent="1" vertex="1">
+                    <mxGeometry x="338" y="880.5" width="85.83" height="23" as="geometry"/>
+                </mxCell>
+                <mxCell id="300" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=light-dark(#000000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="240" target="250" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="129" y="526"/>
+                        </Array>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="301" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=light-dark(#000000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="240" target="260" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="302" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=light-dark(#000000,#000000);entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="240" target="270" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="129" y="721"/>
+                            <mxPoint x="270" y="721"/>
+                        </Array>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="303" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=light-dark(#000000,#000000);" parent="1" source="240" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="129" y="890"/>
+                        </Array>
+                        <mxPoint x="270" y="890" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="310" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;dashed=1;strokeColor=#888888;endArrow=none;endFill=0;" parent="1" source="253" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="500" y="533"/>
+                        </Array>
+                        <mxPoint x="500" y="630" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="312" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;dashed=1;strokeColor=#888888;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="273" target="230" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="530" y="727"/>
+                        </Array>
+                        <mxPoint x="423.83000000000004" y="790.5" as="sourcePoint"/>
+                        <mxPoint x="556" y="790" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="313" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;dashed=1;strokeColor=#888888;endArrow=none;endFill=0;" parent="1" source="293" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="500" y="892"/>
+                            <mxPoint x="500" y="776"/>
+                        </Array>
+                        <mxPoint x="500" y="730" as="targetPoint"/>
+                        <mxPoint x="423.8299999999999" y="940.25" as="sourcePoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="311" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;dashed=1;strokeColor=#888888;endArrow=none;endFill=0;" parent="1" source="263" edge="1">
+                    <mxGeometry relative="1" as="geometry">
+                        <Array as="points">
+                            <mxPoint x="500" y="630"/>
+                            <mxPoint x="500" y="704"/>
+                        </Array>
+                        <mxPoint x="455" y="603.98" as="sourcePoint"/>
+                        <mxPoint x="500" y="730" as="targetPoint"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="314" value="&lt;span style=&quot;&quot;&gt;reference&lt;/span&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];labelBackgroundColor=#DAE8FC;fontColor=#000000;fontSize=10;" parent="311" vertex="1" connectable="0">
+                    <mxGeometry x="0.5" relative="1" as="geometry">
+                        <mxPoint y="42" as="offset"/>
+                    </mxGeometry>
+                </mxCell>
+            </root>
+        </mxGraphModel>
+    </diagram>
+</mxfile>

BIN
docs/pictures/diagrams-ces-fanout-pattern.png


+ 59 - 0
docs/snippets/cluster-external-secret-fanout.yaml

@@ -0,0 +1,59 @@
+{% raw %}
+# Step 1: A single ExternalSecret pulls from the upstream provider.
+apiVersion: external-secrets.io/v1
+kind: ExternalSecret
+metadata:
+  name: shared-credentials
+  namespace: eso-fanout-source
+spec:
+  refreshInterval: "1h"
+  secretStoreRef:
+    name: my-upstream-store
+    kind: ClusterSecretStore
+  target:
+    name: shared-credentials
+  dataFrom:
+  - extract:
+      key: path/to/shared-credentials
+---
+# Step 2: ClusterSecretStore reads the source Secret via the Kubernetes provider.
+apiVersion: external-secrets.io/v1
+kind: ClusterSecretStore
+metadata:
+  name: shared-credentials-store
+spec:
+  provider:
+    kubernetes:
+      remoteNamespace: eso-fanout-source
+      server:
+        caProvider:
+          type: ConfigMap
+          name: kube-root-ca.crt
+          namespace: eso-fanout-source
+          key: ca.crt
+      auth:
+        serviceAccount:
+          name: eso-fanout-reader
+          namespace: eso-fanout-source
+---
+# Step 3: ClusterExternalSecret fans the Secret out to matching namespaces.
+apiVersion: external-secrets.io/v1
+kind: ClusterExternalSecret
+metadata:
+  name: shared-credentials
+spec:
+  externalSecretName: shared-credentials
+  namespaceSelectors:
+  - matchLabels:
+      shared-credentials: "true"
+  externalSecretSpec:
+    refreshInterval: "1h"
+    secretStoreRef:
+      name: shared-credentials-store
+      kind: ClusterSecretStore
+    target:
+      name: shared-credentials
+    dataFrom:
+    - extract:
+        key: shared-credentials
+{% endraw %}