توسيع بنية AWS التحتية باستخدام Direct Connect عبر Terraform: دليل شامل

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

توسيع بنية AWS التحتية باستخدام Direct Connect عبر Terraform: دليل شامل

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

في هذا المقال، سأرشدك خلال الخطوات التي اتخذها فريقي وأنا عند ربط بنية تحتية موجودة على AWS بشبكة خاصة كبيرة باستخدام خدمة Direct Connect. سأقدم لك، على طول الطريق، مقتطفات من أكواد Terraform توضح كيفية تنفيذ جميع هذه المكونات كـ "بنية تحتية ككود" (infrastructure as code) مع مخططات تصميم توضيحية.

ماذا سنتناول في هذا الدليل؟

  • التحديات التي واجهتنا.
  • ما هو AWS Direct Connect؟
  • كيفية دمج Direct Connect.
  • بناء شبكة VPC العابرة (Transit VPC) باستخدام Terraform.
  • تهيئة Direct Connect باستخدام Terraform.
  • ربط الشبكات الافتراضية الخاصة (VPC Peering) بين الـ VPC الرئيسية والعابرة.
  • هل تستخدم OpenVPN (اختياري)؟
  • خدمة التوجيه (Router Service).
  • خاتمة.

التحديات التي واجهتنا

كان لدينا خدمات ضمن شبكة VPC الخاصة بنا، وكان يجب أن تكون قادرة على التواصل مع خدمات أخرى في شبكة افتراضية خاصة منفصلة. لإنشاء هذا الاتصال، كنا بحاجة إلى قبول اتصال مستضاف من AWS من مزود شبكة كجزء من عقد موقع لمنح الوصول إلى الشبكة الافتراضية الخاصة (VPN) باستخدام AWS Direct Connect.

إذًا، كيف كان لنا أن ننفذ كل هذا؟ كيف سنقوم بدمجه في حلنا الحالي الذي كان يُدار باستخدام Terraform؟ وهل كانت هناك أي ممارسات مُثلى للقيام بذلك؟

ما هو AWS Direct Connect؟

AWS Direct Connect يُسهّل إنشاء اتصال شبكة مخصص من موقعك إلى شبكة Amazon VPC الخاصة بك أو بين عدة شبكات Amazon VPC. يمكن لهذا الخيار أن يقلل من تكاليف الشبكة، ويزيد من إنتاجية النطاق الترددي، ويوفر تجربة شبكة أكثر اتساقًا مقارنة بخيارات الاتصال الأخرى بين شبكات VPC.

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

التنفيذ العام من حيث AWS يبدو كالتالي:

  1. تقوم بتهيئة اتصال Direct Connect واحد أو اثنين (احتياطي) في لوحة التحكم، مما ينشئ بوابة Direct Connect Gateway.
  2. ثم تقوم بربط واجهة افتراضية خاصة (private VIF) (واحدة لكل اتصال) بالبوابة.
  3. بمجرد إجراء بعض المكالمات مع مهندسي شبكة المزود وتبادل سياسات التوجيه، يكون الأمر قد اكتمل.

عادةً ما يتم إرسال جميع التعليمات المتعلقة بكيفية تمكين الاتصال إليك من قبل المزود.

كيفية دمج Direct Connect

كان افتراضنا الأول هو أننا سنقوم بتمكين الاتصال في شبكة VPC وإنشاء تهيئة التوجيه لبوابة Direct Connect Gateway للطلبات المطلوبة (على سبيل المثال، كنا سنميزها بواسطة رأس Host أو بواسطة عناوين IP). على مستوى عالٍ، سيبدو الأمر كالتالي:

مخطط يوضح اتصال AWS Direct Connect بين شبكة محلية وشبكة AWS VPC

أثناء مكالمة مع مهندسي شبكة المزود، سألونا عن نطاق IP الخاص بنا الذي كنا نعلن عنه للشبكة. تساءلنا عن السبب. كان ذلك لأن عمل Direct Connect يتم الإعلان عنه بواسطة بروتوكول يسمى BGP (بروتوكول بوابة الحدود). إذا كنت تريد المزيد من المعلومات، فهناك الكثير من مقاطع الفيديو التي ستعلمك عن أحد البروتوكولات الرئيسية للإنترنت التي تعمل في الخلفية.

كان تفكيرنا الأولي أنه يجب أن تكون شبكة فرعية تحتوي على الخدمات التي أردنا الوصول إليها في الشبكة. بعد ذلك، طُلب منا تهيئة الشبكة الفرعية 10.1.2.0/24 كبادئة مسموح بها في تهيئة Direct Connect الخاصة بنا. باختصار، "البادئات المسموح بها" هنا تعني نطاق IP الذي كنا سنعلن عنه لمزود الشبكة ليقوم بتسجيله في سياسات التوجيه.

حسنًا، بعد كل ذلك، لم ينجح الأمر. لم "يرَ" المزود مساراتنا المعلنة على الرغم من أننا كنا نراها. بعد قليل من التحقيق، وجدنا أن AWS سيخصص عناوين IP خاصة (/30) في نطاق 169.x.x.x لجلسة BGP وسيعلن عن كتلة CIDR الخاصة بالـ VPC عبر BGP. يمكنك الإعلان عن المسار الافتراضي عبر BGP. بالإضافة إلى ذلك، وجدنا آخرين واجهوا نفس المشكلة: انتهى بنا الأمر بإنشاء VPC جديدة بكتلة CIDR أصغر أرادها شريكنا.

لذا، بشكل أساسي، نطاق عناوين IP الذي يمكنك الإعلان عنه عبر Direct Connect محدود بـ /30. كما لا يمكنك الإعلان عن شبكات فرعية – بل يجب عليك الإعلان عن كتلة CIDR الكاملة للـ VPC. كانت كتلة CIDR لشبكتنا 10.1.0.0/16 وواجهنا مشكلة في ذلك – كانت كبيرة جدًا بحيث لا يمكن لمزود الشبكة قبولها.

علاوة على ذلك، خلال المكالمة اكتشفنا شيئًا آخر كان علينا القيام به عند الاتصال بالشبكة: كنا بحاجة إلى الاتصال بقسم إدارة الوصول إلى IP في الشبكة (إذا كانت الشبكة كبيرة بما يكفي، كما أفترض) لطلب توفير نطاق فريد لنا داخل الشبكة. بعد ذلك، يجب أن يكون هذا هو كتلة CIDR الجديدة لـ VPC الخاصة بنا. قررنا إنشاء VPC منفصلة. للحصول على بعض إثباتات العمل، وجدنا بعض الأدلة الرسمية من AWS مثل هذا. بعد ذلك بوقت قصير، علمنا أن مجتمع AWS سيبدأ في استخدام مصطلحات منفصلة لتلك الـ VPC المنفصلة – سيطلقون عليها اسم transit VPC (شبكة VPC العابرة).

مخطط يوضح دمج Direct Connect باستخدام Transit VPC

قبل الحصول على رد على طلب نطاق IP فريد في الشبكة، سألنا المزود عن نطاقات IP غير المستخدمة حاليًا حتى نتمكن من تنفيذها بسرعة من جانبنا. سيعطينا هذا إثبات العمل الذي نحتاجه للحل. كل شيء سار على ما يرام. كانت الخطوة التالية هي تنفيذ كل شيء (تهيئة Direct Connect + ربط الشبكات الافتراضية الخاصة) في تهيئة Terraform الموجودة لدينا.

بناء شبكة VPC العابرة (Transit VPC) باستخدام Terraform

أولاً وقبل كل شيء، قبل أن نبدأ في التعمق في الكود، أود أن أقول إنه يمكنك العثور على جميع الأكواد أدناه على GitHub. دعنا نلخص أولاً ما ناقشناه من قبل. لدينا ظروف حيث كان لدينا VPC موجودة. وأردنا أن تكون بعض الخدمات بداخلها قادرة على التواصل عبر الشبكة التي اتصلنا بها باستخدام Direct Connect. تم منحنا اتصالين مستضافين من AWS (أساسي وثانوي، لضمان استمرارية الاتصال). كانت الفكرة الرئيسية هي توسيع بنيتنا التحتية الحالية بطريقة ما. هذه الطريقة كانت تعني Transit VPC – الحل الذي ساعدنا في الاندماج مع هذه الاتصالات.

الآن دعنا نلقي نظرة على بعض الأكواد لتمثيل ما ناقشناه. أول شيء يجب تحديده هو شبكة VPC الرئيسية الخاصة بنا. أرغب في تقديمها لأغراض التوضيح فقط، بحيث تبدو جميع الخطوات اللاحقة أكثر اتساقًا.

variable "main_vpc_name" {
  description = "Name of your main VPC"
}

variable "main_vpc_cidr" {
  description = "CIDR of your main VPC, e.g. 10.1.0.0/16"
}

variable "public_subnet" {
  description = "pubic subnet of your main VPC (if you have), e.g. 10.1.1.0/24"
}

variable "private_app_subnet" {
  description = "private subnet of your main VPC (if you have), e.g. 10.1.2.0/24"
}

variable "main_vpc_key_name" {
  default     = "main-vpc-key"
  description = "Name of SSH key of your main VPC"
}

variable "aws_availability_zone" {
  description = "Your AWS AZ of your main VPC"
}

provider "aws" {
  profile = "your-profile"
  region  = "your-region"
}

terraform {
  backend "s3" {
    bucket  = "your-terraform-states-bucket"
    key     = "terraform.tfstate"
    profile = "your-profile"
    region  = "your-region"
  }
}

module "vpc" {
  version = "~> v2.0"
  source  = "terraform-aws-modules/vpc/aws"

  name = var.main_vpc_name
  cidr = var.main_vpc_cidr

  azs = [
    var.aws_availability_zone,
  ]

  private_subnets = [
    var.private_app_subnet
  ]

  public_subnets = [
    var.public_subnet,
  ]

  single_nat_gateway = true
  one_nat_gateway_per_az = false
  enable_nat_gateway     = true
  enable_vpn_gateway     = false

  tags = {
    Terraform = "true"
  }
}

/* bellow could be defined any other resources from you infrastructure e.g. OpenVPN server, instances, security configuration, key pairs etc.
...
*/

بعد ذلك، سيتم استخدام بعض معلمات الـ VPC الرئيسية في الـ transit VPC. لذا، دعنا نحددها كمخرجات (output):

output "main_vpc_id" {
  value = module.vpc.vpc_id
}

output "main_vpc_range" {
  value = module.vpc.vpc_cidr_block
}

output "main_vpc_az" {
  value = module.vpc.azs.0
}

output "main_vpc_key_name" {
  value = var.main_vpc_key_name
}

output "main_public_routing_table_id" {
  value = module.vpc.public_route_table_ids.0
}

output "main_private_routing_table_id" {
  value = module.vpc.private_route_table_ids.0
}

الآن يمكننا البدء في تهيئة الـ transit VPC الخاصة بنا. من أجل تصميم جيد، قررنا إدارتها في حالة منفصلة ضمن مجلد منفصل (على سبيل المثال، tranist-vpc/). دعنا أولاً نستورد المخرجات أعلاه كمتغيرات محلية (locals):

locals {
  main_private_routing_table = data.terraform_remote_state.main.outputs.main_private_routing_table_id
  main_public_routing_table  = data.terraform_remote_state.main.outputs.main_public_routing_table_id
  main_vpc_id                = data.terraform_remote_state.main.outputs.main_vpc_id
  main_vpc_range             = data.terraform_remote_state.main.outputs.main_vpc_range
  main_vpc_az                = data.terraform_remote_state.main.outputs.main_vpc_az
  main_vpc_key_name          = data.terraform_remote_state.main.outputs.main_vpc_key_name
}

بعد ذلك، يمكننا البدء في تحديد تهيئة الـ transit VPC. أولاً، أرغب في سرد جميع المتغيرات التي نحتاجها (انتبه إلى عناوين IP لخوادم DNS في الشبكة التي نريد الاتصال بها. يجب أن تعرفها لتحديدها كخوادم DNS في الـ transit VPC):

variable "transit_vpc_name" {
  default = "transit-vpc"
}

variable "transit_vpc_cidr" {
  description = "Transit VPC CIDR. Your unique IP range in the network e.g. 10.10.14.0/24"
}

variable "transit_private_subnet" {
  description = "Transit VPC private subnet e.g 10.10.14.0/25"
}

variable "transit_public_subnet" {
  description = "Transit VPC public subnet for the NAT gateway e.g. 10.10.14.128/25"
}

variable "network_dns_server" {
  description = "IP of one of DNS servers in the network. Distributed by provider"
}

variable "network_dns_server_2" {
  description = "IP of one of DNS servers in the network. Distributed by provider"
}

variable "dhcp_options_domain_name" {
  description = "DHCP option domain name depending on your AWS region e.g. {your_region}.compute.internal"
}

وثانيًا، التهيئة:

module "transit-vpc" {
  version = "~> v2.0"
  source  = "terraform-aws-modules/vpc/aws"

  name = var.transit_vpc_name
  cidr = var.transit_vpc_cidr

  azs = [
    local.main_vpc_az,
  ]

  private_subnets = [
    var.transit_private_subnet,
  ]

  public_subnets = [
    var.transit_public_subnet,
  ]

  single_nat_gateway     = true
  one_nat_gateway_per_az = false
  enable_nat_gateway     = true
  enable_vpn_gateway     = false

  enable_dhcp_options            = true
  dhcp_options_domain_name       = var.dhcp_options_domain_name
  dhcp_options_domain_name_servers = [var.network_dns_server, var.network_dns_server_2]

  tags = {
    Terraform = "true"
  }
}

تهيئة Direct Connect باستخدام Terraform

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

variable "bgp_provider_asn" {
  description = "BGP autonomous system number of the provider. Distributed by provider"
}

variable "provider_vln_id" {
  description = "BGP VLN ID of the provider. Distributed by provider"
}

variable "primary_bgp_key" {
  description = "BGP auth key for primary virtual interface. Distributed by provider"
}

variable "secondary_bgp_key" {
  description = "BGP auth key for secondary virtual interface. Distributed by provider"
}

variable "primary_connection_id" {
  description = "BGP auth key for primary virtual interface. Distributed by provider"
}

variable "secondary_connection_id" {
  description = "IP range distributed by provider"
}

variable "primary_amazon_address" {
  description = "IP range distributed by provider"
}

variable "secondary_amazon_address" {
  description = "IP range distributed by provider"
}

variable "primary_customer_address" {
  description = "IP range distributed by provider"
}

variable "secondary_customer_address" {
  description = "IP range distributed by provider"
}

والآن يمكننا القيام ببقية التهيئة:

resource "aws_dx_gateway" "provider-gateway" {
  name            = "provider-dc-gateway"
  amazon_side_asn = "64512" // usually it's a default value
}

resource "aws_dx_gateway_association" "transit" {
  dx_gateway_id         = aws_dx_gateway."provider-gateway".id
  associated_gateway_id = aws_vpn_gateway.transit_vpn_gw.id
  allowed_prefixes      = [
    var.transit_vpc_cidr
  ]
}

resource "aws_dx_private_virtual_interface" "primary" {
  connection_id    = var.primary_connection_id
  name             = "provider-vif-primary"
  vlan             = var.provider_vln_id
  address_family   = "ipv4"
  bgp_asn          = var.bgp_provider_asn
  amazon_address   = var.primary_amazon_address
  customer_address = var.primary_customer_address
  dx_gateway_id    = aws_dx_gateway."provider-gateway".id
  bgp_auth_key     = var.primary_bgp_key
}

resource "aws_dx_private_virtual_interface" "secondary" {
  connection_id    = var.secondary_connection_id
  name             = "provider-vif-secondary"
  vlan             = var.provider_vln_id
  address_family   = "ipv4"
  bgp_asn          = var.bgp_provider_asn
  amazon_address   = var.secondary_amazon_address
  customer_address = var.secondary_customer_address
  dx_gateway_id    = aws_dx_gateway."provider-gateway".id
  bgp_auth_key     = var.secondary_bgp_key
}

الآن، إذا ذهبت إلى لوحة تحكم AWS الخاصة بك، بجانب Direct Connect، يجب أن ترى شيئًا كهذا:

اتصالات Direct Connect المهيأة في لوحة تحكم AWS

اتصالات Direct Connect المهيأة

ربط الشبكات الافتراضية الخاصة (VPC Peering) بين الـ VPC الرئيسية والعابرة

المشكلة الأخيرة التي يجب حلها هي تهيئة الاتصال بين خدماتنا والـ transit VPC من أجل إنشاء الوصول إلى الشبكة. لتحقيق ذلك، قررنا استخدام VPC peering. هنا سنحتاج إلى بعض المتغيرات المحلية (locals) التي استوردناها من قبل:

resource "aws_vpc_peering_connection" "main-to-transit" {
  peer_vpc_id = module."transit-vpc".vpc_id
  vpc_id      = local.main_vpc_id
  auto_accept = true

  tags = {
    Name = "VPC Peering between main and transit VPC"
  }
}

resource "aws_route" "from-main-to-transit" {
  route_table_id            = local.main_private_routing_table
  destination_cidr_block    = var.transit_vpc_cidr
  vpc_peering_connection_id = aws_vpc_peering_connection."main-to-transit".id
}

resource "aws_route" "from-main-public-to-transit" {
  route_table_id            = local.main_public_routing_table
  destination_cidr_block    = var.transit_vpc_cidr
  vpc_peering_connection_id = aws_vpc_peering_connection."main-to-transit".id
}

resource "aws_route" "from-transit-to-main" {
  route_table_id            = module."transit-vpc".private_route_table_ids.0
  destination_cidr_block    = local.main_vpc_range
  vpc_peering_connection_id = aws_vpc_peering_connection."main-to-transit".id
}

بعد ذلك، نحتاج إلى السماح بحركة مرور HTTP الواردة من الـ VPC الرئيسية. يمكن إجراء هذه التهيئة كالتالي:

resource "aws_security_group" "transit_vpc_sg" {
  name        = "transit-vpc-sg"
  description = "Transit VPC SG"
  vpc_id      = module."transit-vpc".vpc_id

  ingress {
    description = "Allow HTTP from main VPC"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = [local.main_vpc_range]
  }

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

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

رائع. الآن لدينا شبكتان VPC مرتبطتان وتتعايشان معًا.

هل تستخدم OpenVPN (اختياري)؟

في حالتنا، لدينا خادم OpenVPN لإدارة الوصول (SSH) إلى الموارد الداخلية للـ VPC الرئيسية. وأردنا الوصول إلى موارد الـ transit VPC بنفس الطريقة. لتحقيق ذلك، كنا بحاجة إلى إنشاء عدد قليل من الموارد الإضافية داخل الـ transit VPC:

resource "aws_vpn_gateway" "transit_vpn_gw" {
  tags = {
    Name = "transit-vpn-gw"
  }
}

resource "aws_vpn_gateway_attachment" "vpn_attachment" {
  vpc_id         = module."transit-vpc".vpc_id
  vpn_gateway_id = aws_vpn_gateway.transit_vpn_gw.id
}

resource "aws_vpn_gateway_route_propagation" "transit" {
  vpn_gateway_id = aws_vpn_gateway.transit_vpn_gw.id
  route_table_id = module."transit-vpc".private_route_table_ids.0
}

ثم أضف قاعدة دخول (ingress rule) إلى transit-vpc-SG التي تم إنشاؤها في الخطوة السابقة:

  ingress {
    description = "Allow SSH from main VPC"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [local.main_vpc_range]
  }

لجعل كل هذا يعمل، تحتاج إلى تحديد CIDR الخاص بالـ transit VPC جنبًا إلى جنب مع CIDR الخاص بالـ VPC الرئيسية في إعدادات توجيه خادم OpenVPN ضمن قسم إعدادات VPN:

إعدادات توجيه خادم OpenVPN

إعدادات توجيه خادم OpenVPN

لذا، نحن الآن على وشك الانتهاء. آخر شيء يجب القيام به هو تصميم وتهيئة كيفية تمكن خدماتنا داخل الـ VPC الرئيسية من الوصول برمجياً إلى الشبكة.

خدمة التوجيه (Router Service)

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

  1. ترحيل الخدمات المطلوبة إلى الـ transit VPC واستخدامها هناك، مع تخصيص عناوين IP خاصة جديدة لها. يجب تعديل التوجيه الداخلي للـ VPC الرئيسية. علاوة على ذلك، يجب إدارة أي وصول إلى خوادم قواعد البيانات، وتخزين السجلات، وما إلى ذلك.
  2. إنشاء خدمة توجيه (router service) (تشغيل HAproxy أو Nginx) داخل الـ transit VPC. أضف عنوان IP الخاص للموجه إلى ملف hosts في كل خدمة في الـ VPC الرئيسية التي تريد الوصول إلى الشبكة بحيث يتم حل عنوان IP خلف اسم النطاق المطلوب.

اخترنا الخيار الثاني لأنه بدا الأكثر توافقًا مع مبدأ الفتح والإغلاق (Open-Closed Principle). إليك كيف يبدو الأمر تقريبًا:

مخطط يوضح خدمة توجيه في Transit VPC

خدمة توجيه الـ transit VPC

دعنا نهيئها في Terraform:

variable "router_private_ip" {
  description = "Private IP of router instance in transit VPC t route request back and forward e.g. 10.10.14.90"
}

resource "aws_instance" "router" {
  ami                     = "ami-0eb89db7593b5d434" // any AMI you prefer
  instance_type           = "t2.micro" //any type you prefer
  availability_zone       = local.main_vpc_az
  key_name                = local.main_vpc_key_name
  subnet_id               = module."transit-vpc".private_subnets.0
  private_ip              = var.router_private_ip
  vpc_security_group_ids  = [
    aws_security_group.router_sg.id,
  ]
  user_data                   = file("router_init.sh")
  associate_public_ip_address = false

  tags = {
    Name    = "transit-vpc-router"
    Managed = "terraform"
  }
}

resource "aws_security_group" "router_sg" {
  name        = "router_security_group"
  description = "router_security_group"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = [
      local.main_vpc_range,
      var.transit_private_subnet
    ]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [
      local.main_vpc_az,
    ]
  }

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

  vpc_id = module."transit-vpc".vpc_id

  tags = {
    Managed = "terraform"
  }
}

هنا، يحتوي ملف router_init.sh على سكريبت لتهيئة وتشغيل خدمة HAproxy في حاوية. لأغراض التوضيح، دعنا نفترض أننا نريد الوصول إلى اسمي نطاق داخليين في الشبكة:

  • domain-name-1.internal.com
  • domain-name-2.internal.com
#! /bin/bash
# Install Docker
apt-get update
apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
apt-get update
apt-get install -y docker-ce
usermod -a -G docker ubuntu
chown -R ubuntu:ubuntu /home/ubuntu/.docker/

# Create HAproxy configuration
cat > /home/ubuntu/haproxy.cfg <<- "EOF"
global
    log stdout local0 daemon
    maxconn 4000

defaults
    log global
    mode http
    option httplog
    timeout connect 5s
    timeout check 5s
    timeout client 60s
    timeout server 60s
    timeout tunnel 3600s

frontend http-in
    bind *:80
    #hosts acls
    acl domain1_acl hdr(host) -i domain-name-1.internal.com
    acl domain2_acl hdr(host) -i domain-name-2.internal.com

    use_backend domain1 if domain1_acl
    use_backend domain2 if domain2_acl

backend domain1
    mode http
    option forwardfor
    http-request replace-header Host .* domain-name-1.internal.com
    server domain1 domain-name-1.internal.com:443 ssl verify none

backend domain2
    mode http
    option forwardfor
    http-request replace-header Host .* domain-name-2.internal.com
    server domain2 domain-name-2.internal.com:443 ssl verify none
EOF

#Launch router
docker run -d --restart always --name haproxy --net=host -v /home/ubuntu:/usr/local/etc/haproxy:ro haproxy:2.1-alpine

الخطوة الأخيرة هي التحقق من إضافة نطاقاتنا إلى ملف hosts على المثيلات في الـ VPC الرئيسية والبدء في إجراء الطلبات عبر HTTP.

الخاتمة

في هذا المقال، عرضت لك كيفية دمج Direct Connect في بنيتك التحتية الحالية على AWS. كما تحدثت عن كيفية إدارتها بكفاءة باستخدام Terraform. ثم ناقشت النهج المناسب لتهيئة توجيه الشبكة الذي سيجعل الحل شفافًا وسهل الصيانة قدر الإمكان.

لقد تبين أن الـ Transit VPC، الذي توصي به AWS لحل مثل هذه التحديات، كان سهل التهيئة بالفعل. وأظهر النهج الذي جربناه مع خدمة التوجيه (router service) داخل الـ transit VPC للوصول إلى الشبكة الخاصة فاعليته. ومع ذلك، لم يبدو أنه أفضل بكثير من البدائل الأخرى.

أخيرًا، قدمت مقتطفات من أكواد Terraform آمل أن تكون مفيدة لأي شخص يرغب في القيام بشيء مماثل. آمل أن تكون قد استمتعت بهذا المقال ووجدته مفيدًا!

الخلاصة التقنية

يُعد توسيع البنية التحتية لـ AWS باستخدام Direct Connect تحديًا يتطلب فهمًا عميقًا لبروتوكولات الشبكة مثل BGP وقيود IP CIDR. الحل الذي يعتمد على نمط Transit VPC، المُدار بواسطة Terraform، يوفر طريقة منظمة وقابلة للتوسع لربط شبكة VPC الحالية بشبكات خارجية كبيرة. في حين أن ربط الشبكات الافتراضية الخاصة (VPC Peering) ضروري للاتصال الداخلي، فإن استراتيجية الوصول إلى الشبكة الخارجية عبر خدمة توجيه مخصصة (مثل HAproxy) في الـ transit VPC توفر مرونة كبيرة وتحافظ على مبدأ الفصل بين الاهتمامات، مما يقلل من التعقيد في الـ VPC الرئيسية. هذا النهج يضمن أمانًا أفضل وإدارة مبسطة للمسارات، وهو أمر حيوي في بيئات السحابة الهجينة.

اترك تعليقاً

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