AWS Config 『高度なクエリ』 を使って バージョンの古いランタイムを利用している Lambda Function を洗い出す

システム技術部の木田です。

2021年7月15日に AWS Lambda での Python 2.7 サポートが終了する予定です。 即座に動作しなくなるわけではありませんが、どこで使われているか把握しておく必要はあるでしょう。

さて、当社では本番環境・開発環境等あわせて50以上のAWSアカウントがあり、管理担当者もバラバラです。 どのようにして調査しましょうか?

  1. 各担当者に連絡し、自分の担当範囲を調査してもらう
  2. 全体管理者が調べて回る

多忙な担当者は調査に非協力的時間がかかるかもしれません。 かと言って、全体管理者が個々のアカウントを調べて回るのも大変そうです。

また、調査結果はどうまとめましょうか。 バラバラなフォーマットで受け取った報告を誰かが集約しますか? それとも共有のExcelに各担当者に記載してもらいますか? あまりやりたくない感が増してきますね。

AWS Config

こんなこともあろうかと、カブコムでは 各アカウントで AWS Config を有効にしてリソース情報を収集し、更にセキュリティ管理用アカウントに集約しています。

engineering.kabu.com

ここからは、既にAWS Config を集約した アカウント*1がある 前提で進めますが、単一アカウントで有効になっている AWS Config でも同様の事が出来ます。

AWS Config では収集したリソース情報に対してSQLライクな『高度なクエリ』を掛ける事が出来ます。 標準状態でもいくつかのクエリが用意されています。

f:id:dividebyneko:20210409200455p:plain
AWS Config 高度なクエリ

今回は ランタイムとして Python 2.7 を使っている Lambda Function を検索するクエリを作ってみましょう。 "lambda" で検索すると nodejs6 を使っている Lambda Function を検索するクエリが出てくるので、これを利用します。

f:id:dividebyneko:20210409200952p:plain
Lambda Function using nodejs6

f:id:dividebyneko:20210409201136p:plain
クエリエディタ

SELECT
  resourceId,
  resourceType,
  configuration.runtime,
  configuration.lastModified,
  configuration.description
WHERE
  resourceType = 'AWS::Lambda::Function'
  AND configuration.runtime = 'nodejs6.10'

クエリを編集して python 2.7 を検索するようにします。 ランタイムバージョンの表記については AWS Lambda の開発者ドキュメント で確認してください。

Lambda ランタイム - AWS Lambda

また、複数アカウントにまたがって検索するので SELECT するカラムに accountId も付け加えましょう。

SELECT
  accountId,
  resourceId,
  resourceType,
  configuration.runtime,
  configuration.lastModified,
  configuration.description
WHERE
  resourceType = 'AWS::Lambda::Function'
  AND configuration.runtime = 'python2.7'

【名前を付けて保存】します。 名前にはピリオドが使えないので python27 にしています。

f:id:dividebyneko:20210409201533p:plain
Lambda Function using python27

ここで実行しても、思うような結果が出てきません。 クエリの実行対象が『このアカウントとリージョンのみ』になっているので、集約した他のAWSアカウントのリソースがヒットしません。

f:id:dividebyneko:20210409201723p:plain
スコープ

AWS Config の集約アカウントとして設定済みであれば、スコープとしてアグリゲータを選択できます。

f:id:dividebyneko:20210409203121p:plain
アグリゲータ

アグリゲータを指定してクエリを実行すると、集約元のすべてのアカウントを対象として Python 2.7 をランタイムとしている Lambda Function の一覧が取得できます。

f:id:dividebyneko:20210409203348p:plain
クエリ結果

AWS Config を利用することで複数のアカウントにまたがってリソースを検索することが出来ました。 クエリ結果はJSONやCSVでエクスポート出来るので、その後の処理に利用するのも容易です。

『高度なクエリ』はオンデマンドのリソース検索ですが、Lambda ランタイムバージョンを指定して Config ルール を作成しておけば、継続的にルールに非準拠の Lambda Function*2 をモニタリングする事が出来ます。もちろん Lambda 以外のリソースについても高度なクエリやルールを作成して管理する事が出来ますが、それはまた別の機会に。

おわりに

AWS Config は組織全体にまたがったセキュリティ強化のため(というかSecurity Hubのため)に導入した側面が強いのですが、収集したリソース情報は運用管理にも有効に活用出来ます。 統制を取るのは重要ですが、それを人力に頼った作業にせず、上手くAWSの機能を活用して実現していくのが私の所属する アプリ基盤グループ のミッションでもあります。 以前より注目していた Control Tower が Tokyoリージョンでサポートされ、より一層管理を強化していこうというところです。

*1:AWS Config のアグリゲータ設定をしているアカウント

*2:好ましくないランタイムバージョンを使っている Lambda Function