目次

Introduction

この記事でやっとCloudFormation(以下CFn)のテンプレートを記載していきます。
[CloudFormation] CFnで環境作り完全版 Part1. IAM User編でも記載している通り、テンプレートの詳しいプロパティの説明は省きます。
この記事は一番始めに監査証跡サービスであるCloudTrailを作成します。
CFnテンプレートをAWSコンソールで流してスタックを作成する際は、Part1で作成したUserにログインしスイッチロールをして操作してください。

今回作成するもの

完成系

AWSリソース

CFn相関図

iam-user.yamlは、Part1. IAM User編で作成したものになります。

HandsOn

IAM作成

CloudTrailを構築する前にCloudTrailのRoleを作成します。

.pre-commit-config.yaml
cloudformation
 L iam-user.yaml
   iam-role.yaml(new)
AWSTemplateFormatVersion: "2010-09-09"
Description: "stackName: iam-role. AWS::IAM::Role AWS::IAM::InstanceProfile"

Resources:
  CloudTrailRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: cloudtrail-role
      Path: /service-role/
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - cloudtrail.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: cloudtrail-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Sid: CloudWatchPutPolicy
                Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*

Outputs:
  CloudTrailRoleArn:
    Description: Output Export AWS::IAM::Role.Arn CloudTrailRole
    Value: !GetAtt CloudTrailRole.Arn
    Export:
      Name: cloudtrail-role-arn

AWSコンソールで流すときのスタック名は、Descriptionに記載のある通りiam-roleにします。今回作成するCFnのDescriptionはCFnのスタック名と作成するリソースの種類を記載しています。ここは、プロジェクトや個人の思想に合わせていただければ。

CloudTrail作成

上記でCloudTrailのRoleを作成したので実際のCloudTrailを作成します。

.pre-commit-config.yaml
cloudformation
 L iam-user.yaml
   iam-role.yaml
   cloudtrail.yaml(new)
AWSTemplateFormatVersion: "2010-09-09"
Description: "stackName: cloudtrail. AWS::CloudTrail::Trail  AWS::Logs::LogGroup AWS::S3::Bucket AWS::S3::BucketPolicy"

Parameters:
  Project:
    Type: String
    Description: Project Name
    Default: example

Resources:
  CloudTrail:
    Type: AWS::CloudTrail::Trail
    Properties:
      TrailName: !Sub ${Project}-cloudtrail
      IsLogging: true
      IncludeGlobalServiceEvents: true
      IsMultiRegionTrail: true
      EnableLogFileValidation: true
      CloudWatchLogsLogGroupArn: !GetAtt CloudTrailCWLogGroup.Arn
      CloudWatchLogsRoleArn: !ImportValue cloudtrail-role-arn
      S3BucketName: !Ref CloudTrailS3Bucket
      S3KeyPrefix: cloudtrail

  CloudTrailCWLogGroup:
    Type: AWS::Logs::LogGroup
    Properties: 
      LogGroupName: !Sub ${Project}-cloudtrail
      RetentionInDays: 180

  CloudTrailS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${Project}-cloudtrail-event-logs
      VersioningConfiguration:
        Status: Enabled
  CloudTrailS3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref CloudTrailS3Bucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement: # https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html
          - Sid: ReadPolicy4CloudTrail
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action:
              - s3:GetBucketAcl
            Resource: !GetAtt CloudTrailS3Bucket.Arn
            Condition:
              StringEquals:
                "aws:SourceArn": !Sub arn:aws:cloudtrail:${AWS::Region}:${AWS::AccountId}:trail/${Project}-cloudtrail
          - Sid: WritePolicy4CloudTrail
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action:
              - s3:PutObject
            Resource: !Sub
              - ${BucketArn}/cloudtrail/AWSLogs/${AWS::AccountId}/*
              - BucketArn: !GetAtt CloudTrailS3Bucket.Arn
            Condition:
              StringEquals:
                "s3:x-amz-acl": bucket-owner-full-control
                "aws:SourceArn": !Sub arn:aws:cloudtrail:${AWS::Region}:${AWS::AccountId}:trail/${Project}-cloudtrail

CloudTrailのログを保存するS3のバケットポリシーは、公式に記載されているのでそれを参考にします。
ParametersのProjectはテンプレートのDefaultのexampleを指定します。ここは基本的になんでもいいのですが、一点注意するところは、S3のバケット名はグローバルに一意でないと作成できないので、同じくexampleにするとスタックが作成できないことがあるので気をつけてください。

終わりに

CloudTrailを作成したので、これで操作ログが保存されるため最低限の監査証跡システムは構築しました。
リソースの作成中に問題が起きた時もCloudTrailで原因がわかることも多々あるので結構便利です。

参考