

# 자습서: 블루/그린 배포를 사용하여 서비스 생성
<a name="create-blue-green"></a>

Amazon ECS가 Amazon ECS 콘솔의 서비스 생성 마법사에 블루/그린 배포를 통합했습니다. 자세한 내용은 [Amazon ECS 롤링 업데이트 배포 생성](create-service-console-v2.md) 섹션을 참조하세요.

다음 자습서에서는 AWS CLI에서 블루/그린 배포 유형을 사용하는 Fargate 작업이 포함된 Amazon ECS 서비스를 생성하는 방법을 설명합니다.

**참고**  
CloudFormation에 블루/그린 배포 수행에 대한 지원이 추가되었습니다. 자세한 정보는 *AWS CloudFormation 사용 설명서*의 [CloudFormation을 사용하여 CodeDeploy를 통한 Amazon ECS 블루/그린 배포 수행](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/blue-green.html)을 참조하세요.

## 사전 조건
<a name="create-blue-green-prereqs"></a>

이 자습서에서는 다음 사전 조건이 충족되었다고 가정합니다.
+ 최신 버전의 AWS CLI가 설치 및 구성됩니다. AWS CLI 설치 또는 업그레이드에 관한 자세한 정보는 [AWS Command Line Interface 설치](https://docs.aws.amazon.com/cli/latest/userguide/installing.html)를 참조하세요.
+ [Amazon ECS 사용 설정](get-set-up-for-amazon-ecs.md)의 단계가 완료되었습니다.
+ IAM 사용자는 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 정책 예제에 지정된 필수 권한을 가집니다.
+ 사용할 VPC 및 보안 그룹이 생성되었습니다. 자세한 내용은 [Virtual Private Cloud 생성](get-set-up-for-amazon-ecs.md#create-a-vpc) 섹션을 참조하세요.
+ Amazon ECS CodeDeploy IAM 역할이 생성됩니다. 자세한 정보는 [Amazon ECS CodeDeploy IAM 역할](codedeploy_IAM_role.md) 섹션을 참조하세요.

## 1단계: Application Load Balancer 생성
<a name="create-blue-green-loadbalancer"></a>

블루/그린 배포 유형을 사용하는 Amazon ECS 서비스에서는 Application Load Balancer 또는 Network Load Balancer 중 하나를 사용해야 합니다. 이 자습서에서는 Application Load Balancer를 사용합니다.

**Application Load Balancer를 생성하려면**

1. [create-load-balancer](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-load-balancer.html) 명령을 사용하여 Application Load Balancer를 생성합니다. 속해 있는 보안 그룹과 가용 영역이 다른 서브넷 2개를 지정합니다.

   ```
   aws elbv2 create-load-balancer \
        --name bluegreen-alb \
        --subnets subnet-abcd1234 subnet-abcd5678 \
        --security-groups sg-abcd1234 \
        --region us-east-1
   ```

   출력에는 다음 형식과 함께 로드 밸런서의 Amazon 리소스 이름(ARN)이 포함됩니다.

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642
   ```

1. 다음과 같이 [create-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-target-group.html) 명령을 사용하여 대상 그룹을 만듭니다. 이 대상 그룹은 서비스에 설정된 원래 작업 세트로 트래픽을 라우팅합니다.

   ```
   aws elbv2 create-target-group \
        --name bluegreentarget1 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id vpc-abcd1234 \
        --region us-east-1
   ```

   출력에는 다음 형식의 대상 그룹 ARN이 포함됩니다.

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4
   ```

1. [create-listener](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-listener.html) 명령을 사용하여 대상 그룹에 요청을 전달하는 기본 규칙이 있는 로드 밸런서 리스너를 생성합니다.

   ```
   aws elbv2 create-listener \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --protocol HTTP \
        --port 80 \
        --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
   ```

   출력에는 다음 형식의 리스너 ARN이 포함됩니다.

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4
   ```

## 2단계: Amazon ECS 클러스터 생성
<a name="create-blue-green-cluster"></a>

[create-cluster](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-cluster.html) 명령을 사용하여 이름이 `tutorial-bluegreen-cluster`인 클러스터를 생성합니다.

```
aws ecs create-cluster \
     --cluster-name tutorial-bluegreen-cluster \
     --region us-east-1
```

출력에는 다음 형식의 클러스터 ARN이 포함됩니다.

```
arn:aws:ecs:region:aws_account_id:cluster/tutorial-bluegreen-cluster
```

## 3단계: 작업 정의 등록
<a name="create-blue-green-taskdef"></a>

[register-task-definition](https://docs.aws.amazon.com/cli/latest/reference/ecs/register-task-definition.html) 명령을 사용하여 Fargate와 호환되는 태스크 정의를 등록합니다. 이를 위해서는 `awsvpc` 네트워크 모드를 사용해야 합니다. 다음은 이 자습서에서 사용된 태스크 정의 예제입니다.

먼저, 다음 내용으로 이름이 `fargate-task.json`인 파일을 생성합니다. 작업 실행 역할에 ARN을 사용해야 합니다. 자세한 정보는 [Amazon ECS 태스크 실행 IAM 역할](task_execution_IAM_role.md) 섹션을 참조하세요.

```
{
    "family": "sample-fargate", 
    "networkMode": "awsvpc", 
    "containerDefinitions": [
        {
            "name": "sample-app", 
            "image": "public.ecr.aws/docker/library/httpd:latest", 
            "portMappings": [
                {
                    "containerPort": 80, 
                    "hostPort": 80, 
                    "protocol": "tcp"
                }
            ], 
            "essential": true, 
            "entryPoint": [
                "sh",
		"-c"
            ], 
            "command": [
                "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
            ]
        }
    ], 
    "requiresCompatibilities": [
        "FARGATE"
    ], 
    "cpu": "256", 
    "memory": "512"
}
```

그런 다음, 생성한 `fargate-task.json` 파일을 사용하여 태스크 정의를 등록합니다.

```
aws ecs register-task-definition \
     --cli-input-json file://fargate-task.json \
     --region us-east-1
```

## 4단계: Amazon ECS 서비스 생성
<a name="create-blue-green-service"></a>

[create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html) 명령을 사용하여 서비스를 생성합니다.

먼저, 다음 내용으로 이름이 `service-bluegreen.json`인 파일을 생성합니다.

```
{
    "cluster": "tutorial-bluegreen-cluster",
    "serviceName": "service-bluegreen",
    "taskDefinition": "tutorial-task-def",
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4",
            "containerName": "sample-app",
            "containerPort": 80
        }
    ],
    "launchType": "FARGATE",
    "schedulingStrategy": "REPLICA",
    "deploymentController": {
        "type": "CODE_DEPLOY"
    },
    "platformVersion": "LATEST",
    "networkConfiguration": {
       "awsvpcConfiguration": {
          "assignPublicIp": "ENABLED",
          "securityGroups": [ "sg-abcd1234" ],
          "subnets": [ "subnet-abcd1234", "subnet-abcd5678" ]
       }
    },
    "desiredCount": 1
}
```

그런 다음, 생성한 `service-bluegreen.json` 파일을 사용하여 서비스를 생성합니다.

```
aws ecs create-service \
     --cli-input-json file://service-bluegreen.json \
     --region us-east-1
```

출력에는 다음 형식의 서비스 ARN이 포함됩니다.

```
arn:aws:ecs:region:aws_account_id:service/service-bluegreen
```

## 5단계: AWS CodeDeploy 리소스 생성
<a name="create-blue-green-codedeploy"></a>

다음 단계를 사용하여 CodeDeploy 애플리케이션, CodeDeploy 배포 그룹의 Application Load Balancer 대상 그룹 및 CodeDeploy 배포 그룹을 생성합니다.

**CodeDeploy 리소스를 생성하려면**

1. [create-application](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-application.html) 명령을 사용하여 CodeDeploy 애플리케이션을 생성합니다. `ECS` 컴퓨팅 플랫폼을 지정합니다.

   ```
   aws deploy create-application \
        --application-name tutorial-bluegreen-app \
        --compute-platform ECS \
        --region us-east-1
   ```

   출력에는 다음 형식의 애플리케이션 ID가 포함됩니다.

   ```
   {
       "applicationId": "b8e9c1ef-3048-424e-9174-885d7dc9dc11"
   }
   ```

1. [create-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-target-group.html) 명령을 사용하여 CodeDeploy 배포 그룹을 생성할 때 사용할 2차 Application Load Balancer 대상 그룹을 생성합니다.

   ```
   aws elbv2 create-target-group \
        --name bluegreentarget2 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id "vpc-0b6dd82c67d8012a1" \
        --region us-east-1
   ```

   출력에는 다음 형식의 대상 그룹 ARN이 포함됩니다.

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc
   ```

1. [create-deployment-group](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment-group.html) 명령을 사용하여 CodeDeploy 배포 그룹을 생성합니다.

   먼저, 다음 내용으로 이름이 `tutorial-deployment-group.json`인 파일을 생성합니다. 이 예제에서는 생성한 리소스를 사용합니다. `serviceRoleArn`에서 Amazon ECS CodeDeploy IAM 역할의 ARN을 지정합니다. 자세한 정보는 [Amazon ECS CodeDeploy IAM 역할](codedeploy_IAM_role.md) 섹션을 참조하세요.

   ```
   {
      "applicationName": "tutorial-bluegreen-app",
      "autoRollbackConfiguration": {
         "enabled": true,
         "events": [ "DEPLOYMENT_FAILURE" ]
      },
      "blueGreenDeploymentConfiguration": {
         "deploymentReadyOption": {
            "actionOnTimeout": "CONTINUE_DEPLOYMENT",
            "waitTimeInMinutes": 0
         },
         "terminateBlueInstancesOnDeploymentSuccess": {
            "action": "TERMINATE",
            "terminationWaitTimeInMinutes": 5
         }
      },
      "deploymentGroupName": "tutorial-bluegreen-dg",
      "deploymentStyle": {
         "deploymentOption": "WITH_TRAFFIC_CONTROL",
         "deploymentType": "BLUE_GREEN"
      },
      "loadBalancerInfo": {
         "targetGroupPairInfoList": [
           {
             "targetGroups": [
                {
                    "name": "bluegreentarget1"
                },
                {
                    "name": "bluegreentarget2"
                }
             ],
             "prodTrafficRoute": {
                 "listenerArns": [
                     "arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4"
                 ]
             }
           }
         ]
      },
      "serviceRoleArn": "arn:aws:iam::aws_account_id:role/ecsCodeDeployRole",
      "ecsServices": [
          {
              "serviceName": "service-bluegreen",
              "clusterName": "tutorial-bluegreen-cluster"
          }
      ]
   }
   ```

   그런 다음, CodeDeploy 배포 그룹을 생성합니다.

   ```
   aws deploy create-deployment-group \
        --cli-input-json file://tutorial-deployment-group.json \
        --region us-east-1
   ```

   출력에는 다음 형식의 배포 그룹 ID가 포함됩니다.

   ```
   {
       "deploymentGroupId": "6fd9bdc6-dc51-4af5-ba5a-0a4a72431c88"
   }
   ```

## 6단계: CodeDeploy 배포 생성 및 모니터링
<a name="create-blue-green-verify"></a>

다음 단계를 사용하여 애플리케이션 사양 파일(AppSpec 파일)과 CodeDeploy 배포를 생성하고 업로드합니다.

**CodeDeploy 배포를 생성하고 모니터링하려면**

1. 다음 단계를 사용하여 AppSpec 파일을 생성하고 업로드합니다.

   1. CodeDeploy 배포 그룹의 내용으로 이름이 `appspec.yaml`인 파일을 생성합니다. 이 예제에서는 자습서 앞부분에서 생성한 리소스를 사용합니다.

      ```
      version: 0.0
      Resources:
        - TargetService:
            Type: AWS::ECS::Service
            Properties:
              TaskDefinition: "arn:aws:ecs:region:aws_account_id:task-definition/first-run-task-definition:7"
              LoadBalancerInfo:
                ContainerName: "sample-app"
                ContainerPort: 80
              PlatformVersion: "LATEST"
      ```

   1. [s3 mb](https://docs.aws.amazon.com/cli/latest/reference/s3/mb.html) 명령을 사용하여 AppSpec 파일용 Amazon S3 버킷을 생성합니다.

      ```
      aws s3 mb s3://tutorial-bluegreen-bucket
      ```

   1. [s3 cp](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) 명령을 사용하여 AppSpec 파일을 Amazon S3 버킷으로 업로드합니다.

      ```
      aws s3 cp ./appspec.yaml s3://tutorial-bluegreen-bucket/appspec.yaml
      ```

1. 다음 단계를 사용하여 CodeDeploy 배포를 생성합니다.

   1. CodeDeploy 배포의 내용으로 이름이 `create-deployment.json`인 파일을 생성합니다. 이 예제에서는 자습서 앞부분에서 생성한 리소스를 사용합니다.

      ```
      {
          "applicationName": "tutorial-bluegreen-app",
          "deploymentGroupName": "tutorial-bluegreen-dg",
          "revision": {
              "revisionType": "S3",
              "s3Location": {
                  "bucket": "tutorial-bluegreen-bucket",
                  "key": "appspec.yaml",
                  "bundleType": "YAML"
              }
          }
      }
      ```

   1. [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html) 명령을 사용하여 배포를 생성합니다.

      ```
      aws deploy create-deployment \
           --cli-input-json file://create-deployment.json \
           --region us-east-1
      ```

      출력에는 다음 형식의 배포 ID가 포함됩니다.

      ```
      {
          "deploymentId": "d-RPCR1U3TW"
      }
      ```

   1. [get-deployment-target](https://docs.aws.amazon.com/cli/latest/reference/deploy/get-deployment-target.html) 명령을 사용하여 배포의 세부 정보를 가져와 이전 출력의 `deploymentId`를 지정합니다.

      ```
      aws deploy get-deployment-target \
           --deployment-id "d-IMJU3A8TW" \
           --target-id tutorial-bluegreen-cluster:service-bluegreen \
           --region us-east-1
      ```

      다음 출력처럼 `Succeeded` 상태가 될 때까지 배포 세부 정보를 계속 가져옵니다.

      ```
      {
          "deploymentTarget": {
              "deploymentTargetType": "ECSTarget",
              "ecsTarget": {
                  "deploymentId": "d-RPCR1U3TW",
                  "targetId": "tutorial-bluegreen-cluster:service-bluegreen",
                  "targetArn": "arn:aws:ecs:region:aws_account_id:service/service-bluegreen",
                  "lastUpdatedAt": 1543431490.226,
                  "lifecycleEvents": [
                      {
                          "lifecycleEventName": "BeforeInstall",
                          "startTime": 1543431361.022,
                          "endTime": 1543431361.433,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "Install",
                          "startTime": 1543431361.678,
                          "endTime": 1543431485.275,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AfterInstall",
                          "startTime": 1543431485.52,
                          "endTime": 1543431486.033,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "BeforeAllowTraffic",
                          "startTime": 1543431486.838,
                          "endTime": 1543431487.483,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AllowTraffic",
                          "startTime": 1543431487.748,
                          "endTime": 1543431488.488,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AfterAllowTraffic",
                          "startTime": 1543431489.152,
                          "endTime": 1543431489.885,
                          "status": "Succeeded"
                      }
                  ],
                  "status": "Succeeded",
                  "taskSetsInfo": [
                      {
                          "identifer": "ecs-svc/9223370493425779968",
                          "desiredCount": 1,
                          "pendingCount": 0,
                          "runningCount": 1,
                          "status": "ACTIVE",
                          "trafficWeight": 0.0,
                          "targetGroup": {
                              "name": "bluegreentarget1"
                          }
                      },
                      {
                          "identifer": "ecs-svc/9223370493423413672",
                          "desiredCount": 1,
                          "pendingCount": 0,
                          "runningCount": 1,
                          "status": "PRIMARY",
                          "trafficWeight": 100.0,
                          "targetGroup": {
                              "name": "bluegreentarget2"
                          }
                      }
                  ]
              }
          }
      }
      ```

## 7단계: 정리
<a name="create-blue-green-cleanup"></a>

이 자습서를 완료한 후에는 사용하지 않는 리소스에 요금이 발생하지 않도록 연결된 리소스를 정리합니다.

**자습서 리소스 정리**

1. [delete-deployment-group](https://docs.aws.amazon.com/cli/latest/reference/deploy/delete-deployment-group.html) 명령을 사용하여 CodeDeploy 배포 그룹을 삭제합니다.

   ```
   aws deploy delete-deployment-group \
        --application-name tutorial-bluegreen-app \
        --deployment-group-name tutorial-bluegreen-dg \
        --region us-east-1
   ```

1. [delete-application](https://docs.aws.amazon.com/cli/latest/reference/deploy/delete-application.html) 명령을 사용하여 CodeDeploy 애플리케이션을 삭제합니다.

   ```
   aws deploy delete-application \
        --application-name tutorial-bluegreen-app \
        --region us-east-1
   ```

1. [delete-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/delete-service.html) 명령을 사용하여 Amazon ECS 서비스를 삭제합니다. `--force` 플래그를 사용하면 작업이 없는 상태로 축소되지 않은 서비스도 삭제할 수 있습니다.

   ```
   aws ecs delete-service \
        --service arn:aws:ecs:region:aws_account_id:service/service-bluegreen \
        --force \
        --region us-east-1
   ```

1. [delete-cluster](https://docs.aws.amazon.com/cli/latest/reference/ecs/delete-cluster.html) 명령을 사용하여 Amazon ECS 클러스터를 삭제합니다.

   ```
   aws ecs delete-cluster \
        --cluster tutorial-bluegreen-cluster \
        --region us-east-1
   ```

1. [s3 rm](https://docs.aws.amazon.com/cli/latest/reference/s3/rm.html) 명령을 사용하여 Amazon S3 버킷에서 AppSpec 파일을 삭제합니다.

   ```
   aws s3 rm s3://tutorial-bluegreen-bucket/appspec.yaml
   ```

1. [s3 rb](https://docs.aws.amazon.com/cli/latest/reference/s3/rb.html) 명령을 사용하여 Amazon S3 버킷을 삭제합니다.

   ```
   aws s3 rb s3://tutorial-bluegreen-bucket
   ```

1. [delete-load-balancer](https://docs.aws.amazon.com/cli/latest/reference/elbv2/delete-load-balancer.html) 명령을 사용하여 Application Load Balancer를 삭제합니다.

   ```
   aws elbv2 delete-load-balancer \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --region us-east-1
   ```

1. [delete-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/delete-target-group.html) 명령을 사용하여 두 개의 Application Load Balancer 대상 그룹을 삭제합니다.

   ```
   aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
   ```

   ```
   aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc \
        --region us-east-1
   ```