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?
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
- Correct Configuration for 1st Generation Functions
- Correct Configuration for 2nd Generation Functions
- Step-by-Step Docker Image Deployment
- Common Issues and Troubleshooting
- Best Practices
Understanding the Resource Differences
Google Cloud Functions has two generations managed differently in Terraform:
- 1st Generation: Uses
google_cloudfunctions_functionresource with direct Docker image support via thedocker_repositoryparameter - 2nd Generation: Uses
google_cloudfunctions2_functionresource 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:
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
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
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 {
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 {
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:
# 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:
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
resource "google_artifact_registry_repository" "docker_repo" {
location = "us-central1"
repository_id = "artifact-repo"
format = "DOCKER"
}
2. Environment-Specific Images
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
latestfor development - Consider using Git commit hashes for tracking
4. Resource Organization
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
- Google Cloud Functions Terraform Tutorial
- Google Cloud Functions 2nd Generation Samples
- Terraform Google Provider Documentation
- Stack Overflow: google_cloudfunctions2_function not supported
- GoogleCloudPlatform Terraform Module
- Medium: Deploy Cloud Functions with Terraform 2nd Gen
Conclusion
- 1st Generation Functions: Use
google_cloudfunctions_functionwith thedocker_repositoryparameter - 2nd Generation Functions: Use
google_cloudfunctions2_functionwith eitherbuild_configortemplate.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:TAGfor 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.