RainでEC2を起動する

# はじめに
[前回](https://qiita.com/handy-dd18/items/ce1ff79b2c7868309c16)の記事でRainの環境設定を実施しました。

今回はそのRainを使用してEC2を構築してみます。

# 環境
Windows 10 Home
WSL(Ubuntu 20.04)
AWS CLI 2.2.29

# 前提
EC2を構築するSubnetは作成済み
SG作成済み(ローカルPCからのRDPポートをインバウンド許可)
keypair作成済み

# 手順
## ymlファイル作成
まずはRainで使用するCloudformationのymlファイルを作成します。

通常であれば以下のドキュメントを参照しながら作成するところですが

* [AWS::EC2::Instance](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html)

以下のコマンドを使用するとCloudformationで利用するAWSリソースの一覧を表示できるので、

```
$ rain build -l
AWS::ACMPCA::Certificate
AWS::ACMPCA::CertificateAuthority
AWS::ACMPCA::CertificateAuthorityActivation
AWS::AccessAnalyzer::Analyzer
AWS::AmazonMQ::Broker
AWS::AmazonMQ::Configuration
AWS::AmazonMQ::ConfigurationAssociation
AWS::Amplify::App
AWS::Amplify::Branch
AWS::Amplify::Domain
AWS::ApiGateway::Account
AWS::ApiGateway::ApiKey
AWS::ApiGateway::Authorizer
AWS::ApiGateway::BasePathMapping
AWS::ApiGateway::ClientCertificate
AWS::ApiGateway::Deployment
AWS::ApiGateway::DocumentationPart
AWS::ApiGateway::DocumentationVersion
AWS::ApiGateway::DomainName
AWS::ApiGateway::GatewayResponse
AWS::ApiGateway::Method
~省略~
```
<br>
その中の作成したいAWSリソースを指定してコマンドを実行して、対象のAWSリソースのパラメータが含まれたCloudformationテンプレートをコンソールに表示して確認します。

```
$ rain build AWS::EC2::Instance
AWSTemplateFormatVersion: "2010-09-09"

Description: Template generated by rain

Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      AdditionalInfo: CHANGEME # Optional
      Affinity: CHANGEME # Optional
      AvailabilityZone: CHANGEME # Optional
      BlockDeviceMappings:
        - DeviceName: CHANGEME
          Ebs: # Optional
            DeleteOnTermination: false # Optional
            Encrypted: false # Optional
            Iops: 0 # Optional
            KmsKeyId: CHANGEME # Optional
            SnapshotId: CHANGEME # Optional
            VolumeSize: 0 # Optional
            VolumeType: CHANGEME # Optional
          NoDevice: {} # Optional
          VirtualName: CHANGEME # Optional
      CpuOptions: # Optional
        CoreCount: 0 # Optional
        ThreadsPerCore: 0 # Optional
      CreditSpecification: # Optional
        CPUCredits: CHANGEME # Optional
      DisableApiTermination: false # Optional
      EbsOptimized: false # Optional
      ElasticGpuSpecifications:
~省略~
```
<br>
このテンプレートをファイルに出力して、そこから必要な部分のみ残しながらymlファイルを作成していきます。

```
$ rain build AWS::EC2::Instance > Ec2_Windows_Rain_20210818.yml
```
<br>
今回は以下のようなymlファイルを作成しました。
Subnetは作成済みなのでAZ-AかAZ-Cで構築するかを選べるようにして、AMIとインスタンスタイプ、Nameタグをパラメータで渡せるようにしました。

```
WSTemplateFormatVersion: "2010-09-09"

Description: Template generated by rain

Mappings:
  SubnetMap:
    subnetA:
      SubnetId: subnet-XXXXXXXXXXXXXXXXX
    subnetC:
      SubnetId: subnet-YYYYYYYYYYYYYYYYY

Parameters:
  Subnet:
    Type: String
    AllowedValues:
      - subnetA
      - subnetB
    Default: subnetA
  ImageID:
    Description: AMI
    Type: String
  InstanceType:
    Description: Instance Type
    Type: String
  HostName:
    Description: EC2 Name
    Type: String

Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: ec2-iam-role
      ImageId:
        Ref: ImageID
      InstanceType:
        Ref: InstanceType
      KeyName: test_keypair
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          SubnetId:
            !FindInMap [ SubnetMap , !Ref Subnet , SubnetId ]
          GroupSet:
            - sg-ZZZZZZZZZZZZZZZ
      Tags:
        - Key: Name
          Value:
            Ref: HostName
```


## ymlファイル実行
パラメータに渡すAMIはAWSが提供しているWindows_Server-2019-Japanese-Full-Baseの最新AMIを使用したいので、CLIで以下のコマンドを実行してAMI IDを取得します。

```
$ aws ssm get-parameters --names /aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-Base --query 'Parameters[0].[Value]' --output text
ami-04b4defd45075280f
```
<br>
Rainのデプロイコマンドを実行します。
この時特に指定しなければ、ymlファイルの名前と同じStackが作成されます。

```
$ rain deploy Ec2_Windows_Rain_20210818.yml --params SubnetType='subnetA',ImageID='ami-04b4defd45075280f',InstanceTypeName='t3.micro',HostName='TEST-SERVER'

Preparing template 'Ec2_Windows_Rain_20210818.yml' ˙ ·Loading AWS config ˙ ·Preparing template 'Ec2_Windows_Rain_20210818.yml' CloudFormation will make the following changes:
Stack Ec2-Windows-Rain-20210818:
  + AWS::EC2::Instance MyInstance
Do you wish to continue? (Y/n) Y
Deploying template 'Ec2_Windows_Rain_20210818.yml' as stack 'Ec2-Windows-Rain-20210818' in ap-northeast-1.
Stack Ec2-Windows-Rain-20210818: CREATE_COMPLETE
Successfully deployed Ec2-Windows-Rain-20210818
```

<br>
CloudformationコンソールからもStackが作成されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/db396ef8-36b6-614f-4d5d-878db8f8a2d3.png)

<br>
無事にEC2が構築されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/dc5176a2-80e4-4bcf-d429-8739d1699bca.png)

# EC2ログイン
構築したEC2にログインしてみます。
通常コンソールからKeypair使ってパスワード生成することが多いですが、今回はCLIでパスワードを生成してみます。

以下のコマンドを実行するとパスワードが生成できます。

```
$ aws ec2 get-password-data --instance-id i-XXXXXXXXXXXX --priv-launch-key 'test_keypair.pem' --query 'PasswordData' --output text
```

<br>
注意点として「--priv-launch-key」でローカルのkeypairを指定していますが、最初フルパス指定をして実行したところ「priv-launch-key should be a path to the local SSH private key file used to launch the instance.」のエラーが出力されました。

keypairが格納されているフォルダ直下に移動して実行するとパスワードが想定通り取得されたので、コマンドを実行するときは実行する場所に注意が必要です。

生成したパスワードを使ってRDPログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/fbb21523-dcc7-9c4d-2fc8-0563797f008d.png)

<br>
問題なくログインができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/042b5115-6dfd-8334-ddd2-64b516b2f7c3.png)

# お片付け
作成したEC2の削除は以下のコマンドを実行するだけです。引数にはStack名を指定します。
※多少時間はかかります

```
$ rain rm Ec2-Windows-Rain-20210818
Stack Ec2-Windows-Rain-20210818: CREATE_COMPLETE
Are you sure you want to delete this stack? (y/N) y
Successfully deleted stack 'Ec2-Windows-Rain-20210818'
```

処理中はDELETE_IN_PROGRESSと表示されるなど、現在どういうステータスなのかが一目でわかりやすくなっています。

<br>
削除したいStack名がわからない場合は、以下のコマンドで現在のStack一覧を表示させることができるので、そこで確認してみてください。

```
$ rain ls
CloudFormation stacks in ap-northeast-1:
  Ec2-Windows-Rain-20210818: CREATE_COMPLETE
```

# おわりに
ymlファイルの作成に少し時間がかかりましたが、問題なくRainでEC2の構築ができました。
本当は色々とエラーとか出ていたのですが、Rainを使用することで同名のStackがあった場合に自動で削除の上実行されたりとかなりCloudformationの実行が楽になりました。
開発で使う分には普通に使いやすいのでお勧めです。