Using Terraform to deploy Flink App or Statement¶
Version
- Created November 2024
- Update December 2025
- Get the last Terraform cli version, from the installation guide..
Core Principals
When you run terraform apply, Terraform calculates the differences between the current actual state (tracked in its state file) and the desired state, and then applies only the necessary changes to bridge that gap. This enables incremental building.
For confluent we can start with an environment, a service account, role binding and add resources over time. If we change a parameter of an existing resource (e.g., change an instance type), Terraform will detect this as a modification and update only that specific resource in place (if possible) or replace it if an in-place update isn't supported by the provider. Terraform automatically determines the correct order of operations based on resource dependencies, ensuring that foundational components are created before dependent components.
For managing different stages like development, staging, and production, the recommended approach is to use separate configurations (often in different directories) with their own dedicated state files.
- See Confluent Terraform sample project for an end-to-end tutorial.
- The Terraform Confluent provider formal documentation, with the deployment examples.
There are two approaches to manage Confluent Platform Kafka cluster in the same Terraform workspace:
- Manage multiple Kafka clusters
- Manage a single cluster
Terraform plugin supports Flink compute pool creation and Flink statement deployments on Confluent Cloud.
-
This repository includes in deployment/cc-terraform Terraform definitions to create:
- Confluent cloud environment
- A Service Account as environement admin
- Kafka Cluster with API key
- A schema registry with API key
- Flink service accounts: flink-app (with ClusterAdmin role, DeveloperRead and DeveloperWrite on schema registry), flink-developer-sa (FlinkDeveloper), Flink API key owned by Flink Developer SA
- Flink compute pools: a default and one for data generations
- Flink statements for clicks, customers, products data generation
Pre-requisites¶
- If not done already, create Confluent Cloud API key with secret for your user or for a service account (See confluent.cloud/settings/api-keys). Your user needs
OrganizationAdminrole to create those keys. For production do not use, user keys but prefer service account keys. -
If not already done create a service account for terraform runner. Assign the OrganizationAdmin role to this service account by following this guide.
-
To get the visibility of the existing keys use the command:
-
Export as environment variables:
-
Recall that terraform.tfstate and env variables should not be committed to git.
Infrastructure¶
For any flink project, we need to define or import the following resources:
- Confluent cloud environment
- A Service Account as environement admin
- Kafka Cluster with API key
- A schema registry with API key
- Kafka Cluster
- Schema Registry
- Flink service accounts: flink-app (with ClusterAdmin role, DeveloperRead and DeveloperWrite on schema registry), flink-developer-sa (FlinkDeveloper), Flink API key owned by Flink Developer SA
- Flink compute pools: a default and one for data generations
- Flink statements for clicks, customers, products data generation
Defining Terraform Provider and Variables¶
-
Create a main.tf with the confluent cloud provider. (see Confluent sample here), or the main.tf in this repo
-
Init:
-
Add variables.tf: we need at least:
confluent_cloud_api_key, confluent_cloud_api_secret, cloud_provider, cloud_region and prefix. Each variable definition has the same structure: -
Define specific variable values using: terraform.tfvars or use default values.
Iterative configuration¶
The approach is to add resources by increment to have a clear understanding of all dependencies. The iteration includes at least the following steps:
- Add resources and variables
- Decide to import existing resources or create new one
- Run CLI:
Environment¶
-
Define the Confluent environment in
env.tf, and use a naming convention as: "${var.prefix}-env". -
For an existing environment, use the import statement:
-
Add service account and role binding as Environment admin
resource "confluent_service_account" "env-manager" { display_name = "${var.prefix}-env-manager" description = "Service account to manage ${var.prefix}-env environment" depends_on = [ confluent_environment.env ] }- or import existing service account id
Kafka¶
See the Product documentation to create kafka cluster with Terraform. The basic cluster sample project describes the needed steps, but it is recommended to use standard kafka cluster with RBAC access control. As an alternate this is the standard cluster definitions.
-
Create a Kafka cluster resources:
resource "confluent_kafka_cluster" "standard" { display_name = "${var.prefix}-kafka" availability = "SINGLE_ZONE" cloud = var.cloud_provider region = var.cloud_region standard {} environment { id = confluent_environment.env.id } lifecycle { prevent_destroy = true } }or import one exisitng
This repository includes a demo with IaC definition in the deployment cc-terraform folder which defines the following components:
- A Service account to manage the environment:
env_managerwith the role ofEnvironmentAdminand API keys - A Kafka cluster in a single AZ (for demo), with service accounts for app-manager, producer and consumer apps
Schema Registry¶
- A schema registry with API keys to access the registry at runtime
Compute pool¶
Flink Compute pool can also be configured with Terraform, and see this example in the Terraform Confluent quickstart repository.
The flink.tf in deployment cc-terraform: defines the following components:
- A flink pool, with 2 service accounts, one for flink app management and one for developing flink statements.
Deploy the configuration¶
-
Use the classical tf commands:
-
If there is a 401 error on accessing Confluent, it is a problem of api_key within the environment variables.
- The output of this configuration needs to be used by other deployment like the Flink statement ones. It can be retrieved at any time with:
Deploy a Flink statement¶
Flink statement can be deployed using Terraform: DDL is the easier part. Automation of DML statement is more complex: the first deployment on a fresh environment is simple, the challenges come when doing canary deployment on existing running statements for logic upgrade. For that see the statement life cycle chapter in the cookbook chapter. and potentially when the number of statements are important and need to take into account running statement, it is recommended to consider adopting shift_left util
See the Terraform definition of the Flink Statement resource.. One important constraint is that all 7 flink_api_key, flink_api_secret, flink_rest_endpoint, organization_id, environment_id, flink_compute_pool_id, flink_principal_id attributes should be set or not set in the provider block at the same time.
resource "confluent_flink_statement" "ddl-dim_tenant-v1" {
properties = {
"sql.current-catalog" = var.current_catalog
"sql.current-database" = var.current_database
}
statement = file("${path.module}/sql-scripts/ddl.dim_tenant.sql")
statement_name = "dml-dim-tenant_v1"
stopped = false # change when updating the statement
}
statement can be a reference to a file, or a string including the statement content.