CloudWatch cross-account observability で特定メトリクスを集約する(CloudFormation使用)

2024.06.03

CloudWatch cross-account observability(クロスアカウントオブザーバビリティ)は、 複数アカウントにまたがる監視を実現するための機能です。 CloudWatch Observability Access Manager(OAM) と呼ばれます。

この機能を使うことで以下のような監視リソースを、 モニタリングアカウントへ集約できます。

  • CloudWatch メトリクス
  • CloudWatch Logs ロググループ
  • X-Ray トレース
  • CloudWatch Application Insights アプリケーション
  • CloudWatch Internet Monitor モニタリング

今回はこれを使って特定のCloudWatchメトリクスを、 モニタリングアカウントへ集約してみます。

img

前提: 本ブログでの集約について

今回は以下のような集約を実現します。

  • ソースアカウントは「特定の組織単位(OU)に所属しているAWSアカウント群」とします
  • モニタリングアカウントへ 「Transit Gateway および NATGateway のメトリクス」を集約します

モニタリングアカウント側の設定

モニタリングアカウントでは シンク(sink) を作成します。 シンクに対してソースアカウントがリンク(link)することで メトリクスやログを集約できます。 なおシンクは「アカウント×リージョン」ごとに1つのみ作成できます。

以下のような CFnテンプレートを作成しました。 AWS::Oam::Sink リソースを作成します。

AWSTemplateFormatVersion: 2010-09-09
Description: "create a sink in CloudWatch cross-account observability"
Parameters:
  SinkName:
    Description: "A name for the sink."
    Type: String
    Default: "sink"
  PrincipalOrgID:
    Description: "An Organization Id."
    Type: String
    Default: "o-xxxxxxxxxxx"
Resources:
  OAMSink:
    Type: AWS::Oam::Sink
    Properties:
      Name: !Ref SinkName
      Policy:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal: "*"
          Resource: "*"
          Action:
            - "oam:CreateLink"
            - "oam:UpdateLink"
          Condition:
            StringEquals:
              aws:PrincipalOrgID: !Ref PrincipalOrgID
            ForAllValues:StringEquals:
              oam:ResourceTypes:
                - "AWS::CloudWatch::Metric"
Outputs:
  OAMSinkArn:
    Value: !Ref OAMSink
    Export:
      Name: !Ref SinkName

パラメータには2つ指定します。

  • SinkName : シンクの名前
  • PrincipalOrgID : 組織ID (管理アカウントで aws organizations list-roots を実行して確認できます)

このテンプレートを展開します。展開には rain (便利なCFn操作ツール)を使いました。

rain deploy \
  ./example/oam-sink.yaml oam-sink \
  --params SinkName="sink",PrincipalOrgID="o-example"

# CloudFormation will make the following changes:
# Stack oam-sink
#   + AWS::Oam::Sink OAMSink
# Do you wish to continue? (Y/n) Y
# Deploying template 'oam-sink.yaml' as stack 'oam-sink' in ap-northeast-1.
# Stack oam-sink: CREATE_COMPLETE
#   Outputs:
#     OAMSinkArn: arn:aws:oam:ap-northeast-1:111111111111:sink/9e11example # exported as sink
# Successfully deployed oam-sink

展開後の シンクARN(OAMSinkArn)は後ほど使うのでメモしておきます。

[CFnテンプレート補足] CloudFormation内で設定している シンクポリシーはAWSアカウントID単位でも指定可能です。 指定方法は AWS::Oam::Sink の Examples を参照ください。

ソースアカウント側の設定

ソースアカウント側では リンク(link) を作成します。 リンク上で「どの監視リソースタイプを送信するか」や 「どのメトリクス(やログ)を送信するか」と指定できます。 アカウント内に最大 5個のリンクを作成できます。

以下のような CFnテンプレートを作成しました。 AWS::Oam::Link リソースを作成します。

AWSTemplateFormatVersion: 2010-09-09
Description: "create a link in CloudWatch cross-account observability"
Parameters:
  SinkAccountId:
    Description: "The monitoring account ID."
    Type: String
  SinkIdentifier:
    Description: "The ARN of the sink in the monitoring account that you want to link to."
    Type: String
Conditions:
  IsNotSinkAccount:
    Fn::Not:
      - !Equals [!Ref "AWS::AccountId" , !Ref SinkAccountId]
Resources:
  OAMLink:
    Condition: IsNotSinkAccount
    Type: AWS::Oam::Link
    Properties:
      LabelTemplate: "$AccountName"
      LinkConfiguration:
        MetricConfiguration:
          Filter: "Namespace IN ('AWS/TransitGateway', 'AWS/NATGateway')"
      ResourceTypes:
        - "AWS::CloudWatch::Metric"
      SinkIdentifier: !Ref SinkIdentifier

パラメータには2つ指定します。

  • SinkAccountId : シンクがあるモニタリングアカウントのID
  • SinkIdentifier : 先ほどメモしたシンクのARN

このテンプレートを展開します。CFn StackSets(service-managed) としてOU単位で展開します。

sink_account_id="111111111111"
sink_id="arn:aws:oam:ap-northeast-1:111111111111:sink/9e11example"
ou_id="ou-aaaa-example"

# スタックセット作成
aws cloudformation create-stack-set \
--stack-set-name OAM-LINK-NETWORK-METRICS \
--description "create a link in CloudWatch cross-account observability" \
--template-body file://./example/oam-link.yaml \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
--parameters \
  ParameterKey=SinkAccountId,ParameterValue="${sink_account_id}" \
  ParameterKey=SinkIdentifier,ParameterValue="${sink_id}" \
--call-as DELEGATED_ADMIN # CFn委任管理者からの実行の場合に必要

# スタックインスタンス展開
aws cloudformation create-stack-instances \
  --stack-set-name OAM-LINK-NETWORK-METRICS \
  --deployment-targets OrganizationalUnitIds="${ou_id}" \
  --regions ap-northeast-1 \
  --call-as DELEGATED_ADMIN

[補足] 制約として、モニタリングアカウントに対して「自分自身のリンク」は作成できません。 そのため CFnテンプレートにて「モニタリングアカウント自身の場合はリンクを作らない」ような Condition を定めています。

確認する

ソースアカウント上で確認

[CloudWatch > 設定 > リンクされたモニタリングアカウント] から設定を確認できます。

img

メトリクスを選択すると、メトリクスクエリが表示されます。

img

モニタリングアカウント上で確認

モニタリングアカウント上で集約したメトリクスが表示できるか、確認します。

Transit Gateway や NATGateway のメトリクスを集約できていました。 [アカウントラベル] が追加されていて、アカウント名でフィルタできる点が大きな特徴です。

img

画像: Transit Gateway Attachment(PacketsIn)のメトリクス一覧

img

画像: NATGateway(PacketsInFromSource)のメトリクス一覧

CloudWatchアラームはモニタリングアカウント上で作成できます。

img

また、AWS CLI でメトリクス一覧を確認(aws cloudwatch list-metrics)する際には、 --include-linked-accounts オプションが必要です。

##### デフォルトだと他アカウントのメトリクスは出てこない
aws cloudwatch list-metrics --output yaml --namespace "AWS/NATGateway"
# Metrics: []

##### include-linked-accounts オプションを付与
aws cloudwatch list-metrics --output yaml --namespace "AWS/NATGateway" \
  --include-linked-accounts | head
# Metrics:
# - Dimensions:
#   - Name: NatGatewayId
#     Value: nat-067aexample
#   MetricName: ErrorPortAllocation
#   Namespace: AWS/NATGateway
# - Dimensions:
#   - Name: NatGatewayId
#     Value: nat-067aexample
#   MetricName: ConnectionAttemptCount

##### owning-account オプションでアカウントを絞れる
aws cloudwatch list-metrics --output yaml --namespace "AWS/NATGateway" \
--include-linked-accounts --owning-account 222222222222 | head
# Metrics:
# - Dimensions:
#   - Name: NatGatewayId
#     Value: nat-0981example
#   MetricName: ErrorPortAllocation
#   Namespace: AWS/NATGateway
# - Dimensions:
#   - Name: NatGatewayId
#     Value: nat-0981example
#   MetricName: ConnectionAttemptCount

おわりに

以上、CloudWatch クロスアカウントオブザーバビリティを使って メトリクスを集約してみました。

複数アカウントに跨って展開したリソースを 監視したいときに非常に便利です。 ダッシュボードやアラームをどんどん集中管理していきましょう。

以上、参考になれば幸いです。

参考