NeuroAgent

Docker Image for Google Cloud Functions Terraform Guide

Complete guide to configuring Docker images for Google Cloud Functions in Terraform. Fix 'Unsupported argument' errors with proper 2nd gen function setup.

Question

How to properly configure a Docker image as source code for Google Cloud Functions using Terraform? I’m encountering an ‘Unsupported argument’ error when trying to use the ‘image’ parameter in the google_cloudfunctions2_function resource. What is the correct way to specify a Docker container image for a Cloud Function in Terraform?

NeuroAgent

The “Unsupported argument” error occurs because the image parameter is not directly supported in the google_cloudfunctions2_function resource for second-generation Cloud Functions. Instead, you need to use a different approach by either building the container image separately or using the build configuration within the Terraform resource.

Contents


Understanding the Resource Differences

Google Cloud Functions has two generations managed differently in Terraform:

  • 1st Generation: Uses google_cloudfunctions_function resource with direct Docker image support via the docker_repository parameter
  • 2nd Generation: Uses google_cloudfunctions2_function resource with different configuration approach

According to the Google Cloud documentation, second-generation Cloud Functions (Cloud Run functions) require a different deployment strategy compared to first-generation functions.


Correct Configuration for 1st Generation Functions

For first-generation functions, you can directly reference a Docker image:

terraform
resource "google_cloudfunctions_function" "docker_function" {
  name        = "docker-example-function"
  runtime     = "python310"  # Still required for validation
  available_memory_mb = 256
  source_archive_bucket = google_storage_bucket.source_bucket.name
  source_archive_object = google_storage_bucket_object.source_object.name
  entry_point = "handler"
  
  docker_repository = "us-central1-docker.pkg.dev/your-project/your-repo/your-image:tag"
  
  trigger_http = true
  
  service_account_email = google_service_account.function.email
}

Correct Configuration for 2nd Generation Functions

For second-generation functions, you have two main approaches:

Method 1: Using Build Configuration

terraform
resource "google_cloudfunctions2_function" "container_function" {
  name     = "container-example-function"
  location = "us-central1"
  
  build_config {
    runtime = "python310"  # For validation only
    entry_point = "handler"
    
    source {
      storage_source {
        bucket = google_storage_bucket.source_bucket.name
        object = google_storage_bucket_object.source_object.name
      }
    }
    
    docker_repository = "us-central1-docker.pkg.dev/your-project/your-repo/your-image"
  }
  
  service_config {
    max_instance_count = 1
    min_instance_count = 0
    available_memory_mb = 256
    timeouts {
      create = "5m"
      update = "5m"
      read   = "5m"
    }
  }
  
  event_trigger {
    trigger {
      pubsub_topic = google_pubsub_topic.topic.id
    }
  }
}

Method 2: Using Pre-built Container Image

terraform
resource "google_cloudfunctions2_function" "prebuilt_function" {
  name     = "prebuilt-example-function"
  location = "us-central1"
  
  service_config {
    max_instance_count = 1
    min_instance_count = 0
    available_memory_mb = 256
    timeouts {
      create = "5m"
      update = "5m"
      read   = "5m"
    }
  }
  
  template {
    containers {
      image = "us-central1-docker.pkg.dev/your-project/your-repo/your-image:tag"
      env {
        name  = "ENV_VAR"
        value = "production"
      }
    }
  }
}

Step-by-Step Docker Image Deployment

Complete Example for 2nd Generation Functions

terraform
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 4.34.0"
    }
    archive = {
      source  = "hashicorp/archive"
      version = "~> 2.2.0"
    }
  }
}

resource "random_id" "bucket_prefix" {
  byte_length = 8
}

resource "google_service_account" "function" {
  account_id   = "function-service-account"
  display_name = "Function Service Account"
}

resource "google_storage_bucket" "source_bucket" {
  name     = "${random_id.bucket_prefix.hex}-gcf-source"
  location = "US"
  uniform_bucket_level_access = true
}

resource "google_storage_bucket_object" "source_object" {
  name   = "function-source.zip"
  bucket = google_storage_bucket.source_bucket.name
  source = data.archive_file.default.output_path
}

data "archive_file" "default" {
  type        = "zip"
  output_path = "/tmp/function-source.zip"
  source_dir  = "./function-source"
}

resource "google_pubsub_topic" "topic" {
  name = "function-trigger-topic"
}

resource "google_cloudfunctions2_function" "container_function" {
  name     = "container-example-function"
  location = "us-central1"
  
  build_config {
    runtime = "python310"
    entry_point = "handler"
    
    source {
      storage_source {
        bucket = google_storage_bucket.source_bucket.name
        object = google_storage_bucket_object.source_object.name
      }
    }
    
    docker_repository = "us-central1-docker.pkg.dev/${var.project_id}/artifact-repo/function-image"
    service_account   = google_service_account.function.email
  }
  
  service_config {
    max_instance_count = 1
    min_instance_count = 0
    available_memory_mb = 256
    timeout_seconds     = 60
    environment_variables = {
      "ENV_VAR" = "production"
    }
  }
  
  event_trigger {
    trigger {
      pubsub_topic = google_pubsub_topic.topic.id
    }
  }
}

Common Issues and Troubleshooting

Provider Version Issues

The google_cloudfunctions2_function resource requires specific provider versions. According to Stack Overflow discussions, ensure you’re using:

terraform
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 4.34.0"
    }
  }
}

Image Format Issues

When referencing pre-built images, ensure you’re using the correct format:

yaml
# Correct format for Artifact Registry
image = "LOCATION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG"

# Example
image = "us-central1-docker.pkg.dev/my-project/my-repo/my-function:v1.0.0"

Service Account Permissions

The build service account needs appropriate permissions:

terraform
resource "google_project_iam_member" "build_permissions" {
  project = var.project_id
  role    = "roles/cloudbuild.builds.builder"
  member  = "serviceAccount:${google_service_account.function.email}"
}

Best Practices

1. Use Artifact Registry

terraform
resource "google_artifact_registry_repository" "docker_repo" {
  location      = "us-central1"
  repository_id = "artifact-repo"
  format        = "DOCKER"
}

2. Environment-Specific Images

terraform
variable "environment" {
  default = "development"
}

resource "google_cloudfunctions2_function" "environment_function" {
  name     = "env-${var.environment}-function"
  location = "us-central1"
  
  template {
    containers {
      image = "us-central1-docker.pkg.dev/${var.project_id}/artifact-repo/function-${var.environment}:latest"
    }
  }
}

3. Image Tagging Strategy

  • Use semantic versioning for production images
  • Use latest for development
  • Consider using Git commit hashes for tracking

4. Resource Organization

terraform
module "cloud_functions" {
  source = "./modules/cloud-function"
  
  function_name = "example-function"
  project_id    = var.project_id
  location      = var.location
  environment   = var.environment
  source_code   = "./src"
}

The key takeaway is that second-generation Cloud Functions require a different approach than first-generation when using Docker images. Instead of a direct image parameter, you need to either use the build_config block for automatic building or the template block with containers for pre-built images.

Sources

  1. Google Cloud Functions Terraform Tutorial
  2. Google Cloud Functions 2nd Generation Samples
  3. Terraform Google Provider Documentation
  4. Stack Overflow: google_cloudfunctions2_function not supported
  5. GoogleCloudPlatform Terraform Module
  6. Medium: Deploy Cloud Functions with Terraform 2nd Gen

Conclusion

  • 1st Generation Functions: Use google_cloudfunctions_function with the docker_repository parameter
  • 2nd Generation Functions: Use google_cloudfunctions2_function with either build_config or template.containers.image
  • Provider Requirements: Ensure Google provider version >= 4.34.0 for 2nd generation support
  • Image References: Use the format LOCATION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG for Artifact Registry
  • Build Process: For 2nd gen functions, Cloud Build automatically creates container images from source code

The “Unsupported argument” error occurs because the image parameter doesn’t exist in the google_cloudfunctions2_function resource structure. Use the correct configuration approaches outlined above to successfully deploy Docker images with second-generation Cloud Functions using Terraform.