AWSのアカウント

みなさんAWSのアカウント使っていますか?
Summitなどでも声高に叫ばれてはいますが、AWSのアカウントは用途ごと、あるいは目的ごと、プロジェクトごとなんかで分離するのが本当におすすめです。

用途や目的ごと、というのはいわゆるプロダクト環境、ステージング、デベロップ環境での分離ポリシーですね。

一つのアカウントに複数のプロジェクトが入り混じる、という形態になるので、少々使いにくい感じになります。

そこでInfrabbitでは基本的にプロジェクト+ステージでの分離ポリシーを推奨しています。

つまり、プロジェクトAの本番系、開発系、検証系、って感じにアカウントをとってしまうことですね。
そもそも開発検証系なんて普段は動いていなくてもいいんですから、最小限のコストで済むでしょうし。

さて、そんな感じで作っていくと馬鹿みたいにアカウントが増えるのは目に見えている話です。というかプロジェクト一つですでに三つアカウントが生まれますから、単純計算でもプロジェクト数×3というふざけた数のアカウントが増殖することになります。

そこで現れるのがAWS OrganizationsとSingle Sign-Onです。

Organizationsとは、AWSの多数のアカウントをルートアカウントを根っことした組織的ツリー構造として相互関係を形成するためのものです。Infrabbitでも導入していますが、大変便利な代物です。

基本的にAWSとのメイン窓口はルートアカウントに集約され、アカウント単位において大きな役割を保有させていくことができます。例えば、Infrabbitでは以下のようなOrganizationsを構成しています。

  1. ルートアカウント
    AWSへの支払い関連はすべてここで集約されます。ルートにぶら下がる子アカウントの支払いは、ここに集約され、アカウント別で確認できるようになっています。また、サポート契約もここで行い、ここで契約したサポート契約が、子アカウントすべてに適用されます。
    ちなみに、クラスメソッドさんなどのAWSアカウント代行業務を行われている企業さんが用いているのが、このOrganizationsです。Organizationsのメリットをフルで受けようと思った場合は、これらの代行業者さんからアカウント発行していただいている場合、それらから外れないといけません(当然ですが、複数のOrganizationsにぶら下がることはできません。

    1. adminグループ/セキュリティアカウント
      ルートアカウント直下にはグローバルアカウントとして、セキュリティアカウントを配しています。こちらは、各アカウントのCloudConfigログや、S3にログバケットなどを作成し、このOrganizationsに含まれるアカウントからの情報のPutを受け取ります。ただし、その情報を参照できるのはセキュリティアカウントへのアクセス権限を持つユーザーのみ、ということになりますので、セキュリティレイヤを分離する、ということができるようになります。
    2. sandboxグループ/サンドボックスアカウント
      グローバルアカウントとして、サンドボックス用のアカウントも用意しています。いわゆるラボに当たります。プロジェクトに依存しない、AWSさんの新機能だとかをちょっと試してみたり、技術講習などでハンズオンを行う場合などに使っています。
    3. プロジェクトグループ/プロジェクトアカウント
      プロジェクトグループの下には、プロジェクトごとのマスタアカウントを一つ用意し、そのマスタアカウントにぶら下がる形で開発系、本番系、検証系のアカウントが用意されています。

      1. プロジェクトマスタ
        プロジェクト全体に影響を及ぼすリソースを定義しています。例えば、メインドメインのRoute53や、共有されるRDSなどです。また、プロジェクトマスタのVPCと配下アカウントのVPCをピアリングし、プロジェクトマスタにBastionサーバを配置します。このため、各子アカウントにおいてPublicSubnetはほぼ用いられておりません。
        プロジェクトマスタにおけるBastionをNATとすることは許容されないので、Proxyとして構成してあり、子アカウントにおけるEC2はProxyとしてBastionを経由してAWSの各リソースなどにアクセスしています。

        1. 本番系アカウント
        2. 検証系アカウント
        3. 開発系アカウント
          それぞれ用途別のアカウントとなり、それぞれに本番用、検証用、開発用のローカル名前解決ゾーンを定義しています。

プロジェクトアカウントにおけるBastionをProxyにしているのは、費用軽減のためで、費用的に問題ないならNAT GatewayやPrivate Linkを用いればよいです(そのほうが構成的に素直ですし、トラフィック問題も起きません。

ルートアカウントにはEC2が一つ作成されており、このEC2からすべてのアカウントへのグローバル設定を実行するTerraformを実行できるようになっています。
また、このTerraformはアカウントの大枠を構成するだけで、各プロジェクト内におけるEC2などの構成を行いません。ただし、各アカウントにVPCなどはこのルートアカウントからリリースしています。これは、複数の異なるプロジェクト間でのリンクが必要になったときに、VPC CIDRがかぶってしまうのを防ぐため、ルートアカウントでIPアドレス管理を行うため、ということになります。
当然、アカウント間でアクセプトとリクエストが必要になるVPCピアリングなどは、プロジェクト間ピアリングであればこちらに実装することになります。

これらのプロジェクト単位のTerraformの実行は別途、各プロジェクトにおけるBastionサーバにおいて行われます。
共通AMIの生成などのためのPackerなどはルートアカウントになりますが、プロジェクト単位の拡張したAMIは各プロジェクトマスタが担うことになります。
プロジェクト内のピアリング、つまりプロジェクトマスタのVPC<->本番系、開発系、検証系VPCとの接続は、このプロジェクトマスタが形成し、また共有DBへの接続情報などもここから各アカウントのSSMに構成情報として出力しています。

現状Proxyの名前解決をPublic DNS名を用いたピアリングでのローカル名前解決としているので、プロジェクトマスタのローカルアドレスが変わるとプロジェクトのEC2にも影響が出てしまうので、Route53 Resolverを組み込もうと思っています。
※もっとも現行プロジェクトはAutoScalingでSpotInstanceを利用しまくったECS環境なのでぶっちゃけいくらでも止められますが。

 

さて、このようにアホほどアカウントが増えてくると困るのが、各アカウントにおけるIAMユーザーの取り扱いということになります。

ここでの切り分けとしては、いくつか考え方はありますが、プロジェクトマスタ以下のIAMに関してはプロジェクトマスタで責任分岐点としています。もちろん、セキュリティアカウントでIAMの構成リソースはCloudConfig/CloudTrail収集を行いますので組織全体のルーリングからはみ出したアカウントの作成は検出されますが。

ただ、そうはいってもではプロジェクトマスタのIAMユーザーはどうするのか、という話が出てきます。

そこで用いられるのがSingle Sign-Onということになります。基本はIAMロールの権限移譲を基にしたディレクトリサービスに当たり、あまり細かいことを必要としないならばSingle Sign-OnだけでIAMユーザーを極力作らない、という制御も行えます。
※その代わり各アカウントには権限移譲を行うIAMロールが自動生成されます。

また、少し前まではほとんどなかったのですが、AWS Single Sign-Onのアプリケーションもかなり豊富になりました。まあSAMLプロバイダならOKなので、基本的にそんなにきつい話でもないわけですが、認証まわりをここに集約可能、というのはとても便利です。

 

なかなかとらえどころのむつかしいサービスだとは思いますが、実際に利用すると手放せなくなります。

利用スタイルを見てみたい、と思われた方はどうぞご連絡を。