Windows Server EC2のファイルリストアをするCloudFormationテンプレート

# はじめに

以前、Windows ServerのEC2のスナップショットからファイルをリストアする方法を記事にしました。

https://qiita.com/a_b_/items/66e2587421fff29f199e

スナップショットからボリュームを作って、新しくEC2を立てて、そこにアタッチさせて取り出す、ということをしました。

今回はそれをCloudFormationで出来るようにしました。

# 概要

CloudFormation実行時に、リストアしたいファイルを含むスナップショットIDを指定します。
するとリストアしたボリュームを、DドライブにアタッチしたEC2インスタンスが起動します。
EC2インスタンスがあるVPCやサブネット、RDPで接続可能としたセキュリティグループなどは作成済みの想定です。

# 参考

https://docs.aws.amazon.com/ja_jp/ebs/latest/userguide/ebs-using-volumes.html

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-instance.html

https://qiita.com/Mikoto_Hashimoto/items/6f43d3f62bdd1164b595

# CloudFormationテンプレート

CloudFormationテンプレートは以下になります。
SnapshotId以外のパラメータに指定するリソースは、リストア用に用意しておき、Defaultで設定しておいています。

```yaml:create_ec2ForFileRestore.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template to create a Windows Server 2022 EC2 instance for File Restore

Parameters:
  # Restore Configuration
  SnapshotId:
    Type: String
  # EC2 Environment Configuration
  VPCID:
    Type: AWS::EC2::VPC::Id
    Default: "vpc-xxxxxxxxxx"
    Description: The VPC ID where the instance will be created
  SubnetId:
    Type: AWS::EC2::Subnet::Id
    Default: "subnet-xxxxxxxxxx"
    Description: The Subnet ID where the instance will be created
  SecurityGroups:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Default: "sg-xxxxxxxxxx"
    Description: Security Groups for the instance
  AvailabilityZone:
    Type: String
    Default: "ap-northeast-1a"
    Description: The Availability Zone for the instance
  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Default: "xxxxxxxxxx"
    Description: The name of the existing EC2 KeyPair to enable RDP access
  ImageId:
    Type: String
    Default: "ami-xxxxxxxxxx"
    Description: Windows Server 2022 EC2 image for File Restore

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Restore Configuration"
        Parameters:
          - SnapshotId
      - Label:
          default: "EC2 Environment Configuration"
        Parameters:
          - VPCID
          - SubnetId
          - SecurityGroups
          - AvailabilityZone
          - KeyName
          - ImageId

Resources:
  RestoreVolume:
    Type: AWS::EC2::Volume
    Properties: 
      AvailabilityZone: !Ref AvailabilityZone
      SnapshotId: !Ref SnapshotId
    DeletionPolicy: Delete

  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref ImageId
      InstanceType: t2.large
      KeyName: !Ref KeyName
      AvailabilityZone: !Ref AvailabilityZone
      NetworkInterfaces: 
        - AssociatePublicIpAddress: "true"
          DeleteOnTermination: true
          DeviceIndex: "0"
          SubnetId: !Ref SubnetId
          GroupSet: !Ref SecurityGroups
      Volumes:
        - Device: "xvdf"
          VolumeId: !GetAtt RestoreVolume.VolumeId
      UserData:
        Fn::Base64: !Sub |
          <powershell>
          echo 'select disk 1' 'attributes disk clear readonly' 'online disk noerr' 'select volume 1' 'assign letter=D' | diskpart
          </powershell>
    DeletionPolicy: Delete
    DependsOn: RestoreVolume
```

EC2起動時にユーザーデータで実行しているdiskpartのコマンドは以下になります。

```
select disk 1 
attributes disk clear readonly 
online disk noerr
select volume 1
assign letter=D
```

## 実行～削除

CloudFormationテンプレートを指定し、パラメータにSnapshotIdを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/740c1134-7645-3547-f11b-a5a46f5bdcd2.png)

作成後RDPで接続し、リストアした内容がDドライブにあることを確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/2dbee063-5874-eef8-bdf5-38254b1b6903.png)

戻したいファイルも確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/7f9caa82-9b3a-80c8-8dba-f7ac1dd86302.png)

CloudFormationスタックを削除すれば、EC2インスタンスもボリュームも削除されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/28c64f84-2bbf-3458-e919-b347660e8d4f.png)

# おわりに
前回コンソールで行ったファイルリストアを、CloudFormationで出来るようにしてみました。
Azureでは機能として可能でしたので、AWSでも簡単に出来るようにしてみました。
この記事がどなたかのお役に立てれば幸いです。