はじめに
ECS(Fargate)を手動構築すると自動でCloudFormation(※以降、CFn)が作成されるのですが、このスタックを誤って削除してしまいました。
今回はたまたまFargateクラスター等の設定は残っていたので、このままの状態でもFargateの動作には影響はないのですが、どうしてもCFnの管理に戻したい場合の復活方法をご紹介します。
今回のこの方法は、ECS(Fargate)のCFnスタックに限らず、作成済みリソースをCloudFormation管理に含めることが可能となります。
スタックの復元方法
残念ながら、ECS(Fargate)を手動構築した際にできたCFnスタックを復元する方法はありませんでした。
※このケースに限りませんが、削除されてしまったスタックを復元することはAWSサポートでもできないようです。
復元方法としては2つの方法が考えられます。
- ECSクラスターを一度削除する等もう一度クラスターを作成する
再作成となるので、切り替え等によるダウンタイム等考慮する必要がありますが、元の状態に戻すことが可能です。 - CFnスタックのリソースインポート機能を利用する
スタックのテンプレートが全く同じとはなりませんが、作成されたリソースを再度CFn管理とすることが可能です。
今回は「2. CFnスタックのリソースインポート機能を利用する」の方法をやっていきます。
ちなみに、元と全く同じCFnテンプレートにしたい場合は、残念ながら①の方法で再作成を実施しか方法はないです。。。
概要
今回はこちらの
スタックへの既存リソースのインポート
を利用することで、CFn管理リソースとしてインポートすることでスタックの復元を行います。
実施する内容は下記の通り、
- ECS(Fargate)を手動構築
- CFnテンプレートのECSクラスターにDeletionPolicyを追加し、スタック削除時にクラスターが削除されないように設定
- 自動で作成されたCFnスタックを削除
- CFnリソースインポートにてスタックを復元
を実施していきます。
また、既存リソースをCFnにインポートしたい場合は「④CFnリソースインポートにてスタックを復元」の手順のみ実施してください。
今回は、DeletionPolicy: Retain(削除しない)を指定しましたが、他にもオプションありますので、詳細は公式ドキュメントよりご確認ください。
注意点
先ほども記載しましたが、スタックへのリソースインポートを利用するには2点注意点があります。
- インポートするリソースにはDeletionPolicyを追加する必要がある
- Outputs プロパティは利用できない
上記、注意して利用してください。
実際にやってみる
1. ECS(Fargate)を手動構築
AWSコンソールにログインし、
Amazon Elastic Container Service > クラスター
から、「クラスターの作成」を押下します。

各設定のうち、
1. クラスター設定 - クラスター名
2. インフラストラクチャ - AWS Fargate(サーバレス)
をそれぞれ入力・選択し、ECSクラスターを作成します。

CloudFormation > スタック
から、先ほど作成したECSクラスター用のCloudFormationスタックが作成されているので確認します。

CloudFormationスタックのテンプレートを確認すると、下記のようなJSONを確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "The template used to create an ECS Cluster from the ECS Console.", "Parameters": { "ECSClusterName": { "Type": "String", "Description": "Specifies the ECS Cluster Name with which the resources would be associated", "Default": "test-ecs-cluster" }, "SecurityGroupIds": { "Type": "CommaDelimitedList", "Description": "Optional - Specifies the Comma separated list of the Security Group Id of an existing Security Group.", "Default": "" }, "VpcId": { "Type": "String", "Description": "Optional - Specifies the ID of an existing VPC in which to launch your container instances. If you specify a VPC ID, you must specify a list of existing subnets in that VPC. If you do not specify a VPC ID, a new VPC is created with at least 1 subnet.", "Default": "", "AllowedPattern": "^(?:vpc-[0-9a-f]{8,17}|)$", "ConstraintDescription": "VPC Id must begin with 'vpc-' and have a valid uuid" }, "SubnetIds": { "Type": "CommaDelimitedList", "Description": "Optional - Specifies the Comma separated list of existing VPC Subnet Ids where ECS instances will run", "Default": "" } }, "Resources": { "ECSCluster": { "Type": "AWS::ECS::Cluster", "Properties": { "ClusterName": { "Ref": "ECSClusterName" }, "CapacityProviders": [ "FARGATE", "FARGATE_SPOT" ], "ClusterSettings": [ { "Name": "containerInsights", "Value": "disabled" } ], "Configuration": { "ExecuteCommandConfiguration": { "Logging": "DEFAULT" } }, "ServiceConnectDefaults": { "Namespace": "test-ecs-cluster" }, "Tags": [] } } }, "Outputs": { "ECSCluster": { "Description": "The created cluster.", "Value": { "Ref": "ECSCluster" } } } } |
次の手順で、こちらにDeletionポリシーを設定します。
2. CFnテンプレートのECSクラスターにDeletionPolicyを追加
右上の「更新」を押下し、「デザイナーでテンプレートを編集する」を選択し、
「デザイナーで表示」を押下してテンプレートを更新します。

31行目付近にある、
1 |
"Type": "AWS::ECS::Cluster", |
の下に下記1行を追加します。
1 |
"DeletionPolicy":"Retain", |

更新したら、左上の「スタックの作成」を押下します。

テンプレートを更新したら、「次へ」を押下します。

その後、「スタックの詳細を指定」、「スタックオプションの設定」、「レビュー」は特に変更せずに「送信」から更新を実行します。

スタックのステータスが「UPDATE_COMPLETE」になったら更新完了です。

3. 自動で作成されたCFnスタックを削除
DeletionPolicyにRetainが設定されましたので、CFnスタックを削除してもECSクラスターが残る設定となりましたので、一度CFnスタックを削除します。

削除が完了すると下記のようにステータスが「DELETE_COMPLETE」となります。

念の為、先ほどDeletionPolicyを設定したECSクラスターを確認しても削除されずにリソースが残っていることが確認できます。

こちらのテンプレートは後ほど利用するので、
テンプレート - クリップボードにコピー
からテンプレートをローカルに「template.json」等の名前で保存しておいてください。
もし、間違ってウィンドウを閉じたりして保存し忘れた場合でも、スタックの「ステータスのフィルター」から「削除済み」を選択すれば、削除済みのスタックの内容も確認することが可能です。
4. CFnリソースインポートにてスタックを復元
こちらが本題の、CloudFormationのリソースインポートを実行する手順となります。
まず、CFn実行に必要なテンプレートファイルを用意します。
先ほどローカルに保存したファイルを更新し、ファイル末尾にある下記Outputsセクションを削除します。
1 2 3 4 5 6 7 8 9 |
, "Outputs": { "ECSCluster": { "Description": "The created cluster.", "Value": { "Ref": "ECSCluster" } } } |
最終的にはこのようなテンプレートとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "The template used to create an ECS Cluster from the ECS Console.", "Parameters": { "ECSClusterName": { "Type": "String", "Description": "Specifies the ECS Cluster Name with which the resources would be associated", "Default": "test-ecs-cluster" }, "SecurityGroupIds": { "Type": "CommaDelimitedList", "Description": "Optional - Specifies the Comma separated list of the Security Group Id of an existing Security Group.", "Default": "" }, "VpcId": { "Type": "String", "Description": "Optional - Specifies the ID of an existing VPC in which to launch your container instances. If you specify a VPC ID, you must specify a list of existing subnets in that VPC. If you do not specify a VPC ID, a new VPC is created with at least 1 subnet.", "Default": "", "AllowedPattern": "^(?:vpc-[0-9a-f]{8,17}|)$", "ConstraintDescription": "VPC Id must begin with 'vpc-' and have a valid uuid" }, "SubnetIds": { "Type": "CommaDelimitedList", "Description": "Optional - Specifies the Comma separated list of existing VPC Subnet Ids where ECS instances will run", "Default": "" } }, "Resources": { "ECSCluster": { "Type": "AWS::ECS::Cluster", "DeletionPolicy": "Retain", "Properties": { "ClusterName": { "Ref": "ECSClusterName" }, "CapacityProviders": [ "FARGATE", "FARGATE_SPOT" ], "ClusterSettings": [ { "Name": "containerInsights", "Value": "disabled" } ], "Configuration": { "ExecuteCommandConfiguration": { "Logging": "DEFAULT" } }, "ServiceConnectDefaults": { "Namespace": "test-ecs-cluster" }, "Tags": [] } } } } |
また、もとのCFnテンプレートとの差分は下記の通りとなります。

作成したいリソースにDeletionPolicyを持った、OutputsがないCFnテンプレートが作成できたらスタックの作成を行います。
CloudFormationコンソールから「スタックの作成」を押下し、「既存のリソースを使用(リソースのインポート)」を選択します。

説明の画面があるので内容を確認します。

必要なもの
テンプレート
このインポート中に、ターゲットリソースを含むスタック全体を記述するテンプレートを指定する必要があります。既存のスタックリソースが、準備済みのテンプレートで変更された場合、インポートは失敗します。識別子の値
このインポート中に、インポートするリソースを (S3 バケット名などで) 特定する必要があります。このプロセスの手順はウィザードに従います
テンプレートの指定画面で、テンプレートのアップロードを選択し、先ほど保存したテンプレートをアップロードし、
「次へ」を押下します。

インポートするリソースに、「CFn管理としたいリソース ※今回の場合はClusterName」を設定し、
「次へ」を押下します。

スタックの詳細を指定 - スタック名
に作成するスタック名を入力して、「次へ」を押下します。
変更の箇所で、指定したECSClusterが「アクション: Import」となっていることを確認し、
「リソースをインポート」を押下してスタックの作成を行います。

注意: Outputsセクションが削除されていないと、変更の箇所に下記エラーが発生します。
この変更セットの作成中にエラーが発生しました
As part of the import operation, you cannot modify or add [Outputs]![]()
しばらくすると、作成したスタックのステータスが、「IMPORT_COMPLETE」となれば設定完了となります。

リソースタブを確認することで無事、リソースがCFn管理となっていることも確認できます。

まとめ
今回のCFnスタックへの既存リソースのインポート機能を利用すれば、手動構築したリソースをCFnの管理に含めることが可能となります。
CFnスタックを削除すると関連しているリソースは全て削除されてしまいます。削除されるとまずいリソース(EC2やRDS等々)についてはDeletionPolicyや削除保護等で削除されないようにしておけば最悪、こちらの方法でCFn管理に戻すことは可能となります。
誤って削除してしまった際は焦らずこのような方法も検討下さい。
投稿者プロフィール
-
2024 Japan AWS Top Engineers
AWSを使ったサーバレスアーキテクチャ・コンテナサービスの設計・構築を担当。
最新の投稿
AWS2025年1月17日AWS X-Ray SDK for Python 実践ガイド:トレース設定から可視化まで深堀りしてみた
NewRelic2024年12月25日【New Relic】アプリ初心者でも大丈夫!インフラエンジニアがはじめるAPM/Browser超入門 〜1時間で始める可視化への第一歩〜
AWS re:Invent 20242024年12月22日Amazon ECSのAmazon CloudWatch Container Insightsでオブザーバビリティ強化されたので、AWS X-Rayとともに検証してみた
AWS2024年12月5日【報告】re:Invent2024のJAMで準優勝しました!〜JAMで学ぶモダンアプリケーション開発〜