НейроАгент

Руководство по Docker-образам для Google Cloud Functions в Terraform

Полное руководство по настройке Docker-образов для Google Cloud Functions в Terraform. Исправление ошибок 'Unsupported argument' с правильной настройкой функций 2-го поколения.

Вопрос

Как правильно настроить Docker-образ как исходный код для Google Cloud Functions с помощью Terraform? Я столкнулся с ошибкой ‘Unsupported argument’ при попытке использовать параметр ‘image’ в ресурсе google_cloudfunctions2_function. Какой правильный способ указать Docker-контейнерный образ для Cloud Function в Terraform?

НейроАгент

Ошибка “Неподдерживаемый аргумент” возникает из-за того, что параметр image не поддерживается напрямую в ресурсе google_cloudfunctions2_function для функций второго поколения Cloud Functions. Вместо этого необходимо использовать другой подход, либо создавая контейнерный образ отдельно, либо используя конфигурацию build в ресурсе Terraform.

Содержание


Понимание различий ресурсов

Google Cloud Functions имеет два поколения, которые управляются по-разному в Terraform:

  • 1-е поколение: Использует ресурс google_cloudfunctions_function с прямой поддержкой Docker-образа через параметр docker_repository
  • 2-е поколение: Использует ресурс google_cloudfunctions2_function с другим подходом к конфигурации

Согласно документации Google Cloud, функции второго поколения Cloud Functions (функции Cloud Run) требуют другой стратегии развертывания по сравнению с функциями первого поколения.


Правильная конфигурация для функций 1-го поколения

Для функций первого поколения можно напрямую ссылаться на Docker-образ:

terraform
resource "google_cloudfunctions_function" "docker_function" {
  name        = "docker-example-function"
  runtime     = "python310"  # Все еще требуется для валидации
  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
}

Правильная конфигурация для функций 2-го поколения

Для функций второго поколения есть два основных подхода:

Метод 1: Использование конфигурации сборки

terraform
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/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
    }
  }
}

Метод 2: Использование предварительно созданного контейнерного образа

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"
      }
    }
  }
}

Пошаговое развертывание Docker-образа

Полный пример для функций 2-го поколения

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
    }
  }
}

Распространенные проблемы и устранение неполадок

Проблемы с версиями провайдера

Ресурс google_cloudfunctions2_function требует определенных версий провайдера. Согласно обсуждениям на Stack Overflow, убедитесь, что вы используете:

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

Проблемы с форматом образа

При ссылке на предварительно созданные образы убедитесь, что вы используете правильный формат:

yaml
# Правильный формат для Artifact Registry
image = "LOCATION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG"

# Пример
image = "us-central1-docker.pkg.dev/my-project/my-repo/my-function:v1.0.0"

Разрешения сервисного аккаунта

Сервисный аккаунт сборки нуждается в соответствующих разрешениях:

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

Лучшие практики

1. Используйте Artifact Registry

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

2. Образы для конкретных сред

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. Стратегия тегирования образов

  • Используйте семантическое версионирование для production-образов
  • Используйте latest для разработки
  • Рассмотрите использование хэшей Git-коммитов для отслеживания

4. Организация ресурсов

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"
}

Ключевой вывод заключается в том, что функции второго поколения Cloud Functions требуют другого подхода по сравнению с первым поколением при использовании Docker-образов. Вместо прямого параметра image необходимо использовать либо блок build_config для автоматической сборки, либо блок template с containers для предварительно созданных образов.

Источники

  1. Учебник по Terraform для Google Cloud Functions
  2. Примеры функций Google Cloud Functions 2-го поколения
  3. Документация провайдера Terraform Google
  4. Stack Overflow: google_cloudfunctions2_function не поддерживается
  5. GoogleCloudPlatform Terraform Module
  6. Medium: Развертывание Cloud Functions с Terraform 2-го поколения

Заключение

  • Функции 1-го поколения: Используйте google_cloudfunctions_function с параметром docker_repository
  • Функции 2-го поколения: Используйте google_cloudfunctions2_function с либо build_config, либо template.containers.image
  • Требования к провайдеру: Убедитесь, что версия Google провайдера >= 4.34.0 для поддержки 2-го поколения
  • Ссылки на образы: Используйте формат LOCATION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG для Artifact Registry
  • Процесс сборки: Для функций 2-го поколения Cloud Build автоматически создает контейнерные образы из исходного кода

Ошибка “Неподдерживаемый аргумент” возникает из-за того, что параметр image не существует в структуре ресурса google_cloudfunctions2_function. Используйте правильные подходы к конфигурации, описанные выше, для успешного развертывания Docker-образов с функциями второго поколения Cloud Functions с помощью Terraform.