Demonstração: Atualizar uma pilha - AWS CloudFormation

Demonstração: Atualizar uma pilha

Com o CloudFormation, você pode atualizar as propriedades dos recursos nas pilhas existentes. Essas mudanças podem variar de simples alterações de configuração, como atualizar o limite do alarme em um alarme do CloudWatch, a alterações mais complexas, como atualizar a Imagem de máquina da Amazon (AMI) em execução em uma instância do Amazon EC2. Muitos dos recursos da AWS em um modelo podem ser atualizados. Nós continuamos a adicionar suporte para outros recursos.

Esta seção demonstra uma simples progressão de atualizações de uma pilha em execução. Ela mostra como o uso de modelos torna possível usar um sistema de controle de versão para a configuração de sua infraestrutura da AWS, da mesma forma que você usa o controle de versão para o software que está executando. Demonstraremos as seguintes etapas:

  1. Criar a pilha inicial: criar uma pilha usando uma AMI básica do Amazon Linux, instalando o Apache Web Server e uma aplicação PHP simples usando os scripts auxiliares do CloudFormation.

  2. Atualizar o aplicativo: atualizar um dos arquivos na aplicação e implantar o software usando o CloudFormation.

  3. Atualizar o tipo de instância: alterar o tipo de instância da instância do Amazon EC2 subjacente.

  4. Atualizar a AMI em uma instância Amazon EC2: alterar a Imagem de Máquina da Amazon (AMI) para a instância do Amazon EC2 na sua pilha.

  5. Adicionar um par de chaves a uma Instância: adicionar um par de chaves do Amazon EC2 à instância e, em seguida, atualizar o grupo de segurança para permitir acesso SSH à instância.

  6. Alterar os recursos da pilha: adicionar e remover recursos da pilha, convertendo-a em uma aplicação com carga balanceada e escalado automaticamente atualizando o modelo.

Um aplicativo simples

Vamos começar com a criação de uma pilha que possamos usar em todo o restante desta seção. Fornecemos um modelo simples, que executa um único aplicativo web de instância PHP hospedado no servidor web Apache e em execução em uma AMI Linux da Amazon.

O servidor Web do Apache, o PHP e o aplicativo PHP simples são instalados pelos scripts auxiliares do CloudFormation instalados por padrão na AMI Linux da Amazon. O snippet de modelo a seguir mostra os metadados que descrevem os pacotes e os arquivos a instalar, neste caso o servidor web Apache e a infraestrutura PHP a partir do repositório Yum da Amazon Linux AMI. O snippet também mostra a seção Services, que garante que o servidor web Apache está em execução. Na seção Properties da definição da instância Amazon EC2, a propriedade UserData contém o script CloudInit que chama cfn-init para instalar os pacotes e arquivos.

"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", : ]]}} } },

A aplicação em si é um exemplo de "Hello, World" muito simples de duas linhas, totalmente definida dentro do modelo. Para um aplicativo do mundo real, os arquivos podem ser armazenados no Amazon S3, no GitHub ou em outro repositório e referenciados a partir do modelo. O CloudFormation pode baixar pacotes (como RPMs ou RubyGems) nem referenciar arquivos individuais e expandir arquivos .zip e .tar para criar os artefatos da aplicação na instância do Amazon EC2.

O modelo habilita e configura o daemon do cfn-hup para ouvir alterações na configuração definida nos metadados da instância Amazon EC2. Usando o daemon cfn-hup, você pode atualizar software de aplicação, como a versão do Apache ou do PHP, ou o próprio arquivo da aplicação PHP no CloudFormation. O snippet a seguir do mesmo recurso do Amazon EC2 no modelo mostra os itens necessários a fim de configurar o cfn-hup para chamar o cfn-init e atualizar o software se todas as alterações nos metadados forem detectadas:

"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 concluir a pilha, o modelo cria um security group do 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 exemplo usa uma única instância Amazon EC2, mas você pode usar os mesmos mecanismos em soluções mais complexas que fazem uso do Elastic Load Balancing e grupos do Amazon EC2 Auto Scaling para gerenciar um conjunto de servidores de aplicações. No entanto, há algumas considerações especiais em relação aos grupos de Auto Scaling. Para obter mais informações, consulte Atualizar grupos de Auto Scaling.

Criar a pilha inicial

Neste exemplo, usaremos o AWS Management Console para criar uma pilha inicial com base no modelo de amostra.

Atenção

A conclusão deste procedimento implantará produtos da AWS dinâmicos. A cobrança será feita de acordo com as tarifas de uso padrão, desde que esses serviços estejam em execução.

Para criar a pilha a partir do AWS Management Console
  1. Copie o modelo anterior e salve-o localmente no sistema como um arquivo de texto. Anote o local, pois será necessário usar o arquivo em uma etapa posterior.

  2. Faça login no console do CloudFormation, em https://console.aws.amazon.com/cloudformation.

  3. Selecione Create New Stack

  4. No assistente Create New Stack (Criar nova pilha), na tela Select Template (Selecionar modelo), digite UpdateTutorial no campo Name (Nome). Na mesma página, selecione Fazer upload de um modelo no Amazon S3, procure o arquivo do qual você fez download na primeira etapa e, em seguida, escolha Próximo.

  5. Na tela Specify Parameters (Especificar parâmetros), na caixa Instance Type (Tipo de instância), digite t1.micro. Em seguida, escolha Próximo.

  6. Na tela Opções, escolha Próximo.

  7. Na tela Revisão, verifique se todas as configurações são as desejadas e, em seguida, clique em Criar.

Depois que o status da pilha for CREATE_COMPLETE, a guia de saída exibirá o URL de seu site. Se você clicar no valor da saída WebsiteURL, verá seu novo aplicativo PHP funcionando.

Atualizar o aplicativo

Agora que implantamos a pilha, vamos atualizar o aplicativo. Vamos fazer uma alteração simples no texto impresso pela aplicação. Para fazer isso, vamos adicionar um comando echo ao arquivo index.php como mostrado neste trecho de modelo:

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

Use um editor de texto para editar manualmente o arquivo de modelo que você salvou localmente.

Agora, vamos atualizar a pilha.

Para atualizar a pilha a partir do AWS Management Console
  1. Faça login no console do CloudFormation, em: https://console.aws.amazon.com/cloudformation.

  2. No painel do CloudFormation, escolha a pilha que você criou anteriormente e, em seguida, escolha Atualizar pilha.

  3. No assistente Atualizar pilha, na tela Selecionar modelo, escolha Carregar um modelo no Amazon S3, selecione o modelo modificado e, em seguida, clique em Próximo.

  4. Na tela Opções, escolha Próximo.

  5. Escolha Próximo, pois a pilha não tem uma política de pilha. Todos os recursos podem ser atualizados sem uma política de sobreposição.

  6. Na tela Revisão, verifique se todas as configurações são as desejadas e, em seguida, clique em Atualizar.

Se você atualizar a pilha a partir do AWS Management Console, perceberá que os parâmetros usados para criar a pilha inicial estão pré-preenchidos na página Parameters (Parâmetros) do assistente Update Stack (Atualizar pilha). Se você usar o comando aws cloudformation update-stack, certifique-se de digitar os mesmos valores para os parâmetros que você usou originalmente para criar a pilha.

Quando a pilha estiver no estado UPDATE_COMPLETE, é possível escolher o valor da saída WebsiteURL novamente para verificar se as alterações do aplicativo tiveram efeito. Por padrão, o daemon cfn-hup é executado a cada 15 minutos, portanto, pode levar até 15 minutos para que o aplicativo seja alterado após a atualização da pilha.

Para ver o conjunto de recursos que foram atualizados, vá para o console do CloudFormation. Na guia Eventos, examine os eventos da pilha. Neste caso específico, os metadados de WebServerInstance da instância do Amazon EC2 foram atualizados, o que fez o CloudFormation reavaliar também os outros recursos (WebServerSecurityGroup) para garantir que não havia outras alterações. Nenhum outro recurso da pilha foi modificado. O CloudFormation só atualiza os recursos da pilha que são afetados por alterações feitas na pilha. Tais alterações podem ser diretas, como alterações de propriedades ou metadados, ou podem ser devidas a dependências ou fluxos de dados por meio de Ref, GetAtt ou outras funções intrínsecas do modelo.

Essa atualização simples ilustra o processo. No entanto, você pode fazer alterações muito mais complexas nos arquivos e pacotes implantados nas instâncias Amazon EC2. Por exemplo, você pode decidir que precisa adicionar o MySQL à instância, junto com suporte PHP para MySQL. Para fazer isso, basta adicionar outros pacotes e arquivos juntamente com todos os serviços adicionais à configuração e, em seguida, atualizar a pilha para implantar as alterações. No snippet de modelo a seguir, as alterações estão destacadas em vermelho:

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

Você pode atualizar os metadados do CloudFormation a fim de atualizar para novas versões dos pacotes usados pela aplicação. Nos exemplos anteriores, a propriedade de versão de cada pacote está vazia, indicando que o cfn-init deve instalar a versão mais recente do pacote.

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

Opcionalmente, você pode especificar uma string de versão para um pacote. Se você alterar a string de versão em chamadas de pilha de atualização subsequentes, a nova versão do pacote será implantada. Veja um exemplo de como usar os números de versão para pacotes do RubyGems. Qualquer pacote compatível com o versionamento pode ter versões específicas.

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

Atualizar grupos de Auto Scaling

Se você estiver usando grupos do Auto Scaling no modelo, ao contrário do que ocorre nos recursos de instância do Amazon EC2, a atualização da aplicação funcionará exatamente da mesma forma. Porém, o CloudFormation não fornece nenhuma sincronização ou serialização em todas as instâncias do Amazon EC2 em um grupo do Auto Scaling. O daemon cfn-hup em cada host será executado de forma independente e atualizará o aplicativo em sua própria programação. Quando você usa o cfn-hup para atualizar a configuração na instância, cada instância executará os hooks do cfn-hup em sua própria programação. Não há coordenação entre as instâncias na pilha. Você deve considerar o seguinte:

  • Se as alterações do cfn-hup estiverem em execução simultânea em todas as instâncias Amazon EC2 no grupo de Auto Scaling, seu serviço pode ficar indisponível durante a atualização.

  • Se as alterações do cfn-hup estiverem em execução em diferentes momentos, as versões antigas e novas do software poderão estar em execução ao mesmo tempo.

Para evitar esses problemas, considere forçar uma atualização contínua nas instâncias no grupo do Auto Scaling. Para obter mais informações, consulte Atributo UpdatePolicy.

Alterar propriedades de recursos

Com o CloudFormation, você pode alterar as propriedades de um recurso existente na pilha. As seções a seguir descrevem várias atualizações que resolvem problemas específicos. No entanto, qualquer propriedade de qualquer recurso que oferece suporte à atualização da pilha pode ser modificada conforme necessário.

Atualizar o tipo de instância

A pilha criada até agora usa uma instância Amazon EC2 t1.micro. Vamos supor que o site recém-criado está recebendo cada vez mais tráfego do que uma instância t1.micro pode processar, e agora você deseja mudar para um tipo de instância Amazon EC2 m1.small. Se a arquitetura do tipo de instância for alterada, a instância será criada com uma AMI diferente. Se você verificar os mapeamentos no modelo, verá que t1.micro e m1.small são as mesmas arquiteturas e usam as mesmas Amazon Linux AMIs.

"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 usar o modelo modificado na seção anterior para alterar o tipo de instância. Como InstanceType era um parâmetro de entrada para o modelo, não é necessário modificá-lo. É possível alterar o valor do parâmetro no Assistente de atualização da pilha na página Especificar parâmetros..

Para atualizar a pilha a partir do AWS Management Console
  1. Faça login no console do CloudFormation, em https://console.aws.amazon.com/cloudformation.

  2. No painel do CloudFormation, escolha a pilha que você criou anteriormente e, em seguida, escolha Atualizar pilha.

  3. No assistente Atualizar pilha, na tela Selecionar modelo, escolha Usar modelo atual e escolha Próximo.

    A página Especificar detalhes é exibida com os parâmetros que foram usados para criar a pilha inicial, pré-preenchidos na seção Specify Parameters (Especificar parâmetros).

  4. Altere o valor da caixa de texto InstanceType de t1.micro para m1.small. Em seguida, escolha Próximo.

  5. Na tela Opções, escolha Próximo.

  6. Escolha Próximo, pois a pilha não tem uma política de pilha. Todos os recursos podem ser atualizados sem uma política de sobreposição.

  7. Na tela Revisão, verifique se todas as configurações são as desejadas e, em seguida, clique em Atualizar.

Você pode alterar dinamicamente o tipo de instância de uma instância do Amazon EC2 baseada no EBS iniciando e parando a instância. O CloudFormation tenta otimizar a alteração atualizando o tipo de instância e reiniciando a instância, de modo que o ID de instância não seja alterado. Quando a instância é reiniciada, no entanto, o endereço IP público da instância é alterado. Para garantir que o endereço IP elástico esteja vinculado corretamente depois da alteração, o CloudFormation também o atualiza. Você pode ver as alterações no console do CloudFormation na guia Eventos.

Para verificar o tipo de instância a partir do AWS Management Console, abra o console do Amazon EC2 e localize sua instância.

Atualizar a AMI em uma instância Amazon EC2

Agora vamos ver como podemos alterar a Imagem de máquina da Amazon (AMI) em execução na instância. Vamos iniciar a alteração da AMI atualizando a pilha para usar um novo tipo de instância do Amazon EC2, como o t2.medium, que é um tipo de instância HVM64.

Como na seção anterior, usaremos nosso modelo existente para alterar o tipo de instância usado pelo nosso exemplo de pilha. No assistente Stack Update, na página Specify Parameters, altere o valor de Instance Type.

Neste caso, não é possível simplesmente iniciar e parar a instância para modificar a AMI. O CloudFormation considera isso uma alteração em uma propriedade imutável do recurso. Para alterar uma propriedade imutável, o CloudFormation precisa iniciar um recurso substituto, neste caso, uma nova instância do Amazon EC2 executando a nova AMI.

Depois que a nova instância está em execução, o CloudFormation atualiza os outros recursos da pilha para que apontem para o novo recurso. Quando todos os novos recursos são criados, o recurso antigo é excluído. Esse processo é conhecido como UPDATE_CLEANUP. Desta vez, você notará que o ID da instância e o URL do aplicativo da instância na pilha foram alterados como resultado da atualização. Os eventos na tabela Event contêm uma descrição "Requested update has a change to an immutable property and hence creating a new physical resource" (A atualização solicitada tem uma alteração em uma propriedade imutável e, portanto, está criando um novo recurso físico) para indicar que um recurso foi substituído.

Se você tem código de aplicativo escrito na AMI que deseja atualizar, pode usar o mesmo mecanismo de atualização de pilha para atualizar a AMI para que ela carregue o novo aplicativo.

Para atualizar a AMI de uma instância na pilha
  1. Crie a nova AMI contendo as alterações no aplicativo ou no sistema operacional. Para obter mais informações, vá para Criar suas próprias AMIs no Manual do usuário do Amazon EC2.

  2. Atualize o modelo para incorporar os novos IDs da AMI.

  3. Atualize a pilha no AWS Management Console, conforme explicado em Atualizar o aplicativo, ou usando o comando aws cloudformation update-stack da AWS.

Ao atualizar a pilha, o CloudFormation detecta que o ID da AMI foi alterado e, em seguida, aciona uma atualização da pilha da mesma maneira que iniciamos a atualização demonstrada acima.

Atualizar a configuração de execução do Amazon EC2 de um grupo de Auto Scaling

Se você estiver usando grupos de Auto Scaling em vez de instâncias Amazon EC2, o processo de atualizar as instâncias em execução será um pouco diferente. Com os recursos de Auto Scaling, a configuração das instâncias Amazon EC2, como o tipo de instância ou o ID da AMI, é encapsulada na configuração de execução do Auto Scaling. Você pode fazer alterações na configuração de execução da mesma maneira que fizemos alterações nos recursos da instância Amazon EC2 nas seções anteriores. No entanto, a alteração da configuração de execução não afeta nenhuma das instâncias do Amazon EC2 em execução no grupo de Auto Scaling. Uma configuração de execução atualizada se aplica apenas a novas instâncias criadas após a atualização.

Se você deseja propagar as alterações na configuração de execução para todas as instâncias em seu grupo de Auto Scaling, pode usar um atributo de atualização. Para obter mais informações, consulte Atributo UpdatePolicy.

Adicionar propriedades de recurso

Até agora, vimos a alteração nas propriedades existentes de um recurso em um modelo. Também é possível adicionar propriedades que não foram originalmente especificadas no modelo. Para ilustrar, vamos adicionar um par de chaves do Amazon EC2 a uma instância do EC2 existente e, em seguida, abrir a porta 22 no Security Group do Amazon EC2 para que você possa usar o Secure Shell (SSH) para acessar a instância.

Adicionar um par de chaves a uma Instância

Para adicionar acesso SSH a uma instância Amazon EC2 existente
  1. Adicione outros dois parâmetros ao modelo para transmitir o nome de um par de chaves do Amazon EC2 existente e a localização do SSH.

    "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. Adicione a propriedade KeyName à instância Amazon EC2.

    "WebServerInstance": { "Type" : "AWS::EC2::Instance", : "Properties": { : "KeyName" : { "Ref" : "KeyName" }, : } },
  3. Adicione a porta 22 e a localização do SSH às regras de entrada referentes ao security group do 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. Atualize a pilha no AWS Management Console, conforme explicado em Atualizar o aplicativo, ou usando o comando aws cloudformation update-stack da AWS.

Alterar os recursos da pilha

Como as necessidades das aplicações podem mudar com o tempo, o CloudFormation permite que você altere o conjunto de recursos que compõem a pilha. Para demonstrar, vamos usar o aplicativo de instância única contido em Adicionar propriedades de recurso e convertê-lo em um aplicativo dimensionado automaticamente e com balanceamento de carga atualizando a pilha.

Isso irá criar um aplicativo PHP simples de única instância usando um endereço IP elástico. Agora, vamos transformá-lo em um aplicativo altamente disponível, dimensionado automaticamente e com balanceamento de carga alterando os recursos durante uma atualização.

  1. Adicione um recurso 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. Converta a instância EC2 no modelo em uma configuração de execução do Auto Scaling. As propriedades são idênticas, por isso precisamos alterar somente o nome do tipo de:

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

    para:

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

    Para termos clareza no modelo, alteramos o nome do recurso de WebServerInstance para LaunchConfig; portanto, você precisará atualizar o nome do recurso referenciado pelo cfn-init e cfn-hup (basta pesquisar por WebServerInstance e substituir por LaunchConfig, exceto para cfn-signal). Para cfn-signal, você precisará sinalizar o grupo do Auto Scaling (WebServerGroup), não a instância, como mostrado no seguinte snippet:

    "# 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. Adicione um recurso de grupo do Auto Scaling.

    "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. Atualize a definição Security Group para bloquear o tráfego para as instâncias do load balancer.

    "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. Atualize as saídas para retornar o nome de DNS do Elastic Load Balancer como o local do aplicativo a partir de:

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

    para:

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

Para referência, a amostra a seguir mostra o modelo completo. Se você usar esse modelo para atualizar a pilha, converterá a instância única simples em uma aplicação altamente disponível, Multi-AZ, com balanceamento de carga e escalada automaticamente. Somente os recursos que precisam ser atualizados serão alterados, assim, se houvesse algum armazenamento de dados para esse aplicativo, os dados teriam permanecido intactos. Agora, você pode usar o CloudFormation para expandir ou aprimorar as pilhas à medida que as suas necessidades mudam.

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

Considerações sobre disponibilidade e impacto

Diferentes propriedades têm diferentes impactos nos recursos na pilha. Você pode usar o CloudFormation para atualizar qualquer propriedade. No entanto, antes de fazer qualquer alteração, você deve considerar estas perguntas:

  1. Como a atualização afeta o recurso em si? Por exemplo, a atualização de um limite de alarme deixará o alarme inativo durante a atualização. Como vimos, a alteração do tipo de instância exige que a instância seja parada e reiniciada. O CloudFormation usa as ações de atualizar ou modificar nos recursos subjacentes para alterá-los. Para compreender o impacto de atualizações, é necessário verificar a documentação dos recursos específicos.

  2. A alteração é mutável ou imutável? Algumas alterações nas propriedades de recursos, como alteração da AMI em uma instância do Amazon EC2, não são compatíveis com os serviços subjacentes. No caso de alterações mutáveis, o CloudFormation usará APIs do tipo Atualizar ou Modificar para os recursos subjacentes. Para alterações de propriedade imutáveis, o CloudFormation criará novos recursos com as propriedades atualizadas e, em seguida, os vinculará à pilha antes de excluir os recursos antigos. Embora o CloudFormation tente reduzir o tempo de inatividade dos recursos de pilha, a substituição de um recurso é um processo de várias etapas e levará tempo. Durante a reconfiguração da pilha, seu aplicativo não estará totalmente operacional. Por exemplo, ele pode não ser capaz de atender a solicitações ou acessar um banco de dados.

Recursos relacionados

Para mais informações sobre como usar o CloudFormation para iniciar aplicativos e sobre a integração com outros serviços de configuração e implantação, como o Puppet e o Opscode Chef, consulte os seguintes whitepapers:

O modelo usado durante essa seção é uma aplicação PHP "Hello, World". A biblioteca de modelos também tem um modelo de exemplo do Amazon ElastiCache que mostra como integrar um aplicativo PHP ao ElasticCache usando cfn-hup e cfn-init para responder a alterações na configuração do cluster de cache do Amazon ElastiCache, o que pode ser feito por Update Stack.