え!! ECS exec でファイルの送受信を!?

出来らぁっ!!!(出来ません)

こんにちは。tonamel チーム所属の瀬戸です。

最近 メルブラ新作 が出てめちゃくちゃテンション上がってしまって近頃は毎週末友人の都合が付いたときは5、6時間対戦してボコボコにされる生活を過ごしてます。もうすこし強くなりたい。

弊社、格ゲーおじさんがたくさんいるので中にはメルブラおじさんもいるような気配を感じているのですが、自分みたいな舞い上がり方してるおじさんはいないみたいでちょっと寂しいです。

またキーボードでメルブラやりたいな〜って思います。(steam版はキーボードに対応してるのですが、メニューと対戦のボタンで重複設定が出来ないみたいで良い感じに設定できず。残念)

あと UNI もメルブラが落ち着いたら更新来ると嬉しいな〜 期待してます 鴨音さん


ということで(?)この記事は Tech KAYAC Advent Calendar 2021 11日目の記事になります。

本番オペレーションにも ECS Exec は便利なのですが

現在自分が所属している tonamel のデプロイ作業のほとんどは CircleCI で manual approve から ecspresso deploy を走らせることで完結しているのですが、DBのマイグレーションだったり一部のデータ反映は手動で行っています。

そういった手動作業には専用のタスクを立ち上げて ssm session manager 越しに ssh でログインしてコマンドを叩くという感じなのですが、近頃は ecs exec なるものがあり「 ecs exec でええんちゃう? ecspresso exec 出来るで(cv大空直美」という雰囲気が漂っていたのでひとまず開発環境で ssh を捨ててみました。

  • --command="bash" だと root で入ってしまうので作業用のユーザを用意していて都合が悪い場合は sudo -u [user] bash すると良さそう
  • 環境変数が消えるので -E つけると良さそう
  • 環境変数の HOME が /root のままで困る場合は -H つけると良さそう

みたいな細々とした調整して最終的に ecspresso exec --command="sudo -H -E -u [user] bash" --container="xxx" --color で作業用ユーザで入る ssh と変わらないログインが実現できています。Makefile にしてあるのでサクっと入れます。

基本的にこれで問題なかったのですが scp したいなと思った時にちょうど良い代替が意外と無いことに気づきました。オペレーション用にリポジトリに入れてた入力ファイルが少しミスっててちょっと書き換えて送り込みたいんだけど commit & push して CI を待つのちょっと重いな〜というとき(あるんか?) scp がとても恋しくなりそうです。

そこで今回は scp の代替について思いを馳せてみました

scp の代わりに

ssh-server

最初から裏切っていきますが ssh は便利なので ssh-server を入れて良いなら素直に入れるのはアリだなと思いました。 さよなら ECS Exec…

ECS Exec を捨てて ssh する時の困りポイントとしては aws ssm session-start--target の指定が ssm-agent を自前で立ててたときより少し特殊なので --target を取得する何がしかの補助ツールがないとちょっと面倒くさそうなところ。

--target の指定の部分は以下の記事が参考になります

so-wh.at

s3

既存のタスク定義を使い回してるといった ssh-server を入れづらい場合の代替として、S3経由はありかもしれません。社内でも「そういうときは s3 を使ってますね〜」という話を聞いたり、例えば以下の様なツールが作られるぐらいには王道のようです。

zenn.dev

最悪 awscli と s3への読み書き権限があれば良いので専用ツールが無くてもなんとかなるのが良いですね。

scp

scp はそれ単体でファイルを書き出すための情報を標準出力したり標準入力を受けてファイルを書き出したりする機能があるそうです。scp 自身がその機能を使ってファイルの送受信をしているのだそう。

orebibou.com

Debian ベースのイメージだと scp は入っていることが多いので ssh は無いけど scp があるという前提で ECS Exec と scp を組み合わせる、具体的には以下のような感じでファイルの送受信が出来るのでは?と思って試してみました。

  • 送信: sprintf \\000\\000\\000\\000\\000\\000\\000 | scp -f [SRC] の出力を ecs exec 越しに scp -t [DST] に食わせる
  • 受信: sprintf \\000\\000\\000\\000\\000\\000\\000 | scp -f [SRC] を ecs exec で実行してその出力を scp -t [DST] に食わせる

送信

sprintf \\000\\000\\000\\000\\000\\000\\000 | scp -f [SRC] の出力を ecs exec 越しに scp -t [DST] に食わせる

ecs exec 越しに scp -t [DST] に食わせる の部分は session-manager-plugin に対して標準入力として与えると可能のようでした。ただし scp -t を ecs exec 越しに実行すると scp が死なないし殺す方法が無いので正常にセッションを閉じれません。苦肉の策として最後に改行を食わせエラーを起こさせて scp に自死してもらうことで上手く終了させることが出来ました。

goでコードに落とし込んだものがこちら

受信

sprintf \\000\\000\\000\\000\\000\\000\\000 | scp -f [SRC] を ecs exec で実行してその出力を scp -t [DST] に食わせる

sprintf \\000\\000\\000\\000\\000\\000\\000 | scp -f [SRC] を ecs exec で実行するのはヌル文字の関係か難しそうでした。また ecs exec 越しに標準入力でヌル文字を食わせるのも上手く動作しなさそうでした。

これまた苦肉の策として scp -f をラップしたバイナリを用意するなどで回避してみます。シェルスクリプトにするだけだと Cannot perform start session: EOF と出たりして動作はするもののセッション周りが怪しかったので微妙かもしれません。

バイナリ 経由して scp -f の出力を受けられるようになったので scp -t [DST] に食わせるのですが、以下のような問題があるのでケアする必要があるようです。

  • session-manager-plugin の出力が標準出力に混じるので除外する
  • \n の改行がなぜか \r\n になって出力されてくるので変換が必要
    • 考えない様にしているが \r\t のままで良い時に困りそう…

ここまでしてようやくファイル受信出来るようです。送信に対してハードルが高いですね…

goでコードに落とし込んだものがこちら

ポートフォワード

ssm session manager はポートフォワード出来るので、ファイル送受信出来るサーバを立ててポートフォワードすれば…

それもう ssh で良いのでは???

結論

  • なんかツール導入して頑張るぐらいなら素直に ssh-server 入れたら良いんじゃないかな?と思いましたマル
    • この記事の発端って実は ecspresso cp が欲しいからだったりするんですが、実現するにはいくつか前提条件を作らないと厳しそうな雰囲気を感じますね。それでもやるなら s3 経由が一番現実的かな
  • メルミナ 楽しいので当時を知るイニシエのおじさんはメルミナやりましょう

カヤックでは格ゲーおじさん(お兄さん/お嬢様/etc...)なエンジニアを募集しています

憎きあいつの顔を思い浮かべながらレバーが折れるまでガチャり合い、ボタンが割れるまで叩き合いましょう!