背景

プライベートサブネットのEC2にSSH接続したいことがあります。

今回のケースは、エクスポートしたDBデータをAWS上のRDSに移行したいというものでした。エクスポートのデータはpostgresqlのものでして、これをpsqlコマンドを使用してAWSに構築したRDSにインポートしたいのです。

しかし、RDSはプライベートサブネットに配置しています。インターネットから直接インポートはできません。

RDSの操作するためにEC2を立てるのは仕方ないにしても、パブリックIPをもたせる踏み台サーバを作るのは怖いです。また、SGで通信を制限するとしてもインターネットに公開されている踏み台サーバをメンテするのも気が滅入ります。

(ここで言っているプライベートサブネットはインターネットと直接通信できないサブネットのこと。)

どうやって実現するか

EICエンドポイントというのがあり、それを活用しました。

ググったら以下に掲載されてました。2023年1月13日付の記事なので、新しい機能のようです。

Amazon EC2 Instance Connect でパブリック IP アドレスなしで SSH 接続と RDP 接続が可能に

terraformで動かしたいので、以下のようにしました。(そのままコピペしているので、terraformのサブモジュールで作ったリソース名になっている

resource "aws_ec2_instance_connect_endpoint" "eic" {
    subnet_id = module.private_subnet.subnet_db_1b_id
    security_group_ids = aws_security_group.ssh_eic.id
    preserve_client_ip = true 

    tags = {
        Name = "eic"
    }
}

EIC Endpointのセキュリティグループはこちら。22番を開ければsshが通ります。ingressのciderを狭めれば、ある程度のセキュリティは確保できそう。

resource "aws_security_group" "ssh_eic" {
    name        = "eic-sg"
    description = "EIC Security Group For Test"
    vpc_id            = module.vpc.vpc_id

    ingress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }

    egress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
}

EICエンドポイントを使用してログインするには、awsクライアントを使用します。i-xxxxxxxxxxは接続したいインスタンスIDです。

aws ec2-instance-connect ssh --instance-id i-xxxxxxxxxx --connection-type eice

使ってみて

接続のコマンドを使ってみてわかったのは、SSHの鍵を使用しないということです。

SSH鍵の管理もしなくていいので、気が楽になります。