Tutorial: Actualización de una pila - AWS CloudFormation

Tutorial: Actualización de una pila

Con AWS CloudFormation, puede actualizar las propiedades de los recursos de sus pilas existentes. Estos cambios pueden variar desde sencillos cambios de configuración, como actualizar el umbral de la alarma en una alarma de CloudWatch, para realizar cambios más complejos, como la actualización de la imagen de Amazon Machine (AMI) que se ejecuta en una instancia Amazon EC2. Se pueden actualizar muchos de los recursos de AWS en una plantilla y seguimos agregando soporte para más.

Esta sección explica con detalle una sencilla progresión de las actualizaciones de una pila. Muestra cómo el uso de las plantillas permite utilizar un sistema de control de versiones para la configuración de su infraestructura de AWS, igual que usted usa el control de versiones para el software que está ejecutando. Le explicaremos con detalle los pasos siguientes:

  1. Cree la pila inicial: cree una pila con una AMI de Amazon Linux básica, e instale el servidor web Apache y una sencilla aplicación PHP con los scripts auxiliares de AWS CloudFormation.

  2. Actualizar la aplicación: actualice uno de los archivos en la aplicación e implemente el software con CloudFormation.

  3. Actualice el tipo de instancia: cambie el tipo de instancia de la instancia de Amazon EC2 subyacente.

  4. Actualice la AMI en una instancia Amazon EC2: cambie la Imagen de máquina de Amazon (AMI) para la instancia de Amazon EC2 en la pila.

  5. Añada un par de claves a una instancia: agregue un par de claves de Amazon EC2 a la instancia y, a continuación, actualice el grupo de seguridad para permitir el acceso de SSH a la instancia.

  6. Cambie los recursos de la pila: agregue y elimine los recursos de la pila, y conviértalos a una aplicación de escalado automático y con equilibrador de carga mediante la actualización de la plantilla.

Una aplicación sencilla

Empezaremos creando una pila que podemos utilizar a lo largo del resto de esta sección. Hemos proporcionado una sencilla plantilla que lanza una aplicación web PHP de una sola instancia alojada en el servidor web Apache y que se ejecuta en una AMI de Amazon Linux.

El servidor web Apache, PHP y la aplicación PHP sencilla están instalados por los scripts auxiliares de CloudFormation que vienen instalados de forma predeterminada en la AMI de Amazon Linux. El siguiente fragmento de la plantilla muestra los metadatos que describe los paquetes y archivos para instalar, en este caso, el servidor web Apache y la infraestructura PHP desde el repositorio Yum para la AMI de Amazon Linux. El fragmento también muestra la sección Servicios, que garantiza que el servidor web Apache se está ejecutando. En la sección Propiedades de la definición de la instancia Amazon EC2, la propiedad UserData contiene el script CloudInit que llama a cfn-init para instalar los paquetes y archivos.

"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "echo '<p>", { "Ref" : "WelcomeMessage" }, "</p>';\n", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, }, : "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" } } } } } }, "Properties": { : "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash\n", "yum install -y aws-cfn-bootstrap\n", : "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", : ]]}} } },

La aplicación en sí es un ejemplo de dos líneas, del tipo “Hola, mundo”, que se define completamente en la plantilla. En el caso de una aplicación real, los archivos pueden almacenarse en Amazon S3, GitHub o en otro repositorio y consultarse desde la plantilla. CloudFormation puede descargar paquetes (como RPM o RubyGems) y los archivos individuales de referencia y expandir archivos .zip y .tar para crear los artefactos de aplicación en la instancia de Amazon EC2.

La plantilla permite y configura el daemon cfn-hup para escuchar los cambios de la configuración definidos en los metadatos de la instancia Amazon EC2. Al utilizar el daemon cfn-hup, puede actualizar el software de aplicación, como la versión de Apache o PHP, o puede actualizar el archivo de la aplicación PHP de AWS CloudFormation. El siguiente fragmento del mismo recurso de Amazon EC2 de la plantilla muestra los elementos necesarios para configurar cfn-hup y así llamar al cfn-init para actualizar, si se detecta un cambio en los metadatos:

"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { : "files" : { : "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackName" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, : }, "Properties": { : "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ : "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n", "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n", : ]]}} } },

Para completar la pila, la plantilla crea un grupo de seguridad de Amazon EC2.

{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "InstanceType" : { "Description" : "WebServer EC2 instance type", "Type" : "String", "Default" : "t2.small", "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge" ], "ConstraintDescription" : "must be a valid EC2 instance type." } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} } }, "Resources" : { "WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "Comment" : "Install a simple PHP application", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackId" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum install -y aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n", "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT5M" } } }, "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} ] } } }, "Outputs" : { "WebsiteURL" : { "Description" : "Application URL", "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] } } } }

Este ejemplo utiliza una única instancia de Amazon EC2, pero puede utilizar los mismos mecanismos en soluciones más complejas que usan Elastic Load Balancing y grupos de Amazon EC2 Auto Scaling para administrar una colección de servidores de aplicaciones. Existen, sin embargo, algunas consideraciones especiales para los grupos de Auto Scaling. Para obtener más información, consulte Actualización de grupos de Auto Scaling.

Cree la pila inicial

Para este ejemplo, vamos a utilizar la AWS Management Console para crear una pila inicial con la plantilla de ejemplo.

aviso

Completar este procedimiento implementará en directo los servicios de AWS. Se le cobrarán las tarifas de uso estándar, siempre que estos servicios estén ejecutándose.

Para crear la pila de la AWS Management Console
  1. Copie la plantilla anterior y guárdela localmente en el sistema como un archivo de texto. Anote la ubicación, porque necesitará usar el archivo en el siguiente paso.

  2. Inicie sesión en la consola de CloudFormation, en https://console.aws.amazon.com/cloudformation.

  3. Elija Create New Stack.

  4. En el asistente Create New Stack (Crear una pila nueva), en la pantalla Select Template (Seleccionar plantilla), escriba UpdateTutorial en el campo Name (Nombre). En la misma página, seleccione Upload a template to Amazon S3 (Cargar una plantilla en Amazon S3) y busque el archivo que ha descargado en el primer paso; a continuación, elija Next (Siguiente).

  5. En la pantalla Specify Parameters (Especificar parámetros), en el cuadro Instance Type (Tipo de instancia), escriba t1.micro. A continuación, elija Siguiente.

  6. En la pantalla Options (Opciones), elija Next (Siguiente).

  7. En la pantalla Review (Revisar), compruebe que todos los ajustes sean de su agrado y, a continuación, elija Create (Crear).

Cuando el estado de la pila sea CREATE_COMPLETE, la pestaña de salida mostrará la URL de su sitio web. Si selecciona el valor de salida de WebsiteURL, verá su nueva aplicación PHP en marcha.

Actualizar la aplicación

Ahora que hemos implementado la pila, vamos a actualizar la aplicación. Haremos un sencillo cambio en el texto impreso por la aplicación. Para ello, agregaremos un comando echo para el archivo index.php tal y como se muestra en este fragmento de la plantilla:

"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { : "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "echo '<p>Updated version via UpdateStack</p>';\n ", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, : } },

Utilice un editor de texto para modificar manualmente el archivo de plantilla que guardó localmente.

Ahora, vamos a actualizar la pila.

Para actualizar la pila de la AWS Management Console
  1. Inicie sesión en la consola de AWS CloudFormation, en: https://console.aws.amazon.com/cloudformation.

  2. En el panel de AWS CloudFormation, seleccione la pila que ha creado anteriormente y, a continuación, elija Update Stack (Actualizar pila).

  3. En el asistente Update Stack (Actualizar pila), en la pantalla Select Template (Seleccionar plantilla), seleccione Upload a template to Amazon S3 (Actualizar plantilla en Amazon S3), seleccione la plantilla modificada y, a continuación, elija Next (Siguiente).

  4. En la pantalla Options (Opciones), elija Next (Siguiente).

  5. Elija Next (Siguiente) porque la pila no tiene una política de pila. Todos los recursos se pueden actualizar sin una política de anulaciones.

  6. En la pantalla Review (Revisar), compruebe que todos los ajustes sean de su agrado y, a continuación, elija Update (Actualizar).

Si actualiza la pila de la AWS Management Console, observará que los parámetros que se usaron para crear la pila inicial se cumplimentaron previamente en la página Parameters (Parámetros) del asistente Update Stack (Actualizar pila). Si utiliza el comando aws cloudformation update-stack, asegúrese de escribir los mismos valores para los parámetros que utilizó originalmente para crear la pila.

Cuando la pila está en el estado UPDATE_COMPLETE, puede seleccionar el valor de salida de WebsiteURL de nuevo, para verificar si han entrado en vigor los cambios de la aplicación. De forma predeterminada, el daemon cfn-hup se ejecuta cada 15 minutos, por lo que la aplicación puede tardar hasta 15 minutos en cambiar una vez actualizado la pila.

Para ver el conjunto de recursos que se actualizaron, vaya a la consola de AWS CloudFormation. En la pestaña Events (Eventos), examine los eventos de pila. En este caso concreto, se actualizaron los metadatos de la instancia WebServerInstance de Amazon EC2, lo que provocó que AWS CloudFormation también revaluara los demás recursos (WebServerSecurityGroup) para asegurarse de que no haya otros cambios. Ninguno de los demás recursos de pila se han modificado. AWS CloudFormation actualizará solo los recursos de la pila que se vean afectados por cualquier cambio en la pila. Estos cambios pueden ser directos, como los cambios de metadatos o la propiedad, o pueden deberse a dependencias o flujos de datos a través de Ref, GetAtt, u otras funciones de plantilla intrínsecas.

Esta sencilla actualización ilustra el proceso; sin embargo, puede realizar cambios mucho más complejos en los archivos y paquetes implementados en las instancias Amazon EC2. Por ejemplo, puede decidir que necesita añadir MySQL a la instancia, junto con el soporte de PHP para MySQL. Para hacerlo, solo tiene que añadir los archivos y paquetes adicionales junto con los servicios adicionales a la configuración y, luego, actualizar la pila para implementar los cambios. En el siguiente fragmento de plantilla, los cambios están marcados en rojo:

"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "Comment" : "Install a simple PHP application", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [], "php-mysql" : [], "mysql-server" : [], "mysql-libs" : [], "mysql" : [] } }, : "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]}, "mysqld" : { "enabled" : "true", "ensureRunning" : "true" } } } } } }, "Properties": { : } }

Puede actualizar los metadatos de CloudFormation de modo que se actualicen según las nuevas versiones de los paquetes que utiliza la aplicación. En los ejemplos anteriores, la propiedad de la versión de cada paquete está vacía, lo que indica que cfn-init debería instalar la última versión del paquete.

"packages" : { "yum" : { "httpd" : [], "php" : [] }

Si lo desea, puede especificar una cadena de versión de un paquete. Si cambia la cadena de versión en las posteriores llamadas de actualización de pila, se implementará la nueva versión del paquete. A continuación se muestra un ejemplo de cómo utilizar los números de versión para paquetes RubyGems. Cualquier paquete compatible con control de versiones puede tener versiones específicas.

"packages" : { "rubygems" : { "mysql" : [], "rubygems-update" : ["1.6.2"], "rake" : ["0.8.7"], "rails" : ["2.3.11"] } }

Actualización de grupos de Auto Scaling

Si está utilizando los grupos de escalado automático en la plantilla, en lugar de los recursos de instancias de Amazon EC2, la actualización de la aplicación funcionará exactamente igual; sin embargo, AWS CloudFormation no ofrece ninguna sincronización ni serialización entre las instancias de Amazon EC2 en un grupo de escalado automático. El daemon cfn-hup de cada host se ejecutará de forma independiente y actualizará la aplicación según su propia programación. Al utilizar cfn-hup para actualizar la configuración en la instancia, cada instancia ejecutará enlaces de cfn-hup según su propia programación; no hay coordinación entre las instancias de la pila. Debe tener en cuenta lo siguiente:

  • Si se ejecutan todos los cambios de cfn-hup en todas las instancias Amazon EC2 del grupo de Auto Scaling al mismo tiempo, su servicio podría no estar disponible durante la actualización.

  • Si se ejecutan los cambios de cfn-hup en diferentes momentos, puede que estén ejecutándose versiones antiguas y nuevas del software al mismo tiempo.

Para evitar estos problemas, considere la posibilidad de forzar una actualización continua en las instancias del grupo de Auto Scaling. Para obtener más información, consulte Atributo UpdatePolicy.

Cambio de propiedades de recurso

Con AWS CloudFormation, puede cambiar las propiedades de un recurso existente en la pila. En la siguiente sección se describen diversas actualizaciones que solucionan problemas específicos; sin embargo, cualquier propiedad de cualquier recurso que admite la actualización en la pila se puede modificar según sea necesario.

Actualice el tipo de instancia

La pila que hemos creado utiliza hasta ahora una instancia Amazon EC2 t1.micro. Supongamos que el sitio web recién creado obtiene más tráfico de lo que puede controlar una instancia t1.micro y ahora desea pasar a un tipo de instancia Amazon EC2 m1.small. Si la arquitectura del tipo de instancia cambia, la instancia se creará con una AMI diferente. Si consulta los mapeos de la plantilla, verá que tanto la t1.micro como la m1.small son la misma arquitectura y usan las mismas AMI de Amazon Linux.

"Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} }

Vamos a utilizar la plantilla que hemos modificado en la sección anterior para cambiar el tipo de instancia. Dado que InstanceType fue un parámetro de entrada de la plantilla, no es necesario modificar la plantilla; se puede cambiar el valor del parámetro en el asistente de actualización de la pila, en la página Specify Parameters (Especificar parámetros).

Para actualizar la pila de la AWS Management Console
  1. Inicie sesión en la consola de AWS CloudFormation, en https://console.aws.amazon.com/cloudformation.

  2. En el panel de CloudFormation, seleccione la pila que ha creado anteriormente y, a continuación, elija Update Stack (Actualizar pila).

  3. En el asistente Update Stack (Actualizar pila), en la pantalla Select Template (Seleccionar plantilla), seleccione Use current template (Usar plantilla actual) y, a continuación, elija Next (Siguiente).

    Aparecerá la página Specify Details (Especificar detalles) con los parámetros que se usaron para crear la pila inicial y que se rellenaron previamente en la sección Specify Parameters (Especificar parámetros).

  4. Cambie el valor del cuadro de texto InstanceType (Tipo de instancia) de t1.micro a m1.small. A continuación, elija Siguiente.

  5. En la pantalla Options (Opciones), elija Next (Siguiente).

  6. Elija Next (Siguiente) porque la pila no tiene una política de pila. Todos los recursos se pueden actualizar sin una política de anulaciones.

  7. En la pantalla Review (Revisar), compruebe que todos los ajustes sean de su agrado y, a continuación, elija Update (Actualizar).

Puede cambiar dinámicamente el tipo de instancia de una instancia de Amazon EC2 respaldada por EBS para iniciar y detener la instancia. AWS CloudFormation intenta optimizar el cambio actualizando el tipo de instancia y reiniciando la instancia, por lo que el ID de instancia no cambia. Cuando la instancia se reinicia, sin embargo, la dirección IP pública de la instancia sí cambia. Para garantizar que se ha vinculado correctamente la dirección IP elástica tras el cambio, AWS CloudFormation también actualizará la dirección IP elástica. Puede ver los cambios en la consola AWS CloudFormation en la pestaña de eventos.

Para comprobar el tipo de instancia desde AWS Management Console, abra la consola de Amazon EC2 y busque allí su instancia.

Actualice la AMI en una instancia Amazon EC2

Ahora veamos cómo podemos cambiar la imagen de máquina de Amazon (AMI) que se ejecutan en la instancia. Vamos a iniciar el cambio de AMI actualizando la pila para usar un nuevo tipo de instancia Amazon EC2, como t2.medium, que es un tipo de instancia HVM64.

Como en la sección anterior, vamos a utilizar nuestra plantilla existente para cambiar el tipo de instancia que usa nuestra plantilla de ejemplo. En el asistente de actualización de pila, en la página Specify Parameters, cambie el valor del tipo de instancia.

En este caso, no podemos iniciar y detener la instancia para modificar la AMI; AWS CloudFormation lo considera un cambio de una propiedad inmutable del recurso. Para cambiar una propiedad inmutable, AWS CloudFormation debe lanzar un recurso de sustitución; en este caso, una nueva instancia de Amazon EC2 que ejecuta la nueva AMI.

Cuando está en ejecución la nueva instancia, AWS CloudFormation actualiza el resto de recursos de la pila para que remita al nuevo recurso. Cuando se crean todos los nuevos recursos, se elimina el recurso anterior, un proceso conocido como UPDATE_CLEANUP. En este momento, podrá observar que el ID de instancia y el URL de la aplicación de la instancia de la pila han cambiado como resultado de la actualización. Los acontecimientos de la tabla de eventos contienen una descripción “La actualización solicitada tiene un cambio de una propiedad inmutable y, por tanto, se ha creado un nuevo recurso físico” para indicar que se reemplazó un recurso.

Si tiene un código de aplicación escrito en la AMI que desea actualizar, puede utilizar el mismo mecanismo de actualización de pila para actualizar la AMI y así cargar su nueva aplicación.

Para actualizar la AMI en una instancia de la pila
  1. Cree nuevas AMI que contengan los cambios del sistema operativo o su aplicación. Para obtener más información, consulte Creación de su propia AMI en la Guía del usuario de Amazon EC2 para instancias de Linux.

  2. Actualice la plantilla para incorporar los nuevos ID de AMI.

  3. Actualice la pila, ya sea desde la AWS Management Console según lo explicado en Actualizar la aplicación o mediante el comando de AWS aws cloudformation update-stack.

Al actualizar la pila, CloudFormation detecta que el ID de AMI ha cambiado y, a continuación, se activa una actualización de la pila de la misma forma que iniciamos el anterior.

Actualice la configuración de lanzamiento de Amazon EC2 para un grupo de Auto Scaling

Si está utilizando grupos de Auto Scaling en lugar de instancias Amazon EC2, el proceso de actualización de las instancias en ejecución es algo diferente. Con los recursos de Auto Scaling, la configuración de las instancias Amazon EC2, como el tipo de instancia o el ID de AMI se encapsula en la configuración de lanzamiento de Auto Scaling. Puede realizar cambios en la configuración de lanzamiento de la misma forma que hemos realizado cambios en los recursos de instancias Amazon EC2 en las secciones anteriores. Sin embargo, cambiar la configuración de lanzamiento no afecta a ninguna de las instancias Amazon EC2 que se ejecuten en el grupo de Auto Scaling. Una configuración de lanzamiento actualizada se aplica únicamente a las nuevas instancias que se crean después de la actualización.

Si desea propagar el cambio de su configuración de lanzamiento a todas las instancias de su grupo de Auto Scaling, puede utilizar un atributo de actualización. Para obtener más información, consulte Atributo UpdatePolicy.

Añadido de propiedades de recursos

Hasta ahora, hemos examinado el cambio de propiedades existentes de un recurso en una plantilla. También puede agregar propiedades que no estaban especificadas originalmente en la plantilla. Para ilustrarlo, vamos a agregar un par de claves de Amazon EC2 a una instancia de EC2 existente y, a continuación, abrir el puerto 22 en el grupo de seguridad de Amazon EC2, para que pueda utilizar Secure Shell (SSH) para acceder a la instancia.

Añada un par de claves a una instancia

Para añadir el acceso SSH a una instancia Amazon EC2 existente
  1. Añada dos parámetros adicionales a la plantilla para transmitirlo en el nombre de una ubicación SSH y un par de claves Amazon EC2 existentes.

    "Parameters" : { "KeyName" : { "Description" : "Name of an existing Amazon EC2 key pair for SSH access", "Type": "AWS::EC2::KeyPair::KeyName" }, "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", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." } : },
  2. Añada la propiedad KeyName a la instancia Amazon EC2.

    "WebServerInstance": { "Type" : "AWS::EC2::Instance", : "Properties": { : "KeyName" : { "Ref" : "KeyName" }, : } },
  3. Añada el puerto 22 y la ubicación de SSH a las reglas de entrada del grupo de seguridad de Amazon EC2.

    "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP and SSH", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}}, {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} ] } },
  4. Actualice la pila, ya sea desde la AWS Management Console según lo explicado en Actualizar la aplicación o mediante el comando de AWS aws cloudformation update-stack.

Cambie los recursos de la pila

Las necesidades de las aplicaciones pueden variar con el tiempo y AWS CloudFormation le permite cambiar el conjunto de recursos que componen la pila. Para demostrarlo, tomaremos la aplicación de instancia única de Añadido de propiedades de recursos y la convertiremos en una aplicación autoescalada y con balanceo de carga actualizando la pila.

Se creará una sencilla aplicación PHP de una sola instancia usando una dirección IP elástica. Ahora convertiremos la aplicación en una aplicación autoescalada con balanceo de carga y de gran disponibilidad, a base de cambiar sus recursos durante una actualización.

  1. Añada un recurso de Elastic Load Balancer.

    "ElasticLoadBalancer" : { "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", "Properties" : { "CrossZone" : "true", "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LBCookieStickinessPolicy" : [ { "PolicyName" : "CookieBasedPolicy", "CookieExpirationPeriod" : "30" } ], "Listeners" : [ { "LoadBalancerPort" : "80", "InstancePort" : "80", "Protocol" : "HTTP", "PolicyNames" : [ "CookieBasedPolicy" ] } ], "HealthCheck" : { "Target" : "HTTP:80/", "HealthyThreshold" : "2", "UnhealthyThreshold" : "5", "Interval" : "10", "Timeout" : "5" } } }
  2. Cambie la instancia de EC2 de la plantilla a una configuración de lanzamiento de Auto Scaling. Las propiedades son idénticas, por lo que solo es necesario cambiar el nombre de tipo:

    "WebServerInstance": { "Type" : "AWS::EC2::Instance",

    a:

    "LaunchConfig": { "Type" : "AWS::AutoScaling::LaunchConfiguration",

    Para tener una plantilla clara, hemos cambiado el nombre del recurso de WebServerInstance a LaunchConfig, por lo que habrá que actualizar el nombre de los recursos a los que hagan referencia cfn-init y cfn-hup (basta con buscar WebServerInstance y reemplazarlo por LaunchConfig, salvo cfn-signal). Para cfn-signal, tendrá que marcar el grupo de Auto Scaling (WebServerGroup), no la instancia, tal y como se muestra en el siguiente fragmento:

    "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerGroup ", " --region ", { "Ref" : "AWS::Region" }, "\n"
  3. Agregue un recurso de grupo de escalado automático.

    "WebServerGroup" : { "Type" : "AWS::AutoScaling::AutoScalingGroup", "Properties" : { "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, "MinSize" : "1", "DesiredCapacity" : "1", "MaxSize" : "5", "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ] }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT15M" } }, "UpdatePolicy": { "AutoScalingRollingUpdate": { "MinInstancesInService": "1", "MaxBatchSize": "1", "PauseTime" : "PT15M", "WaitOnResourceSignals": "true" } } }
  4. Actualice la definición de grupo de seguridad para cerrar el tráfico a las instancias desde el balanceador de carga.

    "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80 locked down to the ELB and SSH access", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]}, "SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]}}, {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} ] } }
  5. Actualice las salidas para devolver el nombre DNS de Elastic Load Balancer como ubicación de la aplicación de:

    "WebsiteURL" : { "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]]}, "Description" : "Application URL" }

    a:

    "WebsiteURL" : { "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]]}, "Description" : "Application URL" }

Si desea consultar una referencia, la siguiente muestra enseña la plantilla completa. Si utiliza esta plantilla para actualizar la pila, convertirá su aplicación sencilla de una sola instancia en una aplicación de alta disponibilidad, Multi-AZ, de escalado automático y con equilibrador de carga. Solo se modificarán los recursos que deban actualizarse, por lo que de haber habido almacenes de datos para esta aplicación, los datos habrían permanecido intactos. Ahora, puede usar AWS CloudFormation para incrementar o mejorar sus pilas a medida que cambien sus necesidades.

{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "KeyName": { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance", "Type": "AWS::EC2::KeyPair::KeyName", "ConstraintDescription" : "must be the name of an existing EC2 KeyPair." }, "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", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "InstanceType" : { "Description" : "WebServer EC2 instance type", "Type" : "String", "Default" : "t2.small", "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge" ], "ConstraintDescription" : "must be a valid EC2 instance type." } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} } }, "Resources" : { "ElasticLoadBalancer" : { "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", "Properties" : { "CrossZone" : "true", "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LBCookieStickinessPolicy" : [ { "PolicyName" : "CookieBasedPolicy", "CookieExpirationPeriod" : "30" } ], "Listeners" : [ { "LoadBalancerPort" : "80", "InstancePort" : "80", "Protocol" : "HTTP", "PolicyNames" : [ "CookieBasedPolicy" ] } ], "HealthCheck" : { "Target" : "HTTP:80/", "HealthyThreshold" : "2", "UnhealthyThreshold" : "5", "Interval" : "10", "Timeout" : "5" } } }, "WebServerGroup" : { "Type" : "AWS::AutoScaling::AutoScalingGroup", "Properties" : { "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, "MinSize" : "1", "DesiredCapacity" : "1", "MaxSize" : "5", "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ] }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT15M" } }, "UpdatePolicy": { "AutoScalingRollingUpdate": { "MinInstancesInService": "1", "MaxBatchSize": "1", "PauseTime" : "PT15M", "WaitOnResourceSignals": "true" } } }, "LaunchConfig": { "Type" : "AWS::AutoScaling::LaunchConfiguration", "Metadata" : { "Comment" : "Install a simple PHP application", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "echo 'Updated version via UpdateStack';\n ", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackId" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r LaunchConfig ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "KeyName" : { "Ref" : "KeyName" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum install -y aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource LaunchConfig ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n", "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerGroup ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} } }, "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80 locked down to the ELB and SSH access", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]},"SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]}}, {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} ] } } }, "Outputs" : { "WebsiteURL" : { "Description" : "Application URL", "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]] } } } }

Consideraciones sobre el impacto y la disponibilidad

Las distintas propiedades afectan de forma diferente a los recursos de la pila. Puede utilizar CloudFormation para actualizar cualquier propiedad; no obstante, antes de realizar cambios, debe tener en cuenta estas preguntas:

  1. ¿Cómo afecta la actualización al propio recurso? Por ejemplo, la actualización de un umbral de alarma inutilizará la alarma durante la actualización. Como hemos visto, cambiar el tipo de instancia requiere detener y reiniciar la instancia. AWS CloudFormation utiliza las acciones de actualización o modificación para que los recursos subyacentes realicen cambios en los recursos. Para comprender el impacto de las actualizaciones, debería comprobar la documentación de los recursos específicos.

  2. ¿Es el cambio mutable o inmutable? Algunos cambios en las propiedades de recursos, como, por ejemplo, el cambio de la AMI en una instancia de Amazon EC2, no son compatibles con los servicios subyacentes. En el caso de cambios mutables, CloudFormation utilizará las API de tipo actualización o modificación para los recursos subyacentes. Para cambios de propiedad inmutables, CloudFormation creará nuevos recursos con las propiedades actualizadas y, a continuación, vincularlas a la pila antes de eliminar los antiguos recursos. Aunque CloudFormation intenta reducir el tiempo de inactividad de los recursos de la pila; sustituir un recurso es un proceso de varios pasos y llevará tiempo. Durante la reconfiguración de pila, su aplicación no estará totalmente operativa. Por ejemplo, es posible que no pueda atender a las solicitudes ni acceder a una base de datos.

Recursos relacionados

Para obtener más información acerca del uso de CloudFormation para iniciar las aplicaciones y de la integración con otros servicios de configuración e implementación como Puppet y Opscode Chef, consulte los siguientes documentos técnicos:

La plantilla utilizada en esta sección es una aplicación PHP del tipo “Hola, mundo”. La biblioteca de plantillas también tiene una muestra de plantilla de Amazon ElastiCache que muestra cómo integrar una aplicación PHP mediante el uso de cfn-hup y cfn-init por parte de ElasticCache, para responder a los cambios de la configuración del clúster de caché de Amazon ElastiCache, que puede llevar a cabo Update Stack.