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

مختبر: CloudFormation

الهدف​

إنشاء قوالب CloudFormation لنشر بنية تحتية كاملة بطريقة قابلة للتكرار.

الجزء 1: قالب أساسي​

تمرين 1.1: Security Group​

قم بإنشاء قالب لـ Security Group يسمح بـ HTTP و SSH:

AWSTemplateFormatVersion: "2010-09-09"
Description: Security Group لخادم الويب

Resources:
WebServerSG:
Type: _______________
Properties:
GroupDescription: _______________
SecurityGroupIngress:
- IpProtocol: ___
FromPort: ___
ToPort: ___
CidrIp: _______________
- IpProtocol: ___
FromPort: ___
ToPort: ___
CidrIp: _______________
💡 الحل
AWSTemplateFormatVersion: "2010-09-09"
Description: Security Group لخادم الويب

Resources:
WebServerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH access
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

تمرين 1.2: إضافة معلمات​

حسن القالب بإضافة معلمات:

Parameters:
SSHLocation:
Type: _______________
Default: _______________
Description: IP range for SSH access
AllowedPattern: _______________
ConstraintDescription: Must be valid CIDR

Environment:
Type: String
AllowedValues:
- ___
- ___
- ___
💡 الحل
Parameters:
SSHLocation:
Type: String
Default: 0.0.0.0/0
Description: IP range for SSH access
AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
ConstraintDescription: Must be valid CIDR (e.g., 10.0.0.0/24)

Environment:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- prod
Description: Environment type

ثم في Security Group:

SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref SSHLocation

الجزء 2: مثيل EC2​

تمرين 2.1: قالب EC2 كامل​

AWSTemplateFormatVersion: "2010-09-09"
Description: Web Server مع EC2

Parameters:
Environment:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]

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

KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: EC2 Key Pair

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

Resources:
# أكمل الموارد
WebServerSG:
Type: _______________
# ...

WebServer:
Type: _______________
Properties:
ImageId: _______________
InstanceType: _______________
KeyName: _______________
SecurityGroupIds:
- _______________
Tags:
- Key: Name
Value: _______________
UserData:
Fn::Base64: |
#!/bin/bash
# أكمل السكربت

Outputs:
PublicIP:
Value: _______________
WebURL:
Value: _______________
💡 الحل الكامل
AWSTemplateFormatVersion: "2010-09-09"
Description: Web Server مع EC2

Parameters:
Environment:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]

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

KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: EC2 Key Pair

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

Resources:
WebServerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and 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

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

Outputs:
InstanceId:
Description: Instance ID
Value: !Ref WebServer

PublicIP:
Description: Public IP
Value: !GetAtt WebServer.PublicIp

WebURL:
Description: Website URL
Value: !Sub "http://${WebServer.PublicIp}"

الجزء 3: VPC كامل​

تمرين 3.1: بنية VPC​

قم بإنشاء قالب لهذه البنية:

┌─────────────────────────────────────────────────────────────┐
│ VPC 10.0.0.0/16 │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Public Subnet │ │ Private Subnet │ │
│ │ 10.0.1.0/24 │ │ 10.0.2.0/24 │ │
│ │ │ │ │ │
│ │ ┌───────────┐ │ │ ┌───────────┐ │ │
│ │ │ EC2 │ │ │ │ EC2 │ │ │
│ │ │ (web) │ │ │ │ (app) │ │ │
│ │ └───────────┘ │ │ └───────────┘ │ │
│ │ │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

قالب لإكماله:

Resources:
# VPC
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: _______________
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-vpc"

# Internet Gateway
InternetGateway:
Type: _______________

AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: _______________
InternetGatewayId: _______________

# Public Subnet
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: _______________
CidrBlock: _______________
MapPublicIpOnLaunch: ___
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-public"

# Private Subnet
PrivateSubnet:
Type: _______________
# أكمل...

# Route Table Public
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC

PublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: _______________
DestinationCidrBlock: _______________
GatewayId: _______________

PublicSubnetRouteAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: _______________
RouteTableId: _______________
💡 الحل
AWSTemplateFormatVersion: "2010-09-09"
Description: VPC مع subnets عامة وخاصة

Parameters:
Environment:
Type: String
Default: dev

Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-vpc"

InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-igw"

AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway

PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
AvailabilityZone: !Select [0, !GetAZs ""]
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-public"

PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
MapPublicIpOnLaunch: false
AvailabilityZone: !Select [0, !GetAZs ""]
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-private"

PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-public-rt"

PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway

PublicSubnetRouteAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable

Outputs:
VPCId:
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}-VPCId"

PublicSubnetId:
Value: !Ref PublicSubnet
Export:
Name: !Sub "${AWS::StackName}-PublicSubnetId"

PrivateSubnetId:
Value: !Ref PrivateSubnet
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnetId"

الجزء 4: استكشاف الأخطاء وإصلاحها​

تمرين 4.1: تحديد الأخطاء​

يحتوي هذا القالب على أخطاء. حددها:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
InstanceType:
Type: string # خطأ 1
Default: t3.micro

Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-12345678
InstanceType: !Ref instancetype # خطأ 2
SecurityGroups:
- !Ref MySG # خطأ 3 (الترتيب)
Tags:
- Key: Name
Value: !Sub ${AWS:StackName}-instance # خطأ 4

MySG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription # خطأ 5
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
💡 الحلول
  1. خطأ 1: string → String (حرف كبير)
  2. خطأ 2: instancetype → InstanceType (احترام حالة الأحرف للمعلمة)
  3. خطأ 3: يجب تعريف MySG قبل أو استخدام DependsOn
  4. خطأ 4: AWS:StackName → AWS::StackName (نقطتان مزدوجتان)
  5. خطأ 5: ينقص : "Description" بعد GroupDescription

القالب المصحح:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
InstanceType:
Type: String
Default: t3.micro

Resources:
MySG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for web server"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0

MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-12345678
InstanceType: !Ref InstanceType
SecurityGroupIds:
- !Ref MySG
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-instance"

الجزء 5: المشروع النهائي​

تمرين 5.1: بنية تحتية كاملة​

قم بإنشاء قالب للبنية التالية:

┌─────────────────────────────────────────────────────────────┐
│ بنية ويب ثلاثية الطبقات │
├─────────────────────────────────────────────────────────────┤
│ │
│ الإنترنت → ALB → EC2 (التوسع التلقائي) → RDS │
│ │
│ المكونات المطلوبة: │
│ • VPC مع 2 subnets عامة و 2 خاصة │
│ • Security Groups (ALB, EC2, RDS) │
│ • Application Load Balancer │
│ • Launch Template + Auto Scaling Group │
│ • RDS MySQL (اختياري) │
│ │
│ المعلمات: │
│ • Environment (dev/staging/prod) │
│ • InstanceType │
│ • MinSize, MaxSize, DesiredCapacity │
│ │
└─────────────────────────────────────────────────────────────┘

معايير التحقق​

المعيارالنقاط
قالب صالح (لا أخطاء)/15
المعلمات معرفة جيدًا/15
VPC مكون بشكل صحيح/20
Security Groups مقيدة/15
ALB + ASG وظيفية/20
مخرجات مفيدة/10
توثيق/تعليقات/5
المجموع/100

التسليم النهائي​

الوثيقة المطلوب إنتاجها​

  1. قالب CloudFormation كامل (YAML)
  2. تعليمات النشر (أوامر CLI)
  3. مخطط البنية
  4. قائمة المعلمات والقيم
  5. اختبارات التحقق المنفذة

نهاية الدورة! نتمنى لك التوفيق في مسيرتك مع AWS.