Provision a Cloud Server with Terraform
Write Terraform code to provision and destroy a VM on Google Cloud.
Introduction
30 Second Summary
Think about how companies manage hundreds of servers. They don't click through web dashboards one by one. They write code that describes exactly what infrastructure they want, and a tool builds it for them automatically.
In this project, you will write a Terraform configuration file that provisions a virtual machine on Google Cloud, connect to it to prove it exists, and then destroy it with a single command.
What You'll Build
A Terraform project that provisions a Compute Engine virtual machine on Google Cloud Platform entirely through code.
By the end of this project, you'll have:
- A working Terraform configuration file (main.tf) that defines a cloud server you can reuse or modify.
- A live virtual machine running on Google Cloud, deployed without clicking a single button in the console.
- Hands-on experience with the full Infrastructure as Code lifecycle: write, plan, apply, verify, and destroy.
- Secret Mission: Extend your config to automatically deploy a web server with a firewall rule.
Are there any prerequisites?
Just a Google account (Gmail). No prior DevOps, coding, or cloud experience is required. All tools are pre-installed in the browser-based terminal you will use.
Set Up Your GCP Account and Cloud Shell
Before you can write any infrastructure code, you need a cloud environment to deploy to. In this step, you will create a Google Cloud account and open a browser-based terminal called Cloud Shell that has all your tools pre-installed.
The best part about Cloud Shell is that you do not need to install anything on your own computer. Terraform and the Google Cloud CLI are already ready to go.
In this step, get ready to:
- Create a Google Cloud account with $300 in free trial credits.
- Open Cloud Shell and verify Terraform and gcloud are pre-installed.
- Set your active project and enable the Compute Engine API.
Create your Google Cloud account
Google Cloud Platform offers a free trial with $300 in credits valid for 90 days. You will not be charged during the trial period.
- Open your browser and go to cloud.google.com/free.
- Click Get started for free.
- Sign in with your Google account (your Gmail account works).
- Follow the prompts to provide your payment details.
- Wait for the Google Cloud Console to load with your My First Project dashboard.
Why do I need payment details?
Google requires a credit card to verify your identity, but you will not be charged during the free trial. The $300 credit lasts 90 days, and Google will not auto-charge you when it runs out.
Don't see the free trial offer?
Make sure you are signed in with a Google account that has never used GCP before. The $300 free trial is only available for new Google Cloud accounts.
help me troubleshoot my GCP free trial signup
Open Cloud Shell and verify your tools
Cloud Shell is a free browser-based Linux terminal built into the Google Cloud Console. It comes with Terraform, gcloud, Git, and other DevOps tools pre-installed and updated weekly.
- In the Google Cloud Console, look at the top-right toolbar.
- Click the Activate Cloud Shell button (the terminal icon that looks like >_).
- Wait for the Cloud Shell terminal to open at the bottom of your browser window.
What is Cloud Shell?
Cloud Shell gives you a full Linux terminal right in your browser. It has 5 GB of persistent storage in your home directory, so your files stick around between sessions.
Because Terraform and gcloud are pre-installed, you can skip the entire local setup process and jump straight into writing infrastructure code.
- Verify Terraform is installed by running this command in Cloud Shell:
terraform version
- Verify the Google Cloud CLI is installed by running:
gcloud --version
✔️ I see version numbers for both
You should see output like Terraform v1.x.x for the first command, and a list of gcloud components with version numbers for the second. Both tools are ready to go.
ⓧ I see 'command not found' or an error
This is very unusual in Cloud Shell since both tools are pre-installed. Try these fixes:
- Make sure you are typing in the Cloud Shell terminal at the bottom of the Console (not your local terminal).
- Close Cloud Shell and reopen it by clicking the >_ icon again.
- If the issue persists, click the three-dot menu in Cloud Shell and select Restart.
help me fix Cloud Shell not recognizing terraform or gcloud commands
Set your active project and enable the Compute Engine API
Terraform needs to know which GCP project to create resources in. You also need to enable the Compute Engine API so that Terraform can create virtual machines.
- Find your project ID by looking at the project selector dropdown at the top of the Google Cloud Console. It appears next to My First Project (it looks something like my-first-project-123456).
- Set your active project by running this command (replace the placeholder with your own project ID):
gcloud config set project [[PROJECT_ID="your GCP project ID"]]
What does this command do?
This tells the gcloud CLI which project to use for all following commands. Every resource you create will go into this project.
- Enable the Compute Engine API by running:
gcloud services enable compute.googleapis.com
Wait about 15-30 seconds for the API to enable. You should see a confirmation message with no errors.
Why do I need to enable the API?
GCP keeps its services disabled by default until you explicitly turn them on. Enabling the Compute Engine API gives Terraform permission to create and manage virtual machines in your project.
Seeing a permissions error?
Make sure you ran the gcloud config set project command first with your correct project ID. If you see a billing-related error, confirm that your free trial is active by checking the Billing page in the Console navigation menu.
help me fix a permissions or billing error when enabling the Compute Engine API
Your cloud environment is ready to go. Next up, you will write your first Terraform configuration file that defines a virtual machine.
Write Your First Terraform Configuration
Your cloud environment is ready. Now it is time to write the code that tells Terraform exactly what infrastructure to create.
Terraform uses a configuration language called HCL (HashiCorp Configuration Language) to describe your desired infrastructure. You will write a single file that declares which cloud provider to use and what resources to create.
In this step, get ready to:
- Create a project directory and your first Terraform file.
- Write a Terraform configuration that defines a virtual machine.
- Initialize Terraform to download the Google Cloud provider plugin.
Create your project directory and Terraform file
Every Terraform project lives in its own directory. You will create a folder for your project and an empty configuration file inside it.
- In your Cloud Shell terminal, create a project directory, move into it, and create your Terraform file by running these commands:
mkdir my-first-server && cd my-first-server && touch main.tf
- Confirm the file was created by running:
ls
You should see main.tf listed in the output.
- Open the Cloud Shell Editor by clicking Open Editor in the Cloud Shell toolbar (the pencil icon near the top of the Cloud Shell pane).
- In the file explorer on the left, expand the my-first-server folder.
- Click main.tf to open it in the editor.
What is the Cloud Shell Editor?
Cloud Shell Editor is a built-in code editor inside the Google Cloud Console. It works like a simplified version of VS Code, right in your browser. You can write and save files without installing anything on your computer.
Define the required provider
Terraform needs to know which cloud provider plugin to download. The terraform block at the top of your file declares this dependency.
- In main.tf, paste the following code at the very top of the file:
# Declare that this project uses the Google Cloud provider
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 7.0"
}
}
}
What does this code do?
The terraform block tells Terraform where to find the Google Cloud plugin. source = "hashicorp/google" points to the official Google provider on the Terraform registry.
The version = "~> 7.0" constraint means "any version in the 7.x range." This keeps your config compatible with updates without jumping to a breaking major version.
Configure the Google provider
Now that Terraform knows which plugin to use, you need to tell the provider which GCP project and region to target.
- Below the terraform block you just added, paste the following provider configuration:
# Configure the Google Cloud provider with your project and region
provider "google" {
project = "[[PROJECT_ID=your-project-id-here]]"
region = "us-central1"
}
What does this code do?
The provider block configures the Google plugin with two settings. project tells Terraform which GCP project to create resources in (use the same project ID you set in Step 1). region sets the default geographic location for your resources.
Find your project ID
Your project ID is displayed in the project selector dropdown at the top of the Google Cloud Console. It looks something like my-first-project-123456. Replace the placeholder with your actual project ID.
Define the virtual machine resource
This is the most important part. The resource block describes the actual cloud server you want Terraform to create on Compute Engine.
- Below the provider block, paste the following resource definition:
# Define a Compute Engine VM instance
resource "google_compute_instance" "devops_vm" {
name = "devops-vm"
machine_type = "e2-micro"
zone = "us-central1-a"
# The operating system disk for the VM
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
}
# Network settings - attach to the default VPC with a public IP
network_interface {
network = "default"
access_config {
// Ephemeral public IP
}
}
}
What does this code do?
This block creates a virtual machine with these settings:
- name gives the VM a human-readable label in the GCP Console.
- machine_type sets the size. e2-micro is the smallest (and free-tier eligible) option.
- boot_disk specifies the operating system. debian-cloud/debian-12 is a lightweight Linux distribution.
- access_config gives the VM a public IP address so you can connect to it later.
Why e2-micro?
GCP's free tier includes one e2-micro instance per month in us-central1. This means your VM costs nothing to run during this project.
- Save main.tf by pressing Cmd+S (macOS) or Ctrl+S (Windows).
✔️ Awesome, I've got everything!
Great. Double check that you have saved your file before moving on.
ⓧ I'd like to double check the full code
Here is the complete main.tf file. Make sure yours matches exactly (except for your project ID):
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 7.0"
}
}
}
provider "google" {
project = "your-project-id-here"
region = "us-central1"
}
resource "google_compute_instance" "devops_vm" {
name = "devops-vm"
machine_type = "e2-micro"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
}
network_interface {
network = "default"
access_config {
// Ephemeral public IP
}
}
}
Initialize Terraform
Before Terraform can use your configuration, it needs to download the Google Cloud provider plugin you declared. The terraform init command handles this setup.
- Switch back to the terminal by clicking Open Terminal in the Cloud Shell toolbar.
- Download the provider plugin by running:
terraform init
You should see output ending with Terraform has been successfully initialized! confirming the Google provider was downloaded.
What does this command do?
The terraform init command reads your main.tf file, finds the required_providers block, and downloads the matching plugin from the Terraform registry. It stores the plugin in a hidden .terraform directory inside your project folder.
- Verify the plugin was downloaded by running:
ls -a
You should see .terraform listed alongside main.tf. The .terraform directory contains the downloaded Google Cloud provider plugin.
Seeing an error during init?
If you see a message about missing provider requirements, make sure your terraform block has the correct source value of hashicorp/google. Check for typos in main.tf and save the file before running terraform init again.
If you see a "directory not found" error, make sure you are inside the my-first-server folder. Run pwd to check your current location.
Help me troubleshoot my terraform init error.
Your Terraform configuration is written and initialized. Next up, you will preview what Terraform plans to create and then deploy your server to the cloud with a single command.
Preview and Deploy Your Server
Your main.tf configuration is written and initialized. Terraform has downloaded the Google Cloud provider plugin and is ready to work with your infrastructure definition.
Now comes the exciting part. You will run the two most important Terraform commands: terraform plan to preview what will be created, and terraform apply to actually build your server in the cloud.
In this step, get ready to:
- Preview your infrastructure changes with terraform plan.
- Deploy your VM to Google Cloud with terraform apply.
- Verify your server is running in the GCP Console.
Preview your infrastructure with terraform plan
Before creating anything real, Terraform lets you preview exactly what it intends to do. This is your safety net. In a real team, you would share this preview with colleagues before making changes to production infrastructure.
- Preview what Terraform will create by running this command in Cloud Shell:
terraform plan
Terraform reads your main.tf file, compares it against the current state (which is empty because nothing exists yet), and shows you what it plans to do.
At the bottom of the output, you should see a summary line: Plan: 1 to add, 0 to change, 0 to destroy. This confirms Terraform will create one resource (your VM) and not modify or delete anything.
What does the rest of the output mean?
Above the summary line, Terraform shows every attribute of the resource it plans to create. Lines starting with + mean something will be added. Values marked (known after apply) are details that Google Cloud will assign once the VM actually exists (like its internal ID).
The plan makes no changes to your cloud account. It only reads and reports.
Seeing an error instead of a plan?
If the output mentions credentials or authentication, your Cloud Shell session may have timed out. Run gcloud auth application-default login and follow the prompts to re-authenticate.
If you see a message about the Compute Engine API not being enabled, run gcloud services enable compute.googleapis.com and try the plan again.
help me debug my terraform plan error
Deploy your VM with terraform apply
The plan looked good. Time to make it real. The terraform apply command calls the Google Cloud API and builds everything described in the plan.
- Deploy your server to Google Cloud by running:
terraform apply
What happens after you run this?
Terraform will show you the same plan output you saw before, then ask for confirmation. It displays a prompt that says Do you want to perform these actions? and waits for your input.
Only typing yes (the full word) will proceed. Anything else cancels without making changes.
- Type yes and press Enter when prompted.
Wait about 30-60 seconds while Terraform provisions your VM. You will see progress messages as the resource is created.
When it finishes, you should see: Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Apply failed or timed out?
If you see a quota error, your project may not have Compute Engine quota available yet. Wait a minute and try terraform apply again. New projects sometimes take a moment for quotas to propagate.
If you accidentally typed something other than yes at the prompt, Terraform cancelled without making changes. Run terraform apply again and type yes this time.
help me fix my terraform apply error
Verify your VM in the Google Cloud Console
The terminal says the VM was created, but let's confirm it with our own eyes in the Console. This builds the habit of verifying infrastructure changes visually.
- Switch back to your Google Cloud Console browser tab.
- Click the navigation menu (the three horizontal lines in the top-left corner).
- Scroll down to Compute Engine and click VM instances.
You should see your VM named devops-vm with a green checkmark and status Running. The machine type column shows e2-micro and the zone shows us-central1-a.
Why verify in the Console?
Terraform told you it succeeded, but the Console gives you independent confirmation. You built this server entirely through code. No clicking, no wizards, no manual configuration. That is Infrastructure as Code in action.
Don't see your VM listed?
Make sure you are looking at the correct project. Check the project selector in the top bar of the Console and confirm it matches the project ID in your main.tf file.
If the VM instances page is still loading, give it a few seconds and refresh. Newly created VMs can take a moment to appear in the Console UI.
help me find my VM in the Google Cloud Console
Your server is live in the cloud. Next up, you will connect to it via SSH and then tear it all down with a single command.
Connect to Your Server and Tear It Down
Your VM is running on Google Cloud, created entirely through code. Now it's time to prove it's real and experience the other side of Infrastructure as Code: tearing things down.
You'll SSH directly into the server to confirm it's a live Debian machine. Then you'll destroy everything with one command, leaving no orphaned resources or surprise bills.
In this step, get ready to:
- SSH into your running cloud server to confirm it's a real Debian machine.
- Destroy the VM with a single Terraform command.
- Verify that the infrastructure is completely gone.
SSH into your cloud server
Your VM is running, but so far you've only seen it in the Console. The real proof is connecting to it directly and running commands on it.
- Connect to your VM by running this command in Cloud Shell:
gcloud compute ssh devops-vm --zone=us-central1-a
What does this command do?
The gcloud compute ssh command handles everything needed to connect to your VM. It generates SSH keys automatically, tunnels the connection through Google's network, and drops you into a terminal session on the remote machine.
You do not need to configure SSH keys manually. Google Cloud manages all of that for you.
- If prompted with a message about the authenticity of the host, type yes and press Enter.
- If prompted to create a passphrase for your SSH key, press Enter twice to leave it empty.
You are now inside your cloud server. Your terminal prompt changes to show you are on the remote machine.
- Confirm you're on a Debian machine by running these commands:
hostname
cat /etc/os-release
You should see devops-vm as the hostname. The os-release output shows Debian GNU/Linux 12 as the operating system.
- Return to Cloud Shell by running:
exit
SSH connection failing?
- Make sure you are in Cloud Shell (not a local terminal). Cloud Shell has gcloud pre-configured with your project credentials.
- Verify the VM is still running by checking the Compute Engine console. If it shows a status other than running, wait a minute and try again.
- Double check the zone matches exactly: us-central1-a. A typo in the zone means gcloud cannot find the VM.
SSH into my VM failing
Destroy the infrastructure
You've proven the VM is real. Now experience the most powerful part of IaC: tearing down infrastructure just as easily as you created it.
- Destroy your infrastructure by running this command:
terraform destroy
What happens when you run terraform destroy?
Terraform reads your state file to see what resources it manages. It then generates a destroy plan showing exactly what will be removed. You'll see a summary line like Plan: 0 to add, 0 to change, 1 to destroy. confirming only your VM will be deleted.
Terraform asks for confirmation before making any changes. This is your safety net. In a real team, you would review this plan carefully before typing yes.
- Review the plan output. It shows 1 resource to destroy.
- Type yes and press Enter to confirm.
Wait about 30 seconds. You should see Destroy complete! Resources: 1 destroyed. confirming the VM has been removed.
Why is this so powerful?
No leftover resources. No surprise bills. No clicking through five different console pages to find and delete things. One command cleans up everything that your code defined.
This is how real DevOps teams manage environments. They spin up infrastructure for testing, use it, and destroy it in minutes. The code stays in version control, ready to recreate everything whenever needed.
Seeing an error during destroy?
- Make sure you are in the my-first-server directory where your main.tf and terraform.tfstate files live. Run ls to confirm.
- If you see a permission error, your Cloud Shell session may have timed out. Run gcloud auth login to re-authenticate.
Help me fix my terraform destroy error
Verify the infrastructure is gone
Trust but verify. You'll confirm the VM is gone in two ways: through the Console and through Terraform's state file.
- Switch to your Google Cloud Console browser tab.
- Navigate to Compute Engine > VM instances using the left navigation menu (or search for VM instances in the search bar).
- Refresh the page if needed.
Your devops-vm should no longer appear in the list. The page either shows no VM instances or only shows other VMs if you have them.
- Back in Cloud Shell, check Terraform's state file by running:
cat terraform.tfstate
You should see an empty resources list in the JSON output. This confirms Terraform knows the infrastructure is gone and is no longer tracking any resources.
What is the state file?
The terraform.tfstate file is Terraform's record of what it manages. After terraform apply, it records every resource and its attributes. After terraform destroy, it empties the list because nothing exists anymore.
This state file is what lets Terraform know the difference between "create this resource" and "this resource already exists." Without it, Terraform would try to create a duplicate VM every time you ran terraform apply.
Secret mission
Add a Web Server with a Firewall Rule
Your Terraform config deploys a bare VM. Can you extend it to automatically install a web server and open the right port so the world can see it?
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely in Google Cloud Shell and uses resources within the GCP free tier. If you already ran terraform destroy at the end of Step 4 or the Secret Mission, your cloud resources are already gone. Decide whether to keep your project files or delete them entirely.
Resources you used:
- Compute Engine VM instance (devops-vm) in us-central1-a.
- Firewall rule (allow-http) on the default network (Secret Mission only).
- The my-first-server directory in Cloud Shell (contains main.tf, .terraform, and terraform.tfstate).
- GCP project with the Compute Engine API enabled.
Keep everything running
No action needed. Choose this if you plan to continue experimenting with Terraform on this project.
- Your my-first-server directory stays in Cloud Shell's persistent 5 GB home storage.
- The VM and firewall rule are already destroyed, so there are no running resources and no charges.
- Your GCP project remains active. The e2-micro free tier allows 1 instance per month at no cost in us-central1, so you can re-deploy any time without charges.
Pause - I'll come back to this later
Since you already ran terraform destroy, there are no running resources to pause. Your files remain in Cloud Shell for when you return.
- Cloud Shell's persistent home directory keeps your my-first-server folder between sessions.
- If you do not open Cloud Shell for 120 days, Google may delete your home directory. Open a session before then to reset the timer.
- No charges apply while the VM and firewall rule remain destroyed.
Delete - I don't want to use this again
Remove all project files and optionally delete the GCP project itself. This is the recommended option for a clean slate.
- If you have not already run terraform destroy, do that first to remove any cloud resources:
- Navigate to the project directory and destroy resources by running:
cd ~/my-first-server
terraform destroy
- Type yes when prompted to confirm.
- Delete the project directory from Cloud Shell by running:
cd ~
rm -rf my-first-server
- (Optional) Delete the GCP project entirely. This removes the project and all associated data by running:
gcloud projects delete [[PROJECT_ID="your-project-id"]]
- Type Y when prompted to confirm. The project enters a 30-day shutdown period before permanent deletion.
What if I want my project back?
Google Cloud keeps deleted projects in a recoverable state for 30 days. If you change your mind, you can restore it by running:
gcloud projects undelete PROJECT_ID
That's a Wrap!
That's a Wrap!
Nice work! You just provisioned and destroyed real cloud infrastructure entirely through code, completing the same workflow that professional DevOps engineers use every day.
You've learned how to:
- Write a Terraform configuration file (main.tf) from scratch using HCL syntax and deploy a virtual machine to Google Cloud with a single command.
- Execute the full Terraform workflow: terraform init, terraform plan, terraform apply, and terraform destroy.
- Connect to a live cloud server via SSH and verify the complete Infrastructure as Code lifecycle from creation to destruction.
- Secret Mission: Extended your config to deploy a web server with a firewall rule, proving how Terraform manages multiple related resources.
Ready to quiz yourself?