AWS

AWS ConfigとSecurity Hubを活用したタグ付け自動化の実践:複数の方法を比較

sho

はじめに

西藤です。

前回に続いて、再びAWSのリソースタグ関連のネタです。

前回の西藤の記事
CloudFormation管理下のリソースに一括でタグをつける方法
CloudFormation管理下のリソースに一括でタグをつける方法

AWSにはリソースにタグをつけることができます。タグをつけることで、リソースを環境ごとに分類したり、アクセス制御に活用したり、コスト管理の分析に役立てることができます。

参考:Best Practices for Tagging AWS Resources

https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html

とくにコスト管理の観点では、漏れずにタグをリソースにつけることが重要で、つけそびれた時にはコスト計算のレポートを正確に出すことができなくなります。

しかし、漏れずにタグをつけると言うのはなかなか大変なものです。とくに、リソースが多い場合や、リソースの増減が頻繁にある場合には、人手でタグをつけることは困難です。

そこで、今回はAWSのリソースに対して、自動的にタグを付与する方法について検討しました。

実現したいことと、検討した構成

実現したいこととして、たとえば、AWS利用料計算を行うために、リソースにはCostCenterというタグがついていることを要求することとします。
その際に、リソース作成時にタグをつけるように求めることは可能ですが、それでもタグの付けもれは発生することはゼロではないでしょう。
そういったタグの付けもれを検出し、自動的にタグを付与する仕組みを作りたいと考えました。

AWSのリソースタグ管理に関するサービスはさまざまあり、その組み合わせはこの限りではないと思いますが、今回は以下の方法を検討しました。

  • 案1:AWS Config Rule + SSM Automation
  • 案2:AWS Config Rule + EventBridge + Lambda
  • 案3:AWS Security Hub + EventBridge + AWS Lambda

では、それぞれの方法の概要と、それぞれの方法の注意点について見ていきます。

案1:AWS Config Rule + SSM Automation

まず初めの実装案として、AWS Config Rulesを使って指定のタグがついていないリソースを検出して、それを起点として修復アクションを起動させる。修復アクションでは修復アクション起動時に引き渡されたリソース情報をもとに、タグを付与する構成を考えます。

すべての仕組みをAWSマネージドな形で実現しようとする構成であり、運用コストを下げるためには一番最初に検討したい方法でしょう。

AWS Configのマネージドルールの中に「required-tags」というルールがあり、このルールを有効化することで、指定のタグがついていないリソースを検出できます。

https://docs.aws.amazon.com/config/latest/developerguide/required-tags.html

また、修復アクションとしては、AWS Systems ManagerのAutomation Document「AWS-SetRequiredTags」を使えないか検討しました。
このAutomation Documentは、リソース情報を引き渡されると、指定のタグを付与する処理を行います。

以上を踏まえると、以下のようなシーケンス図で表現できます。

マネージドに実現できて、すごく良さそうです。しかし、上記の構成で動作検証してみた結果、以下のような注意点が浮き彫りになりました。

案1の注意点1: AWS Config Rulesのリソースタイプによる制約

この構成案の最初の注意点は、AWS Config Rulesのリソースタイプによる制約です。

今回利用した"required-tags"ルールの公式ドキュメントを見ると、決まった数のリソースタイプしかサポートしていないことがわかります。(2024年10月現在:30リソースタイプ)

https://docs.aws.amazon.com/config/latest/developerguide/required-tags.html

そのため、管理しようとしているワークロードにて利用しているリソースタイプがサポートされていない場合、この方法は使えません。

コスト管理において、EC2やRDS,S3などのリソースタイプが関連することが多いと思われ、それらはカバーされていますが、それ以外のリソースタイプに関しては今回の仕組みの最初の「検出」の部分が実現できないことになります。

案1の注意点2:AWS Configからの修復アクション起動時にARNが渡されない

次に修復アクションについても確認します。

Config Ruleによって条件を満たさないリソースがある時には非準拠(noncompliant)としてマークされ、それを起点にRuleに紐づけられた修復アクションを起動させることができます。

マネージドに実現できて、すごく良さそうです。

しかし、修復アクションを起動させるときには次の画像のように"Resource ID parameter"として、リソースのIDしか渡されません。(赤線を引いていますが、あくまで"Resource ID"が渡されると表現されているのがわかる)

つまり、AWS ConfigのRuleで非準拠を検出したとき、ARNがAutomationに渡されません。

その一方で、"AWS-SetRequiredTags" のAutomation Documentは、リソースのARNを引数として受け取るように求める作りになっています。

以下、CloudTrailでのログです。resrouceARNListというARNが入ってくることが期待されるParameterにEC2インスタンスのIDだけが入ってきていることがわかります。

そのため、修復アクションとしてこのDocumentが呼び出されても、付けられずに失敗してしまいます。

AWS Config内で"Resource ID"とARNが同じ構造で格納されているリソースタイプの時に限り成功するのですが、そのようなリソースタイプは珍しい("CloudFormation Stack"などに限られる)と思いますので、この案1は現実的ではないということがわかります。

案2:AWS Config Rule + EventBridge + Lambda

AWSマネージドな仕組みですべてを賄おうとするのは難しいということがわかりました。

では、そのマネージドな仕組みだけで実現できなかったのをカバーするべく、次に検討したのはAWS Config Ruleで非準拠を検出したときに、EventBridgeを使ってLambda Functionを起動させる方法です。

流れとしては以下のような形です。

案2の注意点1: AWS Config Ruleのリソースタイプによる制約

AWS Config Ruleが対応しているリソースタイプの制約は、案1と同様で、同じく注意が必要です。

案2の注意点2: AWS Lambda Functionの実装

この構成上避けられないことですが、AWS Lambda Functionの実装が必要です。また、開発コストやLambdaランタイムのライフサイクル管理の運用コストも考慮が必要です。

また、Lambada Functionに付与する権限も検討が必要です。
各AWSリソースに対してタグを付与するためには、そのリソースタイプごとにタグづけを行うための権限が必要です。
たとえば、EC2インスタンスにタグを付与するためには、ec2:CreateTags、RDSインスタンスであれば、rds:AddTagsToResource、S3バケットであればs3:PutBucketTaggingなど網羅しようとしているリソースタイプにあった権限付与が必要です。
Administrator権限を与えるわけにもいきませんので、適切な権限付与を行う必要があり、Lambda Functionの実装と同様に苦労するポイントとなることでしょう。

案2の注意点3: EventBridgeのイベントでのリソース情報の引き渡し

また、AWS Configでの検出を起点としているため、途中の構成を変えても案1と同じく、リソースのARNが引き渡されないという問題がありました。

AWS Config Ruleにて非準拠を検出した時に発行されるイベントのサンプル(下記)を見ると、リソースのARNが含まれていないことがわかります。

{
  "version": "0",
  "id": "74a450e0-9050-bf0d-1160-e7dbb3e3e763",
  "detail-type": "Config Rules Compliance Change",
  "source": "aws.config",
  "account": "123456789012",
  "time": "2022-03-15T17:33:28Z",
  "region": "us-east-1",
  "resources": [],
  "detail": {
    "resourceId": "fs-0dcc4daeb657adbd5",
    "awsRegion": "us-east-1",
    "awsAccountId": "123456789012",
    "configRuleName": "efs-resources-protected-by-backup-plan",
    "recordVersion": "1.0",
    "configRuleARN": "arn:aws:config:us-east-1:123456789012:config-rule/config-rule-touwmd",
    "messageType": "ComplianceChangeNotification",
    "newEvaluationResult": {
      "evaluationResultIdentifier": {
        "evaluationResultQualifier": {
          "configRuleName": "efs-resources-protected-by-backup-plan",
          "resourceType": "AWS::EFS::FileSystem",
          "resourceId": "fs-0dcc4daeb657adbd5"
        },
        "orderingTimestamp": "2022-03-15T17:32:48.988Z"
      },
      "complianceType": "NON_COMPLIANT",
      "resultRecordedTime": "2022-03-15T17:33:27.770Z",
      "configRuleInvokedTime": "2022-03-15T17:33:25.449Z",
      "annotation": "Resource is not protected by any Backup Plan."
    },
    "notificationCreationTime": "2022-03-15T17:33:28.758Z",
    "resourceType": "AWS::EFS::FileSystem"
  }
}

そのため、resourceIdの値を起点にAWSリソースタイプごとに該当するリソースを特定した上でタグづけを行う処理が必要になります。

結局、案1と同じ理由で、検出時にARNが引き渡されないため、処理の実装は大変そうです。

案3:AWS Security Hubの"Resource Tagging Standard" + AWS Lambda

次に検討したのは、AWS Security Hubを使う方法です。

2024年の4月にAWS Security Hubにおいて、"Resource Tagging Standard"という標準がリリースされました。

https://aws.amazon.com/about-aws/whats-new/2024/04/aws-security-hub-resource-tagging-standard/

この標準は、各AWSリソースにおいてタグキーがついているかをチェックするコントロールが含まれています。そして、パラメータを指定することで「指定のタグキーがついているか」を検査することに使うことができます。

その機能を使った構成としては、以下のようなシーケンス図が考えられます。

Lambda Functionを実装する必要があり、その運用コストは案2にも書いた通りですが、Security HubのFindingsイベントをトリガーにして自動化された形が実現されそうで便利です。

しかし、この方法にも注意点があります。

案3の注意点1:すべてのコントロールでのパラメータ変更作業

現在、"Resource Tagging Standard"には、全部で85のコントロールが含まれており、これはAWSのリソースタイプごとにタグの有無をチェックするものです。

デフォルトで「タグがついているか」ということを検査します。

しかし、組織においては「タグがついているか」ということだけでは足りず、「指定のタグがついているか」ということを検査することが必要になることが多いと思われます。

その際には、コントロールのパラメータのカスタマイズをすることで、指定のタグキーの有無を検査できます。

しかし、このカスタマイズは、コントロールごとに行う必要があります。そのため、85のコントロールすべてに対してカスタマイズを行う必要があります。

現状は一括でそれらのパラメータを変更する方法が提供されていないため、AWS CLIなどを駆使して一括で変更するなどの工夫が必要です。
そして、今後、もしも将来においてコントロールが85よりも増えた時には、その分の更新も必要になることでしょう。
この管理のコストは考慮に入れる必要があります。

案3の注意点2: AWS Lambda Functionの実装

上記の案2と同様に、Lambda Functionの実装が必要で、それに関する実装コストや運用コストは考慮する必要があります。

案3の注意点3: Tagging Standardが対応しているリソースタイプの制約

また、AWS Configの時と似た話になりますが、AWS Security Hubの"Resource Tagging Standard"もAWSのすべてのリソースタイプを網羅しているわけではありません。

現時点でドキュメントを見ると85のリソースタイプに対応しており、この数はAWS Config Ruleの"required-tags"よりも多いですが、それでもAWSのすべてのリソースタイプを網羅しているわけではありません。
https://docs.aws.amazon.com/securityhub/latest/userguide/standards-tagging.html

こちらも同様に、タグづけの自動化を行おうとしているリソースタイプがサポートされているかどうかを確認する必要があります。

案3の注意点4: Resource Groups Tagging APIの制約

この案3の構成を取ることでタグづけ処理を行う仕組み(今回はLambda)にはARNのフォーマットでリソースの情報が引き渡されるため、"Resource Groups Tagging API"を利用してタグづけ処理を行えることが期待できます。

この"Resource Groups Tagging API"というのはAWSリソースに対するタグの作成、管理、検索を一元的に行うためのAPIで、異なるリソースタイプに対して共通のAPIを使ってタグ操作を行える仕組みです。

https://docs.aws.amazon.com/ja_jp/resourcegroupstagging/latest/APIReference/overview.html

そのため、タグづけ処理を実装する際にこのAPIを使うことで、リソースタイプに合わせたAPIの呼び出しが必要でなくなり、汎用的な処理が処理が実装できることが期待できます。

このAPIが使えなかった場合は以下のような処理になったことでしょう。

Resource Groups Tagging APIを使うことで、このようなリソースタイプごとのAPIの呼び出しせずに済んで以下のようなシンプルな実装ができます。

ただし、APIも万能ではなくどのリソースタイプに対応しているかはドキュメントを確認する必要があります。

※サポートされているリソースタイプは以下のリンクから確認できます。
https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/supported-services.html

Security Hubで検出されても、Resource Groups Tagging APIが対応していないリソースタイプであれば、リソースタイプごとのAPIの呼び出しを処理を入れるか、場合によってはそのタイプだけは手動でタグづけを行うという対応が考えられます。
処理の実装のコストと、運用でカバーする際のコストの見極め次第ですね。

また、Resource Groups Tagging APIを介してタグづけを行う際にも、EC2,RDS,S3・・・のように各リソースタイプごとにタグづけを行うための権限は必要となり、必要な最小権限を設計して付与する必要はあります。

番外編:"AddTagsToResource"APIについて

今回の検討を進めていく中で、機能が足りず候補から早めに落ちてしまったのですが、AWS Systems Managerの"AddTagsToResource" APIについても触れておきます。

このAPIもSystems Managerの管轄でされているAPIでリソースにタグをつける仕組みとされております。

https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_AddTagsToResource.html

これもまた便利に使えるAPIかなと思ったのですが、ドキュメントを見るとタグづけできるリソースタイプが限られていました。

対応している種類を見るとSystems Managerの管轄のリソースを対象とした自動化に使うことを意図したAPIのようですね。

これだと自動的なタグづけの仕組みを作る上ではカバーできる範囲が非常に狭くなってしまうので、却下となりました。

まとめ

以上、AWSのリソースタグがついていないことを検出し、その上で自動的にタグを付与する方法について検討しました。

いくつかアプローチを検討しましたが、それぞれの違いを表にして表すと以下の通りです

構成検出できるリソースタイプ数タグづけできるリソースタイプ数実装コストの優位性運用コストの優位性検討結果
案1: AWS Config Rule + SSM Automation30(AWS Config)限られたリソースタイプ(ResourceIdとARNが同一のリソースタイプ)○:完全マネージドに実現○:完全マネージドに実現×:ARNが引き渡されずほとんどのリソースのタグづけを自動化できない
案2: AWS Config Rule + EventBridge + Lambda30(AWS Config)限られたリソースタイプ△:Lambdaの実装が必要△:Lambda関数の運用コスト×:ARNが引き渡されずほとんどのリソースのタグづけを自動化できない
案3: AWS Security Hubの"Resource Tagging Standard" + AWS Lambda85(Security Hub)144(Resource Groups Tagging API)△:Lambdaの実装が必要△:Lambda関数の運用コスト○:Resource Groups Tagging APIが対応しているリソースタイプは共通のAPIでタグづけできる

以上の検討を踏まえると、案3のAWS Security Hubの"Resource Tagging Standard"を使ってリソースタグがついていないことを検出し、検出されたリソースに対して"Resource Groups Tagging API"を使って自動的にタグを付与する方法が一番コスト管理の精度が向上するため、運用効率の改善が期待できます。

今回、この記事を書くための調べた中で感じたのはAWSにおけるタグ管理に関するサービスは非常に多くあり、それぞれのサービスがそれぞれの目的ごとに沿った思想で設計されており、「タグに関してはこのサービスひとつでOK」と言えないのがなかなか難しいと感じました。

各組織によってもタグの付け方やタグの管理方法は異なると思いますので、今回の記事が自分たちの組織にとって最適なタグ管理の方法を見つけるのに役立てば幸いです。

参考資料

AUTHOR
sho
sho
記事URLをコピーしました