AWSアカウントの複数運用課題をAWS SSOとaws-vaultで解決した
今回の記事はグリモア天網チームのケンが担当します。
ここから現在グリモアを支えているエンジニア一同が出陣いたします。
よろしくおねがいします!
1日目に社長が言われていた『悪の組織』を目指すためには、【挑戦する文化】が必要になります。
挑戦しやすい文化を作るために、グリモアでは日々エンジニアリングで手間を解決し、人間でないとできないことにフォーカスを当てていくための活動が日々行われています。
今回はその活動の一貫としてAWSアカウントを複数運用する際の開発効率を上げるため、「AWS Organizations」「AWS Single Sign-On(AWS SSO)」「aws-vault」を利用して安全に、かつ楽に開発できるようになる仕組みを作成したという記事になります。
自己紹介
2021年3月よりグリモアにジョインしてます。
今までゲームとは関係ないウェブアプリを作っていたフルスタックエンジニアでしたが、現在グリモアでもAPIサーバーを中心にインフラからフロントエンドまで幅広く対応しています。
今回はインフラのお話をさせていただきます。
複数アカウントの運用理由
皆さんはAWSアカウントを複数運用していますでしょうか?
もちろんAWS Direct Connect(DX)などを使うにあたってアカウントを一つにしないといけないなどの理由で単一運用することもあると思いますが、多くの方が複数運用をしているのではないかと思います。
複数のアカウントを作成する理由としては以下の2つが挙げられると思います。
リソースの分離
プロダクトごとにアカウントを分けることで他プロダクト運営者からの影響を受けないようにする
そもそもアカウントにアクセスできないので、IAMによる事故を防ぐことができます
sandboxアカウントを設けることで安全にテストできる環境を作る
会計の分離
部署ごとに予算を建てている場合などにタグで運用するよりも楽に計上できます
グリモアでも、特に「リソースの分離」を目的として複数のアカウントを持っており、現在ではプロダクト・社内向け・sandboxごとにアカウントを作成しています。
しかし、複数のアカウントを持つとユーザーの管理と鍵の管理が大変になってきます。
複数アカウントの運用課題
1. ユーザーの管理
新しく参加したり離脱したりする開発者の方がいると、触るAWSアカウントごとにIAMユーザーの作成・削除が必要になります。
またアカウントの数が増えるほど削除漏れなどが発生しがちで、事故に繋がる可能性があります。
2. 鍵の管理および切り替え
これが開発者にとって何よりセンシティブかつめんどくさいのではないかと思います。
AWS CLIを用いてAWSアカウントごとにコマンドをキックする場合、名前付きプロファイルを.credentialsに設定しておいて、
--profile profile-name
で切り替えたり
export AWS_PROFILE=profile-name
してから実行すると思うんですが、大体csvでsecret情報をダウンロードしてきて、.credentialsに平文で保存したり、envchainみたいなツールでセキュアにsecretを使うとしても、そもそもダウンロードされたcsvの対処までは把握しきれなかったりして、結構取り扱いが危険なんですよね…
あと、AWSマネジメントコンソールは同一ブラウザ上で複数のアカウントへのログインができない仕様になっており、
ログアウト→アカウントIDの入力→パスワードの入力→2段階認証という手間が毎回発生するため、アカウントの切り替えが結構めんどくさいです。
解決方法
そこで以下のツールを使って解決することにしました。
AWS Organizations
AWSアカウントを一元管理および統制するためのサービス
AWS SSO
AWS Organizationsの単位でユーザーを作り、各アカウントにアクセスすることができる仕組み
aws-vault
AWSのアクセスキーをOSのキーストアに保存することで暗号化して保持できます
macOSであればKeychain、WindowsであればCredential ManagerKeyChainに保存されます
キーストアがなければpassなどのアプリを導入することで解決できます
これらの導入方法とそれによる恩恵を詳しく説明していきます。
AWS Organizations
AWS Organizations(公式)
AWSアカウントを一元管理および統制するためのサービスです。
これを使うことで全アカウントにおける一括請求を行なうことができます。
一括請求になることでinvoice(請求書)等も全金額とアカウントごとの金額がわかるようになり、アカウント毎での請求ではなくなるので料金のボリューム割引やリザーブドインスタンスの割引も効きやすくなり、さらにはリザーブドインスタンスの共有といったこともできるようになるなど、コスト・リソースの最適化を助けてくれます。
Organizationsへ各アカウントを結びつける際にはダウンタイムも発生しませんので簡単に利用開始できます。
作成の流れ
作業の要点をまとめると以下のとおりです。
マスターアカウントを作成
Organizationsを作成
Organizations Unitを整理
Organizationsに新規アカウント作成 or 既存アカウント招待
billingの設定
上記の結果、このような形になります。
まず、OrganizationsおよびSSOユーザーを作成するためだけのAWSアカウントを新規作成しましょう。
便宜上、この記事においては「マスターアカウント」と呼びます。
マスターアカウントを作成するべき理由としては、権限が強すぎるOrganizations管理アカウントへのアクセスを抑えるためです。
現在グリモアでは、マスターアカウントへのルートユーザーログインは基本禁止にしており、以下のケースのみログインします。
AWS SSOユーザー・グループの管理
アクセスポリシーの管理
マスターアカウントを作った後はOrganizations Unit(OU)を利用してアカウントを整理します。
OUは「フォルダ分け」みたいな機能だと思っていただければ大丈夫です。
「アクション」ボタンからOUを作成することができ、各アカウントのOU移動をすることも可能です。
そして「AWSアカウントを追加」ボタンから「既存アカウントの招待」か「新規アカウントの作成」を選択し、上の画像のように階層を整えれば完成です。
billingの画面には全アカウントの請求情報が溜まっていき、翌月から動作するようになります。
アカウントごとの利用金額も閲覧が可能になります。
ついでに、Cost Explorerも無料なのでONにしておくと良いかと思います。
グリモアではマスターアカウントのbilling情報だけ閲覧できるアクセスポリシーを作成し、関係者のSSOユーザーにポリシーをアタッチすることで、いつでも確認できるようにしています。
補足:メールの運用とGmailの+エイリアス
ちなみに、AWSアカウントの作成にはメールアドレスが必要になりますが、極力グループアドレスを利用するようにしましょう。
個人メールアドレスにしてしまうと退職などが発生した場合に大変手間がかかります。
そして、AWSアカウント作成ごとにメールアドレスを発行するのも良いのですが大変なので、Google Workspaceを利用しているのであればGmailの+エイリアスを利用するのをお勧めします。
これにより、1つのメールアドレスで複数のアカウントに登録できるようになります。
https://support.google.com/a/users/answer/9308648?hl=ja
例えば「xxx@gmail.com」というメールアドレスを発行した際、「xxx+backyard@gmail.com」などのメールアドレスをAWSアカウントに登録することができ、この+エイリアスのメールアドレスは「xxx@gmail.com」に転送されます。
AWS SSO
AWS Single Sign-On(公式)
Organizationsの用意が完了したら次は各アカウントにアクセスできるようにSSOユーザーを作成します。
これによりAWS SSOポータルからマネジメントコンソールに遷移しやすくなり、aws-vaultを使えるようになります。
作成の流れ
最終的にこのような形を目指します。
リージョンを設定
初期値がオハイオになっているため要注意です
違うリージョンで設定しているとアカウントのリソース閲覧ができなくなってしまうため、使いたいリージョンを設定してください
「ユーザー」に移動し、「ユーザーの追加」で追加処理
「グループ」に移動し、「グループの作成」で作成処理
グループにユーザーを追加
「AWSアカウント」から「アクセス権限セット」のタブをクリック
アクセス権限セットを作成
これがIAMロールになります
AWSが用意してくれているプリセットを使うもよし
既存のプリセットを改造してカスタムするもよし
グリモアではecsへのデプロイを行う際にsts:AssumeRole権限が必要だったり、serverlessを使うにあたって多くのIAMのRoleが必要だったので、poweruserをカスタマイズしています
「AWS 組織」のタブへ移動
アクセスさせたいAWS アカウントを選択し、ユーザーの割り当て
ユーザーもしくはグループを選択
作成したアクセス権限セットを選択
アタッチ
「設定」に移動し、「ユーザーポータル」を設定
初期状態ではIDが含まれたURLになっていますが、一度だけ変更することが可能です
このURLにアクセスするとSSOログイン画面に遷移します
以上を設定したら動作確認をしてみましょう。
ユーザーポータルURLにアクセスすると以下のような画面になります。
ユーザー名かメールアドレスでログインが可能です。
そしてログインに成功するとSSOのポータル画面に移動します。
自分に結び付けられているアカウントの数だけ表示され、それぞれ右にあるキャレットをクリックすると、アクセス権限セットが表示されます。
Management consoleをクリックすると、その権限に応じたIAMユーザーとしてマネジメントコンソールへログインします。
aws-vault
マネジメントコンソールへのログインが簡単になったので、次はAWS CLIを楽にセキュアに使います。
利用するのは aws-vault(GitHub) です。
OSのキーストアに暗号化して認証情報を保存し、一時的な認証情報を生成してシェルやアプリが利用します。
導入手順
Homebrewでaws-cliとaws-vaultを導入
`brew install awscli`
すでにaws-cliを導入している人はバージョンを確認し、v2未満の人はアップグレードしてください
`brew install --cask aws-vault`
すでにaws-vaultを導入している人はバージョンを確認し、v6.0.0未満の人はアップグレードしてください
ターミナルで aws configure を設定
`aws configure sso` を実行
SSO start URL [None]: `${ユーザーポータルURL}`
SSO Region [None]: `${ap-northeast-1等、SSOユーザーを作成したリージョンを指定}`
ここまで入力するとブラウザに遷移し、SSOユーザーへのログインを求められるので対応
ログインが完了するとターミナルの対話が再開され、アカウントを選択できるので選択
roleの選択(好きなものを)、Regionの選択(ap-northeast-1等)、output formatの選択(json等)まで行う
CLI profile nameはデフォルトのままだとしんどいので、`sandbox` `product` などを入力しておくと吉です
configureの設定が完了し、内容は `~/.aws/config` に記録されています
aws-vault で aws configure を指定
コマンドは `aws-vault exec {profile_name} -- {command}` という形式
例1(aws command): `aws-vault exec product -- aws s3 ls`
例2(shellもOK): `aws-vault exec product -- ./ecs/ecs_deploy.sh`
aws-vaultはmacであればkeychainに保存するので、keychainがパスワード入力を求めてきます
実行することができればOK
これにより、 `~/.aws/config` に平文が保存されないセキュアなCLI環境が完成します。
補足:CLIでUnrecognizedClientException
アクセスポリシーなどが変更した際、セキュリティトークンが新しくなっている場合があり、aws-vault経由で接続しようとすると以下のようなエラーが発生することがあります。
An error occurred (UnrecognizedClientException) when calling the ListImages operation:
The security token included in the request is invalid.
この場合はaws-vaultのセッションをクリアする必要があるので、
`aws-vault clear` で全セッションをクリアするか、
`aws-vault clear {profile_name}` で指定のprofileだけセッションをクリアし、
再度 `aws-vault exec` コマンドを実行してセッションを張り直してください。
まとめ
複数アカウントを簡単に扱うために、「Organizations」「SSO」「aws-vault」と3つのツールを使って課題解決しました。
Organizationsは全社的な取り組みになるので、そのハードルに起因して同じ構成に取り組んでいる企業さんが少なかったり、それに応じて資料も少なかったりするので、今回の記事が少しでも助けになれば幸いです。
また大きく利点を得られる構成になっていますが、この構成についてまだ何点か問題があるので共有します。
SSOのプロファイル機能が比較的新しいため、対応していないサービスがある
terraformは対応してくれているのですが、serverless frameworkについてはまだ対応されておらず、aws2-wrap(GitHub)を使うなどの方法が求められます
グリモアでもaws2-wrapを動かすためだけにserverless開発用dockerにpythonを入れており、ちょっと微妙
ちなみにaws configure ssoで用意したSSOのプロファイルを以下のコマンドで利用できます
`aws2-wrap --profile ${プロファイル名} sls deploy`
serverlessのissueはこちらですが、状況を見る限り対応はまだ先になりそうです
Google Workspaceと連携したい
グリモアではGoogle Workspaceを利用しているので、AWS SSOとGoogle Workspaceが連携してくれたらユーザー管理の手間がさらに減って最高だなと考えています
公式さんが対応してくれるのを待ったほうが賢そうな気がしているので、ここは頑張らないようにしてます
というように改善点が残っている構成ですが、やはりメリットのほうが大きいかと思います。
現在導入して3ヶ月ほど経ちましたが、だいぶ複数アカウントの煩わしさが減り、開発速度や新しいサービスのテストするまでの着手スピードが向上したと感じます。だいぶオススメできます。
また、対応する前にはAWSJの方へ「こういうことをやりたい」と相談してみるのがとてもオススメです。
アカウントを作成すると実は担当窓口営業の方がアサインされているので、一度問い合わせてみてください。
企業ごとに持っている課題は違うと思うので、Solution Architect(SA)さんに話を聞くとより良い解決方法を提案していただけるかもしれません。
そして、今回この記事にあげた構成とまるっきり同じに載せ替えなくても、載せ替え可能な部分だけ使ってみるのもありだと思います。
グリモアでも「完璧よりも完成を目指せ」という標語を大事にしており、規模が大きすぎて進まないよりも、できることからやっていく方針を取っています。
もし少しでもより良い環境が作れそうなら是非試してみてください。
最後に
ここまでお付き合いいただき、本当にありがとうございました。
グリモアは一緒に【中二病を救う】側になってくれる仲間を大大大募集中です。
少しでも当社に興味を持って頂けましたら、是非とも下記の採用サイトを御覧ください!