

# スタック間でのリソースの移動
<a name="refactor-stacks"></a>

`resource import` 機能を使用すると、スタック間でリソースを移動、または*リファクタリング*できます。まず、移動するリソースに `Retain` 削除ポリシーを追加して、ソーススタックからリソースを削除してターゲットスタックにインポートするときにリソースが保持されるようにする必要があります。

インポートを初めて行う場合は、まず [AWS リソースを CloudFormation スタックにインポートする](import-resources.md) トピックの概要情報を確認することをお勧めします。

**重要**  
すべてのリソースがインポートオペレーションをサポートしているわけではありません。スタックからリソースを削除する前に、「[インポートオペレーションをサポートするリソース](resource-import-supported-resources.md)」を参照してください。インポートオペレーションをサポートしていないリソースをスタックから削除する場合、そのリソースを別のスタックにインポートしたり、ソーススタックに戻したりすることはできません。

## AWS マネジメントコンソール を使用したスタックのリファクタリング
<a name="refactor-stacks-console"></a>

1. 移動元テンプレートで、移動するリソースに `Retain` [DeletionPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html) を指定します。

   次のサンプルソーステンプレートでは、`Games` がこのリファクタリングの対象です。  
**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"
                    }
                 ],
                 "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"
                       }
                   ],
                   "ProvisionedThroughput": {
                       "ReadCapacityUnits": 5,
                       "WriteCapacityUnits": 1
                   }
               }
           }
       }
   }
   ```

1. CloudFormation コンソールを開き、スタック更新を実行して削除ポリシーを適用します。

   1. [**スタック**] ページで、スタックを選択した状態で [**更新**] を選択します。

   1. [**テンプレートを準備**] で、[**現在のテンプレートを置換**] を選択します。

   1. [**Specify template (テンプレートを指定)**] の下にある `GamesTable` で、`DeletionPolicy` 属性により更新されたソーステンプレートを指定し、[**次へ**] を選択します。
      + [**Amazon S3 URL**] を選択し、テキストボックスで更新されたソーステンプレートの URL を指定します。
      + [**Upload a template file (テンプレートファイルのアップロード)**] を選択し、更新されたソーステンプレートファイルを参照します。

   1. [**Specify stack details (スタック詳細の指定)**] ページでは、変更の必要はありません。[**次へ**] を選択します。

   1. [**スタックオプションの設定**] ページでは、変更の必要はありません。[**次へ**] を選択します。

   1. **[*SourceStackName* を確認]** ページで、変更内容を確認します。テンプレートに IAM リソースが含まれる場合は、[**I acknowledge that this template may create IAM resources (このテンプレートが IAM リソースを作成する可能性を認識しています)**] を選択して、テンプレート内の IAM リソースを使用することを指定します。テンプレート内の IAM リソースの使用の詳細については、「[AWS Identity and Access Management で CloudFormation アクセスを制御する](control-access-with-iam.md)」を参照してください。次に、変更セットを作成してソーススタックを更新するか、ソーススタックを直接更新します。

1. ソーステンプレートからリソース、関連パラメータ、および出力を削除し、それらをターゲットテンプレートに追加します。

   ソーステンプレートは次のようになります。  
**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"
                    }
                 ],
                 "ProvisionedThroughput":{
                    "ReadCapacityUnits":5,
                    "WriteCapacityUnits":1
                 }
              }
           }
       }
   }
   ```

   次のターゲットテンプレートの例には、現在 `PlayersTable` リソースがあり、さらに `GamesTable` も含まれています。  
**Example JSON**  

   ```
   {
       "AWSTemplateFormatVersion": "2010-09-09",
       "Description": "Import test",
       "Resources": {
           "PlayersTable": {
               "Type": "AWS::DynamoDB::Table",
               "Properties": {
                   "TableName": "Players",
                   "AttributeDefinitions": [
                       {
                           "AttributeName": "key",
                           "AttributeType": "S"
                       }
                   ],
                   "KeySchema": [
                       {
                           "AttributeName": "key",
                           "KeyType": "HASH"
                       }
                   ],
                   "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"
                       }
                   ],
                   "ProvisionedThroughput": {
                       "ReadCapacityUnits": 5,
                       "WriteCapacityUnits": 1
                   }
               }
           }
       }
   }
   ```

1. ステップ 2～3 を繰り返してソーススタックを再度更新します。今回は、スタックからターゲットリソースを削除します。

1. インポートオペレーションを実行して、`GamesTable` をターゲットスタックに追加します。

   1. [**スタック**] ページで、親スタックを選択した状態で [**Stack actions (スタックアクション)**] を選択し、[**Import resources into stack (リソースをスタックにインポートする)**] を選択します。  
![\[コンソールの [Import resources into stack (リソースをスタックにインポートする)] オプション。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/stack-actions-import.png)

   1. [**Import overview (インポートの概要)**] ページを参照して、このオペレーション中に指定する必要がある項目の一覧を確認してください。**[次へ]** を選択します。

   1. **[Specify template]** (テンプレートを指定) ページで、以下のいずれかの操作を実行し、**[Next]** (次へ) を選択します。
      + [**Amazon S3 URL**] を選択し、テキストボックスで URL を指定します。
      + [**Upload a template file (テンプレートファイルのアップロード)**] を選択し、アップロードするファイルを参照します。

   1. [**Identify resources (リソースの識別)**] ページで、移動するリソース（この例では `GamesTable`）を特定します。詳細については、「[リソース識別子](import-resources-manually.md#resource-import-identifiers-unique-ids)」を参照してください。

      1. [**Identifier property (識別子のプロパティ)**] で、リソース識別子のタイプを選択します。例えば、`AWS::DynamoDB::Table` リソースは `TableName` プロパティを使用して識別できます。

      1. [**Identifier value (識別子の値)**] に、実際のプロパティ値を入力します。例えば、`GamesTables`。

      1. [**次へ**] を選択します。

   1. [**Specify stack details (スタック詳細の指定)**] ページで、任意のパラメータを変更し、[**次へ**] を選択します。これにより、変更セットが自動的に作成されます。
**重要**  
作成、更新、または削除オペレーションを開始する既存のパラメータを変更すると、インポートオペレーションは失敗します。

   1. **[*TargetStackName* を確認]** ページで、インポートしようとしているリソースが正しいことを確認し、**[リソースをインポート]** を選択します。これにより、最後のステップで作成した変更セットが自動的に開始されます。この時点で、インポートされたリソースには[スタックレベルのタグ](cfn-console-create-stack.md#configure-stack-options)が適用されます。

   1. 親スタックの **[Stack details]** (スタックの詳細) ページの **[Events]** (イベント) ペインが表示されます。  
![\[コンソールの [イベント] タブ。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/import-events.png)
**注記**  
`AWS::CloudFormation::Stack` リソースは既に CloudFormation によって管理されているため、このインポートオペレーションの後、親スタックでドリフト検出を実行する必要はありません。

## AWS CLI を使用したスタックのリファクタリング
<a name="refactor-stacks-cli"></a>

1. 移動元テンプレートで、移動するリソースに `Retain` [DeletionPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html) を指定します。

   次のサンプルソーステンプレートでは、`GamesTable` がこのリファクタリングの対象です。  
**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"
                    }
                 ],
                 "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"
                       }
                   ],
                   "ProvisionedThroughput": {
                       "ReadCapacityUnits": 5,
                       "WriteCapacityUnits": 1
                   }
               }
           }
       }
   }
   ```

1. ソーススタックを更新して、削除ポリシーをリソースに適用します。

   ```
   aws cloudformation update-stack --stack-name SourceStackName
   ```

1. ソーステンプレートからリソース、関連パラメータ、および出力を削除し、それらをターゲットテンプレートに追加します。

   ソーステンプレートは次のようになります。  
**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"
                    }
                 ],
                 "ProvisionedThroughput":{
                    "ReadCapacityUnits":5,
                    "WriteCapacityUnits":1
                 }
              }
           }
       }
   }
   ```

   次のターゲットテンプレートの例には、現在 `PlayersTable` リソースがあり、さらに `GamesTable` も含まれています。  
**Example JSON**  

   ```
   {
       "AWSTemplateFormatVersion": "2010-09-09",
       "Description": "Import test",
       "Resources": {
           "PlayersTable": {
               "Type": "AWS::DynamoDB::Table",
               "Properties": {
                   "TableName": "Players",
                   "AttributeDefinitions": [
                       {
                           "AttributeName": "key",
                           "AttributeType": "S"
                       }
                   ],
                   "KeySchema": [
                       {
                           "AttributeName": "key",
                           "KeyType": "HASH"
                       }
                   ],
                   "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"
                       }
                   ],
                   "ProvisionedThroughput": {
                       "ReadCapacityUnits": 5,
                       "WriteCapacityUnits": 1
                   }
               }
           }
       }
   }
   ```

1. ソーススタックを更新して、`GamesTable` リソースとそれに関連するパラメータと出力をスタックから削除します。

   ```
   aws cloudformation update-stack --stack-name SourceStackName
   ```

1. インポートする実際のリソースとその一意の識別子のリストを次の JSON 文字列形式で作成します。詳細については、「[リソース識別子](import-resources-manually.md#resource-import-identifiers-unique-ids)」を参照してください。

   ```
   [{"ResourceType":"AWS::DynamoDB::Table","LogicalResourceId":"GamesTable","ResourceIdentifier":{"TableName":"Games"}}]
   ```

   または、設定ファイルで JSON 形式のパラメータを指定することもできます。

   例えば、`GamesTable` をインポートするには、次の設定を含む *ResourcesToImport.txt* ファイルを作成します。

   ```
   [
     {
         "ResourceType":"AWS::DynamoDB::Table",
         "LogicalResourceId":"GamesTable",
         "ResourceIdentifier": {
           "TableName":"Games"
         }
     }
   ]
   ```

1. 変更セットを作成するには、次の **create-change-set** コマンドを使用してプレースホルダーテキストを置き換えます。`--change-set-type` オプションの場合、**IMPORT** の値を指定します。`--resources-to-import` オプションでは、サンプルの JSON 文字列を、作成した実際の JSON 文字列に置き換えます。

   ```
   aws cloudformation create-change-set \
       --stack-name TargetStackName --change-set-name ImportChangeSet \
       --change-set-type IMPORT \
       --template-body file://TemplateToImport.json \
       --resources-to-import "'[{"ResourceType":"AWS::DynamoDB::Table","LogicalResourceId":"GamesTable","ResourceIdentifier":{"TableName":"Games"}}]'"
   ```
**注記**  
`--resources-to-import` はインライン YAML をサポートしていません。JSON 文字列で引用符をエスケープするための要件は、ターミナルに応じて異なります。詳細については、「*AWS Command Line Interface ユーザーガイド*」の「[Using quotation marks inside strings](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html#cli-usage-parameters-quoting-strings-containing)」を参照してください。

   あるいは、次の例に示すように、`--resources-to-import` オプションの入力としてファイル URL を使用することもできます。

   ```
   --resources-to-import file://ResourcesToImport.txt
   ```

1. 変更セットを確認し、正しいリソースがターゲットスタックにインポートされることを確認します。

   ```
   aws cloudformation describe-change-set \
       --change-set-name ImportChangeSet
   ```

1. 変更セットを開始してリソースをインポートするには、次の **execute-change-set** コマンドを使用してプレースホルダーテキストを置き換えます。この時点で、インポートされたリソースにはスタックレベルのタグが適用されます。オペレーション `(IMPORT_COMPLETE)` が正常に完了すると、リソースは正常にインポートされています。

   ```
   aws cloudformation execute-change-set \
       --change-set-name ImportChangeSet --stack-name TargetStackName
   ```
**注記**  
リソースは既に CloudFormation によって管理されているため、このインポートオペレーションの後、ターゲットスタックでドリフト検出を実行する必要はありません。