AWS CDK で構築した EC2 インスタンスに EC2 Instance Connect で接続する

2024.04.12

こんにちは、CX 事業本部製造ビジネステクノロジー部の若槻です。

前回は Amazon EC2 インスタンスを AWS CDK で構築してみました。

さてこの作成したインスタンスに接続をしてみたいところですが、EC2 インスタンスへの接続にはいくつかの方法があります。その中でもコンソールから Linux インスタンスに簡単に接続する方法として EC2 Instance Connect があります。

今回は、AWS CDK で構築した EC2 インスタンスに EC2 Instance Connect で接続する方法を確認してみました。

やってみた

前提条件

EC2 Instance Connect で EC2 インスタンスに接続するための前提条件は以下に記載されています。

EC2 Instance Connect がプリインストールされている AMI は以下となります。今回は Ubuntu 22.04 の AMI から起動した EC2 インスタンスを使用します。

  • AL2023
  • Amazon Linux 2 2.0.20190618 以降
  • macOS Sonoma 14.2.1 以降
  • macOS Ventura 13.6.3 以降
  • macOS Monterey 12.7.2 以降
  • Ubuntu 20.04 以降

またインスタンスに関連付けられているセキュリティグループで、EC2_INSTANCE_CONNECT の IP アドレス範囲からのインバウンド SSH トラフィックが許可されている必要があります。アドレス範囲は以下の URL から取得できます。

上記をブラウザで開いて、EC2_INSTANCE_CONNECT で検索し、使用したいリージョンの IP アドレス範囲を取得しておきます。このアドレス範囲は CDK での実装時に使用します。

CDK コード

次のようなスタック定義のコード(TypeScript)で CDK アプリケーションを実装します。

SecurityGroup Construct の addIngressRule メソッドを使用して、EC2 Instance Connect 用のインバウンドルールを追加しています。

lib/cdk-sample-stack.ts

import { aws_ec2, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const vpcCidr = '10.100.0.0/16';
    const instanceAmiId = 'ami-0eba6c58b7918d3a1'; // Ubuntu Server 22.04 LTS (HVM), SSD Volume Type (64-bit (x86))
    const region = 'ap-northeast-1';
    const ec2InstanceConnectIpRange = '3.112.23.0/29';

    // VPC を作成
    const vpc = new aws_ec2.Vpc(this, 'Vpc', {
      ipAddresses: aws_ec2.IpAddresses.cidr(vpcCidr),
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'public',
          subnetType: aws_ec2.SubnetType.PUBLIC,
        },
      ],
      maxAzs: 1,
    });

    // セキュリティグループを作成
    const securityGroup = new aws_ec2.SecurityGroup(this, 'SecurityGroup', {
      vpc,
    });

    // セキュリティグループに EC2 Instance Connect 用のインバウンドルールを追加
    securityGroup.addIngressRule(
      aws_ec2.Peer.ipv4(ec2InstanceConnectIpRange),
      aws_ec2.Port.tcp(22),
      'SSH by EC2 Instance Connect in ap-northeast-1'
    );

    // インスタンスを作成
    new aws_ec2.Instance(this, 'Instance', {
      vpc,
      securityGroup,
      instanceType: aws_ec2.InstanceType.of(
        aws_ec2.InstanceClass.T2,
        aws_ec2.InstanceSize.MICRO
      ),
      machineImage: aws_ec2.MachineImage.genericLinux({
        [region]: instanceAmiId,
      }),
      requireImdsv2: true,
    });
  }
}

CDK デプロイをして、各種リソースを作成します。

EC2 Instance Connect で接続してみる

マネジメントコンソールで、作成した EC2 インスタンスを選択し、Connect ボタンをクリックします。

[EC2 Instance Connect]タブを選択し、[Connect]ボタンをクリックします。

するとブラウザの別タブが開き、EC2 インスタンスに接続されます。この画面からコマンドを実行することができます。

インバウンドルールを追加しない場合

EC2 Instance Connect 用のインバウンドルールをセキュリティグループに追加しない場合の挙動を確認してみます。

lib/cdk-sample-stack.ts

import { aws_ec2, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const vpcCidr = '10.100.0.0/16';
    const instanceAmiId = 'ami-0eba6c58b7918d3a1'; // カタログで確認した AMI ID を指定
    const region = 'ap-northeast-1';
    const ec2InstanceConnectIpRange = '3.112.23.0/29';

    // VPC を作成
    const vpc = new aws_ec2.Vpc(this, 'Vpc', {
      ipAddresses: aws_ec2.IpAddresses.cidr(vpcCidr),
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'public',
          subnetType: aws_ec2.SubnetType.PUBLIC,
        },
      ],
      maxAzs: 1,
    });

    // セキュリティグループを作成
    const securityGroup = new aws_ec2.SecurityGroup(this, 'SecurityGroup', {
      vpc,
    });

    // // セキュリティグループに EC2 Instance Connect 用のインバウンドルールを追加
    // securityGroup.addIngressRule(
    //   aws_ec2.Peer.ipv4(ec2InstanceConnectIpRange),
    //   aws_ec2.Port.tcp(22),
    //   'SSH by EC2 Instance Connect in ap-northeast-1'
    // );

    // インスタンスを作成
    // 略
  }
}

EC2 Instance Connect による接続を試みると、エラーとなり接続できません。

Failed to connect to your instance
EC2 Instance Connect is unable to connect to your instance. Ensure your instance network settings are configured correctly for EC2 Instance Connect. For more information, see EC2 Instance Connect Prerequisites at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-connect-prerequisites.html.

パブリック IP アドレスを付与しない場合

VPC からパブリックサブネットを削除して、パブリック IP アドレスを付与しない場合の挙動を確認してみます。

lib/cdk-sample-stack.ts

import { aws_ec2, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const vpcCidr = '10.100.0.0/16';
    const instanceAmiId = 'ami-0eba6c58b7918d3a1'; // カタログで確認した AMI ID を指定
    const region = 'ap-northeast-1';
    const ec2InstanceConnectIpRange = '3.112.23.0/29';

    // VPC を作成
    const vpc = new aws_ec2.Vpc(this, 'Vpc', {
      ipAddresses: aws_ec2.IpAddresses.cidr(vpcCidr),
      // subnetConfiguration: [
      //   {
      //     cidrMask: 24,
      //     name: 'public',
      //     subnetType: aws_ec2.SubnetType.PUBLIC,
      //   },
      // ],
      maxAzs: 1,
    });

    // 中略
  }
}

インスタンスに接続をしようとメニューを開くと、そもそも EC2 Instance Connect による接続の試行ができなくなります。

No public IPv4 address assigned
With no public IPv4 address, you can't use EC2 Instance Connect. Alternatively, you can try connecting using EC2 Instance Connect Endpoint .

インスタンスにパブリック IP アドレスがない場合は、EC2 Instance Connect Endpoint を使用する必要があります。

おわりに

AWS CDK で構築した EC2 インスタンスに EC2 Instance Connect で接続してみました。

SSH での接続と異なり端末側に SSH キーなどのダウンロードを行う必要がないため、手軽に接続できるのは便利です。

参考

以上