انتقل إلى المحتوى الرئيسي

مفاهيم البنية التحتية ككود

ما هو IaC؟​

البنية التحتية ككود (IaC) هي ممارسة إدارة وتوفير البنية التحتية عبر ملفات التكوين بدلاً من العمليات اليدوية.

┌─────────────────────────────────────────────────────────────┐
│ IaC vs MANUEL │
├─────────────────────────────────────────────────────────────┤
│ │
│ PROVISIONING MANUEL │
│ ─────────────────── │
│ 1. Ouvrir la console AWS │
│ 2. Cliquer "Launch Instance" │
│ 3. Configurer manuellement... │
│ 4. Répéter pour chaque ressource │
│ 5. Documenter les paramètres │
│ │
│ Problèmes : │
│ ❌ Non reproductible │
│ ❌ Erreurs humaines │
│ ❌ Pas de versioning │
│ ❌ Documentation obsolète │
│ ❌ Difficile à auditer │
│ │
│ ──────────────────────────────────────────────────────── │
│ │
│ INFRASTRUCTURE AS CODE │
│ ────────────────────── │
│ 1. Écrire un template (YAML/JSON) │
│ 2. Versionner dans Git │
│ 3. Déployer avec CloudFormation │
│ 4. Automatiser via CI/CD │
│ │
│ Avantages : │
│ ✅ Reproductible (même résultat chaque fois) │
│ ✅ Versionné (historique complet) │
│ ✅ Revue de code (peer review) │
│ ✅ Documentation vivante (le code EST la doc) │
│ ✅ Automatisable (CI/CD) │
│ │
└─────────────────────────────────────────────────────────────┘

AWS CloudFormation​

نظرة عامة​

┌─────────────────────────────────────────────────────────────┐
│ CLOUDFORMATION │
├─────────────────────────────────────────────────────────────┤
│ │
│ COMPOSANTS : │
│ │
│ ┌─────────────┐ │
│ │ TEMPLATE │ Fichier YAML/JSON décrivant │
│ │ (code) │ l'infrastructure souhaitée │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ STACK │ Instance d'un template │
│ │ │ avec des ressources réelles │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ RESSOURCES AWS │ │
│ │ │ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │ VPC │ │ EC2 │ │ RDS │ │ ALB │ │ SG │ │ │
│ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ CYCLE DE VIE : │
│ Create → Update → Delete │
│ (ou Rollback si erreur) │
│ │
└─────────────────────────────────────────────────────────────┘

هيكل القالب​

الأقسام​

AWSTemplateFormatVersion: "2010-09-09"
Description: وصف القالب

# 1. PARAMETERS - متغيرات الإدخال
Parameters:
EnvironmentType:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]

# 2. MAPPINGS - جداول البحث
Mappings:
RegionAMI:
us-east-1:
AMI: ami-0123456789

# 3. CONDITIONS - منطق الشرط
Conditions:
IsProd: !Equals [!Ref EnvironmentType, prod]

# 4. RESOURCES - الموارد التي سيتم إنشاؤها (إلزامي)
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]
InstanceType: t3.micro

# 5. OUTPUTS - القيم المصدرة
Outputs:
InstanceId:
Value: !Ref MyEC2Instance
Export:
Name: MyInstanceId

أنواع الموارد الشائعة​

النوعالوصف
AWS::EC2::Instanceمثيل EC2
AWS::EC2::VPCVPC
AWS::EC2::Subnetشبكة فرعية
AWS::EC2::SecurityGroupمجموعة الأمان
AWS::RDS::DBInstanceقاعدة بيانات RDS
AWS::S3::Bucketحاوية S3
AWS::Lambda::Functionوظيفة Lambda
AWS::ElasticLoadBalancingV2::LoadBalancerALB/NLB

الدوال المضمنة​

الأكثر استخدامًا​

Resources:
# !Ref - الإشارة إلى متغير أو مورد
MyInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType # متغير
SubnetId: !Ref MySubnet # مورد

# !GetAtt - الحصول على خاصية من مورد
MyDNSRecord:
Type: AWS::Route53::RecordSet
Properties:
Name: app.example.com
ResourceRecords:
- !GetAtt MyInstance.PublicIp # IP العامة للمثيل

# !Sub - استبدال المتغيرات
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${AWS::StackName}-${AWS::Region}-data"

# !Join - دمج القيم
MyTag:
Type: AWS::EC2::Instance
Properties:
Tags:
- Key: Name
Value: !Join ["-", [web, !Ref EnvironmentType, server]]

# !If - شرط
MyVolume:
Type: AWS::EC2::Volume
Properties:
Size: !If [IsProd, 100, 20] # 100 جيجابايت في الإنتاج، 20 خلاف ذلك

# !FindInMap - البحث في Mappings
MyInstance2:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]

مثال كامل: بنية تحتية ويب​

AWSTemplateFormatVersion: "2010-09-09"
Description: بنية تحتية ويب بسيطة مع EC2 ومجموعة الأمان

Parameters:
Environment:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
Description: اسم البيئة

InstanceType:
Type: String
Default: t3.micro
AllowedValues: [t3.micro, t3.small, t3.medium]

KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: زوج مفاتيح EC2 للوصول عبر SSH

Mappings:
RegionAMI:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
eu-west-1:
AMI: ami-0d729a60

Resources:
# مجموعة الأمان
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: السماح بـ HTTP و SSH
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub "${Environment}-web-sg"
- Key: Environment
Value: !Ref Environment

# مثيل EC2
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref WebSecurityGroup
Tags:
- Key: Name
Value: !Sub "${Environment}-web-server"
- Key: Environment
Value: !Ref Environment
UserData:
Fn::Base64: |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from CloudFormation!</h1>" > /var/www/html/index.html

Outputs:
InstanceId:
Description: معرف المثيل
Value: !Ref WebServer
Export:
Name: !Sub "${Environment}-WebServerId"

PublicIP:
Description: عنوان IP العام
Value: !GetAtt WebServer.PublicIp

WebsiteURL:
Description: عنوان URL للموقع
Value: !Sub "http://${WebServer.PublicIp}"

أوامر CLI​

# التحقق من صحة قالب
aws cloudformation validate-template \
--template-body file://template.yaml

# إنشاء stack
aws cloudformation create-stack \
--stack-name my-web-stack \
--template-body file://template.yaml \
--parameters \
ParameterKey=Environment,ParameterValue=dev \
ParameterKey=KeyName,ParameterValue=my-key

# عرض حالة stack
aws cloudformation describe-stacks \
--stack-name my-web-stack

# عرض الأحداث (تصحيح الأخطاء)
aws cloudformation describe-stack-events \
--stack-name my-web-stack

# تحديث stack
aws cloudformation update-stack \
--stack-name my-web-stack \
--template-body file://template.yaml \
--parameters \
ParameterKey=Environment,ParameterValue=staging

# حذف stack
aws cloudformation delete-stack \
--stack-name my-web-stack

أفضل الممارسات​

┌─────────────────────────────────────────────────────────────┐
│ BONNES PRATIQUES CLOUDFORMATION │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ FAIRE │
│ ──────── │
│ • Versionner les templates dans Git │
│ • Utiliser des paramètres pour la flexibilité │
│ • Ajouter des descriptions claires │
│ • Utiliser des noms logiques significatifs │
│ • Valider avant de déployer │
│ • Utiliser des Change Sets pour preview │
│ • Taguer toutes les ressources │
│ │
│ ❌ ÉVITER │
│ ───────── │
│ • Hardcoder des valeurs (AMIs, IPs...) │
│ • Créer des templates monolithiques (> 500 lignes) │
│ • Ignorer les erreurs de validation │
│ • Déployer sans revue de code │
│ • Oublier les outputs pour les références │
│ │
└─────────────────────────────────────────────────────────────┘

ملخص​

المفهومالوصف
Templateملف YAML/JSON يصف البنية التحتية
Stackمثيل منشور من قالب
Parametersمتغيرات إدخال قابلة للتكوين
Resourcesالموارد AWS التي سيتم إنشاؤها
Outputsالقيم المصدرة للمرجعية
!Refالإشارة إلى مورد أو متغير
!GetAttالحصول على خاصية من مورد

القسم التالي: مختبر CloudFormation