CodeBuildを使ってS3バケットを定期的にバックアップする

## はじめに
あるS3バケットにあるファイルを全て日次で用意したバケットにバックアップするために作成。
ファイルがたくさんあったときに、時間が掛かってLambdaのタイムアウトに引っかかるのが怖かったところ、下記の記事があり、参考にCloudFormationで作成しました。
https://dev.classmethod.jp/articles/s3-sync-with-codebuild-cloudwatch-events/

## 構成
日次でCloudWatchイベントルールでCodeBuildを実行してS3のファイルをバックアップ
![スクリーンショット 2021-09-18 191823.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478113/3e3e6701-e36c-8eec-7943-fef88fe7d02a.jpeg)

## CloudFormationテンプレート
バックアップ元とバックアップ先のバケットは既にある想定でパラメータでバケット名を指定してください。
bulidspec.ymlをS3ファイルに配置はしたくなかったので、`Type`で`NO_SOURCE`を指定してテンプレートに直接`S3 sync`のコマンドを記載しています。
IAMロール、IAMポリシーも作成しています。

```yml:sample.yml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  BackUpTargetBucket:
    Type: String
  BackUpBucket:
    Type: String
Resources:
  S3BackUpCodeBuld:
    Type: 'AWS::CodeBuild::Project'
    Properties:
      Name: S3-sync-codebuild-project
      Artifacts:
        Type: NO_ARTIFACTS
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
        Type: LINUX_CONTAINER
      ServiceRole: !Ref S3AccessRole
      Source:
        Type: NO_SOURCE
        BuildSpec: !Sub |-
          version: 0.2
          phases:
            build:
              commands:
                - aws s3 sync s3://${BackUpTargetBucket} s3://${BackUpBucket}/$(date "+%Y%m%d%H%M%S")
  S3AccessRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: CodeBuildS3SyncRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              Service:
                - "codebuild.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
  S3AccessPolicies:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: S3SyncPolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
            - "s3:ListAllMyBuckets"
          Resource: "arn:aws:s3:::*"
        - Effect: Allow
          Action:
            - "s3:PutObject"
            - "s3:ListBucket"
            - "s3:GetObject"
          Resource:
            - !Sub arn:aws:s3:::${BackUpTargetBucket}
            - !Sub arn:aws:s3:::${BackUpTargetBucket}/*
            - !Sub arn:aws:s3:::${BackUpBucket}
            - !Sub arn:aws:s3:::${BackUpBucket}/*
      Roles:
      - !Ref S3AccessRole
  PutCloudWatchLogs:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: PutCloudWatchLogs
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
            - logs:CreateLogStream
            - logs:DescribeLogStreams
            - logs:CreateLogGroup
            - logs:PutLogEvents
          Resource: "*"
      Roles:
      - !Ref S3AccessRole
  EventsRule:
    Type: 'AWS::Events::Rule'
    Properties:
      Description: sample-rule
      Name: codebuild-s3-sync-event-rule
      ScheduleExpression: 'cron(0 15 * * ? *)'
      State: ENABLED
      Targets:
        - Arn: !GetAtt
          - S3BackUpCodeBuld
          - Arn
          Id: CodeBUildSyncId
          RoleArn: !GetAtt
              - CodeBuildExecuteRole
              - Arn
  CodeBuildExecuteRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: CloudWatchEventCodeBuildExecuteRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              Service:
                - "events.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
  CodebuildStartPolicies:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: s3SyncPolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
            - "codebuild:StartBuild"
          Resource: "*"
      Roles:
      - !Ref CodeBuildExecuteRole

```


作成するリソース

| リソース名 | サービス名 | 用途 |
|:-:|:-:|:-:|
|S3BackUpCodeBuld|CodeBuild   |S3のバックアップの実行|
|S3AccessRole   |IAMロール   |CodeBuildに設定するIAMロール   |
|S3AccessPolicies   |IAMポリシー   |S3 syncを実行するためのポリシー   ​|
| PutCloudWatchLogs  | IAMポリシー  |  CodeBulildからログ出力に必要なポリシー|
|  EventsRule |  CloudWatchイベントルール |  CodeBuidの日時実行|
|  CodeBuildExecuteRole |  IAMロール | イベントルールからCodeBulild実行に必要なポリシー  |
|  CodebuildStartPolicies |  IAMポリシー | CodeBulild実行のポリシー  |