Infrastructure as Code مع 200 مورد: اللي ما تقوله لك دروس Terraform
أنماط IaC إنتاجية لأنظمة حقيقية. إدارة الـ State على نطاق واسع، تصميم الوحدات، CDK + Terraform هجين، كشف الانحراف، GitOps مع Flux، وإدارة 30+ خدمة AWS.
الـ IaC مش "terraform init"
كل دورة Terraform تبدأ بنفس الطريقة: اكتب ملف .tf، نفذ terraform init، نفذ terraform apply، وشاهد الـ EC2 instance تظهر. هذا يوصلك من صفر لمورد واحد. ما يجهزك لإدارة 200+ مورد عبر 30 خدمة AWS مع فريق مهندسين كلهم يحتاجون يسوون تغييرات على البنية التحتية بأمان.
نحن ندير بنية تحتية لعدة أنظمة إنتاجية، من كلاسترات Kubernetes مع Pimcore و OpenSearch لمعماريات Serverless مع Lambda و DynamoDB و API Gateway. الأنماط في هذا المقال هي اللي نجت في الإنتاج. لطريقة نشر التطبيقات على هذي البنية التحتية، شوف صفحة خدماتنا السحابية.
إدارة الـ State على نطاق واسع
الـ Terraform State هو أهم ملف في بنيتك التحتية. يربط ملفات .tf بموارد حقيقية. ضيعه، و Terraform ما يعرف شو موجود. خربه، و Terraform ممكن يدمر موارد الإنتاج.
Remote State (ما فيه نقاش)
# backend.tf
terraform {
backend "s3" {
bucket = "company-terraform-state"
key = "prod/platform/terraform.tfstate"
region = "eu-central-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
| القاعدة | ليش |
|---|---|
| Remote State في S3 (أو ما يعادله) | ملفات State المحلية تضيع، ما تقدر تشاركها |
| تشفير في حالة السكون | الـ State يحتوي على أسرار (كلمات مرور قواعد البيانات، مفاتيح API) |
| DynamoDB Locking | يمنع مهندسَين من تنفيذ apply بنفس الوقت |
| تفعيل الإصدارات على S3 bucket | استرجاع من فساد الـ State بالرجوع لنسخة سابقة |
تنظيم الـ State
ملف State واحد ضخم لكل شي هو كارثة صيانة. قسمه حسب البيئة والنطاق:
terraform/
├── environments/
│ ├── prod/
│ │ ├── platform/ # EKS, VPC, الشبكات
│ │ ├── databases/ # RDS, ElastiCache, OpenSearch
│ │ ├── compute/ # Lambda, ECS, Fargate
│ │ ├── storage/ # S3 buckets, CloudFront
│ │ └── monitoring/ # CloudWatch, التنبيهات
│ ├── staging/
│ │ └── (نفس الهيكل)
│ └── dev/
│ └── (نفس الهيكل)
├── modules/
│ ├── vpc/
│ ├── eks-cluster/
│ ├── rds-postgres/
│ ├── opensearch/
│ ├── redis/
│ └── lambda-function/
└── global/
├── iam/ # أدوار IAM، السياسات
├── route53/ # مناطق DNS
└── ecr/ # سجلات الحاويات
كل مجلد هو Terraform workspace منفصل بملف State خاص فيه. تغييرات على الشبكة ما تخاطر بكسر قاعدة البيانات. تغييرات على المراقبة ما تحتاج خطة تلمس كل مورد.
مراجع Cross-State
الـ Workspaces تحتاج تشير لبعض. الـ VPC workspace يطلع VPC ID. الـ database workspace يقرأها:
# في databases/main.tf
data "terraform_remote_state" "platform" {
backend = "s3"
config = {
bucket = "company-terraform-state"
key = "prod/platform/terraform.tfstate"
region = "eu-central-1"
}
}
resource "aws_db_instance" "main" {
vpc_security_group_ids = [data.terraform_remote_state.platform.outputs.db_security_group_id]
db_subnet_group_name = data.terraform_remote_state.platform.outputs.db_subnet_group_name
}
تصميم الوحدات
متى تستخرج وحدة
مش كل مورد يحتاج وحدة. استخرج لما:
- نفس النمط مستخدم في 3+ أماكن (DRY)
- مجموعة الموارد عندها حدود واضحة (VPC، كلاستر قاعدة بيانات)
- التكوين عنده defaults منطقية تقلل التكرار
لا تستخرج لما:
- مستخدم مرة وحدة (تجريد مبكر)
- الوحدة راح يكون عندها 20+ متغير (كثير مفاتيح)
- التجريد يخفي تفاصيل مهمة (الشبكات، الأمان)
تصميم واجهة الوحدة
الوحدة الجيدة عندها متغيرات مطلوبة قليلة، defaults منطقية، و outputs واضحة:
# modules/rds-postgres/variables.tf
variable "name" {
description = "اسم مثيل قاعدة البيانات"
type = string
}
variable "vpc_id" {
description = "الـ VPC للنشر فيها"
type = string
}
variable "subnet_ids" {
description = "الشبكات الفرعية لمجموعة DB subnet"
type = list(string)
}
variable "instance_class" {
description = "نوع مثيل RDS"
type = string
default = "db.t3.medium"
}
variable "engine_version" {
description = "إصدار PostgreSQL"
type = string
default = "15.4"
}
variable "allocated_storage" {
description = "التخزين بالـ GB"
type = number
default = 50
}
variable "multi_az" {
description = "تفعيل النشر متعدد المناطق"
type = bool
default = false # true للإنتاج، false للتجريب/التطوير
}
مستهلك الوحدة يكتب:
module "database" {
source = "../../modules/rds-postgres"
name = "pimcore-prod"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnet_ids
multi_az = true
}
خمس أسطر بدل خمسين. الوحدة تتكفل بالـ Security Groups، Parameter Groups، مجموعات الشبكات الفرعية، التشفير، الاحتفاظ بالنسخ الاحتياطية، والمراقبة.
CDK + Terraform: النهج العملي الهجين
بعض الفرق تروح كلياً مع CDK. وبعضها كلياً مع Terraform. نحن نستخدم الاثنين، ويشتغل.
| حالة الاستخدام | الأداة | ليش |
|---|---|---|
| الشبكات، قواعد البيانات، الكلاسترات | Terraform | تصريحي، خطة قبل التطبيق، إدارة State |
| دوال Lambda + API Gateway | CDK | تجميع Lambda أفضل، API Gateway constructs |
| سياسات IAM المعقدة | CDK | منطق TypeScript لسياسات شرطية |
| موارد Kubernetes | Kustomize + Flux | GitOps، حلقات Reconciliation |
| بنية تحتية ثابتة | Terraform | بسيط، مقروء، مفهوم |
الحدود واضحة: Terraform يدير البنية التحتية اللي تتغير نادراً (VPC، RDS، كلاستر EKS). CDK يدير البنية التحتية اللي تتغير مع نشر التطبيقات (دوال Lambda، مسارات API). Kustomize + Flux يدير أعباء عمل Kubernetes.
يتعايشون عن طريق الـ Outputs. Terraform يطلع VPC ID، ونقطة نهاية الكلاستر، و connection string لقاعدة البيانات. CDK يقرأهم من SSM Parameter Store أو Terraform remote state.
مشكلة الانحراف (Drift)
الانحراف يصير لما أحد يغير البنية التحتية من الكونسول (ClickOps)، من أمر CLI، أو من أداة ثانية. الحالة الحقيقية تبتعد عن الـ Terraform State.
كشف الانحراف
# نفذ plan بانتظام (CI، وظيفة مجدولة)
terraform plan -detailed-exitcode
# أكواد الخروج:
# 0 = ما فيه تغييرات (الـ State يطابق الواقع)
# 1 = خطأ
# 2 = تغييرات مكتشفة (انحراف!)
شغل كشف الانحراف في CI بجدول (يومياً للإنتاج، أسبوعياً للتجريب). نبه لما ينكشف انحراف. لا تصلح تلقائي. تحقق أول.
أسباب الانحراف الشائعة
| السبب | الوقاية |
|---|---|
| تغييرات من الكونسول (ClickOps) | فرض سياسة "ممنوع تغييرات من الكونسول". استخدم SCPs للتقييد. |
| تغييرات Auto-Scaling | تجاهل سمات Auto-Scaling في Terraform (lifecycle { ignore_changes }) |
| تحديثات خدمات AWS | ثبت إصدارات الـ Provider. حدث بوعي. |
| Terraform فريق ثاني | ملفات State منفصلة لكل فريق/نطاق. |
| إصلاح يدوي أثناء حادث | وثق التغيير. طبقه في Terraform بعد الحادث. |
# تجاهل تغييرات Auto-Scaling (انحراف متوقع)
resource "aws_ecs_service" "app" {
desired_count = 2
lifecycle {
ignore_changes = [desired_count] # Auto-Scaling يغير هذي القيمة
}
}
GitOps مع Flux
لأعباء عمل Kubernetes، نستخدم Flux لـ GitOps. حلقة الـ Reconciliation تستبدل kubectl apply بنموذج قائم على السحب.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Git Repo │────▶│ Flux │────▶│ Kubernetes │
│ (Manifests) │ │ Controller │ │ Cluster │
└─────────────┘ └─────────────┘ └─────────────┘
│
│ يوفق كل 1 دقيقة
│ يكشف الانحراف
│ يطبق تلقائياً
# flux-system/kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: platform
namespace: flux-system
spec:
interval: 1m
sourceRef:
kind: GitRepository
name: infrastructure
path: ./kubernetes/resources/overlay/prod
prune: true
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: pimcore
namespace: production
Flux يستطلع Git repo كل دقيقة. إذا تغيرت الـ Manifests، يطبقها. إذا أحد غير مورد يدوياً (انحراف)، Flux يرجعه ليطابق Git. هذا reconciliation حقيقي، مش مجرد أتمتة نشر.
Sealed Secrets
الأسرار ما تنحط في Git كنص عادي. استخدم Bitnami Sealed Secrets:
# تشفير السر للكلاستر
kubeseal --cert sealed-secrets.pem \
-f secrets/database-secrets.yaml \
-o yaml > secrets/database-secrets-sealed.yaml
# ارفع النسخة المختومة (آمنة في Git)
# Flux يطبقها، الـ controller يفك تشفيرها داخل الكلاستر
لطريقة تعاملنا مع الأسرار في نشر Pimcore على Kubernetes بالتحديد، شوف دليل ترقية Pimcore اللي يغطي ترتيب النشر الكامل.
إدارة 30+ خدمة AWS
على مستوى المؤسسات، أنت تدير خدمات كثيرة. التنظيم مهم.
كتالوج الخدمات
| الفئة | الخدمات | وحدة Terraform؟ |
|---|---|---|
| الشبكات | VPC، شبكات فرعية، NAT، ALB، Route53 | نعم (وحدة vpc) |
| الحوسبة | EKS، ECS Fargate، Lambda | نعم (لكل نوع خدمة) |
| قاعدة البيانات | RDS PostgreSQL، DynamoDB | نعم (وحدة rds-postgres) |
| التخزين المؤقت | ElastiCache Redis | نعم (وحدة redis) |
| البحث | OpenSearch | نعم (وحدة opensearch) |
| التخزين | S3، EFS | مضمن (بسيط بما فيه الكفاية) |
| CDN | CloudFront | مضمن |
| الرسائل | SQS، MSK (Kafka)، RabbitMQ | مضمن |
| المصادقة | Cognito | CDK (تكوين معقد) |
| المراقبة | CloudWatch، X-Ray | مضمن |
| CI/CD | ECR، CodeBuild | مضمن |
| الأمان | IAM، KMS، Secrets Manager | Workspace عام |
استراتيجية التوسيم (Tagging)
كل مورد لازم يكون موسوم لتوزيع التكاليف، تحديد الملكية، وإدارة دورة الحياة:
locals {
common_tags = {
Environment = var.environment # prod, staging, dev
Project = var.project_name # pimcore, commerce, ai
ManagedBy = "terraform"
Team = var.team # platform, backend, data
CostCenter = var.cost_center
}
}
resource "aws_instance" "example" {
tags = merge(local.common_tags, {
Name = "pimcore-web-1"
Role = "web"
})
}
فلتر AWS Cost Explorer بتاق Project عشان تشوف بالضبط كم يكلف كل نظام. فلتر بـ ManagedBy عشان تلاقي الموارد المنشأة يدوياً (مش موسومة كـ "terraform").
الأخطاء الشائعة
-
ملف State واحد لكل شي.
terraform planيلمس 200 مورد ياخذ دقائق وخطأ واحد يأثر على كل شي. قسم حسب النطاق والبيئة. -
بدون State Locking. مهندسَين ينفذون
terraform applyبنفس الوقت. تغييرات واحد تضيع أو الـ State يتخرب. استخدم DynamoDB Locking. -
وحدات بـ 20+ متغير. إذا واجهة وحدتك معقدة بنفس درجة الموارد الخام، التجريد ما يضيف قيمة. خلي واجهات الوحدات صغيرة.
-
إصلاح الانحراف تلقائياً. كشف الانحراف حلو. إصلاحه تلقائياً خطير. "الانحراف" ممكن يكون إصلاح صحيح أثناء حادث. تحقق قبل ما ترجع.
-
أسرار في ملفات الـ State. الـ Terraform State يحتوي كل سمة لكل مورد، بما فيها كلمات مرور قواعد البيانات. شفر الـ State في حالة السكون وقيد الوصول.
-
بدون تثبيت إصدار الـ Provider. تحديث provider يغير سلوك الموارد. ثبت الإصدارات في
required_providersوحدث بوعي. -
ClickOps لـ "بس هالمرة". تغييرات الكونسول تسبب انحراف غير مرئي لحد أول
terraform planجاي. فرض Infrastructure-as-Code لكل شي. -
بدون توسيم. بدون تاقات، ما تقدر توزع التكاليف، ولا تحدد الملكية، ولا تلاقي الموارد المنشأة يدوياً.
أهم النقاط
-
قسم الـ State حسب النطاق والبيئة. الشبكات، قواعد البيانات، الحوسبة، والمراقبة لازم تكون workspaces منفصلة. تغييرات على واحد ما لازم تخاطر بالثاني.
-
الوحدات للأنماط، مش للتجريد. استخرج لما نفس مجموعة الموارد تظهر 3+ مرات. لا تسوي وحدات لموارد تستخدم مرة وحدة.
-
CDK + Terraform نهج عملي. Terraform للبنية التحتية الثابتة، CDK لـ Lambda/API Gateway، Kustomize + Flux لـ Kubernetes. كل أداة وين ما هي أقوى.
-
كشف الانحراف وظيفة مجدولة. شغل
terraform planيومياً في CI. نبه على الانحراف. تحقق قبل ما تصلح. -
GitOps مع Flux يعطيك reconciliation حقيقي. مش مجرد أتمتة نشر. Flux يكشف ويرجع التغييرات اليدوية. Sealed Secrets تخلي بيانات الاعتماد آمنة في Git.
-
وسم كل شي. البيئة، المشروع، الفريق، مركز التكلفة، managed-by. بدون تاقات، توزيع التكاليف وتدقيق الموارد مستحيل.
نحن ندير بنية تحتية لـ النشر السحابي، منصات البرمجيات المخصصة، وأنظمة هندسة البيانات. إذا تحتاج مساعدة بالـ IaC على نطاق واسع، تواصل مع فريقنا أو اطلب عرض سعر.
المواضيع المغطاة
أدلة ذات صلة
الدليل الشامل لأنظمة الذكاء الاصطناعي الوكيلي
دليل تقني لأنظمة الذكاء الاصطناعي الوكيلي في بيئات الأعمال. تعرف على البنية والقدرات والتطبيقات العملية للوكلاء المستقلين.
اقرأ الدليلالتجارة الوكيلية: كيف تخلي وكلاء الذكاء الاصطناعي يشترون بأمان
كيف تصمم تجارة وكيلية محكومة. محركات السياسات، بوابات الموافقة البشرية، إيصالات HMAC، الـ idempotency، عزل المستأجرين، وبروتوكول الدفع الوكيلي الكامل.
اقرأ الدليلالـ 9 أماكن اللي نظام AI تبعك بيسرّب بيانات منها (وكيف تسد كل وحدة)
خارطة منهجية لكل مكان البيانات بتتسرب منه بأنظمة AI. البرومبتات، الـ embeddings، السجلات، استدعاءات الأدوات، ذاكرة الـ agent، رسائل الأخطاء، الكاش، بيانات التدريب، وتسليمات الـ agents.
اقرأ الدليلجاهز لبناء أنظمة ذكاء اصطناعي جاهزة للإنتاج؟
فريقنا متخصص في بناء أنظمة ذكاء اصطناعي جاهزة للإنتاج. خلينا نحكي كيف نقدر نساعد.
ابدأ محادثة