WindowsAMIのEC2インスタンスにRDP接続する

業務の都合で、MacPCからWindowsAMIで立ち上げたEC2インスタンスにRDP接続したかったので、CDKでサクッと作ってみる。



## 必要なもの

- AWS CDK
- AWS CLI
- Windows Remote Desktop



## 手順

### 1.あらかじめEC2に使用するキーペアを作っておく

```sh
# キーペアを作成する
% aws ec2 create-key-pair
	--key-name sandbox-key \
	--query 'KeyMaterial' \
	--output text > sandbox-key.pem

# ファイルがDLされたことを確認
% ls -l | grep sandbox-key.pem
-rw-r--r--@   1 hogehoge  staff    1679 11  2 02:40 sandbox-key.pem
```

作成したキーペアは通常、`chmod 400`によって所有者のみの読み取り専用にするが、今回はRPD接続用のパスワードを入手するためにEC2コンソールにアップロードするだけの用途なので省略する。また、キーペアは秘密鍵なので安全に保管する。



### 2.EC2インスタンスをCDKでデプロイ

（CDKをインストールし、CDKプロジェクトを作成して諸準備をした前提で）下記の2ファイルを用意する。



▫️bin/sandbox-cdk.ts

```typescript
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { WindowsEc2Stack } from '../lib/windows-rdp';

const app = new cdk.App();
new WindowsEc2Stack(app, 'WindowsEc2SandboxStack', {});
```



▫️lib/windows-rdp.ts

```typescript
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class WindowsEc2Stack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // VPCの作成
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      vpcName: 'sandboxVpc',
      maxAzs: 2,
      natGateways: 0,
    });

    const publicSubnets = vpc.publicSubnets;

    // セキュリティグループの作成
    const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
      securityGroupName: 'sandboxSg',
      vpc,
      allowAllOutbound: true,
      description: 'Allow RDP access',
    });

    // RDPのポートを開放
    const myIp = 'XX.XX.XX.XX/32' // IPアドレスは自分のWi-FiのグローバルIP等を入れる
    securityGroup.addIngressRule(ec2.Peer.ipv4(myIp), ec2.Port.tcp(3389), 'Allow RDP access');

    // Windowsインスタンスの作成
    new ec2.Instance(this, 'WindowsInstance', {
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
      // AMIIDはSSMパラメータから撮ってきたほうがよい
      // https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/parameter-store-public-parameters-ami.html
      machineImage: ec2.MachineImage.fromSsmParameter('/aws/service/ami-windows-latest/Windows_Server-2022-Japanese-Full-Base'),
      vpc,
      vpcSubnets: {subnets: publicSubnets},
      securityGroup,
      keyName: 'sandbox-key',
    });
  }
}

```



ここまで準備できたらデプロイ

```sh
npx cdk deploy WindowsEc2Stack
```



### 3.RDPへの接続

ここから先はクラスメソッドさんの記事を参照したので、リンクを貼っておきます。

https://dev.classmethod.jp/articles/conn-ec2-win-with-rdp/



上記リンクの「RDPでの接続手順」に従って操作すれば、下図のようにWindowsのEC2に対してリモートデスクトップ接続ができるはず！:tada:

![スクリーンショット 2024-11-02 3.03.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1345096/fb7e8e1f-9949-b578-d507-8eefa3fd78c8.png)


## 各種コメント

- AMIIDは公式のSSMパラメータから参照してくるのがベター

https://aws.amazon.com/jp/blogs/news/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/parameter-store-public-parameters-ami.html

https://zenn.dev/mnod/articles/0d817d68e60503

- 今回のサンプルコード`lib/windows-rdp.ts`では、EC2インスタンスにEIPをアタッチしていないため、当然、インスタンス停止後に再開するたびにパブリックIPが変わる。すると当然、RDPファイルの中身も変わる。
  - コスト削減のために使用していない時間帯はインスタンスを停止したいが、EIPをつけると今度はインスタンスの停止時に料金が発生するため。毎回RDPファイルをDLしなおすのが面倒な場合はCDKのコードでEIPを追記する必要あり。