APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

【AWS】EC2 Instance Connect EndPointを利用してローカルからAurora/RDSに接続してみる

目次

はじめに

こんにちは、クラウド事業部の上村です。
今回は、EC2 Instance Connect Endpointを利用してポートフォワーディングして、RDSに接続を試してみようと思います。 以前は、EC2 Instance Connect Endpoint でRDSに直接接続することが可能でしたが修正されてしまい、EC2を経由する必要があります。

環境

ローカル環境

Windows 10
PowerShell
awscli v2

前準備

先に下記リソースの作成は完了している前提で進めます。 VPC
プライベートサブネット
踏み台サーバ (AmazonLinux2023)
KeyPair
Aurora (MySQL)

セキュリティグループの設定

踏み台・EICエンドポイント・Auroraのセキュリティグループの設定を行います。

・EICエンドポイントのセキュリティグループ
インバウンドルールは必要なく、アウトバウンドルールでALL Trafficと設定してください。

・踏み台のセキュリティグループ
インバウンドルールには、Port:22でEICエンドポイントのセキュリティグループIDを指定します。 ※後述するEICエンドポイント作成時にクライアント IP の保持を設定することでクライアントIPに絞ることが可能です。

タイプ プロトコル ポート範囲 ソース
SSH TCP 22 sg-xxx(EICのSG)

・Auroraのセキュリティグループ
インバウンドルールに、Port:3306で踏み台セキュリティグループIDを指定します。

タイプ プロトコル ポート範囲 ソース
MYSQL/Aurora TCP 3306 sg-xxx(踏み台のSG)

EICエンドポイントの作成

下記のように設定を進めます。 セキュリティグループは、EC2 Instance Connect Endpoint用に作成したものを指定してください。

IAM関連の作成

awscliを利用するので、今回はAssumeRoleから権限を取得して実行します。
ポリシー作成後は、IAMロール作成及びIAMユーザ(ec2_connect_tunnel_testuser) 作成 を行ってください。
AssumeRole実行できるIAMユーザを制限するために信頼関係で制限しました。

IAMユーザ用ポリシー (AssumeRoleForTunnelAccessPolicy)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::AWSアカウント番号:role/Ec2InstanceConnectOpenTunnelRole"
            ]
        }
    ]
}

IAMロール用ポリシー(Ec2InstanceConnectOpenTunnelRole)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EC2InstanceConnect",
            "Action": "ec2-instance-connect:OpenTunnel",
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Sid": "SSHPublicKey",
            "Effect": "Allow",
            "Action": "ec2-instance-connect:SendSSHPublicKey",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "ec2:osuser": "ami-username"
                }
            }
        },
        {
            "Sid": "Describe",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceConnectEndpoints"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

IAMロールの信頼関係

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AWSアカウント番号:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringLike": {
                    "aws:PrincipalArn": "arn:aws:iam::AWSアカウント番号:user/ec2_connect_tunnel*"
                }
            }
        }
    ]
}

接続用のスクリプト

接続用のスクリプトを実行する前に、IAMユーザのCredentialsを登録します。
作成時に取得したCredentials情報で進めてください。

aws configure —profile test-user

スクリプトは下記になります。
環境に合わせて変数を変更してください。

# AWS 設定
$roleArn = "arn:aws:iam::123456789:role/Ec2InstanceConnectOpenTunnelRole"
$instanceId = "i-xxxxxxx"
$localPort = 10022
$remotePort = 22
$sessionName = "Ec2InstanceConnectSession_" + [System.Guid]::NewGuid().ToString().Substring(0,8)
$profileName = "test-user"
$region = "ap-northeast-1"
$keyFilePath = "example.pem"
$dbhost = "your-db-host"

# AssumeRole の実行
Write-Output "Assuming role: $roleArn ..."
$assumeRole = aws sts assume-role --role-arn $roleArn --role-session-name $sessionName --profile $profileName | ConvertFrom-Json

if (-not $assumeRole.Credentials) {
    Write-Output "Error: AssumeRole failed."
    exit 1
}

# 取得した一時認証情報を環境変数に設定
$env:AWS_ACCESS_KEY_ID = $assumeRole.Credentials.AccessKeyId
$env:AWS_SECRET_ACCESS_KEY = $assumeRole.Credentials.SecretAccessKey
$env:AWS_SESSION_TOKEN = $assumeRole.Credentials.SessionToken
$env:AWS_DEFAULT_REGION = $region

Write-Output "Successfully assumed role. Credentials set."

# 確認のため現在の認証情報を表示
aws sts get-caller-identity

# open-tunnel の実行
Write-Output "Opening tunnel to EC2 instance: $instanceId ..."
aws ec2-instance-connect open-tunnel --instance-id $instanceId --local-port $localPort --remote-port $remotePort

Write-Output "Tunnel successfully opened!"

# SSH接続 + DB接続
ssh -i $keyFilePath ec2-user@localhost -p $localPort -L 3306:${dbhost}:3306 -f -N 

実行権限を設定する必要がある場合

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

準備はできましたので、実行してみます。

無事に実行できました。
こちらはそのまま起動させておき、今回はクライアントツールとして、A5:SQL Mk-2を利用してローカル環境からRDSに接続します。

RDSに接続できていることを確認できました。

まとめ

少し手間な部分もありましたが、無事ローカル環境から踏み台を経由してRDS/Auroraに接続できました。 どなたかの参考になれば幸いです。