

# 가져오기 작업을 통한 드리프트 해결
<a name="resource-import-resolve-drift"></a>

리소스의 구성이 의도된 구성에서 드리프트되어 새 구성을 의도된 구성으로 적용하려는 경우가 있을 수 있습니다. 대부분의 경우 스택 템플릿의 리소스 정의를 새 구성으로 업데이트하여 드리프트 결과를 해결한 다음 스택 업데이트를 수행합니다. 그러나 새 구성에서 교체가 필요한 리소스 속성을 업데이트하면 스택 업데이트 중에 리소스가 다시 생성됩니다. 기존 리소스를 유지하려면 리소스 가져오기 기능을 사용하여 리소스를 업데이트하고 리소스를 교체하지 않으면서 드리프트 결과를 해결할 수 있습니다.

가져오기 작업을 통해 리소스에 대한 드리프트를 해결하는 기본 단계는 다음과 같습니다.
+ [Retain으로 설정된 DeletionPolicy 속성을 리소스에 추가합니다](#resource-import-resolve-drift-console-step-01-update-stack). 이렇게 하면 기존 리소스가 스택에서 제거될 때 삭제되지 않고 보존됩니다.
+ [템플릿에서 리소스를 제거하고 스택 업데이트 작업을 실행합니다](#resource-import-resolve-drift-console-step-02-remove-drift). 이렇게 하면 스택에서 리소스가 제거되지만 삭제되지는 않습니다.
+ [스택 템플릿에서 리소스의 실제 상태를 설명한 다음 기존 리소스를 다시 스택으로 가져옵니다](#resource-import-resolve-drift-console-step-03-update-template). 이렇게 하면 리소스가 스택에 다시 추가되고 드리프트 결과를 유발하는 속성 차이가 해결됩니다.

리소스 가져오기에 대한 자세한 내용은 [수동으로 CloudFormation 스택에 AWS 리소스 가져오기](import-resources-manually.md) 섹션을 참조하세요. 가져오기를 지원하는 리소스의 목록은 [리소스 유형 지원](resource-import-supported-resources.md) 섹션을 참조하세요.

다음 예제에서는 `templateToImport.json`이라는 템플릿을 사용합니다.

------
#### [ Example JSON ]

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Import test",
    "Resources": {
         "ServiceTable":{
           "Type":"AWS::DynamoDB::Table",
           "Properties":{
              "TableName":"Service",
              "AttributeDefinitions":[
                 {
                    "AttributeName":"key",
                    "AttributeType":"S"
                 }
              ],
              "KeySchema":[
                 {
                    "AttributeName":"key",
                    "KeyType":"HASH"
                 }
              ],
              "BillingMode": "PROVISIONED",
              "ProvisionedThroughput":{
                 "ReadCapacityUnits":5,
                 "WriteCapacityUnits":1
              }
           }
        },
        "GamesTable": {
            "Type": "AWS::DynamoDB::Table",
            "Properties": {
                "TableName": "Games",
                "AttributeDefinitions": [
                    {
                        "AttributeName": "key",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "key",
                        "KeyType": "HASH"
                    }
                ],
                "BillingMode": "PROVISIONED",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 5,
                    "WriteCapacityUnits": 1
                }
            }
        }
    }
}
```

------
#### [ Example YAML ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: Import test
Resources:
  ServiceTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Service
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
  GamesTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Games
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
```

------

이 예제에서는 사용자가 CloudFormation 외부의 리소스를 변경했다고 가정해 보겠습니다. 드리프트 감지를 실행한 후 `GamesTable`의 `BillingMode`가 `PAY_PER_REQUEST`로 수정된 것을 발견했습니다. 드리프트 탐지에 대한 자세한 내용은 [드리프트 감지를 사용하여 스택 및 리소스에 대한 비관리형 구성 변경 감지](using-cfn-stack-drift.md) 섹션을 참조하세요.

![\[드리프트 결과가 콘솔에 예상 결과와 실제 결과로 표시됨.\]](http://docs.aws.amazon.com/ko_kr/AWSCloudFormation/latest/UserGuide/images/drift-results-gamestable.png)


스택이 오래되었고 리소스는 라이브 상태이지만 의도된 리소스 구성을 보존하려고 합니다. 가져오기 작업을 통해 서비스 중단 없이 드리프트를 해결하면 이렇게 할 수 있습니다.

## CloudFormation 콘솔을 사용하여 가져오기 작업으로 드리프트 해결
<a name="resource-import-resolve-drift-console"></a>

### 1단계. 보존 삭제 정책을 사용하여 스택 업데이트
<a name="resource-import-resolve-drift-console-step-01-update-stack"></a>

**`Retain` 옵션과 함께 `DeletionPolicy` 속성을 사용하여 스택을 업데이트하려면**

1. AWS Management Console에 로그인하여 [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)에서 CloudFormation 콘솔을 엽니다.

1. **스택(Stacks)** 페이지에서 드리프트된 스택을 선택합니다.

1. **업데이트(Update)**를 선택한 다음 스택 세부 정보(Stack details) 창에서 **현재 템플릿 교체(Replace current template)**를 선택합니다.

1. **템플릿 지정(Specify template)** 페이지에서 다음 방법 중 하나를 사용하여 `Retain` 옵션과 함께 `DeletionPolicy` 속성이 포함되어 있는 업데이트된 템플릿을 제공합니다.
   + **Amazon S3 URL**을 선택한 다음, 텍스트 상자에 템플릿의 URL을 지정합니다.
   + **템플릿 파일 업로드**를 선택한 다음 템플릿을 찾습니다.

   그리고 **다음**을 선택합니다.

1. **스택 세부 정보 지정(Specify stack details)** 페이지를 검토하고 **다음(Next)**을 선택합니다.

1. **스택 옵션 구성(Configure stack options)** 페이지를 검토하고 **다음(Next)**을 선택합니다.

1. ***stack-name* 검토(Review stack-name)** 페이지에서 **스택 업데이트(Update stack)**를 선택합니다.

*결과*: 스택의 **이벤트(Events)** 페이지에서 상태가 `UPDATE_COMPLETE`입니다.

서비스를 중단하지 않고 가져오기 작업을 통해 드리프트를 해결하려면 스택에서 제거할 리소스에 대해 `Retain` [DeletionPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html)를 지정합니다. 다음 예에서는 `Retain`으로 설정된 [DeletionPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html) 속성을 `GamesTable` 리소스에 추가했습니다.

------
#### [ Example JSON ]

```
    "GamesTable": {
        "Type": "AWS::DynamoDB::Table",
        "DeletionPolicy": "Retain",
        "Properties": {
            "TableName": "Games",
```

------
#### [ Example YAML ]

```
  GamesTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: Games
```

------

### 2단계. 드리프트된 리소스, 관련 파라미터 및 출력 제거
<a name="resource-import-resolve-drift-console-step-02-remove-drift"></a>

**드리프트된 리소스, 관련 파라미터 및 출력을 제거하려면**

1. **업데이트(Update)**를 선택한 다음 스택 세부 정보(Stack details) 창에서 **현재 템플릿 교체(Replace current template)**를 선택합니다.

1. **템플릿 지정(Specify template)** 페이지에서 다음 방법 중 하나를 사용하여 스택 템플릿에서 제거된 리소스, 관련 파라미터 및 출력을 업데이트된 템플릿에 제공합니다.
   + **Amazon S3 URL**을 선택한 다음, 텍스트 상자에 템플릿의 URL을 지정합니다.
   + **템플릿 파일 업로드**를 선택한 다음 템플릿을 찾습니다.

   그리고 **다음**을 선택합니다.

1. **스택 세부 정보 지정(Specify stack details)** 페이지를 검토하고 **다음(Next)**을 선택합니다.

1. **스택 옵션 구성(Configure stack options)** 페이지를 검토하고 **다음(Next)**을 선택합니다.

1. ***stack-name* 검토(Review stack-name)** 페이지에서 **스택 업데이트(Update stack)**를 선택합니다.

*결과*: 스택의 **Events**(이벤트) 페이지에서 **Logical ID**(논리적 ID) `GamesTable`이 `DELETE_SKIPPED` 상태입니다.

CloudFormation이 스택 업데이트 작업을 완료할 때까지 기다립니다. 스택 업데이트 작업이 완료되면 스택 템플릿에서 리소스, 관련 파라미터 및 출력을 제거합니다. 그런 다음 업데이트된 템플릿을 가져옵니다. 이러한 작업을 완료한 후 예제 템플릿은 다음과 같습니다.

------
#### [ Example JSON ]

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Import test",
    "Resources": {
         "ServiceTable":{
           "Type":"AWS::DynamoDB::Table",
           "Properties":{
              "TableName":"Service",
              "AttributeDefinitions":[
                 {
                    "AttributeName":"key",
                    "AttributeType":"S"
                 }
              ],
              "KeySchema":[
                 {
                    "AttributeName":"key",
                    "KeyType":"HASH"
                 }
              ],
              "BillingMode": "PROVISIONED",
              "ProvisionedThroughput":{
                 "ReadCapacityUnits":5,
                 "WriteCapacityUnits":1
              }
           }
        }
    }
}
```

------
#### [ Example YAML ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: Import test
Resources:
  ServiceTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Service
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
```

------

### 3단계. 리소스의 라이브 상태와 일치하도록 템플릿 업데이트
<a name="resource-import-resolve-drift-console-step-03-update-template"></a>

**리소스의 라이브 상태와 일치하도록 템플릿을 업데이트하려면**

1. 업데이트된 템플릿을 가져오려면 **스택 작업(Stack actions)**을 선택한 다음 **리소스를 스택으로 가져오기(Import resources into stack)**를 선택합니다.  
![\[콘솔의 스택으로 리소스 가져오기 옵션.\]](http://docs.aws.amazon.com/ko_kr/AWSCloudFormation/latest/UserGuide/images/stack-actions-import.png)

1. **가져오기 개요(Import overview)** 페이지에서 이 작업 중에 제공해야 하는 항목 목록을 검토한 후 **다음(Next)**을 선택합니다.

1. **Specify template(템플릿 지정)** 페이지에서 다음 방법 중 하나를 사용하여 업데이트된 템플릿을 제공합니다.
   + **Amazon S3 URL**을 선택한 다음, 텍스트 상자에 템플릿의 URL을 지정합니다.
   + **템플릿 파일 업로드**를 선택한 다음 템플릿을 찾습니다.

   그리고 **다음**을 선택합니다.

1. **Identify resources(리소스 식별)** 페이지에서 각 대상 리소스를 식별합니다. 자세한 내용은 [리소스 식별자](import-resources-manually.md#resource-import-identifiers-unique-ids) 섹션을 참조하세요.

   1. **Identifier property(식별자 속성)**에서 리소스 식별자의 유형을 선택합니다. 예를 들어, `TableName` 속성은 `AWS::DynamoDB::Table` 리소스를 식별합니다.

   1. **식별자 값(Identifier value)**에서 실제 속성 값을 입력합니다. 예제 템플릿에서 `GamesTable` 리소스의 `TableName`은 `Games`입니다.

   1. **다음**을 선택합니다.

1. **스택 세부 정보 지정(Specify stack details)** 페이지를 검토하고 **다음(Next)**을 선택합니다.

1. **가져오기 개요(Import overview)** 페이지에서 가져올 리소스를 검토한 다음 **리소스 가져오기(Import resources)**를 선택합니다. 그러면 `AWS::DynamoDB::Table` 리소스 유형을 다시 스택으로 가져오게 됩니다.

*결과*: 이 예제에서는 서비스를 중단하지 않고 가져오기 작업을 통해 리소스 드리프트를 해결했습니다. CloudFormation 콘솔의 [이벤트(Events)] 탭에서 가져오기 작업의 진행 상황을 확인할 수 있습니다. 가져온 리소스가 `IMPORT_COMPLETE` 상태가 된 다음 `CREATE_COMPLETE` 상태가 되고 상태 이유로 **리소스 가져오기 완료(Resource import complete)**가 표시됩니다.

CloudFormation이 스택 업데이트 작업을 완료할 때까지 기다립니다. 스택 업데이트 작업이 완료되면 리소스의 실제 드리프트된 상태와 일치하도록 템플릿을 업데이트합니다. 예를 들어 `BillingMode`는 `PAY_PER_REQUEST` 및 `ReadCapacityUnits`로 설정되고 `WriteCapacityUnits`는 `0`으로 설정됩니다.

------
#### [ Example JSON ]

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Import test",
    "Resources": {
         "ServiceTable":{
           "Type":"AWS::DynamoDB::Table",
           "Properties":{
              "TableName":"Service",
              "AttributeDefinitions":[
                 {
                    "AttributeName":"key",
                    "AttributeType":"S"
                 }
              ],
              "KeySchema":[
                 {
                    "AttributeName":"key",
                    "KeyType":"HASH"
                 }
              ],
              "BillingMode": "PROVISIONED",
              "ProvisionedThroughput":{
                 "ReadCapacityUnits":5,
                 "WriteCapacityUnits":1
              }
           }
        },
        "GamesTable": {
            "Type": "AWS::DynamoDB::Table",
            "DeletionPolicy": "Retain",
            "Properties": {
                "TableName": "Games",
                "AttributeDefinitions": [
                    {
                        "AttributeName": "key",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "key",
                        "KeyType": "HASH"
                    }
                ],
                "BillingMode": "PAY_PER_REQUEST",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 0,
                    "WriteCapacityUnits": 0
                }
            }
        }
    }
}
```

------
#### [ Example YAML ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: Import test
Resources:
  ServiceTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Service
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
  GamesTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: Games
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST
      ProvisionedThroughput:
        ReadCapacityUnits: 0
        WriteCapacityUnits: 0
```

------