Skip to content

Commit df4288e

Browse files
jubradclaude
andcommitted
docs: update Kafka connection examples for MATCHING broker rules
Updates user-facing documentation to show the new MATCHING broker rules syntax for Kafka PrivateLink connections. Adds a PrivateLink tab to the Confluent Cloud guide. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a1fc2ad commit df4288e

3 files changed

Lines changed: 178 additions & 30 deletions

File tree

doc/user/content/ingest-data/kafka/confluent-cloud.md

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ of the following steps:
7676

7777
Otherwise, you can find more information about how to do that [here](https://docs.confluent.io/cloud/current/get-started/index.html#step-2-create-a-ak-topic).
7878

79-
4. #### Create a source in Materialize
79+
4. #### Create a connection in Materialize
8080

8181
a. Open the [Confluent Cloud dashboard](https://confluent.cloud/) and select your cluster.
8282

@@ -87,39 +87,114 @@ of the following steps:
8787
d. Connect to Materialize using the [SQL Shell](/console/),
8888
or your preferred SQL client.
8989

90-
e. Run the following command. Replace `<confluent_cloud>` with whatever you
91-
want to name your source. The broker URL is what you copied in step c of
92-
this subsection. The `<topic-name>` is the name of the topic you created in
93-
Step 4. The `<your-api-key>` and `<your-api-secret>` are from the _Create
94-
an API Key_ step.
90+
e. Create the connection. The exact steps depend on your networking
91+
configuration, so start by selecting the relevant option.
92+
93+
{{< tabs >}}
94+
{{< tab "Public cluster">}}
9595

9696
```mzsql
97-
CREATE SECRET confluent_username AS '<your-api-key>';
98-
CREATE SECRET confluent_password AS '<your-api-secret>';
97+
CREATE SECRET confluent_username AS '<your-api-key>';
98+
CREATE SECRET confluent_password AS '<your-api-secret>';
9999
100-
CREATE CONNECTION <confluent_cloud> TO KAFKA (
100+
CREATE CONNECTION confluent_cloud TO KAFKA (
101101
BROKER '<confluent-broker-url>',
102102
SASL MECHANISMS = 'PLAIN',
103103
SASL USERNAME = SECRET confluent_username,
104104
SASL PASSWORD = SECRET confluent_password
105-
);
105+
);
106+
```
107+
108+
{{< /tab >}}
109+
110+
{{< tab "Use AWS PrivateLink (Cloud-only)" >}}
111+
112+
[AWS PrivateLink](https://aws.amazon.com/privatelink/) lets you connect
113+
Materialize to your Confluent Cloud cluster without exposing traffic to the
114+
public internet.
115+
116+
1. In the [Confluent Cloud console](https://confluent.cloud/), navigate to
117+
your cluster's **Networking** settings and set up a PrivateLink endpoint.
118+
Record the **VPC Endpoint Service Name** and the **DNS domain**.
119+
120+
1. In the Materialize [SQL shell](/console/), create a
121+
[PrivateLink connection](/ingest-data/network-security/privatelink/) using
122+
the service name from the previous step. Be sure to specify **all
123+
availability zones** of your Confluent Cloud cluster.
124+
125+
```mzsql
126+
CREATE CONNECTION confluent_privatelink TO AWS PRIVATELINK (
127+
SERVICE NAME 'com.amazonaws.vpce.us-east-1.vpce-svc-0e123abc123198abc',
128+
AVAILABILITY ZONES ('use1-az1', 'use1-az4', 'use1-az6')
129+
);
130+
```
131+
132+
1. Retrieve the AWS principal for the PrivateLink connection:
133+
134+
```mzsql
135+
SELECT principal
136+
FROM mz_aws_privatelink_connections plc
137+
JOIN mz_connections c ON plc.id = c.id
138+
WHERE c.name = 'confluent_privatelink';
139+
```
140+
141+
1. In the Confluent Cloud console, add the AWS principal to the PrivateLink
142+
access list.
106143
107-
CREATE SOURCE <source-name>
144+
1. In Materialize, validate the PrivateLink connection:
145+
146+
```mzsql
147+
VALIDATE CONNECTION confluent_privatelink;
148+
```
149+
150+
If no validation error is returned, move to the next step.
151+
152+
1. Create the Kafka connection. The static broker (used for bootstrapping)
153+
does not need an `AVAILABILITY ZONE` — Materialize will find it across
154+
availability zones. The `MATCHING` rules should specify `AVAILABILITY ZONE`
155+
to route discovered brokers through their specific AZ endpoint.
156+
157+
```mzsql
158+
CREATE SECRET confluent_username AS '<your-api-key>';
159+
CREATE SECRET confluent_password AS '<your-api-secret>';
160+
161+
CREATE CONNECTION confluent_cloud TO KAFKA (
162+
BROKERS (
163+
'<confluent-broker-url>' USING AWS PRIVATELINK confluent_privatelink,
164+
MATCHING '*.use1-az1.*' USING AWS PRIVATELINK confluent_privatelink (AVAILABILITY ZONE = 'use1-az1'),
165+
MATCHING '*.use1-az4.*' USING AWS PRIVATELINK confluent_privatelink (AVAILABILITY ZONE = 'use1-az4'),
166+
MATCHING '*.use1-az6.*' USING AWS PRIVATELINK confluent_privatelink (AVAILABILITY ZONE = 'use1-az6')
167+
),
168+
SASL MECHANISMS = 'PLAIN',
169+
SASL USERNAME = SECRET confluent_username,
170+
SASL PASSWORD = SECRET confluent_password
171+
);
172+
```
173+
174+
The `MATCHING` patterns correspond to the AZ-specific DNS subdomains
175+
from your Confluent Cloud networking settings. Adjust the patterns and
176+
availability zones to match your cluster's configuration.
177+
178+
{{< /tab >}}
179+
{{< /tabs >}}
180+
181+
5. #### Start ingesting data
182+
183+
Once you have created the connection, create a source and start ingesting
184+
data from your topic. By default, the source will be created in the active
185+
cluster; to use a different cluster, use the `IN CLUSTER` clause.
186+
187+
```mzsql
188+
CREATE SOURCE confluent_source
108189
FROM KAFKA CONNECTION confluent_cloud (TOPIC '<topic-name>')
109190
FORMAT JSON;
110191
```
111-
By default, the source will be created in the active cluster; to use a different
112-
cluster, use the `IN CLUSTER` clause.
113192
114-
f. If the command executes without an error and outputs _CREATE SOURCE_, it
193+
If the command executes without an error and outputs _CREATE SOURCE_, it
115194
means that you have successfully connected Materialize to your Confluent
116195
Cloud Kafka cluster.
117196
118-
**Note:** The example above walked through creating a source, which is a way
119-
of connecting Materialize to an external data source. We created a
120-
connection to Confluent Cloud Kafka using SASL authentication and credentials
121-
securely stored as secrets in Materialize's secret management system. For
122-
input formats, we used `JSON`, but you can also ingest Kafka messages
197+
**Note:** The example above used `JSON`, but you can also ingest Kafka messages
123198
formatted in other supported formats; e.g., [Avro and CSV](/sql/create-source/kafka/#syntax).
124199
You can find more details about the various different supported formats and
125200
possible configurations in the [reference documentation](/sql/create-source/kafka/).

doc/user/content/sql/create-connection.md

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,42 @@ SSH bastion host.
320320
{{< include-md file="shared-content/aws-privatelink-cloud-only-note.md" >}}
321321

322322
Depending on the hosted service you are connecting to, you might need to specify
323-
a PrivateLink connection [per advertised broker](#kafka-privatelink-syntax)
324-
(e.g. Amazon MSK), or a single [default PrivateLink connection](#kafka-privatelink-default) (e.g. Redpanda Cloud).
323+
a PrivateLink connection and [per-availability-zone routing rules for brokers](#kafka-privatelinks) (e.g. Confluent Cloud),
324+
a PrivateLink connection [per advertised broker](#kafka-privatelink-syntax) (e.g. Amazon MSK),
325+
or a single [default PrivateLink connection](#kafka-privatelink-default) (e.g. Redpanda Cloud).
326+
327+
##### Dynamic broker discovery {#kafka-privatelinks}
328+
329+
Confluent Cloud does not require listing every broker individually.
330+
Instead, include a static broker address for the initial connection
331+
alongside wildcard `MATCHING` rules for routing dynamically discovered
332+
brokers through PrivateLink.
333+
334+
{{% include-syntax file="examples/create_connection" example="syntax-kafka-aws-privatelinks" %}}
335+
336+
When your Confluent cluster is deployed across multiple AZs and your
337+
PrivateLink connection is configured with matching AZs, you should only
338+
specify `AWS PRIVATELINK` on the static broker, not `AVAILABILITY ZONE`.
339+
This will allow Materialize to attempt to find the bootstrap broker
340+
across availability zones. The `MATCHING` rules should specify
341+
`AVAILABILITY ZONE` to route discovered brokers through their specific
342+
AZ endpoint.
343+
344+
```mzsql
345+
CREATE CONNECTION privatelink_svc TO AWS PRIVATELINK (
346+
SERVICE NAME 'com.amazonaws.vpce.us-east-1.vpce-svc-0e123abc123198abc',
347+
AVAILABILITY ZONES ('use1-az1', 'use1-az4')
348+
);
349+
350+
CREATE CONNECTION kafka_connection TO KAFKA (
351+
BROKERS (
352+
'lkc-xxx.domyyy.us-east-1.aws.confluent.cloud:9092'
353+
USING AWS PRIVATELINK privatelink_svc,
354+
MATCHING '*.use1-az1.*' USING AWS PRIVATELINK privatelink_svc (AVAILABILITY ZONE = 'use1-az1'),
355+
MATCHING '*.use1-az4.*' USING AWS PRIVATELINK privatelink_svc (AVAILABILITY ZONE = 'use1-az4')
356+
)
357+
);
358+
```
325359

326360
##### Broker connection syntax {#kafka-privatelink-syntax}
327361

@@ -347,7 +381,7 @@ broker that you want to connect to via the tunnel.
347381
Field | Value | Required | Description
348382
----------------------------------------|------------------|:--------:|-------------------------------
349383
`AWS PRIVATELINK` | object name | ✓ | The name of an [AWS PrivateLink connection](#aws-privatelink) through which network traffic for this broker should be routed.
350-
`AVAILABILITY ZONE` | `text` | | The ID of the availability zone of the AWS PrivateLink service in which the broker is accessible. If unspecified, traffic will be routed to each availability zone declared in the [AWS PrivateLink connection](#aws-privatelink) in sequence until the correct availability zone for the broker is discovered. If specified, Materialize will always route connections via the specified availability zone.
384+
`AVAILABILITY ZONE` | `text` | | The ID of the availability zone of the AWS PrivateLink service in which the broker is accessible.
351385
`PORT` | `integer` | | The port of the AWS PrivateLink service to connect to. Defaults to the broker's port.
352386

353387
##### Example {#kafka-privatelink-example}
@@ -388,13 +422,6 @@ PrivateLink connection and the port of the bootstrap server instead.
388422

389423
{{% include-syntax file="examples/create_connection" example="syntax-kafka-default-aws-privatelink" %}}
390424

391-
##### Default connection options {#kafka-privatelink-default-options}
392-
393-
Field | Value | Required | Description
394-
----------------------------------------|------------------|:--------:|-------------------------------
395-
`AWS PRIVATELINK` | object name | ✓ | The name of an [AWS PrivateLink connection](#aws-privatelink) through which network traffic for this broker should be routed.
396-
`PORT` | `integer` | | The port of the AWS PrivateLink service to connect to. Defaults to the broker's port.
397-
398425
##### Example {#kafka-privatelink-default-example}
399426

400427
```mzsql

doc/user/data/examples/create_connection.yml

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,57 @@
242242
syntax_elements:
243243
- name: "`AWS PRIVATELINK <privatelink_connection_name>`"
244244
description: |
245+
*Value:* object name. Required.
246+
245247
The name of an AWS PrivateLink connection through which network traffic
246248
should be routed.
247249
- name: "`PORT`"
248250
description: |
249-
The port of the AWS PrivateLink service to connect to.
251+
*Value:* `integer`
252+
253+
The port of the AWS PrivateLink service to connect to. Defaults to the broker's port.
254+
255+
- name: "syntax-kafka-aws-privatelinks"
256+
code: |
257+
CREATE CONNECTION <connection_name> TO KAFKA (
258+
BROKERS (
259+
'<broker_address>' USING AWS PRIVATELINK <privatelink_connection>,
260+
MATCHING '<pattern1>' USING AWS PRIVATELINK <privatelink_connection1> (
261+
PORT <port1>,
262+
AVAILABILITY ZONE = '<az_id1>'
263+
),
264+
MATCHING '<pattern2>' USING AWS PRIVATELINK <privatelink_connection2>
265+
),
266+
...
267+
);
268+
syntax_elements:
269+
- name: "`'<broker_address>' USING AWS PRIVATELINK ...`"
270+
description: |
271+
A static broker address used for bootstrapping the initial connection
272+
to the Kafka cluster. At least one static broker is required when
273+
using `MATCHING` rules. The broker is routed through the specified
274+
AWS PrivateLink connection.
275+
- name: "`MATCHING '<pattern>' USING AWS PRIVATELINK <connection_name>`"
276+
description: |
277+
Routes brokers whose advertised `host:port` matches `<pattern>` through
278+
the named AWS PrivateLink connection.
279+
A pattern may begin with `*` to match any prefix. A pattern may end with `*` to match any suffix.
280+
All other characters in the pattern are matched literally.
281+
Rules are evaluated in order. The first matching rule wins.
282+
If no rule matches, Materialize will attempt to connect to the broker directly, without tunneling.
283+
- name: "`AVAILABILITY ZONE`"
284+
description: |
285+
*Value:* `text`. Optional.
286+
287+
The ID of the availability zone of the AWS PrivateLink service in which
288+
the broker is accessible. If omitted, traffic routes through the default
289+
PrivateLink endpoint, which distributes across all configured availability
290+
zones. Specify this only when you need to pin brokers to specific AZs.
291+
- name: "`PORT`"
292+
description: |
293+
*Value:* `integer`. Optional.
294+
295+
The port of the AWS PrivateLink service to connect to. Defaults to the broker's port.
250296
251297
- name: "syntax-csr"
252298
code: |

0 commit comments

Comments
 (0)