스택 리팩터링 - AWS CloudFormation

스택 리팩터링

스택 리팩터링을 사용하면 기존 리소스 속성 및 데이터를 유지하면서 CloudFormation 스택에서 리소스를 재구성할 수 있습니다. 스택 간에 리소스를 이동하거나 대형 스택을 더 작은 스택으로 분할하거나 여러 스택을 하나로 결합할 수 있습니다.

스택 리팩터링 작동 방식

스택 리팩터링에는 다음 단계가 포함됩니다.

  1. 현재 인프라 평가 - 기존 CloudFormation 스택 및 리소스를 검토하여 스택 리팩터링 기회를 식별합니다.

  2. 리팩터링 계획 - 리소스를 구성하는 방법을 정의합니다. 종속 항목, 이름 지정 규칙 및 운영 제한을 고려합니다. 나중에 CloudFormation 검증에 영향을 미칠 수 있습니다.

  3. 대상 스택 결정 - 리소스를 리팩터링할 스택을 결정합니다. 최소 2개 스택에서 최대 5개 스택(AWS CLI 사용) 사이로 리소스를 이동할 수 있습니다. 중첩 스택 사이에서 리소스를 이동할 수 있습니다.

  4. 템플릿 업데이트 - 템플릿 사이에서 리소스 정의를 이동하는 등 계획된 변경 사항을 반영하도록 CloudFormation 템플릿을 변경합니다. 이 프로세스 중에 논리적 ID의 이름을 바꿀 수 있습니다.

  5. 스택 리팩터링 생성 - 리팩터링하려는 스택 이름 및 템플릿의 목록을 제공합니다.

  6. 리팩터링 영향 검토 및 충돌 해결 - CloudFormation은 사용자가 제공하는 템플릿을 검증하고 스택 간 종속성, 태그 업데이트 문제가 있는 리소스 유형 및 리소스 논리적 ID 충돌을 확인합니다.

    검증이 성공하면 CloudFormation은 실행 중에 발생할 리팩터링 작업의 미리 보기를 생성합니다.

    검증이 실패하면 식별된 문제를 해결하고 다시 시도합니다. 충돌이 있는 경우 충돌하는 리소스의 소스 및 대상을 보여주는 리소스 논리적 ID 매핑을 제공합니다.

  7. 리팩터링 실행 - 변경 사항이 리팩터링 목표에 부합하는지 확인한 후 스택 리팩터링을 완료합니다.

  8. 모니터링 - 실행 상태를 추적하여 작업이 성공적으로 완료되는지 확인합니다.

스택 리팩터링 고려 사항

스택을 리팩터링할 때 다음 사항에 유의하세요.

  • 스택 리팩터링은 기존 리소스를 재구성하는 작업으로 제한됩니다. 리팩터링 중에는 리소스를 생성 또는 삭제하거나 리소스 구성을 수정하거나 새 파라미터, 조건 또는 매핑을 변경하거나 추가할 수 없습니다. 이러한 변경을 수행하려면 먼저 스택을 업데이트한 다음 스택 리팩터링을 수행합니다.

  • 동일한 리소스를 여러 스택으로 리팩터링할 수 없습니다.

  • AWS::StackName과 같이 소스 스택과 대상 스택 간에 값이 다른 가상 파라미터를 참조하는 리소스는 리팩터링할 수 없습니다.

  • CloudFormation은 빈 스택을 지원하지 않습니다. 리팩터링으로 인해 스택에 리소스가 없게 되는 경우 create-stack-refactor를 실행하기 전에 먼저 해당 스택에 리소스를 하나 이상 추가해야 합니다. 이는 AWS::SNS::Topic 또는 AWS::CloudFormation::WaitCondition과 같은 간단한 리소스일 수 있습니다. 예:

    Resources: MySimpleSNSTopic: Type: AWS::SNS::Topic Properties: DisplayName: MySimpleTopic
  • 스택 리팩터링은 정책이 허용 또는 거부하는 대상과 관계없이 스택 정책이 연결된 스택을 지원하지 않습니다.

사전 조건

스택을 리팩터링하려면 수정된 템플릿을 이미 생성한 상태여야 합니다.

get-template 명령을 사용하여 리팩터링하려는 스택의 CloudFormation 템플릿을 검색합니다.

aws cloudformation get-template --stack-name Stack1

템플릿이 있으면 선택한 통합 개발 환경(IDE)을 사용하여 원하는 구조 및 리소스 구성을 사용하도록 템플릿을 업데이트합니다.

스택 리팩터링(콘솔)

다음 절차를 사용하여 콘솔에서 스택을 리팩터링합니다.

스택을 리팩터링하는 방법
  1. AWS Management 콘솔에 로그인하여 https://console.aws.amazon.com/cloudformation에서 CloudFormation 콘솔을 엽니다.

  2. 화면 상단의 탐색 모음에서 스택이 위치한 AWS 리전을 선택하세요.

  3. 왼쪽에 있는 탐색 창에서 스택 리팩터링을 선택하세요.

  4. 스택 리팩터링 페이지에서 스택 리팩터링 시작을 선택하세요.

  5. 설명에 스택 리팩터링을 식별하는 데 도움이 되는 설명을 입력하세요. 그리고 다음을 선택합니다.

  6. 스택 1의 경우 다음을 수행하세요.

    1. 기존 스택의 템플릿 업데이트 또는 새 스택 생성을 선택하세요.

      기존 스택의 템플릿 업데이트를 선택한 경우 목록에서 기존 스택을 선택하세요. 또는 스택 ARN 입력을 선택하여 기존 스택의 ARN을 입력하세요.

      새 스택 생성을 선택한 경우 스택 이름에 새 스택의 이름을 입력하세요.

    2. 기존 템플릿을 리팩터링된 템플릿으로 교체에서 Amazon S3 URL 또는 템플릿 파일 업로드를 선택하여 스택 1에 원하는 템플릿을 업로드하세요.

    3. 다음을 선택합니다.

  7. 스택 2의 경우 다음을 수행하세요.

    1. 기존 스택의 템플릿 업데이트 또는 새 스택 생성을 선택하세요.

      기존 스택의 템플릿 업데이트를 선택한 경우 목록에서 기존 스택을 선택하세요. 또는 스택 ARN 입력을 선택하여 기존 스택의 ARN을 입력하세요.

      새 스택 생성을 선택한 경우 스택 이름에 새 스택의 이름을 입력하세요.

    2. 기존 템플릿을 리팩터링된 템플릿으로 교체에서 Amazon S3 URL 또는 템플릿 파일 업로드를 선택하여 스택 2에 원하는 템플릿을 업로드하세요.

    3. 다음을 선택합니다.

  8. 논리적 리소스 ID 이름 바꾸기 지정 페이지에서 CloudFormation이 표시된 리소스를 올바른 논리적 ID에 매핑하여 스택을 리팩터링하는 방법을 알고 있는지 확인하세요. 스택 리팩터링의 일부로 리소스의 논리적 ID가 변경된 경우 소스 스택 이름, 원래 논리적 ID, 대상 스택 이름 및 이름이 바뀐 논리적 ID를 제공하여 이름이 변경된 방법을 지정해야 합니다. 경우에 따라 CloudFormation 콘솔이 리소스 매핑을 자동으로 감지할 수 있으며, 진행하기 전에 미리 채워진 리소스 매핑이 올바른지 간단히 확인할 수 있습니다.

  9. 다음을 선택합니다.

  10. 검토 및 실행 페이지에서 이전 단계의 모든 선택 사항을 검토하고 모든 항목이 올바르게 설정되었는지 확인하세요.

  11. 스택을 리팩터링할 준비가 되면 스택 리팩터링 실행을 선택하세요.

스택 리팩터링(AWS CLI)

스택 리팩터링을 위한 AWS CLI 명령은 다음과 같습니다.

  • create-stack-refactor: 계획된 변경 사항을 검증하고 미리 보기를 생성합니다.

  • describe-stack-refactor: 스택 리팩터링 작업의 상태 및 세부 정보를 검색합니다.

  • execute-stack-refactor: 검증된 스택 리팩터링 작업을 완료합니다.

  • list-stack-refactors: 계정의 모든 스택 리팩터링 작업을 현재 상태 및 기본 정보와 함께 나열합니다.

  • list-stack-refactor-actions: CloudFormation이 리팩터링 실행 중에 각 스택 및 리소스에서 수행할 특정 작업에 대한 미리 보기를 표시합니다.

AWS CLI를 사용하여 스택을 생성하려면 다음 절차를 따릅니다.

스택을 리팩터링하는 방법
  1. create-stack-refactor 명령을 사용하고 리팩터링할 스택의 스택 이름과 업데이트된 템플릿을 제공합니다. 새 스택이 아직 없는 경우 CloudFormation이 새 스택을 생성하도록 허용하는 --enable-stack-creation 옵션을 포함합니다.

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

    이 명령은 이후 단계에서 사용할 StackRefactorId를 반환합니다.

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

    템플릿 검증 중에 충돌이 감지되면(다음 단계에서 확인할 수 있음) create-stack-refactor 명령을 --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

    다음은 예 resource-mapping.json 파일입니다.

    [ { "Source": { "StackName": "Stack1", "LogicalResourceId": "MySNSTopic" }, "Destination": { "StackName": "Stack2", "LogicalResourceId": "MyLambdaSNSTopic" } } ]
  2. describe-stack-refactor 명령을 사용하여 StatusCREATE_COMPLETE인지 확인합니다. 이렇게 하면 검증이 완료됩니다.

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

    출력 예시:

    { "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" }
  3. list-stack-refactor-actions 명령을 사용하여 실행할 특정 작업을 미리 봅니다.

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

    출력 예시:

    { "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" } } } ] }
  4. 변경 사항을 검토하고 확인한 후 execute-stack-refactor 명령을 사용하여 스택 리팩터링 작업을 완료합니다.

    aws cloudformation execute-stack-refactor \ --stack-refactor-id 9c384f70-4e07-4ed7-a65d-fee5eb430841
  5. describe-stack-refactor 명령을 사용하여 실행 상태를 모니터링합니다.

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

    출력 예시:

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

리소스 제한 사항

  • 스택 리팩터링은 provisioningTypeFULLY_MUTABLE인 리소스 유형만 지원하며, describe-type 명령을 사용하여 이를 확인할 수 있습니다.

  • CloudFormation은 리팩터링 생성 중에 리소스 자격을 검증하고 describe-stack-refactor 명령의 출력에서 지원되지 않는 모든 리소스를 보고합니다.

  • 다음 리소스는 스택 리팩터링에서 지원되지 않습니다.

    • 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::LaunchTemplate

    • AWS::EC2::NetworkInterfacePermission

    • 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