Anleitung: Erstellen einer skalierten Anwendung mit Load Balancing - AWS CloudFormation

Anleitung: Erstellen einer skalierten Anwendung mit Load Balancing

Für diese Anleitung erstellen Sie einen Stack, der Ihnen hilft, eine skalierte und lastverteilte Anwendung einzurichten. Die schrittweise Anleitung enthält eine Beispielvorlage, mit denen Sie den Stack erstellen können. Die Beispielvorlage stellt eine Auto-Scaling-Gruppe, einen Application Load Balancer, Sicherheitsgruppen, die den Datenverkehr zum Load Balancer und zur Auto-Scaling-Gruppe steuern, sowie eine Amazon-SNS-Benachrichtigungskonfiguration zur Veröffentlichung von Benachrichtigungen über Skalierungsaktivitäten bereit.

Diese Vorlage erstellt eine oder mehrere Amazon-EC2-Instances, sowie einen Application Load Balancer. Ihnen werden Gebühren für die verwendeten AWS-Ressourcen berechnet, wenn Sie einen Stack aus dieser Vorlage erstellen.

Vollständige Stack-Vorlage

Fangen wir mit der Vorlage an.

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" } } } } }

Walkthrough zu Vorlagen

Der erste Teil dieser Vorlage spezifiziert die Parameters. Jedem Parameter muss zur Laufzeit ein Wert für AWS CloudFormation zugewiesen werden, damit der Stack erfolgreich bereitgestellt wird. Später in der Vorlage angegebene Ressourcen verweisen auf diese Werte und verwenden die Daten.

  • InstanceType: Der Typ der EC2-Instance, die Amazon EC2 Auto Scaling bereitstellt. Wenn Sie keinen anderen Wert angeben, wird der Standardwert von t3.micro verwendet.

  • KeyName: Ein vorhandenes EC2-Schlüsselpaar, um SSH-Zugriff auf die Instances zu ermöglichen.

  • LatestAmiId: Das Amazon Machine Image (AMI) für die Instances. Wenn nicht angegeben, werden Ihre Instances mit einem Amazon-Linux-2-AMI gestartet, wobei ein öffentlicher AWS Systems Manager-Parameter verwendet wird, der von AWS verwaltet wird. Weitere Informationen finden Sie unter Öffentliche Parameter kennzeichnen im AWS Systems Manager-Benutzerhandbuch.

  • OperatorEmail: Die E-Mail-Adresse, an die Sie Skalierungsaktivitäten senden möchten.

  • SSHLocation: Der IP-Adressbereich, der für SSH-Verbindungen mit den Instances verwendet werden kann.

  • Subnets: Mindestens zwei Subnetze in verschiedenen Availability Zones.

  • VPC: Eine Virtual Private Cloud (VPC) in Ihrem Konto, mit der Ressourcen in öffentlichen Subnetzen eine Verbindung zum Internet herstellen können.

    Anmerkung

    Sie können die Standard-VPC und die Standardsubnetze verwenden, um Instances den Zugriff auf das Internet zu ermöglichen. Stellen Sie in letzterem Fall sicher, dass Ihre VPC über ein Subnetz verfügt, das jeder Availability Zone der Region zugeordnet ist, in der Sie arbeiten. Mindestens zwei öffentliche Subnetze müssen verfügbar sein, um den Load Balancer zu erstellen.

Der nächste Teil dieser Vorlage spezifiziert die Resources. In diesem Abschnitt werden die Stack-Ressourcen und ihre Eigenschaften angegeben.

AWS::EC2::SecurityGroup-Ressource ELBSecurityGroup

  • SecurityGroupIngress enthält eine TCP-Eingangsregel, die Zugriff von allen IP-Adressen („CidrIp“: „0.0.0.0/0") an Port 80 ermöglicht.

AWS::EC2::SecurityGroup-Ressource EC2SecurityGroup

  • SecurityGroupIngress enthält zwei Eingangsregeln: 1) eine TCP-Eingangsregel, die den SSH-Zugriff (Port 22) von dem IP-Adressbereich aus erlaubt, den Sie für den SSHLocation-Eingabeparameter angeben, und 2) eine TCP-Eingangsregel, die den Zugriff vom Load Balancer aus erlaubt, indem Sie die Sicherheitsgruppe des Load Balancers angeben. Die Funktion getATT wird verwendet, um die ID der Sicherheitsgruppe mit dem logischen Namen ELBSecurityGroup abzurufen.

AWS::ElasticLoadBalancingV2::TargetGroup-Ressource EC2TargetGroup

  • Port, Protocol, und HealthCheckProtocol geben den Port (80) und das Protokoll (HTTP) der EC2-Instance an, an die ApplicationLoadBalancer den Datenverkehr weitergeleitet und die Elastic Load Balancing verwendet, um den Zustand der EC2-Instances zu überprüfen.

  • HealthCheckIntervalSeconds gibt an, dass die EC2-Instances einen Abstand von 30 Sekunden zwischen den Zustandsprüfungen haben. HealthCheckTimeoutSeconds ist definiert als die Zeitdauer, die Elastic Load Balancing auf eine Reaktion vom Ziel der Zustandsprüfung wartet (in diesem Beispiel 15 Sekunden). Nach Ablauf der Zeitüberschreitung markiert Elastic Load Balancing die Zustandsprüfung der EC2-Instance als instabil. Wenn eine EC2-Instance drei aufeinanderfolgende Zustandsprüfungen (UnhealthyThresholdCount) nicht besteht, stoppt Elastic Load Balancing das Weiterleiten von Datenverkehr an diese EC2-Instance, bis diese Instance fünf aufeinanderfolgende fehlerfreie Zustandsprüfungen (HealthyThresholdCount) hat. Zu diesem Zeitpunkt betrachtet Elastic Load Balancing die Instance als fehlerfrei und beginnt erneut, Datenverkehr an die Instance weiterzuleiten.

  • TargetGroupAttributes aktualisiert den Wert der Deregistrierungsverzögerung der Zielgruppe auf 20 Sekunden. Standardmäßig wartet Elastic Load Balancing 300 Sekunden, bevor der Abmeldevorgang abgeschlossen wird.

AWS::ElasticLoadBalancingV2::Listener-Ressource ALBListener

  • DefaultActions gibt den Port an, an dem Load Balancer abhört, die Zielgruppe, an die Load Balancer Anforderungen weiterleitet, sowie das Protokoll, das zum Weiterleiten von Anforderungen verwendet wird.

AWS::ElasticLoadBalancingV2::LoadBalancer-Ressource ApplicationLoadBalancer

  • Subnets verwendet den Wert des Subnets-Eingabeparameters als Liste der öffentlichen Subnetze, in denen die Load-Balancer-Knoten erstellt werden.

  • SecurityGroup ruft die ID der Sicherheitsgruppe ab, die als virtuelle Firewall für Ihre Load-Balancer-Knoten dient, um den eingehendem Datenverkehr zu steuern. Die Funktion getATT wird verwendet, um die ID der Sicherheitsgruppe mit dem logischen Namen ELBSecurityGroup abzurufen.

AWS::EC2::LaunchTemplate-Ressource LaunchTemplate

  • ImageId verwendet den Wert des LatestAmiId-Eingabeparameters als das zu verwendende AMI.

  • KeyName verwendet den Wert des KeyName-Eingabeparameters als das zu verwendende EC2-Schlüsselpaar.

  • SecurityGroupIds ruft die ID der Sicherheitsgruppe mit dem logischen Namen EC2SecurityGroup ab, die als virtuelle Firewall für Ihre EC2-Instanzen fungiert, um den eingehenden Datenverkehr zu kontrollieren.

  • UserData ist ein Konfigurationsskript, das ausgeführt wird, nachdem die Instance gestartet wurde. In diesem Beispiel installiert das Skript Apache und erstellt eine index.html-Datei.

AWS::SNS::Topic-Ressource NotificationTopic

  • Subscription verwendet den Wert des OperatorEmail-Eingabeparameters als E-Mail-Adresse für den Empfänger der Benachrichtigungen, wenn Skalierungsaktivitäten stattfinden.

AWS::AutoScaling::AutoScalingGroup-Ressource WebServerGroup

  • MinSize und MaxSize bestimmen die Mindest- und Höchstanzahl von EC2-Instances in der Auto-Scaling-Gruppe.

  • TargetGroupARNs nimmt den ARN der Zielgruppe mit dem logischen Namen EC2TargetGroup. Bei der Skalierung dieser Auto-Scaling-Gruppe werden Instances bei dieser Zielgruppe automatisch registriert und deregistriert.

  • VPCZoneIdentifier verwendet den Wert des Subnets-Eingabeparameters als Liste der öffentlichen Subnetze, in denen die EC2-Instances erstellt werden können.

Schritt 1: Starten des Stacks

Bevor Sie den Stack starten, vergewissern Sie sich, dass Sie über AWS Identity and Access Management (IAM)-Berechtigungen zur Nutzung aller folgenden Services verfügen: Amazon EC2, Amazon EC2 Auto Scaling, AWS Systems Manager, Elastic Load Balancing, Amazon SNS, und AWS CloudFormation.

Das folgende Verfahren beinhaltet das Hochladen der Beispiel-Stack-Vorlage aus einer Datei. Öffnen Sie einen Texteditor auf Ihrem lokalen Computer und fügen Sie eine der Vorlagen hinzu. Speichern Sie die Datei mit dem Namen sampleloadbalancedappstack.template.

So starten Sie die Stack-Vorlage

  1. Melden Sie sich bei der AWS Management Console an und öffnen Sie die AWS CloudFormation-Konsole unter https://console.aws.amazon.com/cloudformation.

  2. Klicken Sie auf Create stack (Stack erstellen), With new resources (standard) (Mit neuen Ressourcen (Standard)).

  3. Unter Vorlage festlegen, wählen Sie Vorlagendatei hochladen aus und wählen Sie dann Datei wählen, um sampleloadbalancedappstack.template hochzuladen.

  4. Wählen Sie Next (Weiter).

  5. Geben Sie auf der Seite Details angeben einen Namen für den Stack ein (beispielsweise SampleLoadBalancedAppStack.)

  6. Überprüfen Sie unter Parameter die Parameter für den Stack und geben Sie Werte für alle Parameter an, die keine Standardwerte haben, einschließlich OperatorEmail, SSHLocation, KeyName, VPC und Subnetze.

  7. Klicken Sie zweimal auf Weiter.

  8. Überprüfen und bestätigen Sie die Einstellungen auf der Seite Review.

  9. Wählen Sie Submit (Absenden) aus.

    Sie können den Status des Stacks in der AWS CloudFormation-Konsole in der Spalte Status anzeigen. Wenn AWS CloudFormation den Stack erfolgreich erstellt hat, erhalten Sie den Status CREATE_COMPLETE.

    Anmerkung

    Nachdem Sie den Stack erstellt haben,müssen Sie das Abonnement bestätigen, bevor die E-Mail-Adresse Benachrichtigungen erleiden kann. Weitere Informationen finden Sie unter Erhalten Sie Amazon-SNS-Benachrichtigungen, wenn Ihre Auto-Scaling-Gruppe skaliert im Benutzerhandbuch für Amazon EC2 Auto Scaling.

Schritt 2: Bereinigen von Beispielressourcen

Um sicherzustellen, dass Ihnen keine ungenutzten Beispielressourcen berechnet werden, löschen Sie den Stack.

So löschen Sie den Stack
  1. Wählen Sie in der AWS CloudFormation-Konsole den Stack SampleWebAppCrossStack aus.

  2. Wählen Sie Delete (Löschen).

  3. Wählen Sie in der Bestätigungsmitteilung die Option Stack löschen aus.

    Der Status für SampleLoadBalancedAppStack ändert sich in DELETE_IN_PROGRESS. Wenn AWS CloudFormation die Löschung des Stacks abgeschlossen hat, dann wird der Stack aus der Liste entfernt.

Verwenden Sie diese Beispielvorlage aus dieser Anleitung, um eigene Stacks zu erstellen. Weitere Informationen finden Sie unter Tutorial: Einrichten einer skalierten Anwendung mit Load Balancing im Benutzerhandbuch zu Amazon EC2 Auto Scaling.