この記事は公開されてから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'