> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Integrate ClickHouse and Amazon Glue

# Integrating Amazon Glue with ClickHouse and Spark

export const ClickHouseSupportedBadge = () => {
  return <div className="ClickHouseSupportedBadge">
            <div className="ClickHouseSupportedIcon">
                <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M1.30762 1.39073C1.30762 1.3103 1.37465 1.22986 1.46849 1.22986H2.64824C2.72868 1.22986 2.80912 1.29689 2.80912 1.39073V14.4886C2.80912 14.5691 2.74209 14.6495 2.64824 14.6495H1.46849C1.38805 14.6495 1.30762 14.5825 1.30762 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M4.2832 1.39073C4.2832 1.3103 4.35023 1.22986 4.44408 1.22986H5.62383C5.70427 1.22986 5.7847 1.29689 5.7847 1.39073V14.4886C5.7847 14.5691 5.71767 14.6495 5.62383 14.6495H4.44408C4.36364 14.6495 4.2832 14.5825 4.2832 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M7.25977 1.39073C7.25977 1.3103 7.3268 1.22986 7.42064 1.22986H8.60039C8.68083 1.22986 8.76127 1.29689 8.76127 1.39073V14.4886C8.76127 14.5691 8.69423 14.6495 8.60039 14.6495H7.42064C7.3402 14.6495 7.25977 14.5825 7.25977 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M10.2354 1.39073C10.2354 1.3103 10.3024 1.22986 10.3962 1.22986H11.576C11.6564 1.22986 11.7369 1.29689 11.7369 1.39073V14.4886C11.7369 14.5691 11.6698 14.6495 11.576 14.6495H10.3962C10.3158 14.6495 10.2354 14.5825 10.2354 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M13.2256 6.6057C13.2256 6.52526 13.2926 6.44482 13.3865 6.44482H14.5662C14.6466 6.44482 14.7271 6.51186 14.7271 6.6057V9.27354C14.7271 9.35398 14.6601 9.43442 14.5662 9.43442H13.3865C13.306 9.43442 13.2256 9.36739 13.2256 9.27354V6.6057Z" fill="currentColor" />
                </svg>
            </div>
            ClickHouse Supported
        </div>;
};

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

<ClickHouseSupportedBadge />

[Amazon Glue](https://aws.amazon.com/glue/) is a fully managed, serverless data integration service provided by Amazon Web Services (AWS). It simplifies the process of discovering, preparing, and transforming data for analytics, machine learning, and application development.

<h2 id="installation">
  Installation
</h2>

To integrate your Glue code with ClickHouse, you can use our official Spark connector in Glue via one of the following:

* Installing the ClickHouse Glue connector from the AWS Marketplace (recommended).
* Manually adding the Spark Connector's jars to your Glue job.

<Tabs>
  <Tab title="AWS Marketplace">
    <Steps titleSize="h3">
      <Step title="Subscribe to the Connector" id="subscribe-to-the-connector">
        To access the connector in your account, subscribe to the ClickHouse AWS Glue Connector from AWS Marketplace.
      </Step>

      <Step title="Grant Required Permissions" id="grant-required-permissions">
        Ensure your Glue job’s IAM role has the necessary permissions, as described in the minimum privileges [guide](https://docs.aws.amazon.com/glue/latest/dg/getting-started-min-privs-job.html#getting-started-min-privs-connectors).
      </Step>

      <Step title="Activate the Connector & Create a Connection" id="activate-the-connector">
        After subscribing, select the Glue version that matches your job requirements. In the **Additional details** section, under **Usage instructions**, click the link to **Open Glue Studio - Add ClickHouse connector**. This opens the Glue connection creation page with key fields pre-filled. Give the connection a name and press create (no need to provide the ClickHouse connection details at this stage).

        <Image img="https://mintcdn.com/private-7c7dfe99-vortex-format/Lkh3d_DOGHrXRD3t/images/integrations/data-ingestion/aws-glue/marketplace-usage-instructions.png?fit=max&auto=format&n=Lkh3d_DOGHrXRD3t&q=85&s=e786dec02c6e5771f17e6ce3cf7a46bd" size="md" alt="AWS Marketplace usage instructions for ClickHouse Glue connector" width="1024" height="182" data-path="images/integrations/data-ingestion/aws-glue/marketplace-usage-instructions.png" />
      </Step>

      <Step title="Use in Glue Job" id="use-in-glue-job">
        In your Glue job, select the `Job details` tab, and expend the `Advanced properties` window. Under the `Connections` section, select the connection you just created. The connector automatically injects the required JARs into the job runtime.

        <Image img="https://mintcdn.com/private-7c7dfe99-vortex-format/Lkh3d_DOGHrXRD3t/images/integrations/data-ingestion/aws-glue/notebook-connections-config.webp?fit=max&auto=format&n=Lkh3d_DOGHrXRD3t&q=85&s=446e26df441f0bb15999f15cca8ce5c2" size="md" alt="Glue Notebook connections config" force="true" width="877" height="742" data-path="images/integrations/data-ingestion/aws-glue/notebook-connections-config.webp" />

        <Note>
          Make sure to select the connector version that matches your Glue job configuration:

          * **Glue 4**: Spark 3.3, Scala 2, Python 3
          * **Glue 5**: Spark 3.5, Scala 2, Python 3
        </Note>
      </Step>
    </Steps>
  </Tab>

  <Tab title="Manual Installation">
    To add the required jars manually, please follow the following:

    <Steps titleSize="h3">
      <Step title="Upload the connector JAR">
        Upload the latest Spark connector JAR (`clickhouse-spark-runtime-3.X_2.X-0.10.X.jar`) to an S3 bucket.
      </Step>

      <Step title="Grant access to the S3 bucket">
        Make sure the Glue job has access to this bucket.
      </Step>

      <Step title="Configure the dependent JAR path">
        Under the `Job details` tab, scroll down and expend the `Advanced properties` drop down, and fill the jars path in `Dependent JARs path`:

        <Image img="https://mintcdn.com/private-7c7dfe99-vortex-format/Lkh3d_DOGHrXRD3t/images/integrations/data-ingestion/aws-glue/dependent_jars_path_option.webp?fit=max&auto=format&n=Lkh3d_DOGHrXRD3t&q=85&s=e7967397418b9a8d8ddd4ad97e3801f2" size="md" alt="Glue Notebook JAR path options" force="true" width="954" height="753" data-path="images/integrations/data-ingestion/aws-glue/dependent_jars_path_option.webp" />
      </Step>
    </Steps>
  </Tab>
</Tabs>

<h2 id="secrets-manager">
  Using AWS Secrets Manager for credentials
</h2>

Rather than hardcoding your ClickHouse user and password in the job, store them in [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/) and reference the secret from your Glue connection or job script. At runtime, Glue fetches the secret and merges its key-value pairs into the connector's connection options.

<h3 id="create-secret">
  Create the secret
</h3>

In AWS Secrets Manager, create a secret of type **Other type of secret** with key-value pairs whose keys match the connector's option names:

| Key        | Value                    |
| ---------- | ------------------------ |
| `user`     | your ClickHouse username |
| `password` | your ClickHouse password |

Any key you put in the secret is forwarded to the connector, so you can also store `host`, `database`, or any other option there if you'd like to keep them out of code.

<h3 id="reference-secret">
  Reference the secret
</h3>

There are two ways to wire the secret into a job.

**Option 1: attach it to the Glue connection.** When creating or editing the ClickHouse connection in Glue Studio, set the **AWS secret** field to the secret's name. Any job that uses this connection resolves the secret automatically — no code changes needed.

**Option 2: pass `secretId` in connection options.** Use this when the secret isn't attached to the connection. Add `secretId` alongside `connectionName`:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    source = glueContext.create_dynamic_frame.from_options(
        connection_type="marketplace.spark",
        connection_options={
            "connectionName": "<your-connection-name>",
            "secretId": "clickhouse/glue/credentials",
            "database": "default",
            "table": "example_table"
        },
        transformation_ctx="clickhouse_source"
    )
    ```
  </Tab>

  <Tab title="Scala">
    ```scala theme={null}
    val source = glueContext.getSource(
      connectionType = "marketplace.spark",
      connectionOptions = JsonOptions(Map(
        "connectionName" -> "<your-connection-name>",
        "secretId" -> "clickhouse/glue/credentials",
        "database" -> "default",
        "table" -> "example_table"
      )),
      transformationContext = "clickhouseSource"
    )
    ```
  </Tab>
</Tabs>

The secret's `user` and `password` keys are merged into the connector options at runtime, so you never need to read them in your script.

<h2 id="example">
  Examples
</h2>

The examples below use `marketplace.spark` and reference the connector by `connectionName`. If you installed the connector manually (Manual Installation tab), use `connection_type="custom.spark"` and pass `className`, `host`, `http_port`, `user`, and `password` directly in the options instead.

If you attached an AWS secret to the connection itself (Option 1 in [Using AWS Secrets Manager for credentials](#secrets-manager)), drop `secretId` from the options — Glue resolves credentials from the connection automatically.

<Tabs>
  <Tab title="Visual Editor">
    You can use the ClickHouse connector as either a source or a target in the Glue Studio visual editor. Simply drag the ClickHouse Spark Connector component onto the canvas and connect it to your data pipeline.

    <Image img="https://mintcdn.com/private-7c7dfe99-vortex-format/Lkh3d_DOGHrXRD3t/images/integrations/data-ingestion/aws-glue/glue-studio-visual-editor.png?fit=max&auto=format&n=Lkh3d_DOGHrXRD3t&q=85&s=26746f85da68a254cb0be309cd0005c4" size="md" alt="Glue Studio visual editor with ClickHouse connector" width="1024" height="645" data-path="images/integrations/data-ingestion/aws-glue/glue-studio-visual-editor.png" />
  </Tab>

  <Tab title="Scala">
    ```java theme={null}
    import com.amazonaws.services.glue.GlueContext
    import com.amazonaws.services.glue.util.{GlueArgParser, Job, JsonOptions}
    import org.apache.spark.SparkContext
    import scala.collection.JavaConverters._

    object ClickHouseGlueExample {
      def main(sysArgs: Array[String]): Unit = {
        val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)

        val sc = new SparkContext()
        val glueContext = new GlueContext(sc)
        Job.init(args("JOB_NAME"), glueContext, args.asJava)

        val readOptions = JsonOptions(Map(
          "connectionName" -> "<your-connection-name>",
          "secretId" -> "clickhouse/glue/credentials",
          "database" -> "default",
          "table" -> "example_table"
        ))

        val source = glueContext.getSource(
          connectionType = "marketplace.spark",
          connectionOptions = readOptions,
          transformationContext = "clickhouseSource"
        )
        val dyf = source.getDynamicFrame()

        val writeOptions = JsonOptions(Map(
          "connectionName" -> "<your-connection-name>",
          "secretId" -> "clickhouse/glue/credentials",
          "database" -> "default",
          "table" -> "target_table"
        ))

        glueContext.getSink(
          connectionType = "marketplace.spark",
          connectionOptions = writeOptions
        ).writeDynamicFrame(dyf)

        Job.commit()
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import sys
    from awsglue.utils import getResolvedOptions
    from pyspark.context import SparkContext
    from awsglue.context import GlueContext
    from awsglue.job import Job

    args = getResolvedOptions(sys.argv, ['JOB_NAME'])

    sc = SparkContext()
    glueContext = GlueContext(sc)
    logger = glueContext.get_logger()
    job = Job(glueContext)
    job.init(args['JOB_NAME'], args)

    read_options = {
        "connectionName": "<your-connection-name>",
        "secretId": "clickhouse/glue/credentials",
        "database": "default",
        "table": "example_table"
    }

    source = glueContext.create_dynamic_frame.from_options(
        connection_type="marketplace.spark",
        connection_options=read_options,
        transformation_ctx="clickhouse_source"
    )
    dyf = source

    logger.info(f"Read {dyf.count()} rows from ClickHouse")

    write_options = {
        "connectionName": "<your-connection-name>",
        "secretId": "clickhouse/glue/credentials",
        "database": "default",
        "table": "target_table"
    }

    glueContext.write_dynamic_frame.from_options(
        frame=dyf,
        connection_type="marketplace.spark",
        connection_options=write_options,
        transformation_ctx="clickhouse_sink"
    )

    job.commit()
    ```
  </Tab>
</Tabs>

For more details, please visit our [Spark documentation](/integrations/apache-spark).
