ソーシャル経済メディア「NewsPicks」でSREをしている美濃部です。
NewsPicksのSREのミッションの1つに「コストを適正化する」というものがあります。サービスの規模拡大に比例してインフラコストが増えないようにし、売上に対するコストの割合を低く維持していくのがミッションになります。
今回はAWSコスト削減の中でもConfigの料金に注目して紹介したいと思います。
まず、SREでは週次でコストモニタリング定例を実施しているのでその内容について簡単に触れさせて頂きます。
コストモニタリング定例について
週次で主に以下のような事を確認しております。
- サービス別のコストを当月の予算と比較し、差分が$100を超えた場合は原因を明確にする
- RI(リザーブドインスタンス)やSavings Planの期限が切れるタイミングで直近のリソース利用状況から次回購入額の確認、及び期限が切れるタイミングで購入をする
- AWS Compute Optimizer、AWS Trusted Advisorのコスト最適化を確認し、過剰なプロビジョニングを確認する
上記とは別にAWS コスト異常検出にて検出された内容を毎日の朝会にて確認するようにしています。
詳細については弊社の高山が書いた記事もご参照頂ければ幸いです。
今回の記事ではConfigのコストが以前よりも大幅に超過した時の調査・対応内容について説明致します。
Configのコスト分析をどうやって行なったか
まずCost ExplorerでConfigサービスでどの使用タイプのコストに変化があったのかを確認したところ「ConfigurationItemRecorded(設定項目の記録)」のコストが上昇していた事がわかりました。Cost Explorerでわかるのはここまでです。さらにどのAWSリソースタイプの記録に変化があったかを調査するために弊社ではConfigのレポートをQuickSightで分析するようにしています。
ConfigのレポートをQuickSightで可視化
ConfigのレポートをQuickSightで可視化するための構成と手順について説明します。
構成
手順
既にConfigの設定で記録がオンになっている前提で説明します。
保存先のS3バケットをAthenaでクエリが実行できるようにテーブルを作成します。(参考: AWS Config の設定項目を月ごとに取得する)
CREATE EXTERNAL TABLE awsconfig ( fileversion string, configSnapshotId string, configurationitems ARRAY < STRUCT < configurationItemVersion : STRING, configurationItemCaptureTime : STRING, configurationStateId : BIGINT, awsAccountId : STRING, configurationItemStatus : STRING, resourceType : STRING, resourceId : STRING, resourceName : STRING, ARN : STRING, awsRegion : STRING, availabilityZone : STRING, configurationStateMd5Hash : STRING, resourceCreationTime : STRING > > ) PARTITIONED BY (`year` string,`month` string,`day` string) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' LOCATION 's3://<BUCKET-NAME>/AWSLogs/<ACCOUNT-ID>/Config/<REGION>/' TBLPROPERTIES ( 'projection.enabled'='true', 'projection.year.interval'='1', 'projection.year.range'='2021,2121', 'projection.year.type'='integer', 'projection.month.interval'='1', 'projection.month.range'='1,12', 'projection.month.type'='integer', 'projection.day.interval'='1', 'projection.day.range'='1,31', 'projection.day.type'='integer', 'storage.location.template'='s3://<BUCKET-NAME>/AWSLogs/<ACCOUNT-ID>/Config/<REGION>/${year}/${month}/${day}/ConfigHistory/')
QuickSightにてAthenaのデータセットを設定(参考: Amazon Athena データを使用したデータセットの作成)
「新しいデータセット」をクリックします。
「Athena」をクリックします。
データソース名、Athenaワークグループを選択し「データソースを作成」をクリックします。
カタログ、データベース、テーブルを選択し「カスタムSQLを使用」をクリックします。
カスタムクエリ名はなんでも良いですがここでは「Config」とします。「カスタム SQL クエリの入力」は以下を設定します。
SELECT configurationItem.resourceId as resourceId ,configurationItem.resourceName as resourceName ,configurationItem.resourceType as resourceType ,configurationItem.arn ,configurationItem.availabilityZone as availabilityZone ,configurationItem.awsRegion as awsRegion ,configurationItem.configurationItemCaptureTime as configurationItemCaptureTime ,configurationItem.configurationItemStatus as configurationItemStatus ,configurationItem.configurationStateId as configurationStateId ,configurationItem.resourceCreationTime as resourceCreationTime FROM config.awsconfig CROSS JOIN UNNEST(configurationitems) t(configurationItem)
「適用」をクリックします。※ 左下のクエリモードは可能であればSPICEを選択してキャッシュを利用するようにした方がクエリのレスポンスが早くなります。(参考: SPICE へのデータのインポート)
クエリの結果が表示されればAthenaのテーブルへのアクセスに成功した事になります。
configurationItemCaptureTime
が文字列になっているので日付タイプに変更し、形式をyyyy-MM-dd'T'HH:mm:ss.SSS'Z'
に設定します。同様の事をresourceCreationTime
にも行います。
「発行して視覚化」をクリックしてデータセットの登録は完了になります。
ここからは視覚化する為の画面になります。まず「作成」をクリックします。
画面に合わせてグラフを伸縮したいので設定で「クラシック」を適用します。
視覚化でビジュアルタイプを「垂直積み上げ棒グラフ」にしてフィールドリストからconfigurationItemCaptureTime
とresourceType
を順番に選択すると以下のようなグラフが表示されました。(「X軸」にconfigurationItemCaptureTime
、「グループ/色」にresourceType
がセットされるはずです)
デフォルトではX軸のconfigurationItemCaptureTime
が日別で表示される為、月に変更します。
月別の推移がわかるようになりましたが、もっと見やすくしていきます。
データラベルを表示します。グラフを選択した状態で右上の鉛筆アイコンをクリックすると左側にビジュアルのフォーマットの設定が表示されるのでデータラベルの「データラベルを表示」「合計を表示」をクリックします。
resourceTypeの並び替え設定をする事により月によってresourceTypeの順番が変わってしまう事を防ぎます。
QuickSightで可視化する事でわかった事
上記の手順を実施すると最終形はこのような感じになり、月別で特定のresourceType
の変化がわかりやすい状態になりました。
そしてマゼンタ色のリソースタイプAWS::EC2::NetworkInterface
が6月から大きく増加している事がわかりました。視覚化すると即座にわかるので良いですね。
手順は省略しますがAWS::EC2::NetworkInterface
タイプをresourceId
でグループ化する事で以下のようにリソース別の調査も可能です。
コスト増加の要因となったリソースタイプがわかったので対応する
まず前提の知識としてConfigの記録設定について説明しておきます。
今までConfigの記録設定は以下の2つのどちらかのみ選択可能でした。
Record all current and future resource types supported in this region
(このリージョンでサポートされる現在および将来のリソースタイプをすべて記録)Record specific resource types
(特定のリソースタイプを記録する)
「指定したAWSリソースタイプを記録する」を選択した場合は新しいAWSリソースタイプが追加されてもその度に手動で対応していく必要があり運用が増えてしまうので「全てのAWSリソースタイプを記録する」を選択していました。
2023年6月19日からは上記に加えて以下が追加されました。
Record all current and future resource types with exclusions
(現在および将来のすべてのリソースタイプを除外を含めて記録します)
これにより特定のリソースタイプを記録対象から除外しつつ将来追加されるリソースタイプも記録できるので対応の幅が広がりました。
話を元に戻しますが、上記の設定ができるようになった事で今回のコストが増加した原因であるAWS::EC2::NetworkInterface
を除外すればコスト削減の観点としては解決になりますが、そもそもConfigで記録をしている目的が何かを改めて考える必要があります。
ConfigはAWS リソースのインベントリ、設定履歴、設定変更通知を提供しているので、特定の時点でどのようにリソースが構成されたかを判断できます。そしてこの機能はコンプライアンス監査、セキュリティ分析、リソース変更の追跡、Configルールによるガバナンスの強化、何かあった場合のトラブルシューティングにも利用できるので基本的には記録しておかない理由はありません。
今回弊社では以下の理由によりコストとのトレードオフでAWS::EC2::NetworkInterface
を記録しないという判断としました。
- 弊社では現状Configルールを設定して違反があった場合に通知し、それを受けてアクションをおこすような運用を行うところまでは実施できていない
- 障害が発生した場合のトラブルシューティングで
AWS::EC2::NetworkInterface
の記録を確認するケースはごく稀だと考えている - 誤ったリソースが作成されづらい環境を構築している
- 本番環境でのエンジニアのIAM権限、およびリソースの作成はcdkによってコードで厳密に管理されておりプルリクがApproveされないと適用しないルールとなっており、誰か1人の判断で勝手にリソースが作られる事は基本おこならい
まとめ
Configのコスト調査について、Cost ExplorerだけではわからないAWSリソースタイプ別の分析を行う手段としてQuickSight + Athenaで行う方法を紹介させて頂きました。
2023年6月19日からConfigのリソースタイプ指定での記録除外が可能になり、特定のリソースタイプを除外する事のハードルが下がりましたが、コンプライアンス・ガバナンスのためのリスク評価と記録コストとのトレードオフで判断することが重要です。