This Terraform code deploys Dify on Google Cloud Platform (GCP) using the Community Edition, with the following design principles:
- π Stay up-to-date β Follow Dify Community Edition upgrades seamlessly.
- βοΈ Minimal changes β No patching of the Dify codebase.
- βοΈ Fully managed β Leverage GCP managed services for database, file storage, and cache.
- π Dify on Google Cloud β Terraform Deployment
This Terraform code creates the following GCP resources:
| Category | Resources |
|---|---|
| π Network | VPC network & subnet, Private Service Access, Firewall rules, Static external IP |
| ποΈ Database | Cloud SQL (PostgreSQL) β Main DB, Cloud SQL (PostgreSQL + pgvector) β Vector DB |
| πΎ Storage | Filestore β File uploads & plugin assets |
| β‘ Cache | Memorystore for Redis β Caching & session storage |
| π₯οΈ Compute | Managed Instance Group, Custom startup script |
| βοΈ Load Balancer | HTTPS Load Balancer, SSL certificates (managed or self-signed) |
| π IAM | Service account for Dify, Auto-assigned required permissions |
graph TB
subgraph Internet["Internet"]
User[User]
end
subgraph GCP["Google Cloud Platform"]
subgraph DNS["DNS (Optional)"]
Domain[Domain Name]
end
LB_IP[Static Global IP]
subgraph LB["Load Balancer"]
HTTPS[HTTPS Forwarding Rule<br/>Port: 443]
SSL[SSL Certificate<br/>Google-managed or Self-signed]
Backend[Backend Service]
HC[Health Check<br/>/console/api/ping]
end
subgraph VPC["VPC Network"]
subgraph Subnet["Subnet"]
subgraph MIG["Managed Instance Group"]
Instance[Compute Instance<br/>Ubuntu 24.04<br/>Docker + Dify]
end
subgraph Storage["Storage"]
FS[Filestore<br/>NFS Share]
end
end
end
subgraph GoogleManaged["Google-Managed VPC"]
subgraph Database["Cloud SQL Instances"]
SQL1[Cloud SQL PostgreSQL<br/>Main DB]
SQL2[Cloud SQL PostgreSQL<br/>pgvector DB]
end
subgraph Cache["Memorystore"]
REDIS[Redis Instance<br/>Cache & Sessions]
end
end
end
User -->|HTTPS| Domain
Domain -->|DNS Resolution| LB_IP
User -->|HTTPS| LB_IP
LB_IP --> HTTPS
HTTPS --> SSL
SSL --> Backend
Backend -->|HTTP:80| MIG
HC -->|Health Check| Instance
Instance -->|NFS Mount| FS
Instance -->|Private IP<br/>via VPC Peering| SQL1
Instance -->|Private IP<br/>via VPC Peering| SQL2
Instance -->|Private IP<br/>via VPC Peering| REDIS
style User fill:#e1f5ff
style LB fill:#fff4e6
style VPC fill:#f0f9ff
style MIG fill:#e8f5e9
style Database fill:#fce4ec
style Cache fill:#e3f2fd
style GoogleManaged fill:#f5f5f5
style Storage fill:#fff9c4
- βοΈ Google Cloud SDK:
gcloudcommand installed - ποΈ Terraform: Version 1.0 or higher
- π GCP Project: Active GCP project
- π Required IAM Roles: The account running Terraform must have the following roles on the target GCP project:
Role Purpose roles/compute.adminVPC, subnets, firewalls, instance templates, MIG, load balancer, SSL certificates roles/iam.serviceAccountAdminCreate the Dify service account roles/iam.serviceAccountUserAttach the service account to VM instances roles/resourcemanager.projectIamAdminGrant IAM roles to the Dify service account roles/cloudsql.adminCreate and manage Cloud SQL (PostgreSQL) instances roles/redis.adminCreate and manage Memorystore for Redis roles/file.editorCreate and manage Filestore instances roles/servicenetworking.networksAdminCreate private VPC connections for Cloud SQL and Redis roles/serviceusage.serviceUsageAdminEnable required GCP APIs roles/iap.admin(Optional) Configure Identity-Aware Proxy (IAP) settings and IAM bindings roles/oauthconfig.editor(Optional) Create OAuth 2.0 credentials for IAP - π Authentication Setup:
gcloud init gcloud auth application-default login
- π§ Enable Required APIs:
gcloud services enable cloudresourcemanager.googleapis.com gcloud services enable compute.googleapis.com gcloud services enable file.googleapis.com gcloud services enable iamcredentials.googleapis.com gcloud services enable redis.googleapis.com gcloud services enable servicenetworking.googleapis.com gcloud services enable sqladmin.googleapis.com gcloud services enable certificatemanager.googleapis.com # Optional: Enable if using Identity-Aware Proxyπ‘οΈ gcloud services enable iap.googleapis.com
cp terraform.tfvars.example terraform.tfvarsEdit terraform.tfvars and set at least the following values:
project_id = "your-gcp-project-id"
# Dify version to be deployed
dify_version = "1.13.0"
# If you have a domain name (recommended)
domain_name = "dify.example.com"
# Or use self-signed certificate
# domain_name = ""
# ssl_certificate = file("certificate.pem")
# ssl_private_key = file("private-key.pem")# Initialize
terraform init
# Review plan
terraform plan
# Execute deployment
terraform apply# Check initial password
terraform output -raw initial_password
# Access via browser
# https://<load_balancer_ip> or https://your-domain.comdomain_name = "dify.example.com"Configure DNS record:
A dify.example.com <LOAD_BALANCER_IP>
Certificate provisioning can take up to 15 minutes.
# Generate certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout private-key.pem -out certificate.pem \
-subj "/C=JP/ST=Tokyo/L=Tokyo/O=Dify/CN=dify.local"domain_name = ""
ssl_certificate = file("certificate.pem")
ssl_private_key = file("private-key.pem")Identity-Aware Proxy (IAP) adds Google authentication to your application, ensuring only authorized users can access it.
-
Create OAuth 2.0 Credentials:
Go to GCP Console > APIs & Services > Credentials
[!note] If this is your first time, you may see the message: "Remember to configure the OAuth consent screen with information about your application." In that case, click "Configure consent screen" and complete the OAuth consent screen setup before proceeding.
- Click "Create Credentials" > "OAuth client ID"
- Application type: "Web application"
- Create and save the Client ID and Client Secret
- Add authorized redirect URI:
https://iap.googleapis.com/v1/oauth/clientIds/<CLIENT_ID>:handleRedirect
-
Enable IAP API:
gcloud services enable iap.googleapis.com -
Configure terraform.tfvars:
iap_enabled = true iap_oauth_client_id = "123456789-abc.apps.googleusercontent.com" iap_oauth_client_secret = "your-client-secret" iap_members = [ "user:admin@example.com", "group:developers@example.com", "domain:example.com" ]
-
Apply Configuration:
terraform apply
| Type | Format |
|---|---|
| π€ Individual user | user:email@example.com |
| π₯ Google Group | group:groupname@example.com |
| π’ Domain | domain:example.com |
| π€ Service account | serviceAccount:name@project.iam.gserviceaccount.com |
After deployment, accessing your application will require users to:
- π Sign in with their Google account
- β
Be granted access if they are in the
iap_memberslist
If you want to add packages to sandbox, write packages into python-requirements.txt.
Note
dify-sandbox restricts system calls by default.
When you add packages into requirements.txt, all system calls are enabled by ./assets/sandbox/config.yaml.
Please refer to this document.
When Terraform is applied:
- π₯ Dify source code (of the specified version) is automatically downloaded to
/opt/dify-<version>. - βοΈ Update Dify environment variables via startup-script.sh.
βΆοΈ Start the Dify application.
Check Dify Release Notes and update startup-script.sh if needed.
dify_version = "1.13.x" # Specify new version tagterraform apply # Apply upgradeWhen Terraform is applied:
- π΄ The old VM is removed first β the service will be temporarily unavailable during the upgrade.
- π’ A new VM is deployed with the migration process.
β±οΈ Upgrade can take up to 15 minutes.
# Check certificate status
gcloud compute ssl-certificates list
gcloud compute ssl-certificates describe dify-ssl-cert --globalAccess the VM via SSH and check logs:
tail -f /var/log/startup-script.logAccess the VM via SSH and check logs:
sudo su - ubuntu
cd /opt/dify-<version>/docker
docker compose ps
docker compose logs -f
β οΈ Warning: This will permanently delete all provisioned resources.
# Delete all resources
terraform destroy
# If you get errors due to deletion protection, remove them from the GCP Console first,
# then run destroy again
terraform destroy