開発者は、GitHubでソースコードの管理を行います。
事前に設定した特定のブランチに変更があると、Webhookでその変更を検知し、CodePipelineがCodeBuildへソースコード一式を渡します。
CodeBuildは受け取ったソースコード上でビルドコマンドを実行し、出来上がったファイル一式をCodePipelineへ再度返します。
その後、CodePipelineは受け取ったファイル一式をS3へ配置します。
インターネット利用者は、Route 53で名前解決を行い、CloudFrontへアクセスすることで、配置されたWebアプリを利用します。インターネット利用者は直接S3を参照できません。
兎にも角にも、まずはWebアプリを作る必要があります。
今回はCreate React Appを使って導入される初期状態のReactで実施していきます。
npx create-react-app my-react-app --use-npm
cd my-react-app
npm start
上記のコマンドを実行して、Reactを導入、動作確認を行います。
今回はCodeBuildでnpm
を使ってビルドするため、--use-npm
オプションでnpm
を使うことを強制しています(yarn
を利用したい場合は、後ほど出てくるbuildspec.yml
でyarn
をインストールする必要が出てきます)。
上記のコマンドがちゃんと動けばとりあえずOKなので、そのソースコードを使って環境を構築していきます。
今導入したReactアプリケーションをGitHubで管理するために、まず任意の名称でリポジトリを作成します(作り方は割愛)。
リポジトリを作成するとき、オプションは選択せず、空のリポジトリを作成してください。
作成後、以下のコマンドでソースコード一式をプッシュします(username
およびrepository
の部分は変更しましょう)。
git remote add origin git@github.com:username/repository.git
git push -u origin master
Create React Appで作成したソースコードは、すでにgit init
やgit commit
されているので、重ねてする必要はありません。
buildspec.yml
の作成プロジェクトのルートにbuildspec.yml
という名称で以下のテキストファイルを作成してください。
version: 0.2
phases:
pre_build:
commands:
- if [ -e /tmp/node_modules.tar ]; then tar xf /tmp/node_modules.tar; fi
- npm install
build:
commands:
- npm run build
post_build:
commands:
- tar cf /tmp/node_modules.tar node_modules
artifacts:
files:
- '**/*'
base-directory: build
cache:
paths:
- /tmp/node_modules.tar
これは、CodeBuildによって実行されるビルド時のコマンドと、ビルド結果のファイルの位置やキャッシュの位置を示したものです。
CodeBuildはこれを読んで、ビルドを実行してくれます。
こちらの変更もコミット・プッシュしておきましょう。
git add buildspec.yml
git commit -m "create buildspec.yml"
git push -u origin master
先に、ビルドされたファイル一式を格納して公開するためのS3バケットを作成します。
「バケットを作成する」をクリックし、以降の画面で作成するバケットの設定を行っていきます。
任意のバケット名を指定します。「オプションの設定」に関しては、環境に合わせ自由に設定します。
今回はインターネットからS3に直接アクセスはしないので、「アクセス許可の設定」でパブリックアクセスは全面的に拒否する設定にしておきます(デフォルトのままでOK)。
この設定で、バケットを作成します。
AWSのコンソールにログインし、CodePipelineの画面を開きます。
「パイプラインの作成」をクリックし、以降の画面で自動ビルド・デプロイの設定を行っていきます。
上記のようにパイプライン名に任意の名称を指定し、次の画面に進みます。
ソースプロバイダに「GitHub」を選択し、「GitHubに接続」からGitHubにログインすると、上記のようにリポジトリとブランチを選択できるようになります。
変更を検知して自動デプロイしたいリポジトリとそのブランチを指定し、次の画面に進みます。
ビルドプロバイダに「AWS CodeBuild」を選択し、「Create project」で新たなプロジェクトを作成します。
Project nameに任意の名前を設定します。
Operating systemで「Ubuntu」を選択、Runtimeで「Node.js」を選択、Runtime version・Image versionは各環境に合わせてビルド時に利用するべきNode.jsのバージョンを指定してください(通常は最も新しいもので良い)。
buildspec.yml
を利用するので、「Use a buildspec file」のままで、buildspec.yml
の位置を変更する場合は、Buildspec nameでそのパスを指定します。
設定し終えたら、「Continue to CodePipeline」で次の画面に進みます。
正常に設定し終わると、先ほどの画面に戻り、プロジェクト名に作成したプロジェクトが挿入されますので、次の画面に進みます。
デプロイプロバイダに「Amazon S3」を選択し、先ほど作成したS3バケットを指定します。
「デプロイする前にファイルを展開する」チェックボックスにチェックを入れ、次の画面に進みます。
確認画面が出ますので、問題なければ「パイプラインの作成」をクリックし、パイプラインを作成します。
パイプラインを作成すると、作成したパイプラインの画面に飛び、最初のビルド・デプロイ処理が走ります。その流れは画面に表示され、途中で失敗した場合には画面でわかるようになっています。運用中に問題が発生した場合には、まずはこの画面を見るようにしましょう。
最初のビルド・デプロイ処理が終わると、指定したS3に出来上がったファイル一式が格納されますので、ここで一度、きちんと動作しているか確認しておきましょう。
S3を公開するにあたり、そのCDNとなるCloudFrontの設定を行います。
CloudFrontを利用しなくてもいい場合は、S3に対してWebサイトホスティングの設定とパブリックアクセスを許可する設定を行い、直接アクセスするようにしましょう。
AWSのコンソールにログインし、CloudFrontの画面を開きます。
「Create Distribution」をクリックし、「Web」のセクションの「Get Started」をクリックし、以降の画面でCloudFrontの設定を行っていきます。
Origin Settingsセクションで、次の設定を行います。
Origin Domain Nameへ、先ほど作成したS3のバケットを指定します(フォーカスすると選択肢が出てきます)。
Restrict Bucket Accessを「Yes」にし、Origin Access Identityで「Create a New Identity」を選択し、Grant Read Permissions on Bucketで「Yes, Update Bucket Policy」を選択します。
また、Distribution Settingsセクションで、次の設定を行います。
Default Root Objectに「index.html」を設定しておきます。
Route 53で独自ドメインでの名前解決を行う場合は、Alternate Domain Names (CNAMEs)へ登録する予定のドメインを設定しておきます。
その他の設定は、ご自身のやりたい動作や環境に合わせて行ってください。ここでCloudFrontの細かい挙動の設定ができますが、個別の解説は長くなるので省略します。
例えば、HTTPSにしたい場合は、AWSで証明書の設定を行えば、AWSだけでHTTPSアクセスに対応させることもできます。
特に動作が決まっていない場合は後からでも変更できるので、デフォルトのままでも大丈夫です。
設定値を入力したら「Create Distribution」をクリックし、ディストリビューションを作成します。
作成後、Stateが「In Progress」から「Deployed」になれば、作成完了です(少し時間がかかります)。
ここまで正常に設定し動作していれば、作成したディストリビューションのDomain Name(*.cloudfront.net
)へアクセスすると、Webアプリの確認ができます。
CloudFront(設定していない場合はS3)へアクセスするためのドメインを独自ドメインのものにするために、Route 53の設定を行います。
独自ドメインの取得方法やRoute 53へのHosted Zoneの設定はここでは解説しません。
AWSのコンソールにログインし、Route 53の画面を開きます。
設定するドメインのゾーンの画面を開き、「Create Record Set」をクリックします。
Nameに設定するドメイン、Typeに「A – IPv4 address」を選択し、Aliasを「Yes」にし、Alias Targetに先ほど作成したCloudFrontのディストリビューションを設定します。
Alias Targetは、フォーカスすると先ほど作成したCloudFrontのディストリビューションが表示されますので、それを選択します。それが表示されない場合、CloudFrontのAlternate Domain Names (CNAMEs)の設定がうまくできていない可能性があります。
CloudFrontでIPv6が有効になっている場合、上記のようにTypeが「AAAA – IPv6 address」の同じレコードも作成します。
Route 53の設定は以上です。少し待つと独自ドメインでアクセスできるようになるかと思います(DNSの反映には環境によって時間がかかる場合があります)。
以上で、全ての設定が終了しました。
試しに何か変更を加えてGitHubにプッシュしてみましょう。自動でWebアプリケーションが更新されます。
なお、CloudFrontでデフォルトのまま設定している場合、即座に変更が確認できません(キャッシュされているため)。
Create React Appで生成されたアプリケーションを初期設定のままで使う場合、JSやCSSに変更があるとファイル名が変わるため、index.html
だけキャッシュされないような設定をCloudFrontに追加すれば、変更が即座に反映されるような状態にすることも可能です。
一時的に変更されたことをすぐに確認したい場合は、CloudFrontのInvalidationでキャッシュを削除しましょう。
上記で、ひとまずReactで作成したWebアプリを、GitHub上で管理して自動でAmazon S3にデプロイできるようになりました。
実際に運用する上では、CloudFrontで更なる細かい設定を行ったり、テストコードを追加してそれを通過した時だけビルドする等の処理を追加したりする必要が出てくるかと思いますので、それぞれの場面に合わせて更なる環境構築を進めてください。