AWSアカウントを取り違えないための試み

SREチームの長田です。

皆さんは操作するAWSアカウントを取り違えたことはありますか? 私はあります

カヤックのSREは複数のプロダクトを担当することも多く、 ひとつのプロダクトでも環境(本番、ステージング、開発、etc.)ごとにAWSアカウントを分ける場合があり、 扱わなければならないAWSアカウントが多くなる傾向にあります *1

今回はうっかり別のアカウントのリソースを削除してしまったーといったオペレーションミスを減らすために個人的に行っている、 「気をつける」以外の対策を紹介します。

間違いに気づくための対策

対象のアカウントが操作の対象として正しいかどうかは、結局は操作している本人にしか分かりません *2。 そのため、「アカウント取り違え自体をなくす」のではなく、 「アカウントを取り違えていることに気づきやすくする」ための対策をしています。

AWSコンソール用の対策

AWSコンソールには、ヘッダーにはアカウントIDしか表示されず、それも常時表示されているわけではないので、 現在どのアカウントでコンソールを開いているのかがわからない場合があります。

もちろんアカウント詳細ページまでたどれば確認はできるのですが、ページ遷移を伴うのは手間です。 面倒なことは人間サボりがちなので、できるだけ簡単に確認できるようにしなければなりません。

AWSコンソールのデフォルト表示

なお、上記のスクリーンショットはAWSコンソールにSSOでログインした場合の表示です。 Switch Roleを利用してログインした場合は、Switche Role時に設定したRole名が表示されるので多少認識しやすくなりますが、 最大5 Roleまでしか履歴が保存されないという制約があります*3。 6 Role以上Switchした場合は、古い設定は消えてしまいます。

ブラウザ拡張の利用

"Display AWS Account Name" というChorem拡張を導入しています。

AWSコンソールに現在選択中のアカウント情報を表示する拡張はいくつかありますが、 ヘッダーの色とアカウント情報を別々にハイライトすることができるという点で気に入っています。

Display AWS Account Nameの利用例

以下のスクリーンショットのように、「プロダクトごとの色」「環境の種類ごとの色」を組み合わせています。

Display AWS Account Nameの設定画面

AWS CLI用の対策

コマンドラインからAWSの操作を行う場合は、AWS Command Line Interface (AWS CLI)を使うことが多いでしょう。

https://docs.aws.amazon.com/cli/

AWS CLIを使う場合、AWSアカウントの指定は環境変数 AWS_PROFILE をセットするか、 コマンドライン引数 --profile を指定することで行います。

$ AWS_PROFILE=foo-production aws s3 ls
$ aws s3 ls --profile foo-production

なお、アカウント認証のためのprofile定義については、今回は割愛させていただきます。 AWS CLIのドキュメントに説明がありますので、 そちらを参照してください。

AWS CLIにおいてAWSアカウントを取り違えるということは、このprofile選択を取り違えるということです。 これに気づくための対策を3つほど紹介します。

環境変数を自動設定する

ディレクトリごとに環境変数を自動セットするツールを使っています。 有名なものに direnv があります。

私も長らく direnv を使っていましたが、 最近は mise の環境変数セット機能を使っています。

プロダクトの関連ディレクトリごとに AWS_PROFILE を設定することで、 「profileを選択する」という操作自体を省略してしまうのです。 操作しなければオペミスは発生しません。

例えば mise を使っている場合に、対象ディレクトリに以下の内容で .mise.toml ファイルを配置すれば、

[env]
AWS_PROFILE = 'foo-dev'

そのディレクトリ及びその配下で環境変数 AWS_PROFILE がセットされます。

$ mise set
key          value    source
AWS_PROFILE  foo-dev ~/src/github.com/kayac/test-foo/.mise.toml

$ printenv AWS_PROFILE
foo-dev

環境変数の自動設定は、AWS CLIだけでなく、TeraformCloudFormationなどのIaCツールにも有効です。

ターミナルのプロンプトにprofileを表示する

環境変数を自動セットするようにしたとして、その結果どのprofileが設定されているのかを確認する方法が欲しくなります。

私はshellとして fish を使っているので、 そのプラグインである "tide" でプロンプトをカスタマイズしています。

tideを導入するとデフォルトでプロンプトにprofile名が表示されるようになります。

プロンプト

もちろんfish以外のshellでも同様にプロンプトのカスタマイズが可能で、 例えばzshの場合は oh my zshのawsプラグインを使用すれば実現できるようです。

こだわる方はプロンプトを自作するのもいいでしょう。

AWS CLI実行時にprofileを表示する

「その場限りのprofileしたつもりができていなかった〜」という場合もあるでしょう。 私はあります

これを防ぐために、実行したAWS CLIコマンドがどのprofileを使ったのかを表示するツールを作りました。

awsc は、AWS CLIが使用するprofile情報を出力したうえで、すべての引数をそのまま使って exec aws します。

こんな設定を書くと、

rules:
  - expression: '-(production|pro?d)$'
    color: red
  - expression: '-(staging|stg)$'
    color: yellow
  - expression: '-(development|dev)$'
    color: blue
extra_info: true

以下のように色付きでprofileとアカウント情報を出力します。

awscの出力

出力行が多すぎるということであれば、テンプレートを定義することで出力をカスタマイズすることができます。 設定ファイルに以下のように書けば、

template: |-
  AWS_PROFILE={{ .Profile }}

このように出力される内容を抑制できます。

awscのテンプレートカスタマイズ

また、リソースの参照以外の操作を行った場合に、確認を求めるようにすることもできます。

実行確認

詳しくは awscREADME を参照してください。

まとめ

人間が操作する限り、オペレーションミスをゼロにすることはできません。 しかし、そのたびに対策をしていくことで、オペレーションミスを減らすことはできます。 失敗を糧に少しずつ改善していきましょう。

カヤックではオペレーションの改善が好きなエンジニアを募集しています!

*1:ちなみに、アカウント管理を受け持っている社内情シスチームでは社内で使用しているすべてのAWSアカウントを扱う可能性があるため、 100個以上のアカウントを適切に切り替える必要があります。 カヤックではクライアントワークを行っていることもあり、アカウント数が非常に多いのです。 そのあたりの話も聞いてみたいところです。

*2:このへんはAIに何とかしてほしいですね。

*3:執筆時点の制約です。