Amazon Web Services 한국 블로그

Amazon ECS 내장 새로운 블루/그린 배포 기반 안전한 소프트웨어 출시 가속하기

컨테이너는 개발 팀이 애플리케이션을 패키징하고 배포하는 방식을 혁신했지만, 개발 팀은 배포 위험을 줄이기 위해 릴리스를 주의 깊게 모니터링하고 사용자 지정 도구를 빌드해야 했으며, 이로 인해 배포 속도가 느려졌습니다. 대규모 기반에서 개발 팀은 비즈니스를 위해 혁신하는 대신 차별화되지 않은 배포 도구를 빌드하고 유지 관리하는 데 귀중한 시간을 할애하고 있습니다.

오늘부터 Amazon Elastic Container Service(Amazon ECS)에서 내장된 블루/그린 배포 기능을 사용하여 애플리케이션을 더 안전하고 일관되게 배포할 수 있습니다. 이 새로운 기능을 사용하면 사용자 지정 배포 도구를 빌드하지 않고도 롤백 기능을 통해 소프트웨어 업데이트를 안정적으로 더 자주 출시할 수 있습니다.

Amazon ECS 콘솔에서 내장된 블루/그린 배포 기능을 활성화하는 방법은 다음과 같습니다.

기존의 ‘블루’ 환경에서 실시간 트래픽을 계속 지원하면서 새로운 ‘그린’ 애플리케이션 환경을 구축합니다. 그린 환경을 철저하게 모니터링하고 테스트한 후 실시간 트래픽을 블루에서 그린 환경으로 라우팅합니다. 이제 Amazon ECS는 이 기능을 통해 컨테이너화된 애플리케이션을 더 안전하고 안정적으로 배포할 수 있는 내장된 기능을 제공합니다.

다음은 애플리케이션 트래픽을 블루 환경에서 그린 환경으로 전환하여 블루/그린 배포의 작동 방식을 보여주는 다이어그램입니다. Amazon ECS 블루/그린 서비스 배포 워크플로 페이지에서 더 자세히 알아볼 수 있습니다.

Amazon ECS는 프로덕션 트래픽을 라우팅하기 전에 가상 트래픽을 사용하여 새 버전을 검증할 수 있는 이벤트 후크를 제공하면서 이 전체 워크플로를 오케스트레이션합니다. 최종 사용자에게 공개하기 전에 프로덕션 환경에서 새 소프트웨어 버전을 검증하고 문제가 발생하면 거의 바로 롤백할 수 있습니다. 이 기능은 Amazon ECS에 직접 내장되어 있으므로 사용자 지정 도구를 빌드하지 않고도 구성을 업데이트하기만 하면 이러한 보호 기능을 추가할 수 있습니다.

시작하기
ECS 서비스의 블루/그린 배포를 구성하고 사용하는 방법을 보여주는 데모를 소개합니다. 그 전에 완료해야 할 몇 가지 설정 단계가 있습니다. 여기에는 AWS Identity and Access Management(IAM) 역할 구성이 포함됩니다. 이 단계는 Required resources for Amazon ECS blue/green deployments 설명서 페이지에서 확인할 수 있습니다.

이 데모에서는 위험을 최소화하기 위해 블루/그린 전략을 사용하여 애플리케이션의 새 버전을 배포하려고 합니다. 먼저 블루/그린 배포를 사용하도록 ECS 서비스를 구성해야 합니다. ECS 콘솔, AWS Command Line Interface(AWS CLI) 또는 인프라형 코드로 사용하여 진행할 수 있습니다.

Amazon ECS 콘솔을 사용하여 평소와 같이 새 서비스를 생성하고 구성합니다.

배포 옵션 섹션에서 배포 컨트롤러 유형으로 ECS를 선택하고 배포 전략으로 블루/그린을 선택합니다. 베이크 소요 시간은 프로덕션 트래픽이 그린으로 전환된 후 블루로 즉시 롤백할 수 있는 시간입니다. 베이크 소요 시간이 만료되면 블루 작업이 제거됩니다.

배포 수명 주기 후크도 도입하였습니다. 이는 배포 워크플로를 보강하는 데 사용할 수 있는 이벤트 기반 메커니즘입니다. 배포 수명 주기 후크로 사용할 AWS Lambda 함수를 선택할 수 있습니다. Lambda 함수는 필요한 비즈니스 로직을 수행할 수 있지만 후크 상태를 반환해야 합니다.

Amazon ECS는 블루/그린 배포 중에 다음과 같은 수명 주기 후크를 지원합니다. 배포 수명 주기 단계 페이지에서 각 단계에 대해 자세히 알아볼 수 있습니다.

  • 스케일 업 이전
  • 스케일 업 이후
  • 프로덕션 트래픽 전환
  • 테스트 트래픽 전환
  • 프로덕션 트래픽 전환 이후
  • 테스트 트래픽 전환 이후

이 애플리케이션에서는 테스트 트래픽 전환을 완료하고 그린 서비스가 모든 테스트 트래픽을 처리하는 시점을 테스트하고 싶습니다. 최종 사용자 트래픽이 없으므로 이 단계에서 롤백은 사용자에게 영향을 주지 않습니다. Lambda 함수에서 테스트 트래픽 전환 이후를 먼저 테스트할 수 있기 때문에 본 사용 사례에는 해당 단계가 적합합니다.

계속 진행하기 전에 잠시 배포를 검증하는 데 사용하는 Lambda 함수를 살펴보겠습니다. 배포 수명 주기 후크로 사용하는 Lambda 함수에서 가상 테스트, 다른 API 직접 호출 또는 메트릭 쿼리와 같은 모든 비즈니스 로직을 수행할 수 있습니다.

Lambda 함수 내에서 hookStatus를 반환해야 합니다. hookStatusSUCCESSFUL일 수 있습니다. 그러면 다음 단계로 진행됩니다. 상태가 FAILED인 경우 블루 배포로 롤백됩니다. IN_PROGRESS인 경우 Amazon ECS는 30초 후에 Lambda 함수를 재시도합니다.

다음 예제에서는 애플리케이션에 대한 테스트 스위트의 일부로 파일 업로드를 수행하는 Lambda 함수를 사용하여 검증을 설정합니다.

import json
import urllib3
import logging
import base64
import os

# Configure logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

# Initialize HTTP client
http = urllib3.PoolManager()

def lambda_handler(event, context):
    """
    Validation hook that tests the green environment with file upload
    """
    logger.info(f"Event: {json.dumps(event)}")
    logger.info(f"Context: {context}")
    
    try:
        # In a real scenario, you would construct the test endpoint URL
        test_endpoint = os.getenv("APP_URL")
        
        # Create a test file for upload
        test_file_content = "This is a test file for deployment validation"
        test_file_data = test_file_content.encode('utf-8')
        
        # Prepare multipart form data for file upload
        fields = {
            'file': ('test.txt', test_file_data, 'text/plain'),
            'description': 'Deployment validation test file'
        }
        
        # Send POST request with file upload to /process endpoint
        response = http.request(
            'POST', 
            test_endpoint,
            fields=fields,
            timeout=30
        )
        
        logger.info(f"POST /process response status: {response.status}")
        
        # Check if response has OK status code (200-299 range)
        if 200 <= response.status < 300:
            logger.info("File upload test passed - received OK status code")
            return {
                "hookStatus": "SUCCEEDED"
            }
        else:
            logger.error(f"File upload test failed - status code: {response.status}")
            return {
                "hookStatus": "FAILED"
            }
            
    except Exception as error:
        logger.error(f"File upload test failed: {str(error)}")
        return {
            "hookStatus": "FAILED"
        }

배포가 후크와 연결된 수명 주기 단계에 도달하면 Amazon ECS가 배포 컨텍스트를 사용하여 Lambda 함수를 자동으로 간접 호출합니다. 검증 함수는 그린 개정본을 기준으로 애플리케이션 상태를 확인하거나 통합 테스트를 실행하거나 성능 메트릭을 검증하는 등 포괄적인 테스트를 실행할 수 있습니다. 그런 다음 함수는 배포를 계속 진행할지 아니면 중단할지 여부를 ECS에 다시 알립니다.

블루/그린 배포 전략을 선택했기 때문에 로드 밸런서 및/또는 Amazon ECS Service Connect도 구성해야 합니다. 로드 밸런싱 섹션에서 Application Load Balancer를 선택합니다.

리스너 섹션에서 포트 80의 기존 리스너를 사용하고 두 개의 대상 그룹을 선택합니다.

이 구성이면 충분하기 때문에 이제 서비스를 생성하고 ECS에서 새 서비스를 프로비저닝할 때까지 기다립니다.

블루/그린 배포 테스트
이제 블루/그린 배포를 테스트할 차례입니다. 이 테스트에서는 테스트 트래픽 전환을 완료한 후 Amazon ECS에서 Lambda 함수를 트리거합니다. 이 경우 Lambda 함수는 애플리케이션에 파일 업로드를 수행하지만 애플리케이션에는 이 기능이 없으므로 FAILED를 반환합니다.

블루/그린 배포 기능이 장애를 감지하면 롤백된다는 점을 알고 있으므로 서비스를 업데이트하고 새 배포 강제 적용을 선택합니다. 작업 정의를 수정하지 않았지만 여전히 새 배포를 트리거해야 하기 때문에 이 옵션을 선택합니다.

이 단계에서는 블루 및 그린 녹색 환경을 모두 실행하고 있으며 그린 개정본이 모든 테스트 트래픽을 처리합니다. 또한 Lambda 함수의 Amazon CloudWatch 로그를 기반으로 배포 수명 주기 후크가 예상대로 작동하고 다음 페이로드를 내보내는 것도 확인했습니다.

[INFO]	2025-07-10T13:15:39.018Z	67d9b03e-12da-4fab-920d-9887d264308e	Event: 
{
    "executionDetails": {
        "testTrafficWeights": {},
        "productionTrafficWeights": {},
        "serviceArn": "arn:aws:ecs:us-west-2:123:service/EcsBlueGreenCluster/nginxBGservice",
        "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123:service-revision/EcsBlueGreenCluster/nginxBGservice/9386398427419951854"
    },
    "executionId": "a635edb5-a66b-4f44-bf3f-fcee4b3641a5",
    "lifecycleStage": "POST_TEST_TRAFFIC_SHIFT",
    "resourceArn": "arn:aws:ecs:us-west-2:123:service-deployment/EcsBlueGreenCluster/nginxBGservice/TFX5sH9q9XDboDTOv0rIt"
}

예상대로 테스트를 수행하지 못했기 때문에 AWS Lambda 함수는 hookStatusFAILED를 반환합니다.

[ERROR]	2025-07-10T13:18:43.392Z	67d9b03e-12da-4fab-920d-9887d264308e	File upload test failed: HTTPConnectionPool(host='xyz.us-west-2.elb.amazonaws.com', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7f8036273a80>, 'Connection to xyz.us-west-2.elb.amazonaws.com timed out. (connect timeout=30)'))

검증이 완료되지 않았으므로 Amazon ECS는 이전에 작업 중인 배포 버전에 해당하는 블루 버전으로 롤백을 시도합니다. 배포 진행 상황을 자세히 보여주는 이벤트 섹션의 ECS 이벤트를 통해 이 프로세스를 모니터링할 수 있습니다.

Amazon ECS가 배포를 이전 작업 버전으로 롤백했습니다. 블루 버전이 계속 실행 중이고 프로덕션 트래픽을 수신할 준비가 되어 있으므로 롤백은 거의 바로 수행됩니다. 프로덕션 트래픽이 새 애플리케이션 버전으로 전환되지 않고 EC가 테스트 트래픽을 원래의 안정적인 버전으로 롤백하기만 했으므로 이 프로세스 동안 최종 사용자에게 미치는 영향은 없습니다. 따라서 기존의 롤링 배포와 관련된 일반적인 배포 가동 중지 시간은 발생하지 않습니다.

마지막 배포 섹션에서도 롤백 상태를 볼 수 있습니다.

테스트를 통해 블루/그린 배포 전략이 일관되고 예측 가능하게 작동한다는 점을 확인했습니다. 또한 배포 수명 주기 후크를 사용하면 배포 동작을 보다 유연하게 제어할 수 있습니다. 각 서비스 버전은 작업 정의, 로드 밸런서 설정, Service Connect 구성을 비롯한 변경 불가능한 구성을 유지합니다. 즉, 롤백은 이전에 실행하던 동일한 환경을 복원합니다.

추가 정보
몇 가지 주요 사항을 알려드립니다.

  • 요금 – 블루/그린 배포 기능은 추가 비용 없이 Amazon ECS에 포함됩니다. 배포 프로세스 중에 사용한 컴퓨팅 리소스에 대한 비용만 지불하면 됩니다.
  • 가용성 – 이 기능은 모든 상용 AWS 리전에서 사용할 수 있습니다.

Amazon ECS 콘솔에서 Amazon ECS 서비스 구성을 업데이트하여 블루/그린 배포를 시작하세요.

만족스러운 배포 경험이 되시길 바랍니다!
Donnie