CloudFormationで既存リソースインポート時に”As part of the import operation, you cannot modify or add [Outputs]”エラーになるときの対処方法

Outputs無しのテンプレートでインポート後、更新もしくは変更セットでOutputs付きテンプレートを読み込む
2022.12.08

みなさんこんにちは、杉金です。 
CloudFormationでは既存リソースのインポートをサポートしています。既存リソースのインポート時に以下のエラーになった場合の対処方法について今回ご紹介します。

As part of the import operation, you cannot modify or add [Outputs]

先に結論

Outputsセクションが含まれるCloudFormationテンプレートは既存リソースのインポートでは使用できません。対処として以下の手順を踏む必要があります。

  1. Outputsセクションの記述を削除したテンプレートで既存リソースのインポートを行う
  2. 作成されたスタックに対して、更新もしくは変更セットからOutputsセクション付きテンプレートで更新

以降では、より詳細な情報や具体的な操作方法を説明していきます。

エラーについて

まず、このエラーに関するAWS公式ページがあり、簡単な説明と解決方法について記載されています。

その中に以下の重要な記述があります。

重要: インポート操作には、論理ID、説明、値、エクスポート、および出力のその他のプロパティへの追加と変更を含めることはできません。

実際に試して動きを見てみましょう。

試してみる

エラーの再現

以下のCloudFormationテンプレートを用意します。セキュリティグループを1つ定義するものです。11〜15行目でOutputsを記述しており、セキュリティグループIDを出力させるようにしています。

AWSTemplateFormatVersion: 2010-09-09
Description: Test importing existing resources into a stack
Resources:
  TestSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: TestSecurityGroup
      GroupDescription : TestSecurityGroup
      VpcId : vpc-xxxxxxxxx
    DeletionPolicy : Retain
Outputs:
  TestSecurityGroupSgId:
    Value: !Ref TestSecurityGroup
    Export:
      Name: TestSecurityGroupSgId

テンプレートで定義されている「TestSecurityGroup」リソースは手動で作成済みとします。既存のリソースとしてCloudFormationスタックにインポートします。AWSマネジメントコンソールのCloudFormation スタック画面から「スタックの作成」→「既存リソースを使用(リソースをインポート)」を選びます。

テンプレートファイルでは上記テンプレートを指定します。テンプレートファイルの指定や既存リソースID指定はスクショを省略します。リソースのインポート直前の画面まで進めていくと今回のエラーになります。

対処方法

まずテンプレートからOutputsセクションを削除します。

AWSTemplateFormatVersion: 2010-09-09
Description: Test importing existing resources into a stack
Resources:
  TestSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: TestSecurityGroup
      GroupDescription : TestSecurityGroup
      VpcId : vpc-xxxxxxxxx
    DeletionPolicy : Retain

修正したテンプレートで再度「既存リソースを使用(リソースをインポート)」を進めると、今度はエラーなくインポートできます。

インポート後にスタックの画面から確認するとリソースとして認識されていることが分かります。

Outputsセクションは削除したため「出力」タブには何も表示されません。

続いて元々のOutputs付きのテンプレートを用意します。

AWSTemplateFormatVersion: 2010-09-09
Description: Test importing existing resources into a stack
Resources:
  TestSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: TestSecurityGroup
      GroupDescription : TestSecurityGroup
      VpcId : vpc-xxxxxxxxx
    DeletionPolicy : Retain
Outputs:
  TestSecurityGroupSgId:
    Value: !Ref TestSecurityGroup
    Export:
      Name: TestSecurityGroupSgId

このテンプレートを読み込む方法としては更新また変更セットの2通りあります。更新に比べて変更セットの方が影響するリソースを変更前にレビューできるため、変更セットの方が個人的にはオススメです。それぞれの違いは以下のページも合わせてご覧ください。

パターン1:変更セットの場合

まずは変更セットの場合から行います。対象のスタックを選び「スタックアクション」→「既存スタックの変更セットを作成」を選択します。

「既存テンプレートを置き換える」を選び、Outputs付きのテンプレートファイルを選択します。

次へと進めていき、最後に「変更セットの作成」を選択します。この段階では変更は行われません。

変更セット作成後に、対象スタックの「変更セット」タブを見ると、実行待ちの変更セットが存在することが分かります。対象を選んで「変更セットを実行」を選択すると変更処理が行われます。ちなみに変更セット名のリンクにアクセスすると影響を受けるリソースを確認できます。

今回は影響を受けるリソースがないため空です。

変更セットの実行後「出力」タブに定義した内容が出力されていることが分かります。

以上が今回の対処方法です。

パターン2:更新の場合

スタックを更新する場合も紹介します。対象のスタックを選び「更新」を選択します。

変更セットの時と同じように「既存テンプレートを置き換える」を選び、対象のテンプレートファイルを選択します。

次へと進めていき最後の「送信」を選択すると、すぐに変更が開始されます。

実行後「出力」タブに定義した内容が出力されていることを確認します。

以上がスタック更新の場合の手順です。

最後に

既存リソースをOutputsで出力してImportValueで読み込ませることを試していたときにこのエラーに遭遇しました。同じエラーに遭遇した方の参考になればと思います。

参考資料