Get a quote

البنية التحتية كود لـ Go SaaS على AWS: إدارة ECS وRDS بـ Terraform

البنية التحتية المُدارة عبر وحدة التحكم تخلق ديوناً تشغيلية تتراكم بسرعة. Terraform يحل هذه المشكلة بجعل حالة البنية التحتية صريحة ومخزنة في نظام التحكم بالإصدارات وقابلة للاستنساخ.

لماذا إدارة AWS عبر وحدة التحكم تخلق ديوناً تشغيلية

البنية التحتية المُدارة يدوياً عبر AWS Console لا تترك أي سجل للقرارات. قاعدة في Security Group تُضاف للتشخيص ولا تُحذف. إعداد في RDS Parameter Group يتغير لحل مشكلة أداء ولا يُوثَّق. خدمة ECS جديدة تُضاف بتسمية مختلفة عن باقي الخدمات.

بعد ستة أشهر من إدارة AWS يدوياً، حتى الفرق الصغيرة في لبنان والمنطقة تصف المشكلة نفسها: لا أحد متأكد تماماً مما يعمل فعلياً، وما تكلفته، وهل إعداداته صحيحة. حين تحتاج لاستنساخ البيئة لعميل جديد أو الاسترداد من اختراق أمني، تبدأ من الذاكرة.

Terraform يحل هذه المشكلة بجعل حالة البنية التحتية صريحة ومخزنة في نظام التحكم بالإصدارات وقابلة للاستنساخ.

هيكل المشروع لنظام Go SaaS على ECS

هيكل Terraform منظم حول حدود البنية التحتية:

infra/
  modules/
    networking/   # VPC، الشبكات الفرعية، Security Groups
    ecs/          # ECS Cluster، Task Definitions، الخدمات
    rds/          # قاعدة بيانات PostgreSQL
    ecr/          # سجلات الحاويات
    iam/          # أدوار الصلاحيات
    alb/          # موازن الحمل
  environments/
    staging/
    production/

كل بيئة تستدعي نفس الموديولات بقيم متغيرة مختلفة. Staging يستخدم db.t3.small بدون Multi-AZ. Production يستخدم db.t3.medium مع Multi-AZ. المنطق متطابق، التكوين وحده يختلف.

تعريف Task ECS لخدمة Go

resource "aws_ecs_task_definition" "api" {
  family                   = "${var.environment}-api"
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = var.task_cpu
  memory                   = var.task_memory
  execution_role_arn       = aws_iam_role.ecs_execution.arn

  container_definitions = jsonencode([{
    name  = "api"
    image = "${aws_ecr_repository.api.repository_url}:${var.image_tag}"
    secrets = [
      { name = "DB_PASSWORD", valueFrom = aws_ssm_parameter.db_password.arn },
      { name = "JWT_SECRET",  valueFrom = aws_ssm_parameter.jwt_secret.arn },
    ]
  }])
}

الـ secrets تُسحب من AWS SSM Parameter Store عند بدء تشغيل الحاوية. لا أسرار في ملف Terraform. لا أسرار في صورة الحاوية.

إدارة RDS PostgreSQL عبر Terraform

resource "aws_db_parameter_group" "main" {
  family = "postgres16"

  parameter {
    name  = "log_min_duration_statement"
    value = "1000"  # يسجل كل استعلام يستغرق أكثر من ثانية
  }
  parameter {
    name  = "shared_preload_libraries"
    value = "pg_stat_statements"
  }
}

log_min_duration_statement بقيمة 1000ms يسجل كل استعلام بطيء تلقائياً. مع pg_stat_statements لديك مراقبة كاملة لأداء الاستعلامات من اليوم الأول بدون أدوات خارجية.

الحالة المشتركة وتعاون الفريق

Terraform يخزن الحالة محلياً افتراضياً. في فريق، هذا يسبب مشاكل فورية حين ينفذ مهندسان terraform apply في نفس الوقت. الحل هو S3 backend مع DynamoDB للقفل:

terraform {
  backend "s3" {
    bucket         = "company-terraform-state"
    key            = "production/terraform.tfstate"
    region         = "eu-west-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }
}

كل فريق يدير بنية تحتية AWS في المنطقة يجب أن يُعِد هذا قبل إعطاء المهندس الثاني صلاحيات AWS.

الدروس الأساسية من الإنتاج

Terraform يُؤتي ثماره بسرعة للفرق التي تُوظّف مهندسين جدداً بانتظام أو تُشغّل أكثر من بيئة واحدة. التكلفة الأولية لكتابة الموديولات يومان إلى ثلاثة أيام. الفائدة المستمرة هي أن كل تغيير بنية تحتية مستقبلي يُراجَع ككود ويُخزَّن في نظام التحكم بالإصدارات.

ابدأ بـ networking وRDS كأول موديولين لأنهما الأكثر تكلفة لإعادة إنشائهما يدوياً. أضف ECS ثانياً.

الحالة المشتركة في S3 مع قفل DynamoDB ليست اختيارية في الفريق. أعدّها قبل أن يحصل أي مهندس آخر على صلاحيات AWS.


هل تريد بناء بنية تحتية AWS جاهزة للإنتاج لمنتجك؟ تواصل مع فريق Voxire على https://voxire.com/get-a-quote/

العودة إلى المدونة
Chat on WhatsApp