Provisioning
Overview
This step executes Terraform to create all GCP infrastructure. The process takes 15-25 minutes and provisions:
- Enabled GCP APIs for all required services
- VPC with GKE, database, public, and PSC subnets plus Cloud NAT
- GKE cluster with system and worker node pools
- Cloud SQL for PostgreSQL with regional HA
- GCS buckets with uniform access and Private Google Access
- Secret Manager with application secrets
- Service accounts with Workload Identity bindings
- Helm releases: NGINX Ingress, External Secrets, ArgoCD, cert-manager, ClickHouse Operator
After completion, you will have a fully provisioned GCP environment ready for Kubernetes workloads.
What happens during provisioning
When you run terraform apply, Terraform:
- Reads your configuration from
terraform.tfvars - Calculates dependencies to determine the order resources must be created
- Creates resources in GCP via API calls
- Tracks state in your GCS backend so it knows what exists
- Outputs important values you’ll need for subsequent steps
The process is mostly automated, but you’ll need to monitor for errors and potentially troubleshoot issues.
Initialize Terraform
From the gcp directory, initialize the working directory:
This command:
- Downloads required provider plugins (Google, Kubernetes, Helm)
- Configures the GCS backend for state storage
- Validates your backend configuration
Expected output:
Backend initialization errors usually mean:
- The state bucket doesn’t exist (create it first)
- You don’t have permission to access the bucket
- The bucket is in a different project than expected
If you see “Error loading state,” verify your backend configuration in provider.tf.
Review the plan
Before creating anything, preview what Terraform will do:
This shows all resources that will be created, modified, or destroyed. For a fresh deployment, you should see only resource additions (green + symbols).
Key resources in the plan:
Save the plan for audit purposes: bash terraform plan -out=plan.tfplan You can then apply this exact plan with terraform apply plan.tfplan.
This is useful if you need approval before applying.
Review the plan carefully if you see any deletions or modifications. For a
new deployment, there should be no - (destroy) or ~ (modify) symbols. If
you see them, something may be misconfigured.
Apply the infrastructure
Once you’ve reviewed the plan, create the resources:
Terraform shows the plan again and asks for confirmation. Type yes to proceed.
Expected duration: 15-25 minutes
Don’t interrupt the process. If you press Ctrl+C or close your terminal,
Terraform may leave resources in a partially created state. If this happens,
just run terraform apply again—it will pick up where it left off.
Common provisioning errors
Permission errors
Your identity lacks permission to create resources. You need:
Editorrole on the project (or custom equivalent)Project IAM Adminfor creating IAM bindingsSecret Manager Adminfor managing secrets
Many organizations restrict IAM binding creation. If you can’t get Project IAM Admin, you may need a platform team member to run the deployment or pre-create the required IAM bindings.
Quota errors
You’ve hit a GCP CPU quota. Common limits:
Quota increases can take hours to days. If you’re in a new project, request increases before starting deployment.
Naming conflicts
GCS bucket names must be globally unique. If you get naming conflicts:
- Change
confident_application_nameto something unique - Verify you’re not running multiple deployments with the same name
GKE creation timeout
GKE can occasionally take longer than expected. Usually just re-running terraform apply continues where it left off. If it keeps failing:
- Check GCP Service Health for regional issues
- Verify your VPC has available secondary ranges
- Check for Org Policy restrictions in your project
Organization Policies can block resource creation. Many enterprises have policies that:
- Restrict which regions you can deploy to (
gcp.resourceLocations) - Require specific labels on all resources
- Block external IPs (
compute.vmExternalIpAccess) - Require CMEK encryption
- Enforce VPC Service Controls
If you get persistent errors, check with your cloud governance team about Organization Policies.
Provider authentication errors
Terraform can’t authenticate to GCP. Verify:
gcloud auth application-default loginwas rungcloud auth listshows your active accountGOOGLE_APPLICATION_CREDENTIALSis set if using a service account key
Helm release errors
This usually means GKE isn’t fully ready when Helm tries to install charts. Re-running terraform apply typically resolves it.
Capture important outputs
After successful completion, Terraform displays outputs. Save these—you’ll need them for subsequent steps:
You can always retrieve outputs later by running terraform output in the
same directory with access to the state file.
What was deployed
Here’s what now exists in your GCP project:
Networking
- VPC Network with DNS support
- GKE subnet — where GKE nodes run (with secondary ranges for pods and services)
- Database PSA range — allocated range for Cloud SQL VPC peering
- Public subnet — for public-facing resources
- Private Service Connect subnet — for GCS private endpoint access
- Cloud NAT — allows GKE nodes to make outbound requests
- Firewall rules — controls traffic to/from the GKE subnet
- Cloud DNS Private Zone — resolves Cloud SQL hostname within the VPC
Compute (GKE)
- GKE Cluster — Kubernetes control plane managed by Google
- System Node Pool — 2x
n2-standard-4running system components - Worker Node Pool — autoscaling pool running application workloads
- Workload Identity — federation enabled for pod identity
Data stores
- Cloud SQL for PostgreSQL — managed database with regional HA and private DNS
- GCS Buckets — uniform-access buckets with versioning and Private Google Access
- GCS Buckets — test cases, payloads, and ClickHouse backups
- Secret Manager — contains all application credentials and connection strings
Kubernetes components (pre-installed via Helm)
- NGINX Ingress Controller — routes traffic from Cloud Load Balancer to services
- External Secrets Operator — syncs secrets from Secret Manager to Kubernetes
- ArgoCD — GitOps tool for managing deployments
- cert-manager — automates TLS certificate lifecycle
- ClickHouse Operator — manages the analytics database
Security
- Service Accounts — separate identities for GKE, storage, external secrets, and ClickHouse backup
- Workload Identity Bindings — links Kubernetes service accounts to GCP service accounts
- IAM Role Bindings — Storage Object Admin, Secret Manager Secret Accessor, Cloud SQL Client
- Firewall rules — controls traffic to/from GKE nodes
What to do if provisioning fails
-
Read the error message carefully. Terraform errors usually indicate exactly what went wrong.
-
Don’t panic. Terraform is idempotent—you can run
applyagain and it will continue from where it failed. -
Check common causes:
- Permissions
- Quota limits
- Network connectivity
- Invalid variable values
-
If stuck, don’t destroy and recreate. This can leave orphaned resources. Instead, fix the configuration and re-apply.
Never run terraform destroy unless you intend to delete everything. If
you’re troubleshooting, fix the issue and re-run apply. Destroying and
recreating can lose data and create inconsistent state.
Next steps
After infrastructure is provisioned, proceed to TLS Certificates to configure HTTPS for your services.