The Aiven Provider for Terraform enables you to define, provision, and manage your Aiven infrastructure using infrastructure-as-code principles.
Infrastructure as Code Define your infrastructure in version-controlled configuration files
Reproducible environments Create identical environments across dev, staging, and production
Plan before apply Preview changes before applying them to your infrastructure
State management Track resource state and dependencies automatically
Prerequisites
Quick start
Create a token
Generate an authentication token from the Aiven Console under User Profile > Tokens
Configure the provider
Create a main.tf file with the provider configuration: terraform {
required_providers {
aiven = {
source = "aiven/aiven"
version = "~> 4.0"
}
}
}
provider "aiven" {
api_token = var . aiven_api_token
}
Create variables file
Create a variables.tf file: variable "aiven_api_token" {
description = "Aiven API token"
type = string
sensitive = true
}
Set your token
Create a terraform.tfvars file (don’t commit this!): aiven_api_token = "YOUR_TOKEN_HERE"
Or set it as an environment variable: export TF_VAR_aiven_api_token = "YOUR_TOKEN_HERE"
Basic examples
Create a PostgreSQL service
resource "aiven_pg" "postgres" {
project = "my-project"
service_name = "my-postgres"
cloud_name = "google-europe-north1"
plan = "startup-4"
maintenance_window_dow = "sunday"
maintenance_window_time = "10:00:00"
pg_user_config {
pg_version = "16"
public_access {
pg = true
}
}
}
# Output the connection URI
output "postgres_uri" {
value = aiven_pg . postgres . service_uri
sensitive = true
}
Create an Apache Kafka service
resource "aiven_kafka" "kafka" {
project = "my-project"
service_name = "my-kafka"
cloud_name = "google-europe-north1"
plan = "business-4"
kafka_user_config {
kafka_version = "3.6"
kafka {
auto_create_topics_enable = true
}
kafka_connect = true
}
}
# Create a Kafka topic
resource "aiven_kafka_topic" "orders" {
project = aiven_kafka . kafka . project
service_name = aiven_kafka . kafka . service_name
topic_name = "orders"
partitions = 3
replication = 2
config {
retention_ms = 604800000 # 7 days
}
}
# Create a Kafka user
resource "aiven_kafka_user" "app_user" {
project = aiven_kafka . kafka . project
service_name = aiven_kafka . kafka . service_name
username = "app-user"
}
# Create ACL for the user
resource "aiven_kafka_acl" "app_user_read" {
project = aiven_kafka . kafka . project
service_name = aiven_kafka . kafka . service_name
username = aiven_kafka_user . app_user . username
permission = "read"
topic = aiven_kafka_topic . orders . topic_name
}
Create a database and user in PostgreSQL
resource "aiven_pg_database" "app_db" {
project = aiven_pg . postgres . project
service_name = aiven_pg . postgres . service_name
database_name = "appdb"
}
resource "aiven_pg_user" "app_user" {
project = aiven_pg . postgres . project
service_name = aiven_pg . postgres . service_name
username = "app_user"
}
Organization setup example
Create an organization with organizational units and projects:
# Create organization
resource "aiven_organization" "main" {
name = "my-company"
}
# Create organizational units
resource "aiven_organizational_unit" "engineering" {
name = "Engineering"
parent_id = aiven_organization . main . id
}
resource "aiven_organizational_unit" "production" {
name = "Production"
parent_id = aiven_organizational_unit . engineering . id
}
resource "aiven_organizational_unit" "development" {
name = "Development"
parent_id = aiven_organizational_unit . engineering . id
}
# Create projects
resource "aiven_project" "prod" {
project = "production-services"
parent_id = aiven_organizational_unit . production . id
}
resource "aiven_project" "dev" {
project = "development-services"
parent_id = aiven_organizational_unit . development . id
}
Advanced features
Service integrations
Integrate services together:
# PostgreSQL service
resource "aiven_pg" "postgres" {
project = "my-project"
service_name = "my-postgres"
cloud_name = "google-europe-north1"
plan = "startup-4"
}
# InfluxDB service for metrics
resource "aiven_influxdb" "metrics" {
project = "my-project"
service_name = "metrics-db"
cloud_name = "google-europe-north1"
plan = "startup-4"
}
# Integrate PostgreSQL metrics to InfluxDB
resource "aiven_service_integration" "pg_to_influx" {
project = "my-project"
integration_type = "metrics"
source_service_name = aiven_pg . postgres . service_name
destination_service_name = aiven_influxdb . metrics . service_name
}
VPC and peering
# Create a VPC
resource "aiven_project_vpc" "vpc" {
project = "my-project"
cloud_name = "google-europe-north1"
network_cidr = "10.0.0.0/24"
}
# Create service in VPC
resource "aiven_pg" "postgres" {
project = "my-project"
service_name = "my-postgres"
cloud_name = "google-europe-north1"
plan = "startup-4"
project_vpc_id = aiven_project_vpc . vpc . id
}
# Create VPC peering connection (AWS example)
resource "aiven_aws_vpc_peering_connection" "peering" {
vpc_id = aiven_project_vpc . vpc . id
aws_account_id = "123456789012"
aws_vpc_id = "vpc-1234567890abcdef0"
aws_vpc_region = "us-east-1"
}
Static IP addresses
resource "aiven_static_ip" "ip" {
project = "my-project"
cloud_name = "google-europe-north1"
}
resource "aiven_pg" "postgres" {
project = "my-project"
service_name = "my-postgres"
cloud_name = "google-europe-north1"
plan = "startup-4"
static_ips = [ aiven_static_ip . ip . static_ip_address_id ]
}
Connection pooling (PostgreSQL)
resource "aiven_connection_pool" "pool" {
project = aiven_pg . postgres . project
service_name = aiven_pg . postgres . service_name
database_name = aiven_pg_database . app_db . database_name
pool_name = "app_pool"
pool_size = 25
pool_mode = "transaction"
username = aiven_pg_user . app_user . username
}
output "pool_uri" {
value = aiven_connection_pool . pool . connection_uri
sensitive = true
}
Workflow commands
Initialize
Download provider and initialize working directory:
Plan
Preview changes before applying:
Save plan to a file:
terraform plan -out=tfplan
Apply
Apply changes to create/update infrastructure:
Apply without confirmation:
terraform apply -auto-approve
Apply a saved plan:
Destroy
Destroy all managed infrastructure:
This will permanently delete all resources defined in your Terraform configuration.
Import
Import existing Aiven resources:
terraform import aiven_pg.postgres my-project/my-postgres
State management
# List resources in state
terraform state list
# Show resource details
terraform state show aiven_pg.postgres
# Remove resource from state (doesn't delete actual resource)
terraform state rm aiven_pg.postgres
Best practices
Store Terraform state remotely for team collaboration: terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "aiven/terraform.tfstate"
region = "us-east-1"
}
}
Create reusable modules for common patterns: module "postgres" {
source = "./modules/postgres"
project = "my-project"
name = "my-postgres"
cloud = "google-europe-north1"
plan = "startup-4"
pg_version = "16"
}
Manage multiple environments: terraform workspace new production
terraform workspace new staging
terraform workspace select production
Reference in configuration: resource "aiven_pg" "postgres" {
service_name = "postgres- ${ terraform . workspace } "
# ...
}
Protect sensitive resources
Prevent accidental deletion: resource "aiven_pg" "postgres" {
# ...
lifecycle {
prevent_destroy = true
}
}
Reference existing resources: data "aiven_project" "existing" {
project = "my-project"
}
resource "aiven_pg" "postgres" {
project = data . aiven_project . existing . project
# ...
}
Available resources
The Aiven Terraform Provider supports a wide range of resources:
Services
PostgreSQL: aiven_pg
MySQL: aiven_mysql
Apache Kafka: aiven_kafka
Apache Kafka Connect: aiven_kafka_connect
Apache Flink: aiven_flink
OpenSearch: aiven_opensearch
Redis: aiven_redis
InfluxDB: aiven_influxdb
Grafana: aiven_grafana
And more…
Service components
Databases: aiven_pg_database, aiven_mysql_database
Users: aiven_pg_user, aiven_kafka_user
Topics: aiven_kafka_topic
ACLs: aiven_kafka_acl
Connectors: aiven_kafka_connector
Connection pools: aiven_connection_pool
Projects: aiven_project
Organizations: aiven_organization
Organizational units: aiven_organizational_unit
VPCs: aiven_project_vpc
VPC peering: aiven_aws_vpc_peering_connection
Static IPs: aiven_static_ip
Troubleshooting
Enable debug logging
export TF_LOG = DEBUG
terraform apply
Check provider version
Refresh state
Migrate existing Aiven resources to Terraform:
Create resource blocks
Write Terraform configuration for existing resources
Import resources
terraform import aiven_pg.postgres my-project/my-postgres
Verify state
Should show no changes needed