MENU

AWS CDKでインフラ構築⑤(SSMでプライベートサブネットのEC2にアクセスする)

やりたいこと

プライベートサブネット内に立てたEC2にセッションマネージャーでアクセスしたい。

やること

プライベートサブネット内にあるEC2はインターネットアクセスが出来ないので、何もしないとSSMには接続できません。

色々調べてみたんですが、接続するには以下の設定が必要になるらしい。

  1. VPCにssm用のエンドポイントを作成する。

  2. EC2用IAMロールに、SSMアクセスに必要なIAMポリシーを紐づける。

  3. EC2インスタンスにSSMエージェントをインストールする。

一つ一つ見ていきます。

VPCにssm用のエンドポイントを作成する

EC2からSSMに接続するには、下記3つのエンドポイントをそれぞれ作る必要があります。

  • com.amazonaws.[vpcRegion].ssm

  • com.amazonaws.[vpcRegion].ec2messages

  • com.amazonaws.[vpcRegion].ssmmessages

エンドポイントは、 [VPC] > [エンドポイント] から作成できます。

[留意点]

  • サブネットはEC2の存在するプライベートサブネットを指定する

  • プライベートDNS名は有効にする

  • セキュリティグループはインバウンドルールに下記の設定を加えたものを作成してアタッチする。

    • タイプ:HTTPS
    • ソース:対象VPCのサブネットのCIDR

構成図にするとこんな感じになります。

EC2用IAMロールに、SSMアクセスに必要なIAMポリシーを紐づける

SSMアクセスに必要なIAMポリシーは AmazonSSMManagedInstanceCore です。 CDKで上記ポリシーを持ったロールを作成し、EC2にアタッチします。

[ロール作成]

    import {  aws_ec2 as ec2, aws_iam as iam } from 'aws-cdk-lib';
    // EC2用のロールを作成
    const ec2Role = new iam.Role(this, 'ec2-role', {
      assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName(
          "AmazonSSMManagedInstanceCore"
        ),
      ],
      roleName: `cdk-test-ec2-role`
    });

[EC2へアタッチ]

    import {  aws_ec2 as ec2, aws_iam as iam } from 'aws-cdk-lib';
    // EC2インスタンス作成
    const ec2Instance = new ec2.Instance(this, 'ec2-instance', {
      vpc: vpc,
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
      machineImage: machineImage,
      securityGroup: ec2SecurityGroup,
      availabilityZone: 'us-east-1a',
      vpcSubnets: {
        subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
      },
      role: ec2Role,  // ここで紐づけ
    })

これで cdk deploy すれば環境に反映されます。

EC2インスタンスにSSMエージェントをインストールする

SSMエージェントは、Amazon Linux2ならデフォルトでインストールされているらしいです。

なので、AMIにAmazonLinux2を指定する形で対応してしまいました。

[AMI作成]

    import {  aws_ec2 as ec2 } from 'aws-cdk-lib';
    const machineImage =  new ec2.AmazonLinuxImage({
      generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
      cpuType: ec2.AmazonLinuxCpuType.X86_64,
    });

参考:class AmazonLinuxImage · AWS CDK

[EC2にアタッチ]

    import {  aws_ec2 as ec2, aws_iam as iam } from 'aws-cdk-lib';
    // EC2インスタンス作成
    const ec2Instance = new ec2.Instance(this, 'ec2-instance', {
      vpc: vpc,
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
      machineImage: machineImage, // ここで紐づけ
      securityGroup: ec2SecurityGroup,
      availabilityZone: 'us-east-1a',
      vpcSubnets: {
        subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
      },
      role: ec2Role,  
    })

これでSSMに必要な設定は完了です。

[AWS Systems Manager] > [Session Manager] > [セッションの開始] で、下記の様にインスタンスが表示されていればOKです。

もしターゲットインスタンスが一つも表示されていなければ、どこかしらで設定を失敗している可能性があります。

参考