電通総研 テックブログ

電通総研が運営する技術ブログ

AWS CloudShellからSSMでポートフォワーディング

ISID X(クロス)イノベーション本部 の三浦です。
筆者の関わっている案件では、コンテナ利用、AWS Fargate利用を進めております。
AWS Fargateのお手軽さは非常に重宝しております。
しかし、そこで問題になってくるのが、管理作業(例:SQL実行、EFSへのファイル配置)をどうするかです。
アプリケーション本体をせっかくAWS Fargateでやっているので、管理作業もできるだけサーバーレスでやりたいですよね?

で、以前の記事では、『業務用の端末⇒AWS_Fargate(ポートフォワード)⇒RDS』といった内容を書きました。

AWS FargateからSSMでRDSに接続

しかし、これには問題点がありまして、業務端末からのDBへの直接接続はセキュリティーポリシー、データ持ち出しの観点で推奨されない場合があります。
そこで他のパターンとしては、『業務用の端末⇒ECS Exec(コンテナにログイン)⇒RDS』といった手段があるのですが、これには下記のような課題があります。

  • コンテナ内に本来不要なDB接続用のライブラリのインストールが必要
  • 巨大な結果セットを返すような不適切なSQL実行時にECSタスクのリソース(例:メモリ)を使用してしまいサービスによくない影響が出る
  • コンテナ内に入ってオペレーションするのは、セキュリティー的に望ましくない場合がある
  • コンテナに本来不要なオペレーション用の権限をつけなければならない場合がある(例:データ授受用のs3へのアクセス権)

ということで、業務用端末からDBへ直接接続せず、下記のようにセキュアなAWS CloudShellから下記のような経路で接続できないか試します。

『業務用の端末⇒AWS CloudShell⇒AWS Fargate(ポートフォワード)⇒RDS』

目次

接続失敗編

下記のように普通にフロントでstart-sessionするとstart-sessionのプロセスがフロントに残ることでそのままでは使えません。
ローカルならば他のターミナルを開いてそちらでDB接続のコマンドを実行すればいいのですが、AWS CloudShellではそれができません。

aws ssm start-session \
--target ecs:${clusterID}_${taskid}_${CONTAINER_ID}  \
--document-name AWS-StartPortForwardingSessionToRemoteHost    \
--parameters "{\"host\":[\"XXXXXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com\"],\"portNumber\":[\"5432\"], \"localPortNumber\":[\"5432\"]}" 

接続成功編

しかし、下記のようにstart-sessionをバックグランド実行することによりAWS CloudShellからポートフォワードして、RDSに接続可能です。

(aws ssm start-session \
--target ecs:${clusterID}_${taskid}_${CONTAINER_ID}  \
--document-name AWS-StartPortForwardingSessionToRemoteHost    \
--parameters "{\"host\":[\"xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com\"],\"portNumber\":[\"5432\"], \"localPortNumber\":[\"5432\"]}" \
 \
)& \

export PGPASSWORD=xxxxxxxxx
psql -U userName -p 5432 -h localhost


終了処理は下記の「ps + kill」で可能です。

ということで、ちょっとした工夫でAWS CloudShellからRDSにポートフォワードで接続できるという内容でした。

執筆:@miura.toshihiko、レビュー:寺山 輝 (@terayama.akira)
Shodoで執筆されました