بدون زحمت برنامه GCP Cloud Run خود را با استفاده از Terraform اجرا کنید

Summarize this content to 400 words in Persian Lang
Terraform به دلیلی محبوبیت بیشتری به دست می آورد زیرا سطح بالایی از انعطاف پذیری کنترل را به عنوان IaC (زیرساخت به عنوان کد) فراهم می کند.
ماژول ها را پشتیبانی می کند، وضعیت زیرساخت شما را پیگیری می کند و اگر پروژه شما پیچیده، چند ابری یا محیط های ترکیبی باشد، مفید است.
پیش نیازها
برای شروع، اگر این کار را نکردهاید، حتماً این راهنما را برای نصب Terraform دنبال کنید و مطمئن شوید که حساب GCP را قبلاً تنظیم کردهاید.
برای درک فرآیند استقرار، پیکربندی پایه، انتقال تدریجی و غیره، باید برنامه را قبلاً از طریق ابزارهای دیگری مانند CLI مستقر کنید.
وبلاگ مرتبط با استقرار دستی در زیر اضافه کردم 👇📖
https://blog.stackademic.com/how-to-deploy-a-go-service-to-gcp-cloud-run-694d01cab5b5
ساختار پروژه
برای ساختار پروژه من این فایل ها و ساختار دایرکتوری را دارم.
terraform/
├── modules/
│ ├── docker/
│ │ ├── docker-artifact.tf
│ │ └── variables.tf
│ ├── gcp/
│ │ ├── cloud-run.tf
│ │ └── variables.tf
├── main.tf
├── set-prod.env.sh
├── terraform.tfvars
├── variables.tf
└── account_key.json
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
main.tf: شامل ارائه دهندگان مورد نیاز و پیکربندی ارائه دهنده Google.
variables.tf: نحوه تعریف متغیرها برای پروژه خود را شرح دهید.
terraform.tfvars: نحوه تنظیم مقادیر متغیر مخصوص محیط * را توضیح دهید.
set-prod.env.sh: متغیرهای محیطی را برای terraform با پرچم پیشوند TF_VAR تنظیم می کند.
ماژول ها: جزئیات docker و cloud-run ماژول ها، نقش آنها و نحوه تعامل آنها را توضیح می دهند.
اسکریپت های IaC
من اسکریپتهای ماژولهای والد به فرزند را برای راهنمایی بیشتر به نمایش میگذارم.به احتمال زیاد شما متغیرهای env خواهید داشت که بهترین راه برای من ایجاد اسکریپت پوسته با آن است TF_VAR_ پیشوند این است که Terraform موارد اولیه را تشخیص داده و از آنها استفاده می کند (اما برای آن بعدا).
#!/bin/bash
#server
export TF_VAR_redis_url=”redis_url”
export TF_VAR_firebase_account_key=”your_account_key.json”
export TF_VAR_client_url=”client_url”
export TF_VAR_gcp_account_key=”client_url”
echo “Environment variables for Terraform GCP set.”
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
متغیرهایی که من به خوبی در سطح ماژول تنظیم کردهام، اما والد معمولاً همه آنها را شامل میشوند، اما در سطح ماژول من موارد مناسب را پاس کردم.
variable “project_id” {
description = “The ID of the Google Cloud project.”
type = string
}
variable “project_name” {
description = “The project name of the Google Cloud Run project.”
type = string
}
variable “region” {
description = “The Google Cloud region.”
type = string
}
variable “redis_url” {
description = “The URL for the Redis instance.”
type = string
}
variable “client_url” {
description = “The URL for the client application.”
type = string
}
variable “gcp_account_key” {
description = “Path to the Google Cloud service account key file.”
type = string
}
variable “firebase_account_key_location” {
description = “Firebase account key location in Docker container.”
type = string
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
فایل اسکریپت دیگری نیز وجود دارد که من ایجاد کردم که حاوی مقادیر کلید خصوصی یا مخفی نیست که به راحتی قابل تغییر است و برای مقادیر پیش فرض مفید است. terraform.tfvars
project_id = “recepies-6e7c0”
project_name = “recipe-service”
region = “europe-north1”
gcp_account_key = “./account_key.json”
firebase_account_key_location = “/app/config/account_key.json”
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
بیایید در مورد 🐘 در اتاق خود صحبت کنیم main.tf اسکریپت
terraform {
required_providers {
google = {
source = “hashicorp/google”
version = “>= 4.0.0”
}
}
required_version = “>= 0.12”
}
provider “google” {
credentials = file(var.gcp_account_key)
project = var.project_id
region = var.region
}
# Get project information
data “google_project” “project” {
project_id = var.project_id
}
module “docker” {
source = “./modules/docker”
project_id = var.project_id
}
module “cloud_run” {
source = “./modules/gcp”
project_id = var.project_id
region = var.region
redis_url = var.redis_url
client_url = var.client_url
firebase_account_key_location = var.firebase_account_key_location
cloudrun_image = “gcr.io/${var.project_id}/recipe-server:latest”
depends_on = [
module.docker
]
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
در ابتدا ارائهدهنده PaaS را تعریف میکنم زیرا از GCP استفاده میکنم. Google اضافه شده است، میتوانید AWS، Azure یا سایر ارائهدهندگان را اضافه کنید. اعتبارنامهها برای تأیید درخواست شما به هر ارائهدهنده ابری ضروری است. gcp_account_key که بهعنوان فایل json ارسال میکنید که من در دایرکتوری terraform والدین دارم.
در اسکرین شات بالا می بینید که من یک کلید حساب سرویس در GCP ایجاد کرده ام و حقوق دسترسی مناسب IAM را پاس کرده ام.
تخصیص حقوق دسترسی صحیح IAM (مدیریت هویت و دسترسی) به account_key.json بسیار مهم است زیرا در غیر این صورت هنگام اجرای Terraform با مشکلات مجوز متفاوتی مواجه خواهید شد. نمایشگر نقش، ویرایشگر، storage.admin، cloudrun.admin، مصنوعات Docker.
یک جایگزین نیز وجود دارد که فقط نقش ها و مجوزها را از طریق IaC اختصاص دهید، اما برای من حداقل تا زمانی که بیشتر با آن آشنا شوم، عجله بیشتری دارد.
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
–member=”serviceAccount:YOUR_SERVICE_ACCOUNT_EMAIL” \
–role=”roles/editor”
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
در بالا نشان می دهد که چگونه می توان آن را انجام داد.
سپس مراحل بعدی اجرای ماژولهای شما است، در صورت نیاز برای ایجاد Docker Artifact در GCP، با docker شروع میکنم و پس از تکمیل آن، همین کار را با Cloud Run انجام میدهم. به خاطر داشته باشید که من به دایرکت دسترسی دارم “./modules/docker” و متغیرهای مورد نیاز را از والدین به فرزند منتقل کنید modules/docker/variables.tf.
resource “google_project_service” “container_registry_api” {
project = var.project_id
service = “containerregistry.googleapis.com”
disable_on_destroy = false
}
resource “null_resource” “docker_build_push” {
triggers = {
always_run = timestamp()
}
provisioner “local-exec” {
command = <<-EOT
# Build the Docker image
docker build -t gcr.io/${var.project_id}/recipe-server:latest .
# Configure docker to authenticate with GCP
gcloud auth configure-docker –quiet
# Push the image
docker push gcr.io/${var.project_id}/recipe-server:latest
EOT
}
depends_on = [
google_project_service.container_registry_api
]
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
را docker-artifact.tf بسیار کوتاه است زیرا تنها فکر می کنیم که ما نیاز داریم این است که منابع مورد استفاده را با شروع تعریف کنیم container_registry_api و دوما docker_build_push اضافه کردن تدارکات برای اجرای محلی و پایان دادن به آن با ساختن و استقرار تصویر grc docker با تصویب در var.project_id + اضافه کنید که بستگی دارد container_registry_api همانطور که مورد نیاز است
در نهایت در IaC ما آن را در حال اجرای آخرین ماژول خود با آن مستقر می کنیم “./modules/gcp”
resource “google_project_service” “required_apis” {
for_each = toset([
“run.googleapis.com”,
“containerregistry.googleapis.com”
])
project = var.project_id
service = each.key
disable_on_destroy = false
}
resource “google_cloud_run_service” “recipe_service” {
name = var.project_name
location = var.region
project = var.project_id
template {
spec {
containers {
image = var.cloudrun_image
env {
name = “REDIS_URL”
value = var.redis_url
}
env {
name = “CLIENT_URL”
value = var.client_url
}
env {
name = “FIREBASE_ACCOUNT_KEY”
value = var.firebase_account_key_location
}
}
}
}
depends_on = [
google_project_service.required_apis
]
}
resource “google_cloud_run_service_iam_member” “public_access” {
location = google_cloud_run_service.recipe_service.location
project = google_cloud_run_service.recipe_service.project
service = google_cloud_run_service.recipe_service.name
role = “roles/run.invoker”
member = “allUsers”
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
همانطور که برای ماژول docker ما منابع مورد نیاز را برای آن تعریف می کنیم “google_cloud_run_service” نام، منطقه، project_id را انتخاب می کنیم سپس تصویری را که از main ارسال شده است انتخاب می کنیم.اگر به متغیرهای env نیاز دارید آنها را نیز پاس کنید. منبع عضو IAM برای اجازه استقرار به Cloud Run اضافه شده است.
استقرار برنامه شما
اکنون که معماری تنظیم و انجام شد مراحل زیر را انجام می دهیم.
1. Terraform را راه اندازی کنید
terraform init
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
Shell Script را اجرا کنید یا به صورت دستی متغیرهای env خود را تنظیم کنید
source set-prod.env.sh
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
برای دسترسی terraform به متغیرهای .env.
پیش نمایش تغییرات در terraform یا استقرار مستقیم آن.
terraform plan //Helps you preview the changes that Terraform will make to your infrastructure.
terraform apply //Run the terraform script to deploy your app through IaC.
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
اگر همه چیز خوب باشد، در نهایت با چیزی شبیه به این خواهید شد.
اگر به GitHub متعهد می شوید، باید توجه داشته باشید که برخی از فایل ها را به .gitignore اضافه کنید زیرا terraform مصنوعات و نسخه پشتیبان تولید می کند.
terraform/set-prod-env.sh
terraform/account_key.json
terraform/.terraform
terraform/.terraform.lock.hcl
terraform/.terraform.tfstate.lock.info
# Ignore Terraform working directory
terraform/.terraform/
# Ignore tfstate files and backups
*.tfstate
*.tfstate.backup
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
نتیجه گیری
در حالی که IaC در مقایسه با راهاندازی دستی کمی پیچیدگی میافزاید، اما همانطور که قبلاً ذکر شد، قابلیت نگهداری و اتوماسیون بیشتر به ویژه تعامل بین چندین ارائهدهنده ابر و غیره را اضافه میکند. همچنین برای من شخصاً به من به عنوان یک توسعهدهنده قدرت بیشتری میدهد! Repo را می توانید در اینجا پیدا کنید.
Terraform به دلیلی محبوبیت بیشتری به دست می آورد زیرا سطح بالایی از انعطاف پذیری کنترل را به عنوان IaC (زیرساخت به عنوان کد) فراهم می کند.
ماژول ها را پشتیبانی می کند، وضعیت زیرساخت شما را پیگیری می کند و اگر پروژه شما پیچیده، چند ابری یا محیط های ترکیبی باشد، مفید است.
پیش نیازها
برای شروع، اگر این کار را نکردهاید، حتماً این راهنما را برای نصب Terraform دنبال کنید و مطمئن شوید که حساب GCP را قبلاً تنظیم کردهاید.
برای درک فرآیند استقرار، پیکربندی پایه، انتقال تدریجی و غیره، باید برنامه را قبلاً از طریق ابزارهای دیگری مانند CLI مستقر کنید.
وبلاگ مرتبط با استقرار دستی در زیر اضافه کردم 👇📖
https://blog.stackademic.com/how-to-deploy-a-go-service-to-gcp-cloud-run-694d01cab5b5
ساختار پروژه
برای ساختار پروژه من این فایل ها و ساختار دایرکتوری را دارم.
terraform/
├── modules/
│ ├── docker/
│ │ ├── docker-artifact.tf
│ │ └── variables.tf
│ ├── gcp/
│ │ ├── cloud-run.tf
│ │ └── variables.tf
├── main.tf
├── set-prod.env.sh
├── terraform.tfvars
├── variables.tf
└── account_key.json
-
main.tf
: شامل ارائه دهندگان مورد نیاز و پیکربندی ارائه دهنده Google. -
variables.tf
: نحوه تعریف متغیرها برای پروژه خود را شرح دهید. -
terraform.tfvars
: نحوه تنظیم مقادیر متغیر مخصوص محیط * را توضیح دهید. -
set-prod.env.sh
: متغیرهای محیطی را برای terraform با پرچم پیشوند TF_VAR تنظیم می کند. - ماژول ها: جزئیات
docker
وcloud-run
ماژول ها، نقش آنها و نحوه تعامل آنها را توضیح می دهند.
اسکریپت های IaC
من اسکریپتهای ماژولهای والد به فرزند را برای راهنمایی بیشتر به نمایش میگذارم.
به احتمال زیاد شما متغیرهای env خواهید داشت که بهترین راه برای من ایجاد اسکریپت پوسته با آن است TF_VAR_
پیشوند این است که Terraform موارد اولیه را تشخیص داده و از آنها استفاده می کند (اما برای آن بعدا).
#!/bin/bash
#server
export TF_VAR_redis_url="redis_url"
export TF_VAR_firebase_account_key="your_account_key.json"
export TF_VAR_client_url="client_url"
export TF_VAR_gcp_account_key="client_url"
echo "Environment variables for Terraform GCP set."
متغیرهایی که من به خوبی در سطح ماژول تنظیم کردهام، اما والد معمولاً همه آنها را شامل میشوند، اما در سطح ماژول من موارد مناسب را پاس کردم.
variable "project_id" {
description = "The ID of the Google Cloud project."
type = string
}
variable "project_name" {
description = "The project name of the Google Cloud Run project."
type = string
}
variable "region" {
description = "The Google Cloud region."
type = string
}
variable "redis_url" {
description = "The URL for the Redis instance."
type = string
}
variable "client_url" {
description = "The URL for the client application."
type = string
}
variable "gcp_account_key" {
description = "Path to the Google Cloud service account key file."
type = string
}
variable "firebase_account_key_location" {
description = "Firebase account key location in Docker container."
type = string
}
فایل اسکریپت دیگری نیز وجود دارد که من ایجاد کردم که حاوی مقادیر کلید خصوصی یا مخفی نیست که به راحتی قابل تغییر است و برای مقادیر پیش فرض مفید است. terraform.tfvars
project_id = "recepies-6e7c0"
project_name = "recipe-service"
region = "europe-north1"
gcp_account_key = "./account_key.json"
firebase_account_key_location = "/app/config/account_key.json"
بیایید در مورد 🐘 در اتاق خود صحبت کنیم main.tf
اسکریپت
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.0.0"
}
}
required_version = ">= 0.12"
}
provider "google" {
credentials = file(var.gcp_account_key)
project = var.project_id
region = var.region
}
# Get project information
data "google_project" "project" {
project_id = var.project_id
}
module "docker" {
source = "./modules/docker"
project_id = var.project_id
}
module "cloud_run" {
source = "./modules/gcp"
project_id = var.project_id
region = var.region
redis_url = var.redis_url
client_url = var.client_url
firebase_account_key_location = var.firebase_account_key_location
cloudrun_image = "gcr.io/${var.project_id}/recipe-server:latest"
depends_on = [
module.docker
]
}
در ابتدا ارائهدهنده PaaS را تعریف میکنم زیرا از GCP استفاده میکنم. Google اضافه شده است، میتوانید AWS، Azure یا سایر ارائهدهندگان را اضافه کنید. اعتبارنامهها برای تأیید درخواست شما به هر ارائهدهنده ابری ضروری است. gcp_account_key که بهعنوان فایل json ارسال میکنید که من در دایرکتوری terraform والدین دارم.
در اسکرین شات بالا می بینید که من یک کلید حساب سرویس در GCP ایجاد کرده ام و حقوق دسترسی مناسب IAM را پاس کرده ام.
تخصیص حقوق دسترسی صحیح IAM (مدیریت هویت و دسترسی) به account_key.json بسیار مهم است زیرا در غیر این صورت هنگام اجرای Terraform با مشکلات مجوز متفاوتی مواجه خواهید شد. نمایشگر نقش، ویرایشگر، storage.admin، cloudrun.admin، مصنوعات Docker.
یک جایگزین نیز وجود دارد که فقط نقش ها و مجوزها را از طریق IaC اختصاص دهید، اما برای من حداقل تا زمانی که بیشتر با آن آشنا شوم، عجله بیشتری دارد.
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:YOUR_SERVICE_ACCOUNT_EMAIL" \
--role="roles/editor"
در بالا نشان می دهد که چگونه می توان آن را انجام داد.
سپس مراحل بعدی اجرای ماژولهای شما است، در صورت نیاز برای ایجاد Docker Artifact در GCP، با docker شروع میکنم و پس از تکمیل آن، همین کار را با Cloud Run انجام میدهم. به خاطر داشته باشید که من به دایرکت دسترسی دارم "./modules/docker"
و متغیرهای مورد نیاز را از والدین به فرزند منتقل کنید modules/docker/variables.tf
.
resource "google_project_service" "container_registry_api" {
project = var.project_id
service = "containerregistry.googleapis.com"
disable_on_destroy = false
}
resource "null_resource" "docker_build_push" {
triggers = {
always_run = timestamp()
}
provisioner "local-exec" {
command = <<-EOT
# Build the Docker image
docker build -t gcr.io/${var.project_id}/recipe-server:latest .
# Configure docker to authenticate with GCP
gcloud auth configure-docker --quiet
# Push the image
docker push gcr.io/${var.project_id}/recipe-server:latest
EOT
}
depends_on = [
google_project_service.container_registry_api
]
}
را docker-artifact.tf بسیار کوتاه است زیرا تنها فکر می کنیم که ما نیاز داریم این است که منابع مورد استفاده را با شروع تعریف کنیم container_registry_api و دوما docker_build_push اضافه کردن تدارکات برای اجرای محلی و پایان دادن به آن با ساختن و استقرار تصویر grc docker با تصویب در var.project_id + اضافه کنید که بستگی دارد container_registry_api همانطور که مورد نیاز است
در نهایت در IaC ما آن را در حال اجرای آخرین ماژول خود با آن مستقر می کنیم "./modules/gcp"
resource "google_project_service" "required_apis" {
for_each = toset([
"run.googleapis.com",
"containerregistry.googleapis.com"
])
project = var.project_id
service = each.key
disable_on_destroy = false
}
resource "google_cloud_run_service" "recipe_service" {
name = var.project_name
location = var.region
project = var.project_id
template {
spec {
containers {
image = var.cloudrun_image
env {
name = "REDIS_URL"
value = var.redis_url
}
env {
name = "CLIENT_URL"
value = var.client_url
}
env {
name = "FIREBASE_ACCOUNT_KEY"
value = var.firebase_account_key_location
}
}
}
}
depends_on = [
google_project_service.required_apis
]
}
resource "google_cloud_run_service_iam_member" "public_access" {
location = google_cloud_run_service.recipe_service.location
project = google_cloud_run_service.recipe_service.project
service = google_cloud_run_service.recipe_service.name
role = "roles/run.invoker"
member = "allUsers"
}
همانطور که برای ماژول docker ما منابع مورد نیاز را برای آن تعریف می کنیم "google_cloud_run_service"
نام، منطقه، project_id را انتخاب می کنیم سپس تصویری را که از main ارسال شده است انتخاب می کنیم.
اگر به متغیرهای env نیاز دارید آنها را نیز پاس کنید.
منبع عضو IAM برای اجازه استقرار به Cloud Run اضافه شده است.
استقرار برنامه شما
اکنون که معماری تنظیم و انجام شد مراحل زیر را انجام می دهیم.
1. Terraform را راه اندازی کنید
terraform init
- Shell Script را اجرا کنید یا به صورت دستی متغیرهای env خود را تنظیم کنید
source set-prod.env.sh
برای دسترسی terraform به متغیرهای .env.
- پیش نمایش تغییرات در terraform یا استقرار مستقیم آن.
terraform plan //Helps you preview the changes that Terraform will make to your infrastructure.
terraform apply //Run the terraform script to deploy your app through IaC.
اگر همه چیز خوب باشد، در نهایت با چیزی شبیه به این خواهید شد.
اگر به GitHub متعهد می شوید، باید توجه داشته باشید که برخی از فایل ها را به .gitignore اضافه کنید زیرا terraform مصنوعات و نسخه پشتیبان تولید می کند.
terraform/set-prod-env.sh
terraform/account_key.json
terraform/.terraform
terraform/.terraform.lock.hcl
terraform/.terraform.tfstate.lock.info
# Ignore Terraform working directory
terraform/.terraform/
# Ignore tfstate files and backups
*.tfstate
*.tfstate.backup
نتیجه گیری
در حالی که IaC در مقایسه با راهاندازی دستی کمی پیچیدگی میافزاید، اما همانطور که قبلاً ذکر شد، قابلیت نگهداری و اتوماسیون بیشتر به ویژه تعامل بین چندین ارائهدهنده ابر و غیره را اضافه میکند. همچنین برای من شخصاً به من به عنوان یک توسعهدهنده قدرت بیشتری میدهد!
Repo را می توانید در اینجا پیدا کنید.