目次
せっかくAWSクラウドプラクティショナーになりましたので、忘れない内にAWSで色々ためそうと思う。
で、AWSのサービス縛りでLaravelのインフラを組んだらどんな感じになるのか試してみることにした💡
一応、AWSが推しているコスト最適と弾力性を目指していくつもり。
やりたい事をまとめると以下の通り。
- アプリケーションサーバの構築
- ビルド・テスト・デプロイの自動化
- RDBに接続できる
- cronを使える様にする(Laravelのタスクスケジュールのトリガー)
- HTTPS対応
- アプリケーションサーバのオートスケール&ロードバランシング
- Redisに接続できる
- リソースをCDNから配信する
アプリケーションサーバのコストについて、Price Calculatorで調べた所、低スペックサーバを水平に並べた方が安いっぽいので、これを基本の戦略とする。
ちなみに、CPU1個、メモリ1GBでリザーブドインスタンスにすると1年契約で月額1300円程度との事。
RDBについてはRDS for MySQLを使う。
db.t3.microでリザーブドインスタンスにすると1年契約で月額2000円程度。
そんな感じでさっそくやっていく👏
Laravelアプリケーションを作る
まずはドキュメントを参考に空のLaravelアプリケーションを作成してGithubにプッシュする。
AWSにCodeCommitというコードのバージョン管理を行うサービスもあるけど、使われているケースを見たことがないし、まぁ餅は餅屋という事でここはGithubを使っておく。
念の為、ローカルで表示できる事を確認しておく👀
Elastic Beanstalkにデプロイしてみる
作成したアプリケーションをElastic Beanstalkにデプロイする。
Elastic Beanstalkはアプリケーションサーバに関するもろもろをよしなにやってくれる便利なやつだよ🤟
プラットフォームは一旦、PHP
にする。
今後色々カスタマイズするならDocker
でイメージを自作する必要があるかもしれない🤔
ここで、デプロイするにはcomposer install
しなきゃいけない事に気づいた🤨
CodeBuildを触ってみる
CodeBuildでビルドやユニットテストの実行ができるらしいです。
ビルドで生成された一連のファイルはアーティファクトと呼ばれて、S3のバケットに保存されるとの事。
ちなみに、自前のDockerイメージでビルドすることも出来るようです。
buildspec.yml
というファイルがリポジトリに含まれている必要があるのでドキュメントとリファレンスを参考に作成する。
PHPの場合、以下の様になった。
php7.3のランタイムを使って、composer install
を実行して、全てのファイルをアーティファクトとして指定しています。
version: 0.2 phases: install: runtime-versions: php: 7.3 build: commands: - composer install artifacts: files: - '**/*'
で、ビルドプロジェクトを作成して実行した所、失敗になった😢
ログを見るとS3のアップロードまで完了している様にみえるが・・・?🤔
フェーズ詳細タブを確認するとエラーメッセージが表示されていた。UPLOAD_ARTIFACTS
というフェーズでS3にファイルをアップロードしているが、CodeBuildプロジェクトのリージョンとS3バケットのリージョンが一致してないため失敗しているらしい。
S3バケットを作り直してリージョンを合わせた。
CLIENT_ERROR: Error in UPLOAD_ARTIFACTS phase: AuthorizationHeaderMalformed: The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'ap-northeast-1' status code: 400
またUPLOAD_ARTIFACTS
フェーズで別のエラーが発生した😭
CLIENT_ERROR: Error in UPLOAD_ARTIFACTS phase: AccessDenied: Access Denied status code: 403
AccessDenied
と言っているので権限周りかなぁと思って、IAMのロールやポリシーをいじくり回したけど解決しなかった。
結局、ビルドプロジェクトを作り直したら発生しなくなった。
これでS3にアーティファクトが保存される様になったが、今度は保存処理がタイムアウトする様になってしまった。
なかなか多難やなぁ😰
BUILD_TIMED_OUT: Build has timed out.
どうやらアーティファクトのファイル数が多いとS3のアップロードが極端に遅くなるっぽいです。
例えばPHPのvendor
フォルダが8000ファイル程あると10分待っても完了しませんでした。
以下の様にzip圧縮してからアップロードする様にすると数秒で完了する様になりました。
改めてElastic Beanstalkにデプロイしてみる
ソースのビルドが出来たのでアーティファクトが保存されているS3のバケットを指定して起動する
Beanstalkにアプリケーションを作成できた。
EC2にもインスタンスが作成されている。
発行されたURLに/public
を付与してアクセスしてみるとLaravelのエラー画面が表示された。
ソース自体は読み込めているっぽい。
内部の状態を確認するためssh
で接続するするeb ssh
コマンドで接続できるらしい。
こちらを参考にeb
コマンドをインストールする。
eb init
でリージョンやアプリケーションを選択するeb ssh --setup
でインスタンスにキーペアを設定する(アプリケーションが再起動するので注意)
改めてeb ssh
する
接続できた!💯
/var/www/html
を確認してみるとソースコードが配置されている事が分かる。
CodeBuildでzip化してS3に保存したが、ちゃんと解凍されて配置されている。
-rw-r--r-- 1 webapp webapp 4497 4月 29 18:35 README.md
drwxr-xr-x 6 webapp webapp 4096 4月 30 07:41 app
-rwxr-xr-x 1 webapp webapp 1686 4月 29 18:35 artisan
drwxr-xr-x 3 webapp webapp 4096 4月 30 07:41 bootstrap
-rw-r--r-- 1 webapp webapp 151 4月 29 18:35 buildspec.yml
-rw-r--r-- 1 webapp webapp 1586 4月 29 18:35 composer.json
-rw-r--r-- 1 webapp webapp 207511 4月 29 18:35 composer.lock
drwxr-xr-x 2 webapp webapp 4096 4月 30 07:41 config
drwxr-xr-x 5 webapp webapp 4096 4月 30 07:41 database
-rw-r--r-- 1 webapp webapp 1013 4月 29 18:35 package.json
-rw-r--r-- 1 webapp webapp 1197 4月 29 18:35 phpunit.xml
drwxr-xr-x 2 webapp webapp 4096 4月 30 07:41 public
drwxr-xr-x 6 webapp webapp 4096 4月 30 07:41 resources
drwxr-xr-x 2 webapp webapp 4096 4月 30 07:41 routes
-rw-r--r-- 1 webapp webapp 563 4月 29 18:35 server.php
drwxr-xr-x 5 webapp webapp 4096 4月 30 07:41 storage
drwxr-xr-x 4 webapp webapp 4096 4月 30 07:41 tests
drwxr-xr-x 44 webapp webapp 4096 4月 30 07:41 vendor
-rw-r--r-- 1 webapp webapp 538 4月 29 18:35 webpack.mix.js
/storage/logs/laravel.log
を確認すると以下のエラーが出ていた。
production.ERROR: No application encryption key has been specified.
.env
ファイルが配置されていないので、環境変数を設定する。eb
コマンドで設定する場合は以下の通り。
# 環境変数を確認
eb printenv
# 環境変数を設定
eb setenv key=value
環境変数はスクリプト化したりしないし(本末転倒なので)GUIで管理したいなぁ。
公式ドキュメントによるとマネジメントコンソールから設定できるっぽい。
無事Laravelアプリケーションが表示された!🤟
コードを更新するとどうなるのか?
トップページのHTMLを書き換えてPUSHする。v2
の表記を追加した。
CodeBuildを手動でトリガーして、S3に新しいフォルダが作られてソースコードが配置された。
で、ElasticBeanstalkでデプロイしようとしたが、S3のフォルダを指定する項目が無いな・・・???
「ファイルのアップロード」しかない・・・。😢
デプロイを自動化する
どうやら手動でS3からデプロイできないらしいので、こちらを参考にCodePipelineを使ってデプロイを自動化する
ソースステージ、ビルドステージ、デプロイステージの3ステップの設定を行う必要があるらしい。
ビルドステージでは既に作成済みのCodeBuildプロジェクトを指定する。
デプロイステージも、既に作成しているElasticBeanstalkのアプリケーションを指定する
CodePipelineを作成すると以下の画面が表示された。
パイプラインの進捗がリアルタイムで確認できる。
男の子だからこういうのワクワクしちゃう・・・🎵
パイプラインの実行が完了したのでBeanstalkのアプリケーションバージョンを確認してみる。
新しいバージョンが作成されている。
Laravelのトップページを開いてみる。
エラーが発生した😱
環境変数が消えてる・・・・。なんで?
再設定しなきゃだめか・・・。数が多いから面倒なんだよな・・・。
eb setenv
コマンドを使えば複数同時に設定できるらしい。
eb setenv foo=bar JDBC_CONNECTION_STRING=hello PARAM4= PARAM5=
コマンド叩いたらエラー出たわ・・・。
1度に設定できるのは最大4096バイトらしい。
キーは最大128文字で値は最大256文字との事。
上記の制限満たしててもエラーになる事あったけど、時間置いたりコマンドを小分けにしたりしてなんとか登録した。
ERROR: ServiceError - Configuration validation exception: Invalid option value
無事、デプロイの自動化が完了して画面も開けた!
バージョンの切り戻しをやってみる。
うっかり誤ったリリースしてしまった時などにバージョンを戻す方法を確認しておく。
過去のバージョンが自動的に保存されていて、アプリケーションバージョンのページから簡単に切り戻しできる。
今日はここまで!🙆
次回はRDBの設定をやっていく!
Webエンジニアをやっています
UX/UIデザインからプログラミング、DB設計、SEO、インフラ構築など幅広く対応してます
PHP/PHPUnit/Laravel/Vue/Nuxt/Docker/Terraform
ご連絡はTwitterのDMまで。
「【Laravel & AWS】Elastic Beanstalkでアプリケーションサーバを構築 & CodePipelineで自動デプロイ【1日目】」への9件のフィードバック