GitLabリポジトリをCodeCommitにミラーリングしてS3に配置する

GitLabリポジトリをCodeCommitにミラーリングしてS3に配置する
この記事をシェアする

はじめに

こんにちは!スカイアーチHRソリューションズのnakaoです!
突然ですが皆さん、コード管理ツールは使っていますか? GitHub、GitLabなどが有名ですね。
私はGitLabをずっと使っています。コード管理ツール、大変便利ですよね。
ミラーリングという機能をご存じでしょうか?
長年GitLabを使っていながら、この前業務で初めてミラーリングを知り、衝撃を受けました!
リポジトリミラーリングは、外部ソースとの間でリポジトリのミラーリングを可能にします。
例えばミラーリングの活用として、静的ウェブサイトをホスティングするために
GitLabでコード管理して、コードを手動でS3にアップロードする
としていたところを
GitLabにPushするだけで、自動でS3にアップロードする
ことが可能になります。非常に便利ですよね。
今回はこのミラーリングを使用して、自動でS3に静的ウェブサイトをホスティングしてみます!

ミラーリングの詳細に関しては以下、GitLab公式日本語ドキュメントを参照してください。

アーキテクチャ

全体のアーキテクチャはこちらです!
処理の流れとしては、以下の順番で実行されます。

①GitLabにソースコード(HTML, JavaScript, CSS)をPushする。
②ミラーリングが実行され、CodeCommitリポジトリにソースコードがミラーリングされる。
③CodeCommitへのミラーリングをトリガーに、CodePipelineが実行される。
④CodePipeline上でCodeBuildが実行される。
⑤CodePipeline上でS3へのデプロイが実行される。

なぜCodeBuildを使用するのか

今回のアーキテクチャですが、CodeBuildを使用しています。
「CodeBuildは必要あるのか?」
そう思われる方も多いと思います。
結論から言うと、CodeBuildがなくてもCodePipeline上の機能でS3へデプロイは可能です。
ただ、問題があります。
S3へソースコードの新規作成、同一ファイルの上書きは可能ですが、削除は不可能です。
GitLabとCodeCommitのソースは同期しているのに、S3だけ同期していない。
なんだか気持ち悪いですよね。
そこでCodeBuildが必要になってくる、というわけです。
今回、CodeBuildでソースのBuildは実行しませんが、Shellスクリプトを実行します。S3にデプロイする前に、S3にある既存のオブジェクトを削除するという処理を実行するためにCodeBuildが必要です。

S3の作成まで

S3の作成

まず、コンテンツ配置用のS3を作成していきます。
バケット名のみ入力して、あとはデフォルト設定のまま作成していきましょう。

静的ウェブサイトホスティング機能の有効化

次に、静的ウェブサイトホスティング機能を有効化します。
先ほど作成したバケットの「プロパティ」タブを選択し、「静的ウェブサイトホスティング」の「編集」を押下してください。

「静的ウェブサイトホスティング」を「有効にする」を選択してください。
また、インデックスドキュメントには「index.html」と入力して、変更を保存してください。

静的ウェブサイトホスティング機能を有効化したら、バケットウェブサイトエンドポイントは控えておきましょう。

ブロックパブリックアクセスの設定

次に、ブロックパブリックアクセスの設定を変更します。
先ほど作成したバケットの「アクセス許可」タブを選択し、「ブロックパブリックアクセス(バケット設定)」の「編集」を押下してください。

「パブリックブロックアクセスをすべてブロック」にチェックが付いているはずですので、そのチェックを外して変更を保存します。

S3のバケットポリシーの設定

最後にS3のバケットポリシーの設定を変更しておきます。
先ほど作成したバケットの「アクセス許可」タブを選択し、「バケットポリシー」を以下、コピペしてください。
<S3 bucket name>には作成したバケット名を書き換えて設定するようにしてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<S3 bucket name>/*"
        }
    ]
}

静的ウェブサイトホスティングのテスト

静的ウェブサイトホスティング設定ができているか、念のため確認しておきましょう。
以下、ソースコードをコピペしてindex.htmlファイルを作成し、バケットにアップロードしてください。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Website Home Page</title>
</head>
<body>
  <h1>Welcome to my website</h1>
  <p>Now hosted on Amazon S3!</p>
</body>
</html>

先ほど控えたバケットウェブサイトエンドポイントにアクセスして、コンテンツの表示を確認しておきましょう。
私はGoogle Chromeを使用します。

問題なく、静的ウェブサイトホスティングはできていますね!
S3の作成に関しては以上です。

CodeCommitリポジトリの作成まで

CodeCommitリポジトリの作成

まず、空のCodeCommitリポジトリを作成していきましょう。
リポジトリ名のみ入力して、あとはデフォルト設定のまま作成していきましょう。
リポジトリ名は後に使用するので控えておきましょう。

また、作成したCodeCommitリポジトリのURLも控えておきましょう。

CodeCommitリポジトリの作成に関しては以上です。

IAMユーザーの作成まで

GitLabからCodeCommitにミラーリング設定をする際に使用するので、認証情報を払い出しておきます。

IAMポリシーの作成

まず、IAMポリシーを作成します。
IAMからポリシーの作成を選択し以下、コピペしてIAMポリシーを作成してください。
<AWS アカウント ID>、<CodeCommit リポジトリ名>はそれぞれ書き換えて設定してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "codecommit:GitPull",
                "codecommit:GitPush"
            ],
            "Resource": "arn:aws:codecommit:ap-northeast-1:<AWS アカウント ID>:<CodeCommit リポジトリ名>"
        }
    ]
}

IAMユーザーの作成

IAMからユーザーを作成します。
先ほど作成したIAMポリシーをアタッチしてIAMユーザーを作成してください。
作成したIAMユーザーの「セキュリティ認証情報」タブを選択し、「AWS CodeCommitのHTTPS Git 認証情報」から「認証情報を生成」を押下してください。

ポップアップが表示されます。
ユーザー名とパスワードは忘れないように控えておきましょう。

IAMユーザーの作成に関しては以上です。
以下、参考にした記事です。

GitLabリポジトリの作成まで

GitLabリポジトリの作成

まず、プライベートなGitLabリポジトリを作成します。

ミラーリング設定

次に、作成したリポジトリの「Settings」から「Repository」を選択します。

「Mirroring repositories」から「Add new mirror repository」を設定していきます。
「Git repository URL」にはCodeCommitリポジトリのURLを修正して設定します。
<user name>には先ほど生成したGit認証情報のユーザー名、<CodeCommitリポジトリ名>はそれぞれ書き換えて設定するようにしてください。
「Username」にはGit認証情報のユーザー名を設定してください。
「Password」にはGit認証情報のパスワードを設定してください。
設定後、「Mirror repository」を押下して設定を保存します。

https://<user name>@git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/<CodeCommitリポジトリ名>

GitLabリポジトリの作成に関しては以上です。

CodeBuildビルドプロジェクトの作成まで

CodeBuildを使用するために、CodeBuildビルドプロジェクトを作成していきます。

CodeBuildビルドプロジェクトの作成

まず、CodeBuildの「ビルドプロジェクト」から「ビルドプロジェクトを作成する」を押下してビルドプロジェクトを作成していきます。

「プロジェクト名」には任意のプロジェクト名を設定してください。

「ソースプロパイダ」にはCodeCommit、「リポジトリ」には先ほど作成したCodeCommitリポジトリを選択してください。「ブランチ」はmainを選択します。

「環境イメージ」はマネージド型イメージを選択し、オペレーティングシステム以下は、下記図のように設定してください。「イメージ」と「イメージのバージョン」は最新バージョンがある場合、最新バージョンを使用するようにしてください。

「サービスロール」は新しいサービスロールを作成します。
あとはデフォルト設定のままビルドプロジェクトを作成していきましょう。

CodeBuild用環境変数の設定

先ほど作成したCodeBuildプロジェクトの「ビルドの詳細」タブを選択してください。
「環境」から環境変数を設定しておきましょう。Buildspec内で環境変数を利用するために設定します。
また、ビルドプロジェクト作成時に作成したCodeBuild用のIAMロールを修正します。

CodeBuild用IAMロールの修正

今回新しく作成したCodeBuild用のIAMロールだと、Buildspec実行時にS3へのアクセス権限が不足してしまいます。
「許可を追加」から「ポリシーをアタッチ」して、AmazonS3FullAccess権限を付与しておきましょう。
※本来FullAccess権限のポリシーを付与するのは良くないです。必要最低限のポリシーを付与するようにしましょう。今回はこのままFullAccess権限を付与して進めます。

CodeBuildビルドプロジェクトの作成に関しては以上です。

CodePipelineの作成まで

最後に、CodePipelineのパイプラインを作成していきます。

CodePipelineの作成

まず、CodePipelineの「パイプラインを作成する」からパイプラインを作成していきます。
「パイプライン名」には任意のパイプライン名を設定し、「サービスロール」は新しいサービスロールを作成します。

ソースステージを追加します。
「ソースプロパイダ」はCodeCommit、リポジトリ以下は先ほど作成したCodeCommitの情報を設定します。

ビルドステージを追加します。
「プロパイダーを構築する」はCodeBuildを選択し、「プロジェクト名」は先ほど作成したビルドプロジェクトを選択してください。
環境変数はビルドプロジェクトで設定したので、ここでは設定しません。

デプロイステージを追加します。
「デプロイプロパイダー」はS3を選択し、「バケット」は最初に作成した静的ウェブサイトホスティング用のバケットを選択します。
また、「デプロイする前にファイルを抽出する」のチェックボックスをオンにしておきましょう。

設定を再確認して、パイプラインを作成します。
パイプラインの作成に関しては以上です。

GitLabリポジトリにソースコードをPushして静的ウェブサイトの確認

さあ、とうとうここまできましたね!
GitLabリポジトリにソースコードをPushして、静的ウェブサイトを確認してみましょう!

GitLabリポジトリにソースコードをPush

以下の構成でGitLabにソースコードを作成します。

「src」ディレクトリ以下にS3へデプロイするソースコードを配置しています。

h2 {
    color: red;
}
alert('Hello World!')
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/main.css">
</head>
<body>
    <h2>GitLabレポジトリをCodeCommitにミラーリングしてS3に配置する</h2>
    <script src="js/main.js"></script>
</body>
</html>

ルートディレクトリ直下に「buildspec.yml」を配置しています。
CodeBuildのビルドプロジェクト実行時にこちらのbuildspec.ymlが読み込まれます。
今回はこちらにShellスクリプトを記述してあります。
CodeBuildビルドプロジェクト環境変数として設定した<S3_BUCKET_NAME>をここで読み込んでいます。
また、ビルド後に出力されるソースとして、「src」ディレクトリ以下の全てのファイルを出力するよう設定しています。

version: 0.2

phases:
  post_build:
    commands:
      - echo Delete S3 Bucket object...
      - aws s3 rm s3://${S3_BUCKET_NAME} --recursive
artifacts:
  files:
    - '**/*'
  base-directory: 'src'
GitLabレポジトリ(mirroring-test)からCodeCommitレポジトリ(mirroring-codecommit-test)へのミラーリングテスト

それでは、GitLabにPushします!

GitLabへのPush成功です!

CodeCommitリポジトリの確認

次に、CodeCommitリポジトリを確認します。

GitLabから、CodeCommitへのミラーリング成功です!

CodePipelineの確認

次に、CodePipelineを確認します。

CodePipelineのステージ全て成功してますね!

S3と静的ウェブサイトの確認

それでは最後に、S3バケットと静的ウェブサイトの確認をしていきましょう!

S3バケット直下にCodeCommitの「src」ディレクトリ以下のファイルが全て配置されていますね!
バケットウェブサイトエンドポイントにアクセスします。

想定通りの挙動になりました!

おわりに

お疲れ様でした!
GitLabからPushするだけで、S3に静的ウェブサイトを配置できましたね!
S3バケットが公開状態になっているため、非公開設定、もしくはリソースを削除しておきましょう。
今回は単純な静的ウェブサイトをホスティングしましたが、インフラリソースをCloudFormationなどでコード管理して、Pushされたらインフラリソースをビルド・デプロイして展開するなど、まだまだ活用方法はたくさんありそうです!

私の記事が少しでも皆様のご参考になれば幸いです!

この記事をシェアする
著者:nakao
IoT、サーバーレスな開発に興味深々。AWSエンジニア。