本日も乙

ただの自己満足な備忘録。

AWS Cost and Usage Reportを分割してメンバーアカウントに共有する(1)

AWS Cost and Usage Report(AWSのコストと使用状況レポート、以下 CUR)は、AWS のコストやリソースの使用状況を S3 や Redshift にアップロードしてくれる機能です。EC2 インスタンスや S3 バケットなどのリソース名を請求データに含めることができるため、AWS Cost Explorer より細かいコスト分析ができます。

個人で AWS アカウントを作成・管理している人は意識されないと思いますが、AWS Organizations で AWS アカウントを管理している場合は、管理アカウントで CUR を設定することができます。CUR には組織内すべてのメンバーアカウントの請求データが含まれます。

実現したいこと

AWS Organizations で作成された組織内の複数の AWS アカウント(メンバーアカウント)のコストをまとめて分析・可視化したい場合があるかと思います(ないかもしれません)。例えば、部門単位の組織ユニット(OU)の下に本番・ステージング・開発・テストなどといった AWS アカウントがアタッチされているとします。下図の青い枠のように部門単位でひとくくりにしてコストを分析・可視化する方法について考えてみます。

share-cost-by-aws-ou

管理アカウントに設定されている CUR には組織内すべての AWS アカウントの請求データが含まれていると説明しました。管理アカウントは厳格に管理されるべきなので、CUR にアクセスできる人も当然限られてしまいます。自分が管理している部署やチームの AWS アカウントのコスト分析を CUR で行いたくても管理アカウントへのアクセスが厳しくて思うようにいかないかもしれません。

代替手段として、メンバーアカウントの Amazon QuickSight(以下、QuickSight)から管理アカウントの Amazon Athena(以下、Athena)にアクセスできるように権限許可をする方法が考えられます。コスト分析したい人は QuickSight からコスト分析ができるようになりますが、Athena のクエリ料金は管理アカウントに請求されてしまうため、管理アカウントの管理者にとっては Athena の利用料金に悩まされることになります。Athena と AWS Glue(以下、Glue)をメンバーアカウント側に設定し、データカタログの作成から Athena のクエリ実行をメンバーアカウントに任せる方法もありますが、CUR によってアップロードされる S3 オブジェクト(請求データファイル)のオブジェクト ACL によって一筋縄ではいきません(詳しくは後述)。

会社の方針などにより関係のない部門のコストを知られたくないケースがあるかもしれません。その場合は一部のメンバーアカウントの請求データのみをアクセスできるように制限をかける必要があります。

メンバーアカウントからCURを利用するのは簡単?

実は、2020年2月のアップデートでメンバーアカウントで CUR を利用できるようになりました。

aws.amazon.com

メンバーアカウントで CUR をセットアップした場合、そのアカウントのコストと使用状況のみ見ることができます。個々のメンバーアカウントから CUR でコストを見るのであればこれで十分ですが、複数のメンバーアカウントの請求データをひとくくりにすることができません。また、サービス制御ポリシー(SCP)によってメンバーアカウントで CUR の設定ができない場合もあります。

AWSから提供されているソリューション

この問題に対して、管理アカウント上の CUR の一部データを抽出してメンバーアカウントからアクセスすることで解決できます。AWS から以下のワークショップと公式ブログでその方法が紹介されています。

しかし、ワークショップの内容はやや古く、CUR で使用されている(CloudFormationで管理されている)Lambda 関数を直接編集するため、良い方法とはいえません。もう一つの公式ブログの方は良い方法かつ CloudFormation テンプレートが GitHub にありますが、権限が足りない等の問題があります。

前置きが長くなってしまいましたが、本記事では、この2つのソリューションをベースに、複数のメンバーアカウントに関する CUR データを抽出し、メンバーアカウントに共有する方法について紹介します。

CloudFormation テンプレート、Terraform はコード化できる時間がとれれば公開する予定です。

構成

split-cur-for-member-account

1~4が CUR が提供している CloudFormation テンプレートによって構築される部分です。本記事のメインは5~11です。

  1. 最新の CUR データファイルが S3 にアップロードされる
  2. S3 の PUT Object イベントをトリガーに AWS Lambda(AWSCURInitializer)が呼ばれる
  3. AWSCURInitializer から AWS Glue クローラーが実行される
  4. AWS Glue クローラーによってデータカタログが更新される
  5. Event Bridge で3の AWS Glue クローラーの実行成功を検知する
  6. AWS Lambda(SubAcctSplit)が呼ばれる
  7. SubAcctSplit から CREATE TABLE AS(CTAS)クエリでメンバーアカウントのコストデータを一時テーブルに格納
  8. Apache Parquet フォーマットでメンバーアカウント共有の S3 バケットにアップロードする
  9. S3 の PUT Object イベントをトリガーに AWS Lambda(S3LinkedPutACL)が呼ばれる
  10. メンバーアカウントから読み込めるように S3 オブジェクトの ACL を変更する
  11. メンバーアカウントの AWS Glue クローラーを定期実行し、データカタログを更新する
  12. メンバーアカウントから 8 の S3 バケットに対して Athena でクエリ実行する

ここから実際に設定をしていくのですが、長くなるので続きは別記事にします。

参考URL