

# Refatoração de pilhas
<a name="stack-refactoring"></a>

Com a refatoração de pilhas, é possível reorganizar os recursos em suas pilhas do CloudFormation enquanto preserva as propriedades e os dados dos recursos existentes. É possível mover recursos entre pilhas, dividir pilhas grandes em pilhas menores ou combinar várias pilhas em uma única pilha.

**Topics**
+ [Como a refatoração de pilhas funciona](#stack-refactoring-overview)
+ [Considerações sobre refatoração de pilhas](#stack-refactoring-considerations)
+ [Pré-requisitos](#stack-refactoring-prerequisites)
+ [Refatorar pilhas (console)](#stack-refactoring-console)
+ [Refatorar pilhas (AWS CLI)](#stack-refactoring-cli)
+ [Limitações do recurso](#stack-refactoring-resource-limitations)

## Como a refatoração de pilhas funciona
<a name="stack-refactoring-overview"></a>

A refatoração de pilhas envolve as seguintes fases:

1. **Avaliação da infraestrutura atual**: analise suas pilhas e recursos existentes do CloudFormation para identificar oportunidades de refatoração de pilhas.

1. **Planejamento da refatoração**: defina como os recursos devem ser organizados. Considere suas dependências, convenções de nomenclatura e limites operacionais. Isso pode afetar a validação do CloudFormation posteriormente.

1. **Determinção das pilhas de destino**: decida em quais pilhas você refatorará os recursos. Você pode mover recursos entre pelo menos duas pilhas (usando o console) e no máximo cinco pilhas (usando a AWS CLI). Os recursos podem ser movidos entre pilhas aninhadas.

1. **Atualização de modelos**: altere seus modelos do CloudFormation para refletir a alteração planejada, como mover definições de recursos entre modelos. É possível renomear IDs lógicos durante esse processo.

1. **Criação da refatoração de pilhas**: forneça uma lista dos nomes e modelos da pilha que você deseja refatorar.

1. **Análise do impacto da refatoração em sua infraestrutura e resolução de quaisquer conflitos**: o CloudFormation valida os modelos fornecidos por você e verifica dependências entre pilhas, tipos de recursos com problemas de atualização de tags e conflitos de ID lógico de recursos.

   Se a validação for bem-sucedida, o CloudFormation gerará uma prévia das ações de refatoração que ocorrerão após a execução.

   Se a validação falhar, resolva os problemas identificados e tente novamente. Em caso de conflitos, forneça um mapeamento de ID lógico de recurso que mostre a origem e o destino dos recursos conflitantes.

1. **Execução da refatoração**: após confirmar se as alterações estão alinhadas com suas metas de refatoração, conclua a refatoração da pilha.

1. **Monitoramento**: acompanhe o status da execução para garantir que a operação seja concluída com êxito.

## Considerações sobre refatoração de pilhas
<a name="stack-refactoring-considerations"></a>

Ao refatorar suas pilhas, lembre-se do seguinte:
+ A refatoração da pilha se limita à reorganização dos recursos existentes. Você não pode criar ou excluir recursos, modificar configurações de recursos ou alterar ou adicionar novos parâmetros, condições ou mapeamentos durante a refatoração. Para fazer essas alterações, primeiro atualize suas pilhas e, em seguida, realize a refatoração da pilha.
+ Não é possível refatorar o mesmo recurso em várias pilhas.
+ Você não pode refatorar recursos que se referem a pseudoparâmetros cujos valores diferem entre as pilhas de origem e destino, como `AWS::StackName`.
+ O CloudFormation não oferece suporte a pilhas vazias. Se a refatoração deixar uma pilha sem recursos, você deve primeiro adicionar pelo menos um recurso a essa pilha antes de executar o [create-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack-refactor.html) Isso pode ser um recurso simples, como `AWS::SNS::Topic` ou `AWS::CloudFormation::WaitCondition`. Por exemplo:

  ```
  Resources:
    MySimpleSNSTopic:
      Type: AWS::SNS::Topic
      Properties:
        DisplayName: MySimpleTopic
  ```
+ A refatoração de pilha não é compatível com pilhas que tenham políticas de pilha anexadas, independentemente do que as políticas permitam ou neguem.

## Pré-requisitos
<a name="stack-refactoring-prerequisites"></a>

Para refatoração de pilhas, você já deve ter criado os modelos revisados.

Use o comando [get-template](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/get-template.html) para recuperar os modelos do CloudFormation para as pilhas que você deseja refatorar.

```
aws cloudformation get-template --stack-name Stack1
```

Quando tiver os modelos, use o ambiente de desenvolvimento integrado (IDE) de sua escolha para atualizá-los para usar a estrutura e a organização de recursos desejadas.

## Refatorar pilhas (console)
<a name="stack-refactoring-console"></a>

Use o procedimento a seguir para refatorar uma pilha usando o console.

**Para refatorar pilhas**

1. Faça login no Console de gerenciamento da AWS e abra o console CloudFormation em [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Na barra de navegação na parte superior da tela, escolha a Região da AWS em que as pilhas estão localizadas.

1. No painel de navegação à esquerda, escolha **Refatorações de pilha**.

1. Na página **Refatorações de pilha**, escolha **Iniciar refatoração de pilha**.

1. Em **Descrição**, forneça uma descrição para ajudar a identificar a refatoração da pilha. Em seguida, escolha **Próximo**.

1. Na Pilha 1, faça o seguinte:

   1. Escolha **Atualizar o modelo para uma pilha existente** ou **Criar nova pilha**.

      Se você escolher **Atualizar o modelo para uma pilha existente**, selecione uma pilha existente na lista. Ou escolha **Inserir um ARN de pilha** para inserir o ARN de uma pilha existente.

      Se você escolher **Criar nova pilha**, em **Nome da pilha**, forneça um nome para a nova pilha.

   1. Em **Substituir modelo existente por modelo refatorado**, escolha **URL do Amazon S3** ou **Fazer upload de um arquivo de modelo** para carregar o modelo desejado para a Pilha 1.

   1. Escolha **Próximo**.

1. Na Pilha 2, faça o seguinte:

   1. Escolha **Atualizar o modelo para uma pilha existente** ou **Criar nova pilha**.

      Se você escolher **Atualizar o modelo para uma pilha existente**, selecione uma pilha existente na lista. Ou escolha **Inserir um ARN de pilha** para inserir o ARN de uma pilha existente.

      Se você escolher **Criar nova pilha**, em **Nome da pilha**, forneça um nome para a nova pilha.

   1. Em **Substituir modelo existente por modelo refatorado**, escolha **URL do Amazon S3** ou **Fazer upload de um arquivo de modelo** para carregar o modelo desejado para a Pilha 2.

   1. Escolha **Próximo**.

1. Na página **Especificar renomeações de IDs de recursos lógicos**, certifique-se de que o CloudFormation saiba como refatorar pilhas mapeando todos os recursos mostrados para seus IDs lógicos corretos. Como parte da refatoração da pilha, se os IDs lógicos de algum recurso forem alterados, você precisará especificar como ele foi renomeado fornecendo o nome da pilha de origem, o ID lógico original, o nome da pilha de destino e o ID lógico renomeado. Em alguns casos, o console do CloudFormation pode detectar automaticamente o mapeamento de recursos, e você pode simplesmente verificar se o mapeamento de recursos pré-preenchido está correto antes de continuar.

1. Escolha **Próximo**.

1. Na página **Revisar e executar**, revise todas as seleções das etapas anteriores e confirme que tudo está configurado corretamente.

1. Quando tudo estiver pronto para refatorar as pilhas, escolha **Executar refatoração da pilha**.

## Refatorar pilhas (AWS CLI)
<a name="stack-refactoring-cli"></a>

Os comandos da AWS CLI para refatoração de pilha incluem:
+ [create-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack-refactor.html) para validar e gerar uma prévia das alterações planejadas.
+ [describe-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stack-refactor.html) para recuperar o status e os detalhes de uma operação de refatoração de pilha. 
+ [execute-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/execute-stack-refactor.html) para concluir a operação validada de refatoração da pilha. 
+ [list-stack-refactors](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-stack-refactors.html) para listar todas as operações de refatoração de pilha em sua conta com seu status atual e informações básicas. 
+ [list-stack-refactor-actions](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-stack-refactor-actions.html) para mostrar uma prévia das ações específicas que o CloudFormation executará em cada pilha e recurso durante a execução da refatoração. 

Use o procedimento a seguir para refatorar uma pilha usando a AWS CLI. 

**Para refatorar pilhas**

1. Use o comando [create-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack-refactor.html) e forneça os nomes das pilhas e os modelos atualizados para que as pilhas sejam refatoradas. Inclua a opção `--enable-stack-creation` para permitir que o CloudFormation crie novas pilhas se elas ainda não existirem. 

   ```
   aws cloudformation create-stack-refactor \
     --stack-definitions \
       StackName=Stack1,TemplateBody@=file://template1-updated.yaml \
       StackName=Stack2,TemplateBody@=file://template2-updated.yaml \
     --enable-stack-creation
   ```

   O comando retorna um `StackRefactorId` que você usará em etapas posteriores.

   ```
   {
       "StackRefactorId": "9c384f70-4e07-4ed7-a65d-fee5eb430841"
   }
   ```

   Se forem detectados conflitos durante a validação do modelo (o que você pode confirmar na próxima etapa), use o comando [create-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack-refactor.html) com a opção `--resource-mappings`.

   ```
   aws cloudformation create-stack-refactor \
     --stack-definitions \
       StackName=Stack1,TemplateBody@=file://template1-updated.yaml \
       StackName=Stack2,TemplateBody@=file://template2-updated.yaml \
     --enable-stack-creation \ 
     --resource-mappings file://resource-mapping.json
   ```

   Veja a seguir um exemplo de arquivo `resource-mapping.json`.

   ```
   [
       {
           "Source": {
               "StackName": "Stack1",
               "LogicalResourceId": "MySNSTopic"
           },
           "Destination": {
               "StackName": "Stack2",
               "LogicalResourceId": "MyLambdaSNSTopic"
           }
       }
   ]
   ```

1. Use o comando [describe-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stack-refactor.html) para verificar se `Status` é `CREATE_COMPLETE`. Isso verifica se a validação foi concluída.

   ```
   aws cloudformation describe-stack-refactor \
     --stack-refactor-id 9c384f70-4e07-4ed7-a65d-fee5eb430841
   ```

   Resultado do exemplo:

   ```
   {
       "StackRefactorId": "9c384f70-4e07-4ed7-a65d-fee5eb430841",
       "StackIds": [
           "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf",
           "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b"
       ],
       "ExecutionStatus": "AVAILABLE",
       "Status": "CREATE_COMPLETE"
   }
   ```

1. Use o comando [list-stack-refactor-actions](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-stack-refactor-actions.html) para visualizar as ações específicas que serão executadas.

   ```
   aws cloudformation list-stack-refactor-actions \
     --stack-refactor-id 9c384f70-4e07-4ed7-a65d-fee5eb430841
   ```

   Resultado do exemplo:

   ```
   {
       "StackRefactorActions": [
           {
               "Action": "MOVE",
               "Entity": "RESOURCE",
               "PhysicalResourceId": "MyTestLambdaRole",
               "Description": "No configuration changes detected.",
               "Detection": "AUTO",
               "TagResources": [],
               "UntagResources": [],
               "ResourceMapping": {
                   "Source": {
                       "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf",
                       "LogicalResourceId": "MyLambdaRole"
                   },
                   "Destination": {
                       "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b",
                       "LogicalResourceId": "MyLambdaRole"
                   }
               }
           },
           {
               "Action": "MOVE",
               "Entity": "RESOURCE",
               "PhysicalResourceId": "MyTestFunction",
               "Description": "Resource configuration changes will be validated during refactor execution.",
               "Detection": "AUTO",
               "TagResources": [
                   {
                       "Key": "aws:cloudformation:stack-name",
                       "Value": "Stack2"
                   },
                   {
                       "Key": "aws:cloudformation:logical-id",
                       "Value": "MyFunction"
                   },
                   {
                       "Key": "aws:cloudformation:stack-id",
                       "Value": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b"
                   }
               ],
               "UntagResources": [
                   "aws:cloudformation:stack-name",
                   "aws:cloudformation:logical-id",
                   "aws:cloudformation:stack-id"
               ],
               "ResourceMapping": {
                   "Source": {
                       "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf",
                       "LogicalResourceId": "MyFunction"
                   },
                   "Destination": {
                       "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b",
                       "LogicalResourceId": "MyFunction"
                   }
               }
           }
       ]
   }
   ```

1. Depois de revisar e confirmar suas alterações, use o comando [execute-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/execute-stack-refactor.html) para concluir a operação de refatoração da pilha.

   ```
   aws cloudformation execute-stack-refactor \
     --stack-refactor-id 9c384f70-4e07-4ed7-a65d-fee5eb430841
   ```

1. Use o comando [describe-stack-refactor](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stack-refactor.html) para monitorar o status da execução.

   ```
   aws cloudformation describe-stack-refactor \
     --stack-refactor-id 9c384f70-4e07-4ed7-a65d-fee5eb430841
   ```

   Resultado do exemplo:

   ```
   {
       "StackRefactorId": "9c384f70-4e07-4ed7-a65d-fee5eb430841",
       "StackIds": [
           "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf",
           "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b"
       ],
       "ExecutionStatus": "SUCCEEDED",
       "Status": "COMPLETE"
   }
   ```

## Limitações do recurso
<a name="stack-refactoring-resource-limitations"></a>
+ A refatoração de pilha só suporta tipos de recursos com um `provisioningType` de `FULLY_MUTABLE`, que você pode verificar usando o comando [describe-type](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-type.html). 
+ O CloudFormation validará a qualificação do recurso durante a criação da refatoração e relatará quaisquer recursos não suportados na saída do comando [describe-stack-refactor.](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stack-refactor.html) 
+ Os seguintes recursos não são compatíveis com refatoração de pilhas:
  + `AWS::ACMPCA::Certificate`
  + `AWS::ACMPCA::CertificateAuthority`
  + `AWS::ACMPCA::CertificateAuthorityActivation`
  + `AWS::ApiGateway::BasePathMapping`
  + `AWS::ApiGateway::Method`
  + `AWS::AppConfig::ConfigurationProfile`
  + `AWS::AppConfig::Deployment`
  + `AWS::AppConfig::Environment`
  + `AWS::AppConfig::Extension`
  + `AWS::AppConfig::ExtensionAssociation`
  + `AWS::AppStream::DirectoryConfig`
  + `AWS::AppStream::StackFleetAssociation`
  + `AWS::AppStream::StackUserAssociation`
  + `AWS::AppStream::User`
  + `AWS::BackupGateway::Hypervisor`
  + `AWS::CertificateManager::Certificate`
  + `AWS::CloudFormation::CustomResource`
  + `AWS::CloudFormation::Macro`
  + `AWS::CloudFormation::WaitCondition`
  + `AWS::CloudFormation::WaitConditionHandle`
  + `AWS::CodeDeploy::DeploymentGroup`
  + `AWS::CodePipeline::CustomActionType`
  + `AWS::Cognito::UserPoolRiskConfigurationAttachment`
  + `AWS::Cognito::UserPoolUICustomizationAttachment`
  + `AWS::Cognito::UserPoolUserToGroupAttachment`
  + `AWS::Config::ConfigRule`
  + `AWS::Config::ConfigurationRecorder`
  + `AWS::Config::DeliveryChannel`
  + `AWS::DataBrew::Dataset`
  + `AWS::DataBrew::Job`
  + `AWS::DataBrew::Project`
  + `AWS::DataBrew::Recipe`
  + `AWS::DataBrew::Ruleset`
  + `AWS::DataBrew::Schedule`
  + `AWS::DataZone::DataSource`
  + `AWS::DataZone::Environment`
  + `AWS::DataZone::EnvironmentBlueprintConfiguration`
  + `AWS::DataZone::EnvironmentProfile`
  + `AWS::DataZone::Project`
  + `AWS::DataZone::SubscriptionTarget`
  + `AWS::DirectoryService::MicrosoftAD`
  + `AWS::DynamoDB::GlobalTable`
  + `AWS::EC2::CustomerGateway`
  + `AWS::EC2::EIP`
  + `AWS::EC2::LaunchTemplate`
  + `AWS::EC2::NetworkInterfacePermission`
  + `AWS::EC2::PlacementGroup`
  + `AWS::EC2::SpotFleet`
  + `AWS::EC2::VPCDHCPOptionsAssociation`
  + `AWS::EC2::VolumeAttachment`
  + `AWS::EMR::Cluster`
  + `AWS::EMR::InstanceFleetConfig`
  + `AWS::EMR::InstanceGroupConfig`
  + `AWS::ElastiCache::CacheCluster`
  + `AWS::ElastiCache::ReplicationGroup`
  + `AWS::ElastiCache::SecurityGroup`
  + `AWS::ElastiCache::SecurityGroupIngress`
  + `AWS::ElasticBeanstalk::ConfigurationTemplate`
  + `AWS::ElasticLoadBalancing::LoadBalancer`
  + `AWS::ElasticLoadBalancingV2::ListenerCertificate`
  + `AWS::Elasticsearch::Domain`
  + `AWS::FIS::ExperimentTemplate`
  + `AWS::Glue::Schema`
  + `AWS::GuardDuty::IPSet`
  + `AWS::GuardDuty::PublishingDestination`
  + `AWS::GuardDuty::ThreatIntelSet`
  + `AWS::IAM::AccessKey`
  + `AWS::IAM::UserToGroupAddition`
  + `AWS::ImageBuilder::Component`
  + `AWS::IoT::PolicyPrincipalAttachment`
  + `AWS::IoT::ThingPrincipalAttachment`
  + `AWS::IoTFleetWise::Campaign`
  + `AWS::IoTWireless::WirelessDeviceImportTask`
  + `AWS::Lambda::EventInvokeConfig`
  + `AWS::Lex::BotVersion`
  + `AWS::M2::Application`
  + `AWS::MSK::Configuration`
  + `AWS::MSK::ServerlessCluster`
  + `AWS::Maester::DocumentType`
  + `AWS::MediaTailor::Channel`
  + `AWS::NeptuneGraph::PrivateGraphEndpoint`
  + `AWS::Omics::AnnotationStore`
  + `AWS::Omics::ReferenceStore`
  + `AWS::Omics::SequenceStore`
  + `AWS::OpenSearchServerless::Collection`
  + `AWS::OpsWorks::App`
  + `AWS::OpsWorks::ElasticLoadBalancerAttachment`
  + `AWS::OpsWorks::Instance`
  + `AWS::OpsWorks::Layer`
  + `AWS::OpsWorks::Stack`
  + `AWS::OpsWorks::UserProfile`
  + `AWS::OpsWorks::Volume`
  + `AWS::PCAConnectorAD::Connector`
  + `AWS::PCAConnectorAD::DirectoryRegistration`
  + `AWS::PCAConnectorAD::Template`
  + `AWS::PCAConnectorAD::TemplateGroupAccessControlEntry`
  + `AWS::Panorama::PackageVersion`
  + `AWS::QuickSight::Theme`
  + `AWS::RDS::DBSecurityGroup`
  + `AWS::RDS::DBSecurityGroupIngress`
  + `AWS::Redshift::ClusterSecurityGroup`
  + `AWS::Redshift::ClusterSecurityGroupIngress`
  + `AWS::RefactorSpaces::Environment`
  + `AWS::RefactorSpaces::Route`
  + `AWS::RefactorSpaces::Service`
  + `AWS::RoboMaker::RobotApplication`
  + `AWS::RoboMaker::SimulationApplication`
  + `AWS::Route53::RecordSet`
  + `AWS::Route53::RecordSetGroup`
  + `AWS::SDB::Domain`
  + `AWS::SageMaker::InferenceComponen`
  + `AWS::ServiceCatalog::PortfolioPrincipalAssociation`
  + `AWS::ServiceCatalog::PortfolioProductAssociation`
  + `AWS::ServiceCatalog::PortfolioShare`
  + `AWS::ServiceCatalog::TagOptionAssociation`
  + `AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation`
  + `AWS::ServiceCatalogAppRegistry::ResourceAssociation`
  + `AWS::StepFunctions::StateMachineVersion`
  + `AWS::Synthetics::Canary`
  + `AWS::VoiceID::Domain`
  + `AWS::WAF::ByteMatchSet`
  + `AWS::WAF::IPSet`
  + `AWS::WAF::Rule`
  + `AWS::WAF::SizeConstraintSet`
  + `AWS::WAF::SqlInjectionMatchSet`
  + `AWS::WAF::WebACL`
  + `AWS::WAF::XssMatchSet`
  + `AWS::WAFv2::IPSet`
  + `AWS::WAFv2::RegexPatternSet`
  + `AWS::WAFv2::RuleGroup`
  + `AWS::WAFv2::WebACL`
  + `AWS::WorkSpaces::Workspace`