
Datadog のAWS監視にIAMロールを利用してみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
AWSチームのすずきです。
監視SaaSとして知られるDatadog、AWSのCloudwatch、CloudTrailの監視を行う AWS Integrationは、IAMロールを利用して監視対象の情報を取得します。
今回、DatadogのAWSアカウントをクロスアカウントアクセスの許可先としたIAMロールを作成し、 Datadog のAWS Integration (Role Delegation)を実施する設定について、紹介させて頂きます。
※ AWS Integration は、中国とGovCloudを除き、IAMロールの設定が必須となりました。(2017年5月追記)
設定
Datadogの公式ドキュメントに準じ、AWS Integration、CloudTrail Integration の設定を行います。
外部IDの発行
- Datadog AWS Integration の設定画面を開きます。
 

- AWSアカウントの設定画面を開き、AWS External IDを確認します。
 

IAMロールの作成
- AWS コンソール、IAMロール画面より「新しいロールの作成」を実行します
 

- ロール名は、公式ドキュメントに準じ「DatadogAWSIntegrationRole」とします
 

- ロールタイプの選択としてクロスアカウントアクセスのロールを指定し、「サードパーティの AWS アカウントの IAM ユーザーに、アカウントへのアクセスを許可します。」を選択します。
 

- 信頼性の確立で、DatadogのAWSアカウント(464622532012)を記入します。
 - 外部IDは、DatadogのAWS Integration画面で確認したAWS External IDを記入します
 - MFAが必要のオプションはチェックしません。
 

- 詳細なポリシーを後ほど作成して利用するので、管理ポリシーのアタッチは実施せず、次に進みます。
 

- 作成したIAMロール「DatadogAWSIntegrationRole」の変更画面を開きます。
 - Datadogが必要とするIAM権限、インラインポリシーで反映します。
 

- カスタムポリシーを指定し、PolicyEditorの使用を選択します
 

- ポリシー名は「DatadogAWSIntegrationPolicy」
 - ポリシードキュメントには 公式ドキュメント記載のJSONを反映します。
 

- DatadogAWSIntegrationPolicy (2017/5時点)
 
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "autoscaling:Describe*",
        "budgets:ViewBudget",
        "cloudtrail:DescribeTrails",
        "cloudtrail:GetTrailStatus",
        "cloudwatch:Describe*",
        "cloudwatch:Get*",
        "cloudwatch:List*",
        "dynamodb:list*",
        "dynamodb:describe*",
        "ec2:Describe*",
        "ec2:Get*",
        "ecs:Describe*",
        "ecs:List*",
        "elasticache:Describe*",
        "elasticache:List*",
        "elasticloadbalancing:Describe*",
        "elasticmapreduce:List*",
        "elasticmapreduce:Describe*",
        "es:ListTags",
        "es:ListDomainNames",
        "es:DescribeElasticsearchDomains",
        "kinesis:List*",
        "kinesis:Describe*",
        "logs:Get*",
        "logs:Describe*",
        "logs:FilterLogEvents",
        "logs:TestMetricFilter",
        "rds:Describe*",
        "rds:List*",
        "route53:List*",
        "s3:GetBucketTagging",
        "s3:ListAllMyBuckets",
        "ses:Get*",
        "sns:List*",
        "sns:Publish",
        "sqs:ListQueues",
        "support:*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
- CloudTrail Integrationを利用するため、S3に保管されているログを参照するためのポリシーを、DatadogAWSIntegrationRoleに付与します。
 - CloudTrailのログ保管先のS3バケット「cloudtrail-<リージョン>-<アカウントID>」、「cloudtrail-*」にcloudtrail用途以外のバケットは無いものとして設定しました。可能であればログ保管先のS3バケット名は明示し、Datadogが参照可能なS3を限定して利用される事をお勧めします。
 - 
DatadogAWSCloudTrailReadOnlyAccessPolicy
 
{ "Statement": [
  {
    "Action": [
      "s3:ListBucket",
      "s3:GetBucketLocation",
      "s3:GetObject"
    ],
    "Effect": "Allow",
    "Resource": [
      "arn:aws:s3:::cloudtrail-*"
    ]
  } ]
}

- ロールARNの確認
 - アカウントIDと、ロール名を確認します。
 

Datadog アカウント設定
- AWS Account ID と、ロール名を記入します。
 - ロール情報入力後、「Account credentials are valid」と有効性が確認出来ない場合には、記入情報を見直します
 

- External IDが変更となった場合、IAMロール(DatadogAWSIntegrationRole)の信頼関係の編集で、Condition→StringEquals→sts:ExternalIdの値を差し替えます。
 

- Datadogを監視対象台数に応じた有償ライセンスで利用する場合、「Optionally limit metrics collection」→ 「To hosts with tag:」を設定し、監視対象のEC2インスタンスを限定する事をお薦めします。
 

- 「To hosts with tag: datadog-enable:true」とする事で、EC2のタグとして「キー:datadog-enable、値: true」と明示したインスタンスのみが、EC2監視の対象となります。
 

動作確認
- AWS Integrationの設定後、30分〜1時間後位をめどに確認を実施します。
 
AWS Integrationのメトリック
- DatadogのMetrics→Summary画面より「aws」、AWS Integrationのメトリックを確認します
 

- ロールを追加したアカウントに該当する項目をタグなどで選択し、グラフ表示を確認します。
 

監視ホスト数
- Datadogの課金、監視対象となったEC2台数に応じて発生します。(Proの場合、1台月額18$)
 - Datadogの管理画面より、「Usage」を開き、監視対象のホスト数が意図した台数であるか確認します。
 


アクセスキーの撤去
- 過去にDatadogで利用していたアクセスキーが存在する場合、意図せぬ利用を回避するためアクセスキーの撤去、無効化をお薦めします。
 - アクセスキーを発行したIAMユーザを選択し、アクセスキーの管理を開きます。
 

- ステータス欄が「Active」なキーを「無効化」、または「削除」します。
 

- Datadog専用のIAMユーザを作成されていた場合には、IAMユーザごとの撤去がお勧めです。
 
まとめ
IAMアクセスキーを利用する場合、アクセスキー、シークレットキーが悪意をもった第三者に漏れた場合の対策を 常に意識することが必要でした。
適切なクロスアカウントアクセス設定を施したIAMロールの利用により、キーが不正利用されるリスクを大きく軽減でき、 シークレットキーの隠匿や、定期的なアクセスキー、シークレットキーの更新運用などからも開放されます。
今回、DatadogのAWS IntegrationでもIAMロールの利用が可能となりました。 新規導入の環境だけでなく、従来のアクセスキーを登録されている環境も、 IAMロールによる認証 (Role Delegation) へ切り替える事をおすすめします。
参考
CloudFormation
- Datadog用のIAMロールを作成するテンプレートを用意しました。
 - Datadogが示す「AWS External ID」を、CloudFormationのパラメータとして指定する事で、Datadog用のロールを作成する事が可能です。
 - Datadogに反映する設定値(ロール名)は、CreateStack実行後、Outputsで確認可能です
 

- YAML版
 
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  DatadogExternalID:
    Default: ExternalID
    Description: Datadog AWS External ID
    Type: String
Resources:
  DatadogAWSIntegrationRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Condition:
            StringEquals:
              sts:ExternalId: !Ref 'DatadogExternalID'
          Principal:
            AWS: arn:aws:iam::464622532012:root
      Path: /
  DatadogAWSIntegrationPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: DatadogAWSIntegration
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Action:
          - autoscaling:Describe*
          - budgets:ViewBudget
          - cloudtrail:DescribeTrails
          - cloudtrail:GetTrailStatus
          - cloudwatch:Describe*
          - cloudwatch:Get*
          - cloudwatch:List*
          - dynamodb:list*
          - dynamodb:describe*
          - ec2:Describe*
          - ec2:Get*
          - ecs:Describe*
          - ecs:List*
          - elasticache:Describe*
          - elasticache:List*
          - elasticloadbalancing:Describe*
          - elasticmapreduce:List*
          - elasticmapreduce:Describe*
          - es:ListTags
          - es:ListDomainNames
          - es:DescribeElasticsearchDomains
          - kinesis:List*
          - kinesis:Describe*
          - logs:Get*
          - logs:Describe*
          - logs:FilterLogEvents
          - logs:TestMetricFilter
          - rds:Describe*
          - rds:List*
          - route53:List*
          - s3:GetBucketTagging
          - s3:ListAllMyBuckets
          - ses:Get*
          - sns:List*
          - sns:Publish
          - sqs:ListQueues
          - support:*
          Effect: Allow
          Resource: '*'
      Roles:
      - !Ref 'DatadogAWSIntegrationRole'
  DatadogAWSCloudTrailReadOnlyAccessPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: DatadogAWSCloudTrailReadOnlyAccess
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Action:
          - s3:ListBucket
          - s3:GetBucketLocation
          Effect: Allow
          Resource: '*'
        - Action:
          - s3:GetObject
          Effect: Allow
          Resource: arn:aws:s3:::cloudtrail-*
      Roles:
      - !Ref 'DatadogAWSIntegrationRole'
Outputs:
  RoleName:
    Description: The IAM Role to share with Datadog (Name)
    Value: !Ref 'DatadogAWSIntegrationRole'
  RoleArn:
    Description: The IAM Role to share with Datadog (ARN)
    Value: !GetAtt 'DatadogAWSIntegrationRole.Arn'
  DatadogExternalID:
    Description: Datadog AWS External ID
    Value: !Ref 'DatadogExternalID'
  AwsAccoutID:
    Description: AWS Account ID
    Value: !Ref 'AWS::AccountId'






