Creazione di un'applicazione dimensionata e con carico bilanciato - AWS CloudFormation

Creazione di un'applicazione dimensionata e con carico bilanciato

Per questa procedura dettagliata, viene creato uno stack che aiuta a configurare un'applicazione dimensionata e con carico bilanciato. La procedura guidata fornisce un modello di esempio che potrai usare per creare lo stack. Il modello di esempio prevede un gruppo con dimensionamento automatico, un Application Load Balancer, gruppi di sicurezza che controllano il traffico verso il sistema di bilanciamento del carico e il gruppo con dimensionamento automatico e una configurazione di notifica Amazon SNS per pubblicare notifiche sulle attività di dimensionamento.

Questo modello consente di creare una o più istanze Amazon EC2 e un Application Load Balancer. Se crei uno stack da questo modello, ti verranno addebitate le risorse AWS utilizzate.

Modello full stack

Cominciamo con il modello.

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

Spiegazione passo per passo del modello

La prima parte di questo modello specifica i Parameters. A ogni parametro deve essere assegnato un valore di runtime per consentire ad CloudFormation di effettuare il provisioning dello stack. Le risorse specificate più avanti nel modello fanno riferimento a questi valori e utilizzano i dati.

  • InstanceType: il tipo di istanza EC2 fornito da Amazon EC2 Auto Scaling. Se non viene specificato, viene utilizzato il valore predefinito t3.micro.

  • KeyName: una coppia di chiavi EC2 esistente per consentire l'accesso SSH alle istanze.

  • LatestAmiId: l'Amazon Machine Image (AMI) per le istanze. Se non specificato, le istanze vengono avviate con un'AMI Amazon Linux 2, utilizzando un parametro pubblico AWS Systems Manager gestito da AWS. Per ulteriori informazioni, consulta Ricerca dei parametri pubblici nella Guida per l'utente di AWS Systems Manager.

  • OperatorEmail: l'indirizzo e-mail a cui desideri inviare le notifiche sulle attività di dimensionamento.

  • SSHLocation: l'intervallo di indirizzi IP che può essere utilizzato per inviare SSH alle istanze.

  • Subnets: almeno due sottoreti pubbliche in diverse zone di disponibilità.

  • VPC: un cloud privato virtuale (VPC) nel tuo account che consente alle risorse nelle sottoreti pubbliche di connettersi a Internet.

    Nota

    Puoi utilizzare il VPC e le sottoreti predefiniti per consentire alle istanze di accedere a Internet. In quest'ultimo caso, assicurati che il VPC abbia una sottorete mappata a ciascuna zona di disponibilità della Regione in cui stai lavorando. Per creare il load balancer, ti serviranno almeno due sottoreti pubbliche.

La parte successiva di questo modello specifica le Resources. Questa sezione specifica le risorse dello stack e le relative proprietà.

Risorsa AWS::EC2::SecurityGroup ELBSecurityGroup

  • SecurityGroupIngress contiene una regola di ingresso TCP che consente l'accesso da tutti gli indirizzi IP ("CIDRIP": "0.0.0.0/0") sulla porta 80.

Risorsa AWS::EC2::SecurityGroup EC2SecurityGroup

  • SecurityGroupIngress contiene due regole di ingresso: 1) una regola di ingresso TCP che consente l'accesso SSH (porta 22) dall'intervallo di indirizzi IP fornito per il parametro di input SSHLocation e 2) una regola di ingresso TCP che consente l'accesso dal sistema di bilanciamento del carico specificando il gruppo di sicurezza del sistema di bilanciamento del carico. La funzione GetAtt viene utilizzata per ottenere l'ID del gruppo di sicurezza con il nome logico ELBSecurityGroup.

EC2TargetGroup della risorsa AWS::ElasticLoadBalancingV2::TargetGroup

  • Port, Protocol e HealthCheckProtocol specificano la porta (80) e il protocollo (HTTP) dell'istanza EC2 verso cui ApplicationLoadBalancer indirizza il traffico e che Elastic Load Balancing utilizza per verificare l'integrità delle istanze EC2.

  • HealthCheckIntervalSeconds specifica che le istanze EC2 hanno un intervallo di 30 secondi tra un controllo dell'integrità e un altro. Per HealthCheckTimeoutSeconds si intende il periodo di tempo che Elastic Load Balancing attende per una risposta della destinazione del controllo dell'integrità (15 secondi in questo esempio). Al termine del periodo di timeout, Elastic Load Balancing contrassegna il controllo dell'integrità dell'istanza EC2 come non integra. Quando un'istanza EC2 non supera tre controlli di integrità consecutivi (UnhealthyThresholdCount), Elastic Load Balancing interrompe l'instradamento del traffico verso quell'istanza EC2 fino a quando quell'istanza non ha cinque controlli dell'integrità consecutivi (HealthyThresholdCount). A quel punto, Elastic Load Balancing considera l'istanza integra e ricomincia a indirizzare il traffico verso l'istanza.

  • TargetGroupAttributes aggiorna il valore del ritardo di annullamento della registrazione del gruppo di destinazione a 20 secondi. Per impostazione predefinita, Elastic Load Balancing attende 300 secondi prima di completare il processo di annullamento della registrazione.

ALBListener della risorsa AWS::ElasticLoadBalancingV2::Listener

  • DefaultActions specifica la porta su cui il sistema di bilanciamento del carico ascolta, il gruppo di destinazione a cui il sistema di bilanciamento del carico inoltra le richieste e il protocollo utilizzato per instradare le richieste.

ApplicationLoadBalancer della risorsa AWS::ElasticLoadBalancingV2::LoadBalancer

  • Subnets prende il valore del parametro di input Subnets come elenco di sottoreti pubbliche in cui verranno creati i nodi del sistema di bilanciamento del carico.

  • SecurityGroup ottiene l'ID del gruppo di sicurezza che funge da firewall virtuale per i nodi del sistema di bilanciamento del carico per controllare il traffico in entrata. La funzione GetAtt viene utilizzata per ottenere l'ID del gruppo di sicurezza con il nome logico ELBSecurityGroup.

LaunchTemplate della risorsa AWS::EC2::LaunchTemplate

  • ImageId prende il valore del parametro di input LatestAmiId come AMI da utilizzare.

  • KeyName prende il valore del parametro di input KeyName come la coppia di chiavi EC2 da usare.

  • SecurityGroupIds ottiene l'ID del gruppo di sicurezza con il nome logico EC2SecurityGroup che funge da firewall virtuale per le istanze EC2 per controllare il traffico in entrata.

  • UserData è uno script di configurazione che viene eseguito dopo che l'istanza è attiva e funzionante. In questo esempio, lo script installa Apache e crea un file index.html.

NotificationTopic della risorsa AWS::SNS::Topic

  • Subscription prende il valore del parametro di input OperatorEmail come indirizzo e-mail del destinatario delle notifiche in caso di attività di scalabilità.

WebServerGroup della risorsa AWS::AutoScaling::AutoScalingGroup

  • MinSize e MaxSize impostano il numero minimo e massimo di istanze EC2 nel gruppo con dimensionamento automatico.

  • TargetGroupARNs prende l'ARN del gruppo di destinazione con il nome logico EC2TargetGroup. Man mano che questo dimensionamento automatico si dimensiona, registra le istanze e ne annulla automaticamente la registrazione con questo gruppo di destinazione.

  • VPCZoneIdentifier prende il valore del parametro di input Subnets come elenco di sottoreti pubbliche in cui verranno create le istanze EC2.

Fase 1: Avvio dello stack

Prima di avviare lo stack, verifica di disporre delle autorizzazioni AWS Identity and Access Management (IAM) per utilizzare tutti i seguenti servizi: Amazon EC2, Amazon EC2 Auto Scaling, AWS Systems Manager, Elastic Load Balancing, Amazon SNS e CloudFormation.

La procedura seguente prevede il caricamento del modello di stack di esempio da un file. Apri un editor di testo sul tuo computer locale e aggiungi uno dei modelli. Salva il file con il nome sampleloadbalancedappstack.template.

Avvio del modello dello stack
  1. Accedere alla Console di gestione AWS e aprire la console di CloudFormation all'indirizzo https://console.aws.amazon.com/cloudformation.

  2. Scegliere Create stack (Crea stack), With new resources (standard) (Con nuove risorse (standard)).

  3. In Specifica modello, seleziona Carica un file di modello e poi Scegli file per caricare il file sampleloadbalancedappstack.template.

  4. Scegli Next (Successivo).

  5. Nella pagina Specifica i dettagli dello stack, immetti il nome dello stack (ad esempio, SampleLoadBalancedAppStack).

  6. In Parametri, esamina i parametri per lo stack e fornisci i valori per tutti i parametri che non hanno valori predefiniti, inclusi OperatorEmail, SSHLocation, KeyName, VPC e Subnets.

  7. Scegliere Next (Successivo) due volte.

  8. Nella pagina Rivedi, verifica e conferma le impostazioni.

  9. Scegli Invia.

    Puoi visualizzare lo stato dello stack nella console CloudFormation nella colonna Stato. Una volta che CloudFormation ha creato correttamente lo stack, riceverai lo stato CREATE_COMPLETE.

    Nota

    Dopo aver creato lo stack, perché l'indirizzo e-mail possa iniziare a ricevere notifiche devi confermare la sottoscrizione. Per ulteriori informazioni, consulta l'argomento relativo alla ricezione di notifiche Amazon SNS quando il gruppo di dimensionamento automatico viene dimensionato nella Guida per l'utente di Amazon EC2 Auto Scaling.

Fase 2: Cancellazione delle risorse di esempio

Per assicurarti che non ti vengano addebitati costi per le risorse di esempio inutilizzate, elimina lo stack.

Per eliminare lo stack
  1. Nella console CloudFormation selezionare lo stack SampleLoadBalancedAppStack.

  2. Scegli Elimina.

  3. Nel messaggio di conferma, scegli Elimina stack.

    Lo stato di SampleLoadBalancedAppStack cambia in DELETE_IN_PROGRESS. Quando CloudFormation completa l'eliminazione dello stack, rimuove lo stack dall'elenco.

Usa i modelli di esempio di questa procedura guidata per creare i tuoi modelli stack. Per ulteriori informazioni, consulta Tutorial: Configurazione di un'applicazione con dimensionata e con bilanciamento del carico nella Guida per l'utente di Amazon EC2 Auto Scaling.