Cloud FormationでIP固定EC2のWindowsサーバーを起動し、リモートデスクトップでアクセスする方法

# はじめに
当記事はAWSのCloudFormationを用いてIPを固定したWindows Serverを立ち上げる方法を示しています。
AWS初心者が書いているので間違いやアドバイス等ございましたら指摘していただけると幸いです。

なお、当記事は大いに以下の記事様を参考に書かせていただいております。
[AWS CloudFormationでEC2を構築](https://qiita.com/tyoshitake/items/c5176c0ef4de8d7cf5d8)

# インフラ構成図
インフラ構成図は以下の通りです。
パブリックサブネットにWindows ServeのEC2を起動し、そこにElastic IPをアタッチしています。
また、ローカルのPCからクラウド上のWindows Serverへ接続するには特定のIPからのみアクセスできるように制限してあります。

![exlog-ec2-win.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/3a522a80-f8d1-e064-4479-e8fef6f4db47.png)

## テンプレート
テンプレートの解説は参考にさせていただいた記事様が非常に詳しく書いてくださっておりますので、そちらをご参考ください。
[AWS CloudFormationでEC2を構築](https://qiita.com/tyoshitake/items/c5176c0ef4de8d7cf5d8)
ここでは差分の解説を行います。

### EC2のAMIをwindows Serverに変更する

```yaml:yaml
  EC2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0500753a8b9c3c925 # 変更 Windows Server AMI
      KeyName: !Ref KeyName
      InstanceType: t2.micro
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PubSub
          GroupSet:
            - !Ref EC2SG
      UserData: !Base64 |
        #!/bin/bash
        sudo yum install -y git
      Tags:
          - Key: Name
            Value: ec2-a-cf
```

### EC2のSecurityGroupの追加

リモートデスクトップで接続するためのセキュリティーグループを追加します。
また、元記事の方ではMyIPを代入している部分はCidr表記で書く必要があり、IPだけを書き込むと型がおかしいと怒られます。
`!Sub ${MyIP}/32`と記述することで回避することができます。

```yaml:yml
  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: ec2-sg-cf
      GroupDescription: Allow RDP access only MyIP
      VpcId: !Ref VPC
      SecurityGroupIngress:
        # rdp　以下追加
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          CidrIp: !Sub ${MyIP}/32
```

### Elastic IPのアタッチ

Elastic IPは予め取得しておいてください。
Elastic IPのIDを`AllocationId`に書き換えます。

```yaml:yml
  # Elastic IPをEC2にアタッチ
  EC2EIPAttouch:
    Type: AWS::EC2::EIPAssociation
    Properties:
      AllocationId: eipalloc-[eip_id] # ElasticIPのIDに書き換える
      InstanceId: !Ref EC2
```

### Outputsの削除

IPは固定されているてOutputする必要がないので削除。

### 全体像

<details><summary>コード全体像</summary>

```yaml:yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Provision EC2

Parameters:
  KeyName:
    Description: The EC2 Key Pair to allow RDP access to the instance
    Type: "AWS::EC2::KeyPair::KeyName"

  MyIP:
    Description: IP address allowed to access EC2
    Type: String

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: vpc-cf

  IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: igw-cf

  # IGWをVPCにアタッチ
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW

  PubSub:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-1a
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      Tags:
        - Key: Name
          Value: pub-sub-a-cf

  PubSubRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: pub-sub-a-rt-cf

  # PubSub-インターネット間のルーティング
  PubSubToInternet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PubSubRT
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW

  # ルートテーブルをサブネットに関連付け
  AssoPubSubRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PubSub
      RouteTableId: !Ref PubSubRT

  EC2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0500753a8b9c3c925　# 変更 Windows Server AMI
      KeyName: !Ref KeyName
      InstanceType: t2.micro
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PubSub
          GroupSet:
            - !Ref EC2SG
      UserData: !Base64 |
        #!/bin/bash
        sudo yum install -y git
      Tags:
          - Key: Name
            Value: ec2-a-cf

  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: ec2-sg-cf
      GroupDescription: Allow RDP access only MyIP
      VpcId: !Ref VPC
      SecurityGroupIngress:
        # rdp　以下追加
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          # CidrIp: 0.0.0.0/0
          CidrIp: !Sub ${MyIP}/32

  # Elastic IPをEC2にアタッチ
  EC2EIPAttouch:
    Type: AWS::EC2::EIPAssociation
    Properties:
      AllocationId: eipalloc-[eip_id] # ElasticIPのIDに書き換える
      InstanceId: !Ref EC2

```
</details>

## スタックの作成

1. AWSにログインし、[CloudFormation](https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/)へアクセスし、スタックの作成をクリックする。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/c71cfc3d-40b2-0193-0e89-3079b76fc9e3.png)

2. ymlファイルをアップロードし、次へをクリックする。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/f48d74eb-b8ff-f961-f751-873cc393448f.png)

3. スタックの名前を適当に入力し、KeyPairと、自分のIPを入力し、次へボタンをクリックする。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/9e43eb47-42fd-9e03-31f8-e6b7479747a5.png)

4. 「ステップ3 スタックオプションの設定」は「次へ」をクリック、「ステップ4 レビュー」　は「送信」をクリックする。

5. 作成したスタックのステータスが「CREATE_IN_PROGRESS」から「CREATE_COMPLATE」に変わるのを待つ。

6. 「EC2」　→ 「インスタンス」　へ移動する。

7. 起動したEC2インスタンスを選択し、「接続」ボタンをクリックする。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/7ea39c1f-4525-5651-70db-ccbe5d862fbf.png)

8. 「RDPクライアント」タブを選択し、「リモートデスクトップファイルのダウンロード」をクリックしダウンロードし、「パスワードを取得」ボタンをクリックする。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/10d9aaf7-10aa-30d5-61d9-73ab8aec13fd.png)

9. 「プライベートキーファイルのアップロード」ボタンをクリックし、手順5で設定したキーペアをアップロードし、「パスワードを複合化」ボタンをクリックする。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/5be98c33-f6be-94fa-9323-a5b4917c74a6.png)

10. パスワードが表示されるのでメモする。

11. 手順8でダウンロードしたリモートデスクトップファイルを使い、リモートデスクトップ接続をする。
    （windowsPCを用いている場合はリモートデスクトップアプリから接続する。MacPCの場合はApp StoreからMicrosoft Remote Desktopアプリをダウンロードして利用する。当記事はMac OSで実行している。）

12. パスワードを聞かれるので、先程メモしたパスワードを入力し、ボタンをクリックしていくとWindows Serverへ接続される。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/0db4e07f-aa2c-c41a-19e7-dd6ce1c78fe0.png)

13. Windows Serverが不要になったらCloudFormationの起動したスタックを選択し、「削除」ボタンをクリックすることで削除することができる。

# 終わりに

煩雑なAWSアーキテクトをCloudFormationと数クリック程度で構築できるのは非常に便利な反面、書き方が個人的にはまだ難しくドキュメントと睨めっこな状態です。
もっと精進していきたいと思います。


# 参考

* [AWS CloudFormationでEC2を構築](https://qiita.com/tyoshitake/items/c5176c0ef4de8d7cf5d8)
* [AWS CloudFormation Documentation公式](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html)