إنشاء شبكات سحابية (VPC) وقواعد بيانات مُدارة بالكامل عبر الأكواد

دقائق القراءة: 6

مقدمة

عندما تنتقل من إنشاء الموارد السحابية يدوياً إلى تعريفها بالأكواد، فأنت لا تكتفي بتوفير الوقت، بل تبني طبقة تشغيل يمكن مراجعتها واختبارها وإعادة إنتاجها بثبات. هذا هو جوهر البنية التحتية ككود (IaC): لماذا يجب أن نتخلى عن إنشاء السيرفرات يدوياً؟، حيث تصبح الشبكات وقواعد البيانات أجزاء قابلة للتتبع داخل المستودع البرمجي مثلها مثل التطبيق نفسه.

في البيئات الحديثة، لا يكفي إنشاء VPC وقاعدة بيانات مُدارة فقط، بل يجب تصميم العزل الشبكي، التحكم في المسارات، سياسات الوصول، وربط ذلك مع أنظمة CI/CD بحيث يصبح النشر متسقاً وآمناً وقابلاً للتوسع.

هذا الأسلوب يتكامل أيضاً مع مفاهيم ما هو DevOps؟ ولماذا تدفع الشركات ثروات لمهندسي الأتمتة السحابية؟ لأن فريق التطوير والتشغيل يعملان على نفس المصدر الموثوق، وتصبح مراجعة التغييرات على الشبكة أو قاعدة البيانات جزءاً من دورة التطوير المعتادة بدلاً من أن تكون عملاً منفصلاً في لوحة التحكم.

لماذا نعرّف الشبكات وقواعد البيانات بالأكواد؟

تعريف البنية الشبكية وقواعد البيانات عبر Terraform يمنحك أربع مزايا حاسمة: التكرار، التدقيق، التوثيق، وتقليل الأخطاء البشرية. بدلاً من نسيان منفذ مفتوح أو ربط مورد في منطقة خاطئة، يصبح كل شيء واضحاً داخل ملفات يمكن مراجعتها قبل التنفيذ.

كما أن هذا النهج يساعدك على بناء بيئات متعددة مثل dev وstaging وproduction بنفس المعمارية تقريباً مع اختلافات مدروسة في الأحجام والسياسات. هذا يقلل ظاهرة اختلاف السلوك بين البيئات التي نراها كذلك في عالم الحاويات كما شرحنا في مشكلة “الكود يعمل على جهازي فقط” وكيف يحلها Docker نهائياً؟.

المعمارية المقترحة لإنشاء VPC وقاعدة بيانات مُدارة

السيناريو العملي الأكثر أماناً يبدأ بشبكة سحابية تحتوي على شبكات فرعية عامة وخاصة. الموارد المكشوفة للإنترنت، مثل Load Balancer أو بوابة الترجمة، تُوضع في public subnets، بينما التطبيق وقاعدة البيانات يبقيان داخل private subnets.

أما قاعدة البيانات المُدارة مثل RDS PostgreSQL أو MySQL، فتوضع في مجموعات شبكات فرعية خاصة مع قواعد جدار ناري تسمح فقط لتطبيقات محددة بالاتصال عليها. هذه البنية تقلل السطح الهجومي بشكل كبير، وتمنع الوصول المباشر إلى البيانات من الإنترنت العام.

المكونات الأساسية

  • شبكة VPC بعنوان CIDR واضح.
  • شبكتان فرعيتان عامتان وشبكتان خاصتان على منطقتين مختلفتين.
  • بوابة إنترنت Internet Gateway.
  • جداول توجيه Route Tables.
  • مجموعة أمان للتطبيق وأخرى لقاعدة البيانات.
  • مجموعة شبكات لقاعدة البيانات DB Subnet Group.
  • مثيل قاعدة بيانات مُدارة مع نسخ احتياطي ومراقبة.

مثال عملي باستخدام Terraform

إذا كنت قد قرأت تثبيت Terraform وربطه مع مزود خدمة سحابي (AWS أو DigitalOcean) عبر الـ API وكتابة أول ملف Terraform لإنشاء سيرفر (VPS) سحابي برمجياً فالمثال التالي يمثل خطوة متقدمة تنقلنا من إنشاء خادم منفرد إلى بناء طبقة شبكة وقاعدة بيانات إنتاجية.

terraform init
terraform plan
terraform apply
mkdir -p terraform-vpc-db
cd terraform-vpc-db
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "eu-central-1"
}

resource "aws_vpc" "main" {
  cidr_block           = "10.20.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "prod-vpc"
  }
}

resource "aws_subnet" "public_a" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.20.1.0/24"
  availability_zone       = "eu-central-1a"
  map_public_ip_on_launch = true
}

resource "aws_subnet" "private_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.20.11.0/24"
  availability_zone = "eu-central-1a"
}

resource "aws_subnet" "private_b" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.20.12.0/24"
  availability_zone = "eu-central-1b"
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
}

resource "aws_route" "default_internet" {
  route_table_id         = aws_route_table.public.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.igw.id
}

resource "aws_route_table_association" "public_a_assoc" {
  subnet_id      = aws_subnet.public_a.id
  route_table_id = aws_route_table.public.id
}

resource "aws_security_group" "app_sg" {
  name   = "app-sg"
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 3000
    to_port     = 3000
    protocol    = "tcp"
    cidr_blocks = ["10.20.0.0/16"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "db_sg" {
  name   = "db-sg"
  vpc_id = aws_vpc.main.id

  ingress {
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    security_groups = [aws_security_group.app_sg.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_db_subnet_group" "db_subnets" {
  name       = "prod-db-subnets"
  subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
}

resource "aws_db_instance" "postgres" {
  identifier              = "prod-postgres-db"
  engine                  = "postgres"
  engine_version          = "15.4"
  instance_class          = "db.t3.micro"
  allocated_storage       = 20
  db_name                 = "appdb"
  username                = "appadmin"
  password                = "ChangeThisSecurely123!"
  db_subnet_group_name    = aws_db_subnet_group.db_subnets.name
  vpc_security_group_ids  = [aws_security_group.db_sg.id]
  skip_final_snapshot     = false
  backup_retention_period = 7
  multi_az                = false
  publicly_accessible     = false
}

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

كيف ندمج هذا مع أنظمة CI/CD؟

القيمة الحقيقية تظهر عندما يتم تشغيل أوامر التخطيط والمراجعة تلقائياً عبر خط أنابيب. يمكنك استخدام GitHub Actions بحيث يتم تنفيذ terraform fmt وterraform validate وterraform plan عند كل طلب دمج.

هذا يتوافق مباشرة مع ما هو الـ CI/CD؟ ولماذا نؤتمت عمليات اختبار ونشر الأكواد؟ ومقدمة في GitHub Actions: كتابة أول مسار عمل (Workflow)، لأننا نعامل البنية التحتية كجزء من المنتج البرمجي نفسه، وليس كمهمة تشغيلية منفصلة.

name: terraform-plan

on:
  pull_request:
    paths:
      - 'terraform/**'

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3

      - name: Terraform Init
        run: terraform -chdir=terraform init

      - name: Terraform Validate
        run: terraform -chdir=terraform validate

      - name: Terraform Plan
        run: terraform -chdir=terraform plan

أفضل الممارسات الأمنية والمعمارية

لا تضع كلمات مرور قواعد البيانات مباشرة داخل ملفات Terraform في المشاريع الحقيقية. استخدم خدمات إدارة الأسرار أو متغيرات آمنة داخل أنظمة الأتمتة، ويمكنك الاستفادة من مبادئ إدارة الأسرار (GitHub Secrets) لحماية كلمات المرور ومفاتيح الـ API في الأتمتة.

احفظ ملف حالة البنية Terraform State في مخزن بعيد وآمن مع قفل للتزامن، لأن فقدانه أو العبث به قد يؤدي إلى قرارات تدميرية على الموارد. راجع إدارة حالة البنية التحتية (Terraform State) وكيف تحافظ عليها من الضياع.

اجعل قاعدة البيانات private دائماً ما لم يكن هناك سبب معماري بالغ الوضوح، وفعّل النسخ الاحتياطي، التشفير، والمراقبة. أي تساهل هنا قد يرفع احتمالات الاختراق أو يطيل زمن التعافي بعد الأعطال Downtime.

أخطاء شائعة يجب تجنبها

  • وضع التطبيق وقاعدة البيانات في نفس الشبكة الفرعية العامة.
  • السماح بالوصول إلى منفذ 5432 أو 3306 من أي عنوان عام.
  • تنفيذ apply مباشرة على بيئة الإنتاج دون مراجعة plan.
  • عدم استخدام وسمات tags لتصنيف الموارد وتسهيل التتبع المالي والتشغيلي.
  • إهمال تقسيم البيئات باستخدام ملفات متغيرات أو مجلدات منفصلة.

خاتمة

إنشاء شبكات سحابية وقواعد بيانات مُدارة بالكامل عبر الأكواد ليس رفاهية تقنية، بل ممارسة تشغيلية أساسية لأي فريق يريد بنية يمكن الوثوق بها. عندما تصمم VPC بعناية، وتربطها بقاعدة بيانات مُدارة ضمن طبقات عزل واضحة، فأنت تبني أساساً مستقراً للتوسع، المراقبة، والتعافي من الأعطال.

ومع دمج هذه الملفات داخل مستودع المشروع وخطوط Pipelines، تتحول البنية التحتية من عبء يدوي إلى أصل هندسي قابل للمراجعة والاختبار والتحسين المستمر. هذه هي النقلة التي تميز الفرق الاحترافية في عالم السحابة الحديث.

2 comments

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *