これは Livesense Advent Calendar 2022 DAY 7 の記事です。
リブセンス インフラエンジニアの中野(etsxxx)です。VPoEをまだやってます。最近カメラ本体を新調して、レンズも買い増ししたい欲求に駆られています。Techな話よりそっちを語れる自信があります。
背景
AWSのサービスをちょっとだけ利用したいとき、aws-cliのインストールがだるいって思ったことはないでしょうか?私はあります。
Amazon S3に置いているファイルを、古いOS上あるいはコンテナビルド中にダウンロードしたくて、aws-cliをインストール。
このインストール作業。手作業はもちろん、プロビジョニングコードに実装してもだるいのですが・・・ それ以前に、古いOSではOpenSSLが古すぎてhttpsなURLに接続できずにプロビジョニングで詰んで困ったこともあるのです。※1
私はただS3からダウンロードしたいだけなのに!そのダウンロードまでの道のりが険しすぎる!
どうするか?
Goでシングルバイナリを作りました。
タイトルとここまでの説明が全てで、もうそれ以上の話はありません。時間が惜しい人はもう読了でOKですw
※1 : aws-cliそのものは、v2になってからOSのPythonとの依存関係がなくなって、インストールが改善されました。悪いのは古いOSおよびプロビジョニングとの相性です。
s3getのご紹介
リポジトリはこちら: https://github.com/livesense-inc/go-aws-s3get
コンセプトと狙い
s3getは『馬鹿なくらいシンプルなAmazon S3ダウンロード専用クライアント』というコンセプトで作られました。シンプルだからこそ、改修が必要になった時に、誰もが気軽にチャレンジできることを狙っています。
s3getと似たようなコンセプトのものは世の中にたくさんあり、ネーミングもどれも似てるので、同じような単語でネットを探せば色々な実装が見つかります。言語が違うものもあれば、Goでほぼ同じ実装をしたものも見つかるはずです。
それらを採用せず自作したのは以下のような理由です。
- 実装が古くてメンテされていないものが多かった
- AWS署名バージョンv4(SigV4)に対応した実装が当時はほぼなかった
- そもそも野良リポジトリって怖い
ということで、意図的に車輪の再発明をすることにしたわけです。
自作するにあたっては、負債化しないことを一番大事にしていました。そのため、以下の点に注意しています。
- 多機能にしない (滅多に使わない機能はそもそも入れない)
- 現時点で必要な最小限のコードにする (脆弱性やバグを生みにくくする)
- 過度に一般化せず、自分たちにとって必要な機能で設計する (Publicリポジトリだが、Publicのために設計はしない)
そのため、かなり初期に s3get
という名前は決定し、 stupid simple
という説明文も決まっていました。
なお、アップロード機能を付けて s3cp
と名乗るかどうかはかなり悩んでいたところでしたが、最後は「必要になったら分割したバイナリ作ればいいじゃん」と割り切りました。
このような割り切りのため、実装はあっという間に終わり、どちらかというとCIやREADMEを整えるのに時間を掛けています。
必要な機能は必要になってから作る。そんなとき、自分ではない誰かが、できればGoの初学者が、試しに挑戦する場になれば良いと思っています。
使い方
CLIとしては、wgetやaws-cliを意識したオプション体系にしました。
ほぼREADMEに書いていますが、こんなふうに使えます。
AWS Profileを設定してある環境であれば、以下。
s3get s3://bucket-name/path/to/file output-file
Historyに残ることを気にしない環境であれば、コマンドラインでSecretを渡すこともできます。(おすすめとは言いません)
s3get -i AWS_ACCESS_KEY_ID -s AWS_SECRET_ACCESS_KEY -r AWS_REGION_NAME s3://bucket-name/path/to/file output-file
テストやちょっとしたテキスト処理に便利なので、標準出力も実装しています。
s3get s3://bucket-name/path/to/file - | md5
最後にちょっとだけ補足
今年はAdvent Calendarのネタを用意できず、やむを得ず去年末の技術投資を記事にしました。(弊社には技術投資10%というルールがあります)
この記事を書くにあたって、流石に1年前の実装のままでは格好が付かないなぁと思い、少しテコ入れをしました。Goとライブラリのバージョンアップ、MinIOを使ったCIテストの追加などです。READMEも少し直しました。
突然のPRを出してもレビューしてくれたリブセンスのインフラグループには感謝です。
ビルドされたバイナリが正常に動作することをCIでテストするようにしたので、今後は安心して自動的なアップグレードなども組めることでしょう。
バイナリのテストなので、本当は配布している全てのOSでテストをすべきですが、そこは記事執筆に間に合いませんでしたw
また、バイナリサイズを小さくしたくてupxを試していましたが、MacOS + Apple Siliconでの動作が怪しいので今は見送っています。(バイナリのテストはupxのための布石でもありました)
『車輪の再発明はするな』というのが常識ですが、あえてそれを実行したお話でした。
良い年末を!