Tutorial: Creación de una aplicación con escalado y equilibrio de carga - AWS CloudFormation

Tutorial: Creación de una aplicación con escalado y equilibrio de carga

Para este tutorial, creará una pila que lo ayudará a configurar una aplicación con escalado y equilibrio de carga. El tutorial proporciona una plantilla de ejemplo que utilizará para crear la pila. La plantilla de ejemplo proporciona un grupo de escalado automático, un equilibrador de carga de aplicación, grupos de seguridad que controlan el tráfico al equilibrador de carga y al grupo de escalado automático y una configuración de notificaciones de Amazon SNS para publicar notificaciones sobre las actividades de escalado.

Esta plantilla crea una o varias instancias de Amazon EC2 y un equilibrador de carga de aplicación. Se le facturarán los recursos de AWS que utilice si crea una pila a partir de esta plantilla.

Plantilla de pila completa

Empecemos por la plantilla.

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

Tutorial de plantilla

La primera parte de esta plantilla especifica los Parameters. A cada parámetro se le debe asignar un valor en tiempo de ejecución para que AWS CloudFormation aprovisione correctamente la pila. Los recursos especificados más adelante en la plantilla hacen referencia a estos valores y utilizan los datos.

  • InstanceType: el tipo de instancia de EC2 que Amazon EC2 Auto Scaling aprovisiona. Si no se especifica, se usa el valor predeterminado de t3.micro.

  • KeyName: un par de claves de EC2 existente para permitir el acceso SSH a las instancias.

  • LatestAmiId: el ID de imagen de máquina de Amazon (AMI) para las instancias. Si no se especifica, las instancias se lanzan con una AMI de Amazon Linux 2, mediante un parámetro AWS Systems Manager público mantenido por AWS. Para obtener más información, consulte Buscar parámetros públicos en la Guía del usuario de AWS Systems Manager.

  • OperatorEmail: la dirección de correo electrónico a la que desea enviar notificaciones de actividad de escalado.

  • SSHLocation: el intervalo de direcciones IP que se puede usar para enviar SSH a las instancias.

  • Subnets: al menos dos subredes en diferentes zonas de disponibilidad.

  • VPC: una nube privada virtual (VPC) en su cuenta que permite a los recursos de subredes públicas conectarse a Internet.

    nota

    Puede usar la VPC predeterminada y las subredes predeterminadas para permitir que las instancias accedan a Internet. Si utiliza supropia VPC, asegúrese de que tiene una subred asignada a cada zona de disponibilidad de la región de en la que esté trabajando. Como mínimo, debe tener dos subredes públicas disponibles para crear el balanceador de carga.

La siguiente parte de esta plantilla especifica los Resources. Esta sección especifica los recursos de la pila y sus propiedades.

Recurso ELBSecurityGroup de AWS::EC2::SecurityGroup

  • SecurityGroupIngress contiene una regla de entrada TCP que permite el acceso desde todas las direcciones IP (“CidrIp”: “0.0.0.0/0”) en el puerto 80.

Recurso EC2SecurityGroup de AWS::EC2::SecurityGroup

  • SecurityGroupIngress contiene dos reglas de entrada: 1) una regla de entrada TCP que permite el acceso SSH (puerto 22) desde el rango de direcciones IP que usted proporciona para el parámetro de entrada de SSHLocation y 2) una regla de entrada TCP que permite el acceso desde el equilibrador de carga al especificar el grupo de seguridad del equilibrador de carga. La función GetAtt se usa para obtener el ID del grupo de seguridad con el nombre lógico ELBSecurityGroup.

Recurso EC2TargetGroup de AWS::ElasticLoadBalancingV2::TargetGroup

  • Port, Protocol y HealthCheckProtocol especifican el puerto de instancia de EC2 (80) y el protocolo (HTTP) a los que el ApplicationLoadBalancer enruta el tráfico y que Elastic Load Balancing usa para comprobar el estado de las instancias de EC2.

  • HealthCheckIntervalSeconds especifica que las instancias de EC2 tengan un intervalo de 30 segundos entre las comprobaciones de estado. HealthCheckTimeoutSeconds se define como el periodo de tiempo en el que Elastic Load Balancing espera una respuesta del destino de comprobación de estado (15 segundos en este ejemplo). Cuando termina el tiempo de espera, Elastic Load Balancing marca la comprobación de estado de las instancias de EC2 como en mal estado. Cuando una instancia de EC2 falla tres comprobaciones consecutivas (UnhealthyThresholdCount), Elastic Load Balancing detiene el tráfico de enrutamiento a dicha instancia de EC2 hasta que esa instancia tenga cinco comprobaciones correctas consecutivas (HealthyThresholdCount). En ese momento, Elastic Load Balancing considera que la instancia tiene un estado correcto y comienza a redirigir el tráfico a la instancia nuevamente.

  • TargetGroupAttributes actualiza el valor de retraso de anulación del registro del grupo objetivo a 20 segundos. De forma predeterminada, Elastic Load Balancing espera 300 segundos para completar el proceso de anulación del registro.

Recurso ALBListener de AWS::ElasticLoadBalancingV2::Listener

  • DefaultActions especifica el puerto que el equilibrador de carga escucha, el grupo objetivo al que el equilibrador de carga reenvía las solicitudes y el protocolo utilizado para enrutar solicitudes.

Recurso ApplicationLoadBalancer de AWS::ElasticLoadBalancingV2::LoadBalancer

  • Subnets toma el valor del parámetro de entrada Subnets como la lista de subredes públicas donde se crearán los nodos del equilibrador de carga.

  • SecurityGroup obtiene el ID del grupo de seguridad que funciona como un firewall virtual para los nodos del equilibrador de carga con el objetivo de controlar el tráfico entrante. La función GetAtt se usa para obtener el ID del grupo de seguridad con el nombre lógico ELBSecurityGroup.

Recurso LaunchTemplate de AWS::EC2::LaunchTemplate

  • ImageId toma el valor del parámetro de entrada LatestAmiId como la AMI que se va a utilizar.

  • KeyName adopta el valor del parámetro de entrada KeyName como el par de claves de EC2 que se usará.

  • SecurityGroupIds obtiene el ID del grupo de seguridad con el nombre lógico EC2SecurityGroup que funciona como un firewall virtual para las instancias de EC2 con el objetivo de controlar el tráfico entrante.

  • UserData es un script de configuración que se ejecuta una vez que la instancia está operativa y en ejecución. En este ejemplo, el script instala Apache y crea un archivo index.html.

Recurso NotificationTopic de AWS::SNS::Topic

  • Subscription toma el valor del parámetro de entrada OperatorEmail como la dirección de correo electrónico del destinatario de las notificaciones cuando hay actividades de escalado.

Recurso WebServerGroup de AWS::AutoScaling::AutoScalingGroup

  • MinSize y MaxSize establecen el número mínimo y máximo de instancias de EC2 en el grupo de escalado automático.

  • TargetGroupARNs toma el ARN del grupo de destino con el nombre lógico EC2TargetGroup. A medida que este grupo de escalado automático escala, registra y anula automáticamente las instancias en este grupo de destino.

  • VPCZoneIdentifier toma el valor del parámetro de entrada Subnets como la lista de subredes públicas donde pueden crearse las instancias de EC2.

Paso 1: Lance la pila

Antes de lanzar la pila, compruebe que tiene permisos de AWS Identity and Access Management (IAM) para utilizar todos los siguientes servicios: Amazon EC2, Amazon EC2 Auto Scaling, AWS Systems Manager, Elastic Load Balancing, Amazon SNS y AWS CloudFormation.

El siguiente procedimiento implica cargar la plantilla de pila de ejemplo desde un archivo. Abra un editor de texto en su equipo local y agregue una de las plantillas. Guarde el archivo con el nombre sampleloadbalancedappstack.template.

Para lanzar la plantilla de pila

  1. Inicie sesión en la AWS Management Console y abra la consola de AWS CloudFormation en https://console.aws.amazon.com/cloudformation.

  2. Elija Create stack (Crear pila), With new resources (standard) (Con nuevos recursos [estándar]).

  3. En (Especificar plantilla, seleccione Actualizar un archivo de plantilla y, a continuación, elija Elegir archivo para cargar el archivo sampleloadbalancedappstack.template.

  4. Elija Next (Siguiente).

  5. En la página Especificar detalles de pila, en Nombre de pila, escriba un nombre para la pila (por ejemplo, SampleLoadBalancedAppStack).

  6. En Parámetros, revise los parámetros de la pila y proporcione valores para todos los parámetros que no tengan valores predeterminados, incluidos OperatorEmail, SSHLocation, KeyName, VPC y Subnets.

  7. Seleccione Next (Siguiente) dos veces.

  8. En la página Review, revise y confirme la configuración.

  9. Elija Submit (Enviar).

    Puede ver el estado de la pila en la consola de AWS CloudFormation en la columna Status (Estado). Cuando AWS CloudFormation haya creado correctamente la pila, recibirá el estado CREATE_COMPLETE.

    nota

    Después de crear la pila, debe confirmar la suscripción antes de que la dirección de correo electrónico pueda comenzar a recibir notificaciones. Para obtener más información, consulte Obtener notificaciones de Amazon SNS cuando su grupo de escalado automático escala en la Guía del usuario de Amazon EC2 Auto Scaling.

Paso 2: Eliminar los recursos de ejemplo

Para asegurarse de que no se cobra por recursos de ejemplo no utilizados, elimine la pila.

Para eliminar la pila
  1. En la consola de AWS CloudFormation, elija la pila SampleLoadBalancedAppStack.

  2. Elija Eliminar (Delete).

  3. En el mensaje de confirmación, elija Eliminar pila.

    El estado de SampleLoadBalancedAppStack cambia a DELETE_IN_PROGRESS. Cuando AWS CloudFormation completa la eliminación de la pila, quita la pila de la lista.

Use la plantilla de ejemplo de este tutorial para crear sus propias plantillas de pila. Para obtener más información, consulte Tutorial: Configuración de una aplicación con escalado y equilibrio de carga aplicados en la Guía del usuario de Amazon EC2 Auto Scaling.