2020年に作ったDevOps内製ツール
見出し画像

2020年に作ったDevOps内製ツール

電通デジタルでSite Reliability Engineer(SRE)をしている齋藤です。

電通デジタルアドベントカレンダー20202日目の記事になります。前回の記事は「Dentsu Digital Tech Advent Calendar 2020開始します!」でした。

本記事では2020年にSREチームで作ったDevOps内製ツールについてご紹介させていただきたいと思います。内部プロダクトのユーティリティーなど細々したものは色々あるのですが、今回は日常的に利用頻度の高い以下2つのツール

・Auth0をIdPにしたAWSマルチアカウントSSOのクレデンシャル取得ツール(auth02aws)
・オンデマンドでBastionホストを起動して使うツール(bastion-session.sh)

を紹介させていただきます。

Auth0をIdPにしたAWSマルチアカウントSSOのクレデンシャル取得 (auth02aws)

以前の記事

でもご紹介したシングルサインオンマルチアカウント構成のAWSでアカウントを切り替えながら使うためのツールです。処理としては

1. ユーザがアイデンティティプロバイダー(以下IdP)にリクエスト
2. アイデンティティストアで認証
3. IdPでルールを適応してSAMLを作成
4. ユーザがSAML内にあるAWSアカウントを選択
5. STSへのSAMLでのAssume Roleリクエスト
6. 対象アカウントからクレデンシャルがユーザに返却

を行います。

ユーザは

# 実際には一行で実行
$(auth02aws --username USERNAME \   # IdPのユーザ名
           --profile ACCOUNT_NAME \ # AWSのアカウント名
           --keyring \              # IdPパスワードはkeyringから取得
           --sh                     # シェルの環境変数として出力
)

といったコマンドを実行することで、対象AWSアカウントのクレデンシャルを環境変数に出力することができます(shオプションをつけなければローカルのAWS設定ファイルにこのスクリプト用のプロファイルのセクションを書き出します)。

今後の検討事項としては

1. Unix/Linux環境でのkeyringの対応

作成当初からの機能変更はパスワードをkeyring(macOSだとキーチェーン)から取得することくらいで、この処理はkeyringパッケージを使っています。

Windows/macOSはこのパッケージ(と依存パッケージ)をインストールすることで簡単に対応ができたのですが、他のOSの場合事前インストールが諸々必要な状態です。今後、WSLの進化に伴ってWSL上のLinuxでの利用も想定されるので、対応を考えていきたいと思っています。

2. Go 実装化、OSSツールへの還元

また、前回の記事で複数IdPとAWSでSAML連携するときのクレデンシャル取得ツールの

が弊社利用IdPのAuth0に対応しておらず、コントリビュートしたい旨書いていたのですが、まだできていません(テストが足りてない、MFAの対応が不十分など)。Issueはあるものの誰も担当していないので頑張っていきたいと思います。

オンデマンドでBastionホストを起動して使うツール(bastion-session.sh)

AWS Session Managerを利用して必要なときだけBastionホストを起動して使うツールです。以下エントリ

の話で、インフラやIAMの設定ができている前提で

1. 通信したいプライベートサブネットと通信できるプライベートサブネットにBastionホストを起動
2. AWS CLIのセッションマネージャー経由でBastionホストに接続

を行います。

もう少し具体的に書くと

・対象の環境の対象ネットワーク内にAWS CLIでEC2を作成して起動
 ・ --cli-input-json オプションでインスタンスの設定を渡す (オプションの詳細は公式ドキュメント「Generating AWS CLI skeleton and input parameters from a JSON or YAML input file」を参照)
    ・ --user-data オプションで起動時の初期化処理(ツールインストールなどを含む)を実行するスクリプトを渡す(オプションの詳細は公式ドキュメント「User Data Format」を参照)
・上記の実行結果からEC2のインスタンスIDを取得
・AWS CLIでEC2インスタンスが起動するまで待つ
・セッションマネージャープラグインでEC2インスタンスへログイン
・(終了時の処理として)スクリプトの終了シグナルを受け取ってEC2インスタンスを終了

といった処理になります。

加えて、上記の手順で起動したEC2インスタンスにデータ/ファイルを送りたいという場合を考えて以下2つの対応をしています

1. 設定ファイルやスクリプトなどの容量が小さいファイルの場合(16KBまで)、 UserDataとしてローカルからbase64エンコードしたものを流し込んでBastionホスト側でデコードして配置する
2. 作業用のツールバイナリ、テスト用のデータなどは、インスタンスに特定のS3へのアクセスを許可しておき、初期化スクリプトや起動後の手作業でS3から取得

1はUserDataの本来の使い方ではないのですが、作業用のラッパースクリプトなどであれば圧縮/アーカイブを加味すれば十分な容量なので簡易的に使っています。2は色々なものの持ち込みができてしまうため、S3の権限設定を別途設定して管理しています。

ユーザは事前にAWS CLI(含むセッションマネージャプラグイン)、jq、前述したauth02awsをインストールして以下のコマンド

bastion-session.sh -e ENV_NAME \ # 環境名
                  [-f FILE]      # 起動したBastionにアップロードしたいファイル

を実行することで、指定したAWSアカウントの作業用プライベートネットワーク内に起動したBastionサーバにSSMを使ってログインできます。

今後の検討事項としては

1. シェルスクリプトでメンテしていくのか?

ツールの名称から分かるように、シェルスクリプト製なので現状からの機能拡張がそろそろ苦しくなってきたことです。やろうと思えば可能ではありますが、あまり凝るとメンテナンスできるメンバーが減ってしまうののが悩みどころです。

2. EC2インスタンスが終了せずに残っている場合への対応

接続元が長時間アイドルになっているケースなどで、EC2インスタンスが終了せずに残っている場合があります。EC2インスタンス作成時にインスタンス名や、タグなどでBastionホストを見分けられるように設定しているので、起動時間などの条件で終了する仕組みの検討をしたほうが良いと思っています。

3. BastionホストとしてFargateを利用するか?

現状EC2で困っていることや問題になっていることはそうないのですが、プロダクトでメインで使っているのがFargateなので、そちらへの移行も考えられます。

まとめ

2020年に作成したDevOpsツールである

・Auth0をIdPにしたAWSマルチアカウントSSOのクレデンシャル取得ツール(auth02aws)
・オンデマンドでBastionホストを起動して使うツール(bastion-session.sh)

についてご紹介しました。

来年は他のツールとまとめた大統一DevOps CLIの作成に着手したいなと思っています。CLIの名称に社名を使いたいところですが、弊社の略称既にPOSIXのddコマンドやDataDog社のコマンドで使われているので名称をどうしようかと思っています。

3日目は「Reactアプリケーション内でGoogle Analytics計測をする際、react-gaを使わず、gtag.jsを利用した方法とその選択理由」です。次回もよろしくお願いいたします。