Skip to main content

N8N_GKE Module — Configuration Guide

n8n is an open-source workflow automation platform that lets you connect services, run logic, and build automated pipelines through a visual node-based interface. This module deploys n8n on GKE Autopilot with a managed PostgreSQL database, GCS-backed storage persistence, and optional NFS for shared volumes.

N8N_GKE is a wrapper module built on top of App_GKE. It uses App_GKE for all GCP infrastructure provisioning (GKE Autopilot cluster, networking, Cloud SQL Auth Proxy, GCS, secrets, CI/CD) and adds n8n-specific application configuration on top.

Note: Variables marked as platform-managed are set and maintained by the platform. You do not normally need to change them.


How This Guide Is Structured

This guide documents only the variables that are unique to N8N_GKE or that have n8n-specific defaults that differ from the App_GKE base module. For all other variables — project identity, GKE backend configuration, CI/CD, GCS storage, backup, custom SQL, observability, networking, IAP, and Cloud Armor — refer directly to the App_GKE Configuration Guide.

Variables fully covered by the App_GKE guide:

Configuration AreaApp_GKE_Guide SectionN8N-Specific Notes
Module Metadata & ConfigurationGroup 0Different defaults for module_description and module_documentation.
Project & IdentityGroup 1Refer to base App_GKE module documentation.
Application IdentityGroup 2See N8N Application Identity below for n8n-specific defaults.
Runtime & ScalingGroup 3See N8N Runtime Configuration below. cpu_limit and memory_limit are top-level variables.
Environment Variables & SecretsGroup 4See N8N Environment Variables below for SMTP defaults.
GKE Backend ConfigurationGroup 5Refer to base App_GKE module documentation (service_type, workload_type, session_affinity, gke_cluster_name, namespace_name, etc.). See StatefulSet Configuration for n8n StatefulSet-specific variables.
Jobs & Scheduled TasksGroup 6Refer to base App_GKE module documentation.
CI/CD & GitHub IntegrationGroup 7Refer to base App_GKE module documentation.
Storage — NFSGroup 8NFS is enabled by default (enable_nfs = true). See Platform-Managed Behaviours.
Storage — GCSGroup 9Refer to base App_GKE module documentation.
Database ConfigurationGroup 10See N8N Database Configuration below. db_name and db_user replace application_database_name and application_database_user.
Backup Schedule & RetentionGroup 11Refer to base App_GKE module documentation.
Custom SQL ScriptsGroup 12Refer to base App_GKE module documentation.
Observability & HealthGroup 13Refer to base App_GKE module documentation for startup_probe_config, health_check_config, uptime_check_config, and alert_policies.
Reliability PoliciesGroup 14Refer to base App_GKE module documentation (enable_pod_disruption_budget, enable_resource_quota).
Resource QuotaGroup 15Refer to base App_GKE module documentation.
Custom Domain, Static IP & NetworkGroup 16Refer to base App_GKE module documentation.
Identity-Aware ProxyGroup 17Refer to base App_GKE module documentation. Note: GKE IAP requires iap_oauth_client_id and iap_oauth_client_secret.
Cloud ArmorGroup 18Refer to base App_GKE module documentation.

Platform-Managed Behaviours

The following behaviours are applied automatically by N8N_GKE regardless of the variable values in your tfvars file. They cannot be overridden by user configuration.

BehaviourDetail
Encryption key auto-generatedA 32-character random encryption key is generated and stored in Secret Manager as N8N_ENCRYPTION_KEY, then synced to a Kubernetes Secret. This key encrypts all n8n credentials (API keys, OAuth tokens, workflow passwords). Back up this secret before destroying the module — credentials encrypted with one key cannot be decrypted with a different key.
SMTP password auto-generatedA placeholder SMTP password is generated and stored in Secret Manager as N8N_SMTP_PASS. Replace the secret value with your real SMTP credentials before enabling email sending.
n8n port fixed at 5678N8N_PORT=5678 is injected automatically via the application configuration. The container_port variable defaults to 5678 to match.
Database type set to PostgreSQLDB_TYPE=postgresdb is injected automatically. n8n requires PostgreSQL — do not change database_type to MySQL or SQL Server.
Database connection variables injectedDB_POSTGRESDB_HOST, DB_POSTGRESDB_PORT, DB_POSTGRESDB_DATABASE, DB_POSTGRESDB_USER, and DB_POSTGRESDB_PASSWORD are injected automatically from the Cloud SQL instance provisioned by App_GKE. The n8n Pod connects via the Cloud SQL Auth Proxy sidecar running at 127.0.0.1.
Webhook and editor URLs auto-setWEBHOOK_URL and N8N_EDITOR_BASE_URL are set to the predicted service URL. When enable_custom_domain = true and application_domains is non-empty, the first domain is used. Otherwise the internal ClusterIP service URL (http://<service>.<namespace>.svc.cluster.local) is used.
Workload Identity for IAMThe n8n Pod uses Workload Identity to authenticate to GCP services (Cloud SQL, GCS, Secret Manager) without needing to embed service account keys in the container.
GCS persistence for workflow datan8n stores workflow data in a GCS Fuse volume. This persists data across Pod restarts and rescheduling.
Database initialisation jobA Kubernetes Job (db-init) is created automatically to provision the n8n_db database and n8n_user PostgreSQL user before the n8n Deployment starts.

N8N Application Identity

These variables control how the n8n deployment is named and described. They correspond to Group 2 variables in App_GKE but carry n8n-specific defaults.

VariableDefaultOptions / FormatDescription & Implications
application_name"n8n"[a-z][a-z0-9-]{0,19}Internal identifier used as the base name for GKE workloads, Cloud SQL, GCS buckets, Kubernetes namespace, and Artifact Registry. Do not change after initial deployment — it is embedded in resource names and changing it will cause resources to be recreated.
display_name"N8N Workflow Automation"Any stringHuman-readable name shown in the platform UI and GKE monitoring dashboards. Equivalent to application_display_name in App_GKE. Can be updated freely without affecting resource names.
description"n8n Workflow Automation - Workflow automation platform on GKE Autopilot"Any stringBrief description of the deployment. Populated into Kubernetes resource annotations and platform documentation.
application_version"2.4.7"n8n version string, e.g. "2.4.7", "latest"Version tag applied to the container image and used for deployment tracking. Increment this value to trigger a new image build and revision. See n8n releases for available versions.

Validating Application Identity

# Confirm the Deployment exists with the expected name
kubectl get deployments -n NAMESPACE -o wide

# View annotations (description is stored here)
kubectl describe deployment n8n -n NAMESPACE | grep -A5 Annotations

N8N Runtime Configuration

n8n exposes cpu_limit and memory_limit as dedicated top-level variables rather than requiring users to set the full container_resources object.

VariableDefaultOptions / FormatDescription & Implications
cpu_limit"2000m"Kubernetes CPU quantity (e.g. "1000m", "2000m", "4")CPU limit for the n8n container in GKE Autopilot. 2 vCPU is the recommended minimum for production workflow automation. n8n executes workflow nodes concurrently and complex workflows with many nodes are CPU-bound. In GKE Autopilot, the CPU limit also determines Pod scheduling and billing.
memory_limit"4Gi"Kubernetes memory quantity (e.g. "2Gi", "4Gi", "8Gi")Memory limit for the n8n container. 4 Gi is recommended for active deployments. n8n caches workflow state and credential data in memory. Setting below 1Gi risks OOMKilled Pod restarts during complex workflow executions.
min_instance_count1Integer ≥ 0Minimum number of n8n Pod replicas. Set to 1 to ensure continuous webhook availability — n8n webhooks are only active while at least one Pod is running. Set to 0 only in development environments where downtime is acceptable.
max_instance_count3Integer ≥ 1Maximum number of n8n Pod replicas allowed by the HPA. The default of 3 permits horizontal scaling. Enable Redis queue mode (enable_redis = true) before scaling beyond 1 replica — without Redis, multiple replicas will conflict on workflow state and execution locks.
timeout_seconds300Integer, 0–3600Maximum request duration before the ingress layer times out. Increase for long-running workflow executions.

Note on container_resources: The full container_resources object (as documented in App_GKE_Guide Group 3) is also available. If container_resources is set explicitly in your tfvars, it takes precedence over the top-level cpu_limit and memory_limit variables. Use container_resources when you also need to set cpu_request or mem_request.

N8N-specific runtime defaults that differ from App_GKE:

VariableApp_GKE DefaultN8N_GKE DefaultReason
container_port80805678n8n's native port.
cpu_limit"1000m""2000m"Workflow automation is CPU-intensive for concurrent node execution.
memory_limit"512Mi""4Gi"n8n requires substantial memory for workflow state and credential caching.
min_instance_count11Ensures webhook availability at all times.
enable_nfsfalsetrueNFS provides shared persistence for workflow data and credentials.
enable_cloudsql_volumetruetruen8n connects to Cloud SQL via the Auth Proxy sidecar.
session_affinity"None""ClientIP"Ensures a user's browser session consistently reaches the same n8n Pod, which is required for the n8n editor UI to function correctly.

Validating Runtime Configuration

# View resource requests and limits on the running n8n Pod
kubectl describe pod -n NAMESPACE -l app=n8n | grep -A10 "Limits:"

# Check the HPA (if min/max_instance_count > 1)
kubectl get hpa -n NAMESPACE

StatefulSet Configuration

When workload_type = "StatefulSet" (see App_GKE_Guide Group 5), N8N_GKE exposes additional variables to configure the StatefulSet's persistent volume claim and Pod management behaviour. These variables are unique to N8N_GKE — they do not exist in App_GKE.

Use workload_type = "StatefulSet" when n8n must retain local state across Pod restarts and you require stable network identities or ordered Pod startup. For most deployments, the default workload_type = "Deployment" with GCS Fuse persistence is sufficient.

VariableDefaultOptions / FormatDescription & Implications
stateful_pvc_enabledfalsetrue / falseWhen true and workload_type = "StatefulSet", provisions a PersistentVolumeClaim per Pod for local storage. Use this when n8n's filesystem persistence requirements exceed what GCS Fuse provides (e.g., high-frequency small file writes). Only effective when workload_type = "StatefulSet".
stateful_pvc_size"10Gi"Kubernetes storage quantity (e.g. "10Gi", "50Gi", "100Gi")Size of the PVC provisioned for each StatefulSet Pod. Size the PVC based on expected workflow execution data and binary file storage volume. Only used when stateful_pvc_enabled = true.
stateful_pvc_mount_path"/data"Absolute path stringFilesystem path inside the n8n container where the PVC is mounted. Override to /home/node/.n8n if you want n8n's data directory to be backed by a PVC instead of GCS Fuse. Only used when stateful_pvc_enabled = true.
stateful_pvc_storage_class"standard-rwo"GKE storage class name (e.g. "standard-rwo", "premium-rwo")Kubernetes StorageClass for the PVC. standard-rwo uses standard persistent disk with ReadWriteOnce access. Use premium-rwo for higher IOPS when n8n processes high volumes of binary workflow data. Only used when stateful_pvc_enabled = true.
stateful_headless_servicetruetrue / falseWhen true, creates a headless Kubernetes Service (ClusterIP: None) for the StatefulSet, giving each Pod a stable DNS entry (<pod-name>.<service>.<namespace>.svc.cluster.local). Required for n8n queue mode webhook routing when running multiple replicas as a StatefulSet. Only effective when workload_type = "StatefulSet".
stateful_pod_management_policy"OrderedReady""OrderedReady" / "Parallel"Controls the order in which StatefulSet Pods are started and stopped. OrderedReady starts Pods sequentially and waits for each to be ready before starting the next — recommended for n8n to ensure the primary instance initialises the database schema before replicas start. Parallel starts all Pods simultaneously and is only safe when Redis queue mode is enabled. Only effective when workload_type = "StatefulSet".
stateful_update_strategy"RollingUpdate""RollingUpdate" / "OnDelete"Controls how StatefulSet Pods are updated when the Pod template changes. RollingUpdate replaces Pods automatically in reverse ordinal order. OnDelete requires manual Pod deletion to trigger updates — use this when you need to control the exact timing of n8n restarts during maintenance windows. Only effective when workload_type = "StatefulSet".

Validating StatefulSet Configuration

# Confirm the StatefulSet exists (when workload_type = "StatefulSet")
kubectl get statefulsets -n NAMESPACE

# Check PVCs created for the StatefulSet
kubectl get pvc -n NAMESPACE

# Verify stable DNS entries for each Pod
kubectl exec -n NAMESPACE <any-pod> -- nslookup n8n-0.n8n.NAMESPACE.svc.cluster.local

Redis Configuration

These variables are unique to N8N_GKE — the base App_GKE module does not include a Redis configuration group. Redis is required for n8n queue mode, which enables reliable multi-replica workflow execution.

VariableDefaultOptions / FormatDescription & Implications
enable_redistruetrue / falseEnables Redis as the n8n queue mode backend by injecting REDIS_HOST and REDIS_PORT environment variables into the n8n Pod. When true and redis_host is empty, the module defaults to the NFS server IP discovered from Services_GCP. Required when max_instance_count > 1 to avoid workflow state conflicts between replicas.
redis_host"" (auto-discovered)Hostname or IP, e.g. "10.0.0.5", "redis.internal"Hostname or IP of the Redis server. Leave blank to use the NFS server IP auto-discovered from Services_GCP. Override with a dedicated Redis/Memorystore instance endpoint for production deployments requiring higher availability or AUTH.
redis_port"6379"Port string, e.g. "6379"TCP port of the Redis server. Must match the port configured on the Redis instance.
redis_auth""Sensitive stringAuthentication password for the Redis server. Leave empty for unauthenticated Redis. For Google Cloud Memorystore with AUTH enabled, set this to the instance auth string. Treated as sensitive — never stored in Terraform state in plaintext.

Validation guard: When enable_redis = true, either redis_host must be set or enable_nfs must be true. If neither condition is met, Terraform will reject the configuration with an error explaining that REDIS_HOST would be empty, causing the n8n queue worker to fail to connect.

Validating Redis Configuration

# Confirm REDIS_HOST and REDIS_PORT are set in the n8n Pod
kubectl describe pod -n NAMESPACE -l app=n8n | grep -E "REDIS"

N8N Database Configuration

n8n requires PostgreSQL. This module exposes db_name and db_user as short top-level variables in place of the application_database_name and application_database_user variables documented in App_GKE_Guide Group 10.

All other database variables (database_password_length, enable_auto_password_rotation, rotation_propagation_delay_sec, secret_rotation_period, etc.) behave identically to the App_GKE equivalents — refer to App_GKE_Guide Group 10 for their documentation.

VariableDefaultOptions / FormatDescription & Implications
db_name"n8n_db"[a-z][a-z0-9_]{0,62}Name of the PostgreSQL database created within the Cloud SQL instance. Injected automatically as DB_POSTGRESDB_DATABASE. Do not change after initial deployment — renaming the database requires a full backup-and-restore migration.
db_user"n8n_user"[a-z][a-z0-9_]{0,31}PostgreSQL user created for n8n. Injected automatically as DB_POSTGRESDB_USER. The password is auto-generated, stored in Secret Manager, synced to a Kubernetes Secret, and injected as DB_POSTGRESDB_PASSWORD.

Validating Database Configuration

# Confirm the database and user were created
gcloud sql databases list --instance=INSTANCE_NAME --project=PROJECT_ID

gcloud sql users list --instance=INSTANCE_NAME --project=PROJECT_ID

# Confirm DB env vars are injected into the n8n Pod
kubectl describe pod -n NAMESPACE -l app=n8n | grep -E "DB_POSTGRES"

N8N Environment Variables

The environment_variables variable (documented in App_GKE_Guide Group 4) has n8n-specific defaults that configure email delivery.

Default environment_variables in N8N_GKE:

environment_variables = {
SMTP_HOST = ""
SMTP_PORT = "25"
SMTP_USER = ""
SMTP_PASSWORD = ""
SMTP_SSL = "false"
EMAIL_FROM = "ghost@example.com"
}

Override the SMTP values to enable n8n email notifications (workflow failure alerts, credential sharing invitations). For providers such as SendGrid or Mailgun that use API key authentication, set SMTP_USER = "apikey" and store the actual key in secret_environment_variables.

Do not set N8N_PORT, DB_TYPE, DB_POSTGRESDB_*, N8N_ENCRYPTION_KEY, WEBHOOK_URL, or N8N_EDITOR_BASE_URL in environment_variables — these are injected automatically by the platform and will be overridden.


Configuration Examples

Basic Deployment

Deploys n8n on GKE using default settings. Suitable for evaluation and development.

# config/basic.tfvars
resource_creator_identity = ""
project_id = "my-project-123"
tenant_deployment_id = "basic"

Advanced Deployment

Production-grade deployment with Redis queue mode, CI/CD, GKE-specific reliability policies, and full observability.

# config/advanced.tfvars
resource_creator_identity = ""
project_id = "my-project-123"
tenant_deployment_id = "prod"

application_name = "n8n"
display_name = "N8N Workflow Automation"

# Scaling & Performance
cpu_limit = "4000m"
memory_limit = "8Gi"
min_instance_count = 1
max_instance_count = 5

# Redis (required for multi-replica scaling)
enable_redis = true

# Database
database_password_length = 32

# GKE Specific
enable_resource_quota = true
enable_pod_disruption_budget = true
enable_network_segmentation = true
enable_vertical_pod_autoscaling = true

# CI/CD & Cloud Deploy
enable_cicd_trigger = true
enable_cloud_deploy = true
cloud_deploy_stages = [
{ name = "dev", require_approval = false, auto_promote = false },
{ name = "staging", require_approval = false, auto_promote = false },
{ name = "prod", require_approval = true, auto_promote = false },
]

# Security
enable_iap = true
enable_binary_authorization = true
enable_cloud_armor = true

# Backup
backup_schedule = "0 2 * * *"
backup_retention_days = 30

# Observability
uptime_check_config = {
enabled = true
path = "/healthz"
check_interval = "60s"
timeout = "10s"
}

alert_policies = [
{
name = "high-cpu"
metric_type = "kubernetes.io/container/cpu/usage_time"
comparison = "COMPARISON_GT"
threshold_value = 2000
duration_seconds = 300
aggregation_period = "60s"
}
]

StatefulSet Deployment

Deploys n8n as a StatefulSet with a PVC for local data storage, suitable for high-frequency workflow executions with binary file output.

# config/custom.tfvars
resource_creator_identity = ""
project_id = "my-project-123"
tenant_deployment_id = "stateful"

application_name = "n8n"

# StatefulSet
workload_type = "StatefulSet"
min_instance_count = 1
max_instance_count = 3

# StatefulSet PVC
stateful_pvc_enabled = true
stateful_pvc_size = "50Gi"
stateful_pvc_mount_path = "/home/node/.n8n"
stateful_pvc_storage_class = "premium-rwo"

# StatefulSet behaviour
stateful_headless_service = true
stateful_pod_management_policy = "OrderedReady"
stateful_update_strategy = "RollingUpdate"

# Redis (required for multi-replica StatefulSet)
enable_redis = true

# Custom Container Build
container_image_source = "custom"
container_build_config = {
enabled = true
dockerfile_path = "Dockerfile"
context_path = "scripts"
dockerfile_content = null
build_args = {}
artifact_repo_name = "n8n-repo"
}

# SMTP
environment_variables = {
SMTP_HOST = "smtp.sendgrid.net"
SMTP_PORT = "587"
SMTP_USER = "apikey"
SMTP_SSL = "true"
EMAIL_FROM = "noreply@example.com"
}

secret_environment_variables = {
SMTP_PASSWORD = "sendgrid-api-key-secret"
}