建置擴展和負載平衡的應用程式 - AWS CloudFormation

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

建置擴展和負載平衡的應用程式

在此逐步解說中,您將建立可協助您設定已擴展和已負載平衡應用程式的堆疊。逐步解說提供您將用於建立堆疊的範例範本。範例範本佈建 Auto Scaling 群組、應用程式負載平衡器、控制負載平衡器流量的安全群組和 Auto Scaling 群組,以及 Amazon SNS 通知組態,以發佈有關擴展活動的通知。

此範本會建立一或多個 Amazon EC2 執行個體和應用程式負載平衡器。若您從此範本建立堆疊,您必須為使用的 AWS 資源支付費用。

完整堆疊範本

讓我們從範本開始。

YAML

AWSTemplateFormatVersion: 2010-09-09 Parameters: InstanceType: Description: The EC2 instance type Type: String Default: t3.micro AllowedValues: - t3.micro - t3.small - t3.medium KeyName: Description: Name of an existing EC2 key pair to allow SSH access to the instances Type: 'AWS::EC2::KeyPair::KeyName' LatestAmiId: Description: The latest Amazon Linux 2 AMI from the Parameter Store Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' OperatorEmail: Description: The email address to notify when there are any scaling activities Type: String SSHLocation: Description: The IP address range that can be used to SSH to the EC2 instances Type: String MinLength: 9 MaxLength: 18 Default: 0.0.0.0/0 ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Subnets: Type: 'List<AWS::EC2::Subnet::Id>' Description: At least two public subnets in different Availability Zones in the selected VPC VPC: Type: 'AWS::EC2::VPC::Id' Description: A virtual private cloud (VPC) that enables resources in public subnets to connect to the internet Resources: ELBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: ELB Security Group VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 EC2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: EC2 Security Group VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: Fn::GetAtt: - ELBSecurityGroup - GroupId - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SSHLocation EC2TargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckIntervalSeconds: 30 HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 15 HealthyThresholdCount: 5 Matcher: HttpCode: '200' Name: EC2TargetGroup Port: 80 Protocol: HTTP TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: '20' UnhealthyThresholdCount: 3 VpcId: !Ref VPC ALBListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref EC2TargetGroup LoadBalancerArn: !Ref ApplicationLoadBalancer Port: 80 Protocol: HTTP ApplicationLoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internet-facing Subnets: !Ref Subnets SecurityGroups: - !GetAtt ELBSecurityGroup.GroupId LaunchTemplate: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateName: !Sub ${AWS::StackName}-launch-template LaunchTemplateData: ImageId: !Ref LatestAmiId InstanceType: !Ref InstanceType KeyName: !Ref KeyName SecurityGroupIds: - !Ref EC2SecurityGroup UserData: Fn::Base64: !Sub | #!/bin/bash yum update -y yum install -y httpd systemctl start httpd systemctl enable httpd echo "<h1>Hello World!</h1>" > /var/www/html/index.html NotificationTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref OperatorEmail Protocol: email WebServerGroup: Type: AWS::AutoScaling::AutoScalingGroup Properties: LaunchTemplate: LaunchTemplateId: !Ref LaunchTemplate Version: !GetAtt LaunchTemplate.LatestVersionNumber MaxSize: '3' MinSize: '1' NotificationConfigurations: - TopicARN: !Ref NotificationTopic NotificationTypes: ['autoscaling:EC2_INSTANCE_LAUNCH', 'autoscaling:EC2_INSTANCE_LAUNCH_ERROR', 'autoscaling:EC2_INSTANCE_TERMINATE', 'autoscaling:EC2_INSTANCE_TERMINATE_ERROR'] TargetGroupARNs: - !Ref EC2TargetGroup VPCZoneIdentifier: !Ref Subnets

JSON

{ "AWSTemplateFormatVersion":"2010-09-09", "Parameters":{ "InstanceType":{ "Description":"The EC2 instance type", "Type":"String", "Default":"t3.micro", "AllowedValues":[ "t3.micro", "t3.small", "t3.medium" ] }, "KeyName":{ "Description":"Name of an existing EC2 key pair to allow SSH access to the instances", "Type":"AWS::EC2::KeyPair::KeyName" }, "LatestAmiId":{ "Description":"The latest Amazon Linux 2 AMI from the Parameter Store", "Type":"AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>", "Default":"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" }, "OperatorEmail":{ "Description":"The email address to notify when there are any scaling activities", "Type":"String" }, "SSHLocation":{ "Description":"The IP address range that can be used to SSH to the EC2 instances", "Type":"String", "MinLength":9, "MaxLength":18, "Default":"0.0.0.0/0", "ConstraintDescription":"Must be a valid IP CIDR range of the form x.x.x.x/x." }, "Subnets":{ "Type":"List<AWS::EC2::Subnet::Id>", "Description":"At least two public subnets in different Availability Zones in the selected VPC" }, "VPC":{ "Type":"AWS::EC2::VPC::Id", "Description":"A virtual private cloud (VPC) that enables resources in public subnets to connect to the internet" } }, "Resources":{ "ELBSecurityGroup":{ "Type":"AWS::EC2::SecurityGroup", "Properties":{ "GroupDescription":"ELB Security Group", "VpcId":{ "Ref":"VPC" }, "SecurityGroupIngress":[ { "IpProtocol":"tcp", "FromPort":80, "ToPort":80, "CidrIp":"0.0.0.0/0" } ] } }, "EC2SecurityGroup":{ "Type":"AWS::EC2::SecurityGroup", "Properties":{ "GroupDescription":"EC2 Security Group", "VpcId":{ "Ref":"VPC" }, "SecurityGroupIngress":[ { "IpProtocol":"tcp", "FromPort":80, "ToPort":80, "SourceSecurityGroupId":{ "Fn::GetAtt":[ "ELBSecurityGroup", "GroupId" ] } }, { "IpProtocol":"tcp", "FromPort":22, "ToPort":22, "CidrIp":{ "Ref":"SSHLocation" } } ] } }, "EC2TargetGroup":{ "Type":"AWS::ElasticLoadBalancingV2::TargetGroup", "Properties":{ "HealthCheckIntervalSeconds":30, "HealthCheckProtocol":"HTTP", "HealthCheckTimeoutSeconds":15, "HealthyThresholdCount":5, "Matcher":{ "HttpCode":"200" }, "Name":"EC2TargetGroup", "Port":80, "Protocol":"HTTP", "TargetGroupAttributes":[ { "Key":"deregistration_delay.timeout_seconds", "Value":"20" } ], "UnhealthyThresholdCount":3, "VpcId":{ "Ref":"VPC" } } }, "ALBListener":{ "Type":"AWS::ElasticLoadBalancingV2::Listener", "Properties":{ "DefaultActions":[ { "Type":"forward", "TargetGroupArn":{ "Ref":"EC2TargetGroup" } } ], "LoadBalancerArn":{ "Ref":"ApplicationLoadBalancer" }, "Port":80, "Protocol":"HTTP" } }, "ApplicationLoadBalancer":{ "Type":"AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties":{ "Scheme":"internet-facing", "Subnets":{ "Ref":"Subnets" }, "SecurityGroups":[ { "Fn::GetAtt":[ "ELBSecurityGroup", "GroupId" ] } ] } }, "LaunchTemplate":{ "Type":"AWS::EC2::LaunchTemplate", "Properties":{ "LaunchTemplateName":{ "Fn::Sub":"${AWS::StackName}-launch-template" }, "LaunchTemplateData":{ "ImageId":{ "Ref":"LatestAmiId" }, "InstanceType":{ "Ref":"InstanceType" }, "KeyName":{ "Ref":"KeyName" }, "SecurityGroupIds":[ { "Ref":"EC2SecurityGroup" } ], "UserData":{ "Fn::Base64":{ "Fn::Join":[ "", [ "#!/bin/bash\n", "yum update -y\n", "yum install -y httpd\n", "systemctl start httpd\n", "systemctl enable httpd\n", "echo \"<h1>Hello World!</h1>\" > /var/www/html/index.html" ] ] } } } } }, "NotificationTopic":{ "Type":"AWS::SNS::Topic", "Properties":{ "Subscription":[ { "Endpoint":{ "Ref":"OperatorEmail" }, "Protocol":"email" } ] } }, "WebServerGroup":{ "Type":"AWS::AutoScaling::AutoScalingGroup", "Properties":{ "LaunchTemplate":{ "LaunchTemplateId":{ "Ref":"LaunchTemplate" }, "Version":{ "Fn::GetAtt":[ "LaunchTemplate", "LatestVersionNumber" ] } }, "MaxSize":"3", "MinSize":"1", "NotificationConfigurations":[ { "TopicARN":{ "Ref":"NotificationTopic" }, "NotificationTypes":[ "autoscaling:EC2_INSTANCE_LAUNCH", "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", "autoscaling:EC2_INSTANCE_TERMINATE", "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" ] } ], "TargetGroupARNs":[ { "Ref":"EC2TargetGroup" } ], "VPCZoneIdentifier":{ "Ref":"Subnets" } } } } }

範本演練

此範本的第一部分會指定 Parameters。每個參數都必須在執行階段指派值, AWS CloudFormation 才能成功佈建堆疊。在範本中稍後指定的資源會參考這些值並使用資料。

  • InstanceType:Amazon EC2 Auto Scaling 佈建的EC2執行個體類型。如果未指定,則會使用預設的 t3.micro

  • KeyName:允許SSH訪問實例的現有 EC2 key pair。

  • LatestAmiId:執行個體的 Amazon 機器映像 (AMI)。如果未指定,您的執行個體會透過 Amazon Linux 2 啟動AMI,並使用由維護的 AWS Systems Manager 公用參數 AWS。如需詳細資訊,請參閱《AWS Systems Manager 使用者指南》中的尋找公有參數

  • OperatorEmail:您要傳送擴展活動通知的電子郵件地址。

  • SSHLocation:可用於執行個體的 IP 位址範圍。SSH

  • Subnets:至少兩個公有子網路位於不同的可用區域。

  • VPC: 您帳戶中的虛擬私有雲 (VPC),可讓公用子網路中的資源連線至網際網路。

    注意

    您可以使用預設VPC和預設子網路來允許執行個體存取網際網路。如果使用您自己的VPC,請確定它具有對應至您正在使用之區域的每個可用區域的子網路。必須至少有兩個可用的公有子網路,您才能建立負載平衡器。

此範本的下一部分會指定 Resources。此區段指定堆疊資源及其屬性。

AWS::EC2::SecurityGroup資源 ELBSecurityGroup

  • SecurityGroupIngress包含一個TCP輸入規則,允許從連接埠 80 上的所有 IP 位址 (「CidrIp」:「0.0.0/0") 進行存取。

AWS::EC2::SecurityGroup資源 EC2SecurityGroup

  • SecurityGroupIngress包含兩個輸入規則:1) 允許從您為SSHLocation輸入參數提供的 IP 位址範圍SSH存取 (通訊埠 22) 的輸入規則,以及 2) 允許透過指定負載平TCP衡器的安全性群組從負載平衡器存取的輸入規則。TCP該GetAtt函數用於獲取具有邏輯名稱的安全組的 ID ELBSecurityGroup

AWS:: ElasticLoadBalancing V2:: TargetGroup 資源 EC2TargetGroup

  • PortProtocol、,並HealthCheckProtocol指定將流量ApplicationLoadBalancer路由傳送至的EC2執行個體連接埠 (80HTTP) 和通訊協定 (),以及 Elastic Load Balancing 用來檢查EC2執行個體健康狀態。

  • HealthCheckIntervalSeconds指定執行個EC2體在健康狀態檢查之間有 30 秒的間隔。HealthCheckTimeoutSeconds 的定義為 Elastic Load Balancing 等待來自運作狀態檢查目標回應的時間長度 (此範例中為 15 秒)。逾時期限過後,Elastic Load Balancing 會將該EC2執行個體的健康狀態檢查標記為狀況不良。當EC2執行個體連續三次運作狀態檢查 (UnhealthyThresholdCount) 失敗時,Elastic Load Balancing 會停止將流量路由傳送至該EC2執行個體,直到該執行個體連續進行五次健康狀態檢查 (HealthyThresholdCount) 此時,Elastic Load Balancing 會將執行個體視為狀態良好,並再次開始將流量路由到該執行個體。

  • TargetGroupAttributes 將目標群組的取消註冊延遲值更新為 20 秒。依預設,Elastic Load Balancing 會等待 300 秒,然後再完成取消註冊程序。

AWS:: ElasticLoadBalancing V2:: 監聽器資源 ALBListener

  • DefaultActions 指定負載平衡器監聽的連接埠、負載平衡器轉寄請求的目標群組,以及用來路由請求的通訊協定。

AWS:: ElasticLoadBalancing V2:: LoadBalancer 資源 ApplicationLoadBalancer

  • SubnetsSubnets 輸入參數的值做為公有子網路的清單,負載平衡器節點將在該清單中建立。

  • SecurityGroup 獲取安全群組的 ID,該安全群組充當您的負載平衡器節點的虛擬防火牆,以控制傳入的流量。該GetAtt函數用於獲取具有邏輯名稱的安全組的 ID ELBSecurityGroup

AWS::EC2: LaunchTemplate 資源 LaunchTemplate

  • ImageId會採用LatestAmiId輸入參數的值做為AMI要使用的值。

  • KeyName需要KeyName輸入參數的值作為要使用的 EC2 key pair。

  • SecurityGroupIds取得具有邏輯名稱的安全群組識別碼,EC2SecurityGroup該邏輯名稱可做為EC2執行個體控制傳入流量的虛擬防火牆。

  • UserData 是在執行個體啟動並運行後執行的組態指令碼。在此範例中,指令碼會安裝 Apache,並建立 index.html 檔案。

AWS:::SNS: 主題資源 NotificationTopic

  • 當有任何擴展活動時,Subscription 會將 OperatorEmail 輸入參數的值做為通知收件人的電子郵件地址。

AWS::AutoScaling: AutoScalingGroup 資源 WebServerGroup

  • MinSize,並MaxSize設定「Auto Scaling」群組中的最小和最大EC2執行個體數目。

  • TargetGroupARNs採用具有邏輯名稱ARN的目標群組EC2TargetGroup。當此 Auto Scaling 群組擴展時,它會自動向此目標群組註冊和取消註冊執行個體。

  • VPCZoneIdentifier會將 Subnets input 參數的值做為可建立EC2執行個體的公用子網路清單。

步驟 1:啟動堆疊

在啟動堆疊之前,請檢查您是否擁有 AWS Identity and Access Management (IAM) 許可以使用下列所有服務:Amazon EC2、Amazon EC2 Auto Scaling AWS Systems Manager、Elastic Load Balancing SNS、Amazon 和 AWS CloudFormation.

下列程序涉及從檔案上傳範例堆疊範本。在本機電腦上打開文字編輯器,然後新增其中一個範本。儲存檔案,並將其命名為 sampleloadbalancedappstack.template

啟動堆疊範本

  1. 請登入 AWS Management Console 並開啟 AWS CloudFormation 主控台,網址為 https://console.aws.amazon.com/cloudformation

  2. 選擇 Create stack (建立堆疊)With new resources (standard) (使用新資源 (標準))

  3. 指定範本下,選擇上傳範本檔案,然後選擇選擇檔案以上傳 sampleloadbalancedappstack.template 檔案。

  4. 選擇下一步

  5. 指定詳細資訊頁面上,輸入堆疊名稱 (例如 SampleLoadBalancedAppStack)。

  6. 參數下,檢閱堆疊的參數,並為沒有預設值的所有參數提供值,包括OperatorEmailSSHLocationKeyNameVPC、和子網路

  7. 選擇 Next (下一步) 兩次。

  8. 檢視 頁面上,檢視和確認的設定。

  9. 選擇提交

    您可以在 AWS CloudFormation 主控台的 [狀態] 欄中檢視堆疊的狀態。 AWS CloudFormation 成功建立堆疊後,您會收到 CREATE_ 的狀態COMPLETE。

    注意

    在建立堆疊之後,您必須先確認訂閱,電子郵件地址才能開始接收通知。如需詳細資訊,請參閱 SNSAmazon 自動擴展使用者指南中的「當您的自EC2動擴展群組擴展時取得 Amazon 通知」。

步驟 2:清除您的資源範例

若要確保您不會為未使用的資源範例付費,請刪除堆疊。

刪除堆疊
  1. 在主 AWS CloudFormation 控台中,選取SampleLoadBalancedAppStack堆疊。

  2. 選擇刪除

  3. 在確認訊息中,選擇刪除堆疊

    SampleLoadBalancedAppStack變更為 DELETE_IN_ PROGRESS 的狀態。當 AWS CloudFormation 完成堆棧的刪除,它從列表中刪除堆棧。

使用此逐步解說的範例範本建置您自己的堆疊範本。如需詳細資訊,請參閱 Amazon EC2 Auto Scaling 使用者指南中的教學課程:設定可調整且負載平衡的應程式。