CodeCommitにPushする度に、S3にバックアップする
以下のAWS公式ページで、 CodeCommitの内容をS3にバックアップする方法が紹介されています。
この構成の意義ですが、以下のように説明されています。
このパターンは、 CodeCommit リポジトリに変更が加えられた後、Amazon Simple Storage Service (Amazon S3) バケットに自動的にバックアップする方法を示しています。 CodeCommit リポジトリが後で削除されても、 point-in-time このバックアップ戦略は回復オプションを提供します。
CodeBuild とイベントを使用して、から Amazon S3 CodeCommit CloudWatch へのイベント駆動型バックアップを自動化
本ページでは、上記を参考にした構成をご紹介します。
構築する環境
ソースコードリポジトリとして、CodeCommitを使用します。
CodeBuildでは、CodeCommit内のソースコードをcloneします。
取得したファイルをZIP化して、S3バケットに保存します。
CodeBuildが実行されるきっかけですが、EventBridgeを使用します。
CodeCommitのmasterブランチが更新される度に、CodeBuildを実行するように、EventBridgeルールを設定します。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-fa/tree/main/136
テンプレートファイルのポイント解説
S3バケット
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref Prefix
AccessControl: Private
Code language: YAML (yaml)
ソースコードのバックアップ先として使用するS3バケットです。
特別な設定は不要です。
CodeCommit
Resources:
CodeCommitRepository:
Type: AWS::CodeCommit::Repository
Properties:
RepositoryName: !Ref Prefix
Code language: YAML (yaml)
ソースコードリポジトリです。
こちらも特別な設定は不要です。
CodeBuild
Resources:
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: NO_ARTIFACTS
Cache:
Type: NO_CACHE
Environment:
ComputeType: !Ref ProjectEnvironmentComputeType
EnvironmentVariables:
- Name: BRANCH_NAME
Type: PLAINTEXT
Value: !Ref BranchName
- Name: BUCKET_NAME
Type: PLAINTEXT
Value: !Ref BucketName
- Name: REPO_REGION
Type: PLAINTEXT
Value: !Ref AWS::Region
- Name: REPOSITORY_NAME
Type: PLAINTEXT
Value: !GetAtt CodeCommitRepository.Name
Image: !Ref ProjectEnvironmentImage
ImagePullCredentialsType: CODEBUILD
Type: !Ref ProjectEnvironmentType
PrivilegedMode: true
LogsConfig:
CloudWatchLogs:
Status: DISABLED
S3Logs:
Status: DISABLED
Name: !Ref Prefix
ServiceRole: !GetAtt CodeBuildRole.Arn
Source:
Type: NO_SOURCE
BuildSpec: !Sub |
version: 0.2
phases:
install:
commands:
- pip install git-remote-codecommit
build:
commands:
- env
- git clone -b $BRANCH_NAME codecommit::$REPO_REGION://$REPOSITORY_NAME
- dt=$(date '+%d-%m-%Y-%H:%M:%S');
- echo "$dt"
- zip -yr $dt-$REPOSITORY_NAME-backup.zip ./
- aws s3 cp $dt-$REPOSITORY_NAME-backup.zip s3://$BUCKET_NAME/
Visibility: PRIVATE
Code language: YAML (yaml)
CodeBuildに関する基本的な事項は、以下のページをご確認ください。
ポイントを3つ取り上げます。
1点目はArtifactsプロパティです。
今回はアーティファクトはありませんので、本プロパティに「NO_ARTIFACTS」を指定します。
2点目はEnvironmentVariablesプロパティです。
CodeBuild内の環境変数を設定できます。
今回は先述のS3バケット名や、CodeCommitリポジトリ名等を指定します。
3点目はBuildSpecプロパティです。
本プロパティでBuildSpec.ymlの内容を直接記述することができます。
こちらについては、以下のページを参考に記載しています。
実行する内容ですが、git-remote-codecommitをインストール後、CodeCommitからソースコードをcloneします。
取得したコード類をZIP化し、S3バケットにアップロードします。
以下はCodeBuild用のIAMロールです。
Resources:
CodeBuildRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: CodeBuildExecutionPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:PutObject
Resource:
- !Sub "arn:aws:s3:::${BucketName}/*"
- Effect: Allow
Action:
- codecommit:GitPull
Resource:
- !GetAtt CodeCommitRepository.Arn
Code language: YAML (yaml)
CodeCommitからソースコードを取得する権限と、S3にオブジェクトをアップロードする権限を与えます。
EventBridge
Resources:
EventsRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.codecommit
detail-type:
- CodeCommit Repository State Change
resources:
- !GetAtt CodeCommitRepository.Arn
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- !Ref BranchName
Name: !Ref Prefix
Targets:
- Arn: !GetAtt CodeBuildProject.Arn
Id: !Sub "${Prefix}-CodeBuild"
InputTransformer:
InputPathsMap:
account: $.account
referenceType: $.detail.referenceType
referenceName: $.detail.referenceName
region: $.region
repositoryName: $.detail.repositoryName
InputTemplate: |
{"referenceType":"<referenceType>","region":"<region>","repositoryName":"<repositoryName>","account":"<account>","referenceName":"<referenceName>"}
RoleArn: !GetAtt EventsRuleRole.Arn
Code language: YAML (yaml)
CodeCommitのmasterブランチに変更があった場合、これをトリガーにしてCodeBuildを実行させます。
ルールや入力トランスフォーマーに関する記述についても、以下のページを参考にしました。
以下がEventBridge用のIAMロールです。
Resources:
EventsRuleRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- events.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: PipelineExecutionPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- codebuild:StartBuild
Resource:
- !GetAtt CodeBuildProject.Arn
Code language: YAML (yaml)
CodeBuildを開始するための権限を与えます。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- S3バケット:fa-136
- CodeCommit:fa-136
- CodeBuild:fa-136
- EventBridge:fa-136
作成されたリソースをAWS Management Consoleから確認します。
CodeCommitを確認します。
確かにリポジトリが作成されています。
EventBridgeを確認します。
CodeCommitの作成・更新がトリガーの条件に設定されています。
ターゲットには、CodeBuildが指定されていることもわかります。
CodeBuildを確認します。
CloudFormationテンプレートで指定した通りに設定されていることがわかります。
動作確認
準備が整いました。
まずCodeCommitをプルします。
$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/fa-136
Cloning into 'fa-136'...
warning: You appear to have cloned an empty repository.
Code language: Bash (bash)
空のリポジトリがプルされました。
リポジトリにテストファイルを加えます。
touch ./fa-136/test.txt
Code language: Bash (bash)
テストファイルをCodeCommitにプッシュします。
(master) $ git add .
(master) $ git commit -m "first commit"
[master (root-commit) 5a16cf1] first commit
...
1 file changed, 9 insertions(+)
create mode 100644 test.txt
(master) $ git push
...
* [new branch] master -> master
Code language: Bash (bash)
正常にプッシュできました。
改めてCodeCommitを確認します。
確かにテストファイルがプッシュされています。
ファイルのプッシュをトリガーとして、EventBridgeが動作して、CodeBuildが開始されるはずです。
しばらく待機してからCodeBuildを確認します。
確かにCodeBuildの実行が正常に完了しています。
S3バケットを確認します。
確かにZIPファイルがアップロードされています。
ダウンロードして、内容を確認します。
$ aws s3 cp s3://fa-136/25-05-2023-11:40:34-fa-136-backup.zip .
download: s3://fa-136/25-05-2023-11:40:34-fa-136-backup.zip to ./25-05-2023-11:40:34-fa-136-backup.zip
$ unzip -l 25-05-2023-11:40:34-fa-136-backup.zip
Archive: 25-05-2023-11:40:34-fa-136-backup.zip
Length Date Time Name
--------- ---------- ----- ----
0 05-25-2023 11:40 fa-136/
0 05-25-2023 11:40 fa-136/.git/
0 05-25-2023 11:40 fa-136/.git/branches/
73 05-25-2023 11:40 fa-136/.git/description
0 05-25-2023 11:40 fa-136/.git/hooks/
478 05-25-2023 11:40 fa-136/.git/hooks/applypatch-msg.sample
896 05-25-2023 11:40 fa-136/.git/hooks/commit-msg.sample
4726 05-25-2023 11:40 fa-136/.git/hooks/fsmonitor-watchman.sample
189 05-25-2023 11:40 fa-136/.git/hooks/post-update.sample
424 05-25-2023 11:40 fa-136/.git/hooks/pre-applypatch.sample
1643 05-25-2023 11:40 fa-136/.git/hooks/pre-commit.sample
416 05-25-2023 11:40 fa-136/.git/hooks/pre-merge-commit.sample
1374 05-25-2023 11:40 fa-136/.git/hooks/pre-push.sample
4898 05-25-2023 11:40 fa-136/.git/hooks/pre-rebase.sample
544 05-25-2023 11:40 fa-136/.git/hooks/pre-receive.sample
1492 05-25-2023 11:40 fa-136/.git/hooks/prepare-commit-msg.sample
2783 05-25-2023 11:40 fa-136/.git/hooks/push-to-checkout.sample
3650 05-25-2023 11:40 fa-136/.git/hooks/update.sample
0 05-25-2023 11:40 fa-136/.git/info/
240 05-25-2023 11:40 fa-136/.git/info/exclude
0 05-25-2023 11:40 fa-136/.git/refs/
0 05-25-2023 11:40 fa-136/.git/refs/heads/
41 05-25-2023 11:40 fa-136/.git/refs/heads/master
0 05-25-2023 11:40 fa-136/.git/refs/tags/
0 05-25-2023 11:40 fa-136/.git/refs/remotes/
0 05-25-2023 11:40 fa-136/.git/refs/remotes/origin/
32 05-25-2023 11:40 fa-136/.git/refs/remotes/origin/HEAD
23 05-25-2023 11:40 fa-136/.git/HEAD
260 05-25-2023 11:40 fa-136/.git/config
0 05-25-2023 11:40 fa-136/.git/objects/
0 05-25-2023 11:40 fa-136/.git/objects/pack/
0 05-25-2023 11:40 fa-136/.git/objects/info/
0 05-25-2023 11:40 fa-136/.git/objects/e6/
15 05-25-2023 11:40 fa-136/.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
0 05-25-2023 11:40 fa-136/.git/objects/ac/
159 05-25-2023 11:40 fa-136/.git/objects/ac/24cc10720d0e07a8d3fbd16767ef704663d5ee
0 05-25-2023 11:40 fa-136/.git/objects/5e/
53 05-25-2023 11:40 fa-136/.git/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034
114 05-25-2023 11:40 fa-136/.git/packed-refs
0 05-25-2023 11:40 fa-136/.git/logs/
0 05-25-2023 11:40 fa-136/.git/logs/refs/
0 05-25-2023 11:40 fa-136/.git/logs/refs/remotes/
0 05-25-2023 11:40 fa-136/.git/logs/refs/remotes/origin/
179 05-25-2023 11:40 fa-136/.git/logs/refs/remotes/origin/HEAD
0 05-25-2023 11:40 fa-136/.git/logs/refs/heads/
179 05-25-2023 11:40 fa-136/.git/logs/refs/heads/master
179 05-25-2023 11:40 fa-136/.git/logs/HEAD
137 05-25-2023 11:40 fa-136/.git/index
0 05-25-2023 11:40 fa-136/test.txt
--------- -------
25197 49 files
Code language: JavaScript (javascript)
確かにテストファイルを含むリポジトリの内容がバックアップされていることがわかります。
まとめ
CodeCommitにPushする度に、S3にバックアップを取る方法を確認しました。