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 det3.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.
ELBSecurityGroup
de recurso 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.
EC2SecurityGroup
de recurso 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 deSSHLocation
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ógicoELBSecurityGroup
.
Recurso EC2TargetGroup
de AWS::ElasticLoadBalancingV2::TargetGroup
-
Port
,Protocol
yHealthCheckProtocol
especifican el puerto de instancia de EC2 (80) y el protocolo (HTTP) a los que elApplicationLoadBalancer
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 entradaSubnets
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ógicoELBSecurityGroup
.
Recurso LaunchTemplate
de AWS::EC2::LaunchTemplate
-
ImageId
toma el valor del parámetro de entradaLatestAmiId
como la AMI que se va a utilizar. -
KeyName
adopta el valor del parámetro de entradaKeyName
como el par de claves de EC2 que se usará. -
SecurityGroupIds
obtiene el ID del grupo de seguridad con el nombre lógicoEC2SecurityGroup
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 entradaOperatorEmail
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
yMaxSize
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ógicoEC2TargetGroup
. 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 entradaSubnets
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
-
Inicie sesión en la AWS Management Console y abra la consola de AWS CloudFormation en https://console.aws.amazon.com/cloudformation
. -
Elija Create stack (Crear pila), With new resources (standard) (Con nuevos recursos [estándar]).
-
En (Especificar plantilla, seleccione Actualizar un archivo de plantilla y, a continuación, elija Elegir archivo para cargar el archivo
sampleloadbalancedappstack.template
. -
Elija Siguiente.
-
En la página Especificar detalles de pila, en Nombre de pila, escriba un nombre para la pila (por ejemplo,
SampleLoadBalancedAppStack
). -
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.
-
Seleccione Next (Siguiente) dos veces.
-
En la página Revisar, revise y confirme la configuración.
-
Seleccione Enviar.
Puede ver el estado de la pila en la consola de AWS CloudFormation en la columna 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
-
En la consola de AWS CloudFormation, elija la pila SampleLoadBalancedAppStack.
-
Elija Eliminar.
-
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.