AWS organizationsでcloudtrailを別Accountへ権限移譲する
AWS Organizationsの連携機能を色々と試しており、
cloudtrailでも連携機能を試してみました。
下記を参考にさせて頂いており、
KMSも含めて権限移譲をやろうとすると割と面倒で、
最終的にcloudformationを作成したのでブログ化してみました。
fu3ak1.hatenablog.com
Organizations とCloudtrail連携機能(AWS純正)
AWS Organizationsでは、Cloudtrailと連携し、
複数アカウントでのcloudtrail設定を簡単に実現できます。
cloudtrailで単純にorganizations連携をすると
下記のようになります。
上記でも十分にcloudtrailログを集約できるのですが
AWSのマルチアカウントのベストプラクティスでは、
ログ集約用の目的別のアカウント
(以下、LogArchiveアカウントと表現します)の別途作成を推奨しています。
要は何でもかんでも、親アカウントに集めるのは
権限が集約しすぎて良くないということですね。
上記理由から、純正機能でのcloudtrail集約をそのまま利用すると
ベストプラクティスに沿っていないのかと思いました。
aws.amazon.com
ベストプラクティス風にするには
LogArchiveアカウントを別にした構成を考えると
下記のように設定したいと考えました。
別途LogArchiveアカウントを作成し、
AdminAccountで収集したcloudtrailログを
LogArchiveアカウントに集約します。
上記、手動で設定しても良いですが、
割とポリシー系が面倒だったので、
cloudformationを作ってしてみました。
1.LogArchiveアカウントでの作業
まず、LogArchiveアカウントで、
S3とKMSを作成します。
LogArchiveアカウントで以下のcloudformationを適応します。
AWSTemplateFormatVersion: "2010-09-09" Description: A templete for Parameters: EnvPrefix: Type: String Default: OrgTrail orgAccountId: Type: String Default: xxxxxxxxxxxx Description: "Organization Admin Account Id" S3BucketName: Type: String Default: xxxxxxxxxxxxxxxxxxxxxxxxxx Description: "bucket name for cloudtrail" Resources: mykms: Type: AWS::KMS::Key Properties: Description: !Sub ${EnvPrefix}Key Enabled: true EnableKeyRotation: true KeyUsage: ENCRYPT_DECRYPT PendingWindowInDays: 30 KeyPolicy: Version: '2012-10-17' Id: key-policy Statement: - Sid: Enable IAM User Permissions Effect: Allow Principal: AWS: !Sub arn:aws:iam::${AWS::AccountId}:root Action: kms:* Resource: "*" - Sid: Allow use of the key Effect: Allow Principal: AWS: !Sub arn:aws:iam::${orgAccountId}:root Action: - kms:Encrypt - kms:Decrypt - kms:ReEncrypt* - kms:GenerateDataKey* - kms:DescribeKey Resource: "*" - Sid: Allow attachment of persistent resources Effect: Allow Principal: AWS: !Sub arn:aws:iam::${orgAccountId}:root Action: - kms:CreateGrant - kms:ListGrants - kms:RevokeGrant Resource: "*" Condition: Bool: kms:GrantIsForAWSResource: 'true' - Sid: Enable IAM User Permissions Effect: Allow Principal: AWS: - !Sub arn:aws:iam::${orgAccountId}:root Action: kms:* Resource: "*" - Sid: Allow CloudTrail to encrypt logs Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: kms:GenerateDataKey* Resource: "*" Condition: StringLike: 'kms:EncryptionContext:aws:cloudtrail:arn': !Sub arn:aws:cloudtrail:*:${orgAccountId}:trail/* - Sid: Allow CloudTrail to describe key Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: kms:DescribeKey Resource: "*" - Sid: Allow principals in the account to decrypt log files Effect: Allow Principal: AWS: "*" Action: - kms:Decrypt - kms:ReEncryptFrom Resource: "*" Condition: StringEquals: kms:CallerAccount: !Ref orgAccountId StringLike: 'kms:EncryptionContext:aws:cloudtrail:arn': !Sub arn:aws:cloudtrail:*:${orgAccountId}:trail/* - Sid: Allow alias creation during setup Effect: Allow Principal: AWS: "*" Action: kms:CreateAlias Resource: "*" Condition: StringEquals: kms:CallerAccount: !Ref orgAccountId kms:ViaService: ec2.us-east-1.amazonaws.com - Sid: Enable cross account log decryption Effect: Allow Principal: AWS: "*" Action: - kms:Decrypt - kms:ReEncryptFrom Resource: "*" Condition: StringEquals: kms:CallerAccount: !Ref orgAccountId StringLike: 'kms:EncryptionContext:aws:cloudtrail:arn': !Sub arn:aws:cloudtrail:*:${orgAccountId}:trail/* # Outputs: # Outputskmsid: # Description: kms-trail-organizations # Value: !GetAtt mykms.Arn # Export: # Name: !Sub ${EnvPrefix}-kms S3BucketOrg: Type: "AWS::S3::Bucket" Properties: BucketName: !Ref S3BucketName PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true S3BucketpublicdataBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref S3BucketOrg PolicyDocument: Statement: - Sid: AWSCloudTrailAclCheck Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: "s3:GetBucketAcl" Resource: !Sub arn:aws:s3:::${S3BucketName} - Sid: AWSCloudTrailWrite Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: 's3:PutObject' Resource: !Sub arn:aws:s3:::${S3BucketName}/AWSLogs/${orgAccountId}/* Condition: StringEquals: 's3:x-amz-acl': bucket-owner-full-control - Sid: AWSCloudTrailWriteMyaccount Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: 's3:PutObject' Resource: !Sub arn:aws:s3:::${S3BucketName}/AWSLogs/${AWS::AccountId}/* Condition: StringEquals: 's3:x-amz-acl': bucket-owner-full-control
2.AdminAccount(親アカウント)での作業
次にAdminAccount(organizationsの親アカウント)で、
cloudtrailを作成します。
この時、パラメータに上記で作成したLogArchiveアカウントの
S3の名前とKMSのidを設定します。
AdminAccountで以下のcloudformationを適応します。
AWSTemplateFormatVersion: "2010-09-09" Description: A templete for taf init Parameters: S3BucketName: Type: String Default: xxxxxxxxxxxxxxxxxx Description: "bucket name for cloudtrail. this is expected to be log Archive's account bucket name" kmsid: Type: String Default: 3e20a5ef-xxxxxxx-xxxx-xxxx Description: "kms-id in log Archive Account" AccountIdLog: Type: String Default: xxxxxxxxxx Description: "AWS Account Id of logArchive" Resources : mytrail: Type: AWS::CloudTrail::Trail Properties: # CloudWatchLogsLogGroupArn: String # CloudWatchLogsRoleArn: String EnableLogFileValidation: true # EventSelectors: # - EventSelector IncludeGlobalServiceEvents: true IsLogging: true IsMultiRegionTrail: true KMSKeyId: !Sub arn:aws:kms:us-east-1:${AccountIdLog}:key/${kmsid} S3BucketName: !Ref S3BucketName # S3KeyPrefix: String # SnsTopicName: String # Tags: # - Resource Tag TrailName: !Ref S3BucketName
cloudtrailをorganizations連携する
上記適応後に、AWSコンソールから作成されたcloudtrailを開き、
「Enable for all accounts in my organization」を有効化します。
cloudformationでは、この設定値が設定できなかったので、
ここだけ手動設定になります。
上記でベストプラクティス風の構成が実現できました。
さいごに
AWSでcloudtrailの権限移譲を構成してみました。
冒頭で紹介したブログは、cloudtrail以外にも、
Organiztions関連の連携まとめが記載されており分かりやすいです。
いつも参考にさせてもらっています。
ありがとうございます。
このブログもどなたか参考にして頂けると嬉しいです。
fu3ak1.hatenablog.com