AWS CloudFormationでStackを削除したときにリソースを消さない設定

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CloudFormationで環境構築

CloudFormationは、JSONによるテンプレートからAWSの環境を丸ごと復元する便利なサービスです。DRをはじめさまざまなシーンで利用可能です。今回は、構築した環境(=スタック)を削除する際に、リソースを消さない設定について紹介したいと思います。

DeletionPolicy

DeletionPolicyは、その名の通り、削除するかどうか指定する属性です。以下の3つの種類があります。

  • Delete : 特に指定しない場合にはこれが選択されます。リソースを削除します。
  • Retain : リソースを削除せずに残します。
  • Snapshot : EC2やRDSに指定することができ、スナップショットを作成してから削除します。

S3のバケットを残す

それでは、早速最も簡単なサンプルを作成してみたいと思います。S3のバケット作成と削除です。以下の例は、DeletionPolicyにRetainを指定していますのでスタックを削除してもバケットは消えません。

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "Simple S3 Template Stack",

  "Resources" : {
    "S3Bucket" : {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
        "AccessControl" : "Private"      
      },
      "DeletionPolicy" : "Retain"
    }
  },

  "Outputs" : {
    "S3BucketSecureURL" : {
      "Value" : { "Fn::Join" : [ "", [ "https://", { "Fn::GetAtt" : [ "S3Bucket", "DomainName" ] } ] ] },
      "Description" : "Name of S3 bucket"
    }
  } 
}

上記のテンプレートを指定してスタックを作成しました。

screenshot 2015-07-04 15.32.53

実際にS3バケットが作成されてます。

screenshot 2015-07-04 15.34.00

続けて削除してみます。

screenshot 2015-07-04 15.34.21

削除成功しました。

screenshot 2015-07-04 15.35.10

基本的にはこれで終わりですが、他のケースも考えてみたいと思います。

S3バケットが消えない

DeletionPolicyを指定せずに、デフォルト動作のバケット削除を確認してみたいと思います。以下の様なJSONテンプレートです。

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "Simple S3 Template Stack",

  "Resources" : {
    "S3Bucket" : {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
        "AccessControl" : "Private"      
      }
    }
  },

  "Outputs" : {
    "S3BucketSecureURL" : {
      "Value" : { "Fn::Join" : [ "", [ "https://", { "Fn::GetAtt" : [ "S3Bucket", "DomainName" ] } ] ] },
      "Description" : "Name of S3 bucket"
    }
  } 
}

そして、作成されたバケットに何かオブジェクトを置きます。そして、スタックを削除してみましょう。

screenshot 2015-07-04 15.46.15

スタックの削除に失敗してしまいました。これは、S3バケットを削除する際に、中身のオブジェクトが空でないといけないためです。

EC2インスタンスのスナップショットを取得する

続きまして、CloudFormationテンプレートでEC2を構築しまして、スタックを削除するときにスナップショットを取得したいと思います。

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "EC2",
  "Resources" : {
    "EC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "KeyName" : "mykey",
        "ImageId" : "ami-27f90e27",
				"InstanceType" : "t1.micro"
      }
    },
		"NewVolume" : {
		   "Type" : "AWS::EC2::Volume",
		   "Properties" : {
         "Size" : "1",
         "AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ] }
       },
		   "DeletionPolicy" : "Snapshot"
		},
    "MountPoint" : {
      "Type" : "AWS::EC2::VolumeAttachment",
      "Properties" : {
        "InstanceId" : { "Ref" : "EC2Instance" },
        "VolumeId"  : { "Ref" : "NewVolume" },
        "Device" : "/dev/sdh"
      }
    }     
  },

  "Outputs" : {
    "InstanceId" : {
      "Description" : "InstanceId of the newly created EC2 instance",
      "Value" : { "Ref" : "EC2Instance" }
    }
  }
}

上記のテンプレートから新しいスタックを作成し、続けてスタックを削除しました。

screenshot 2015-07-07 18.55.19

スタック削除の履歴を見ると、スナップショット作成が実行されていることがわかりました!

まとめ

CloudFormationを使って環境を構築するときは、片付けるときのことを考えておきましょう。S3、EC2ボリューム、RDSなどは、スタックを削除しても中身のデータは使いまわしたいことが多いはずです。まちがって消さないように、DeletionPolicyを設定するクセを付けましょう!

参考資料

AWS CloudFormation ユーザーガイド - DeletionPolicy 属性

AWS CloudFormation ユーザーガイド - AWS Lambda-backed カスタムリソース