IaC-инструменты для GCP
| Инструмент | Тип | Статус | Рекомендация |
|---|---|---|---|
| Deployment Manager | GCP native, YAML | Legacy | Не для новых проектов |
| Terraform | Мультиклауд, HCL | Активный | Рекомендуется |
| Pulumi | Мультиклауд, Python/TS | Активный | Хорошая альтернатива |
| Config Connector | Kubernetes CRD | Активный | Для GKE-окружений |
Google рекомендует Terraform вместо Deployment Manager для новых проектов.
Terraform для GCP CRC
Полный конфиг
# main.tf
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
variable "project_id" {
description = "GCP Project ID"
type = string
}
variable "region" {
default = "us-central1"
}
# ========== STORAGE (Frontend) ==========
resource "google_storage_bucket" "frontend" {
name = "${var.project_id}-resume"
location = var.region
website {
main_page_suffix = "index.html"
not_found_page = "error.html"
}
uniform_bucket_level_access = true
cors {
origin = ["*"]
method = ["GET"]
response_header = ["Content-Type"]
max_age_seconds = 86400
}
}
resource "google_storage_bucket_iam_member" "public_read" {
bucket = google_storage_bucket.frontend.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
# ========== FIRESTORE ==========
resource "google_firestore_database" "default" {
project = var.project_id
name = "(default)"
location_id = var.region
type = "FIRESTORE_NATIVE"
}
# ========== CLOUD FUNCTION ==========
resource "google_storage_bucket" "function_source" {
name = "${var.project_id}-function-source"
location = var.region
}
data "archive_file" "function_zip" {
type = "zip"
source_dir = "${path.module}/backend/"
output_path = "${path.module}/function.zip"
}
resource "google_storage_bucket_object" "function_source" {
name = "function-${data.archive_file.function_zip.output_md5}.zip"
bucket = google_storage_bucket.function_source.name
source = data.archive_file.function_zip.output_path
}
resource "google_cloudfunctions2_function" "visitor_counter" {
name = "visitor-counter"
location = var.region
build_config {
runtime = "python312"
entry_point = "visitor_counter"
source {
storage_source {
bucket = google_storage_bucket.function_source.name
object = google_storage_bucket_object.function_source.name
}
}
}
service_config {
max_instance_count = 10
min_instance_count = 0
available_memory = "128Mi"
timeout_seconds = 60
environment_variables = {
PROJECT_ID = var.project_id
}
}
}
# Allow unauthenticated access
resource "google_cloud_run_v2_service_iam_member" "invoker" {
project = google_cloudfunctions2_function.visitor_counter.project
location = google_cloudfunctions2_function.visitor_counter.location
name = google_cloudfunctions2_function.visitor_counter.name
role = "roles/run.invoker"
member = "allUsers"
}
# ========== OUTPUTS ==========
output "function_url" {
value = google_cloudfunctions2_function.visitor_counter.service_config[0].uri
}
output "frontend_url" {
value = "https://storage.googleapis.com/${google_storage_bucket.frontend.name}/index.html"
}
Деплой
# Инициализация
terraform init
# Preview
terraform plan -var="project_id=my-crc-project"
# Деплой
terraform apply -var="project_id=my-crc-project"
# Удаление
terraform destroy -var="project_id=my-crc-project"
Deployment Manager (Legacy)
# deployment.yaml
resources:
- name: crc-bucket
type: storage.v1.bucket
properties:
name: my-crc-resume
location: us-central1
website:
mainPageSuffix: index.html
notFoundPage: error.html
- name: crc-function
type: gcp-types/cloudfunctions-v2:projects.locations.functions
properties:
parent: projects/PROJECT_ID/locations/us-central1
functionId: visitor-counter
buildConfig:
runtime: python312
entryPoint: visitor_counter
# Деплой Deployment Manager
gcloud deployment-manager deployments create crc \
--config deployment.yaml
# Удаление
gcloud deployment-manager deployments delete crc
Pulumi (Python)
# __main__.py
import pulumi
import pulumi_gcp as gcp
# Storage bucket
bucket = gcp.storage.Bucket("frontend",
location="us-central1",
website=gcp.storage.BucketWebsiteArgs(
main_page_suffix="index.html",
not_found_page="error.html"
)
)
# Cloud Function
function = gcp.cloudfunctionsv2.Function("visitor-counter",
location="us-central1",
build_config=gcp.cloudfunctionsv2.FunctionBuildConfigArgs(
runtime="python312",
entry_point="visitor_counter",
),
service_config=gcp.cloudfunctionsv2.FunctionServiceConfigArgs(
max_instance_count=10,
available_memory="128Mi"
)
)
pulumi.export("function_url", function.service_config.uri)