Terraform Tutorial (2nd gen)


This tutorial demonstrates how to deploy an HTTP function by uploading a function source code zip file to a Cloud Storage bucket, using Terraform to provision the resources. Terraform is an open source tool that lets you provision Google Cloud resources with declarative configuration files.

This tutorial uses a Node.js HTTP function as an example, but it also works with Python, Go, and Java HTTP functions. The instructions are the same regardless of which of these runtimes you are using.

Objectives

  • Learn how to use Terraform to deploy an HTTP function.

Costs

In this document, you use the following billable components of Google Cloud:

For details, see Cloud Functions pricing.

To generate a cost estimate based on your projected usage, use the pricing calculator. New Google Cloud users might be eligible for a free trial.

Before you begin

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Cloud Functions, Cloud Run, Cloud Build, Artifact Registry, and Cloud Storage APIs.

    Enable the APIs

  5. Install the Google Cloud CLI.
  6. To initialize the gcloud CLI, run the following command:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  8. Make sure that billing is enabled for your Google Cloud project.

  9. Enable the Cloud Functions, Cloud Run, Cloud Build, Artifact Registry, and Cloud Storage APIs.

    Enable the APIs

  10. Install the Google Cloud CLI.
  11. To initialize the gcloud CLI, run the following command:

    gcloud init
  12. If you already have the gcloud CLI installed, update it by running the following command:

    gcloud components update
  13. Prepare your development environment.

    Go to the Node.js setup guide

Setting up your environment

In this tutorial, you run commands in Cloud Shell. Cloud Shell is a shell environment with the Google Cloud CLI already installed, including the Google Cloud CLI, and with values already set for your current project. Cloud Shell can take several minutes to initialize:

Open Cloud Shell

Preparing the application

In Cloud Shell, perform the following steps:

  1. Clone the sample app repository to your Cloud Shell instance:

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
  2. Change to the directory that contains the Cloud Functions sample code:

    cd nodejs-docs-samples/functions/helloworld/helloworldHttp

    The Node.js sample used in this tutorial is a basic "Hello World" HTTP function.

  3. Create a zip file containing the function source code that Terraform will upload to a Cloud Storage bucket:

    zip -r function-source.zip .
    

    Note that the root of the zip file must be the root directory of your function source code, so the above command includes the files within the helloworldHttp directory but does not include the directory itself.

Create your main.tf file

  1. In the nodejs-docs-samples/functions/ directory, create a main.tf file for the Terraform configuration:

    touch main.tf
    
  2. Copy this Terraform configuration into your main.tf file:

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = ">= 4.34.0"
        }
      }
    }
    
    resource "random_id" "default" {
      byte_length = 8
    }
    
    resource "google_storage_bucket" "default" {
      name                        = "${random_id.default.hex}-gcf-source" # Every bucket name must be globally unique
      location                    = "US"
      uniform_bucket_level_access = true
    }
    
    data "archive_file" "default" {
      type        = "zip"
      output_path = "/tmp/function-source.zip"
      source_dir  = "functions/hello-world/"
    }
    resource "google_storage_bucket_object" "object" {
      name   = "function-source.zip"
      bucket = google_storage_bucket.default.name
      source = data.archive_file.default.output_path # Add path to the zipped function source code
    }
    
    resource "google_cloudfunctions2_function" "default" {
      name        = "function-v2"
      location    = "us-central1"
      description = "a new function"
    
      build_config {
        runtime     = "nodejs16"
        entry_point = "helloHttp" # Set the entry point
        source {
          storage_source {
            bucket = google_storage_bucket.default.name
            object = google_storage_bucket_object.object.name
          }
        }
      }
    
      service_config {
        max_instance_count = 1
        available_memory   = "256M"
        timeout_seconds    = 60
      }
    }
    
    resource "google_cloud_run_service_iam_member" "member" {
      location = google_cloudfunctions2_function.default.location
      service  = google_cloudfunctions2_function.default.name
      role     = "roles/run.invoker"
      member   = "allUsers"
    }
    
    output "function_uri" {
      value = google_cloudfunctions2_function.default.service_config[0].uri
    }
  3. Edit the main.tf file to make sure it has the correct values for the following items. You need to edit this file whenever your configuration changes (for example, to use a different runtime or deploy a different function):

    • Runtime: In this example, the runtime is nodejs16.
    • Function entry point: In this example, the function entry point is helloHttp.
    • Path to zip file: In this example, if you placed your main.tf file in the nodejs-docs-samples/functions/ directory as described above, the path is ./helloworld/helloworldHttp/function-source.zip.

Initialize Terraform

In the nodejs-docs-samples/functions/ directory containing your main.tf file, run this command to add the necessary plugins and build the .terraform directory:

terraform init

Apply the Terraform configuration

In the nodejs-docs-samples/functions/ directory containing your main.tf file, deploy the function by applying the configuration. When prompted, enter yes:

terraform apply

Test the function

  1. When the function finishes deploying, take note of the URI property or find it using the following command:

    gcloud functions describe function-v2 --gen2 --region=us-central1 --format="value(serviceConfig.uri)"
    
  2. Make a request to this URL to see your function's "Hello World" message. Note that the function is deployed requiring authentication. Therefore you must provide credentials in your request:

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" YOUR_FUNCTION_URL
    

Clean up

After completing the tutorial, you can delete everything that you created so that you don't incur any further costs.

Terraform lets you remove all the resources defined in the configuration file by running the terraform destroy command in the nodejs-docs-samples/functions/ directory containing your main.tf file:

terraform destroy

Enter yes to allow Terraform to delete your resources.