目次
AWSのサービス縛りでコスト最適で弾力性のあるLaravelアプリケーションのインフラを作ろうという企画の第2回です。
前回、アプリケーションサーバの構築とビルド・デプロイの自動化をしたので、今回は「RDBへの接続」と「cronを使える様にする」をやっていきます!🤟
ちなみにやりたい事の一覧は以下の通り。
アプリケーションサーバの構築ビルド・デプロイの自動化- RDBに接続できる
- テストの自動化
- cronを使える様にする(Laravelのタスクスケジュールのトリガー)
- HTTPS対応
- アプリケーションサーバのオートスケール&ロードバランシング
- Redisに接続できる
- リソースをCDNから配信する
ElasticBeanstalkの課金を停止するには?
いきなり脱線しますが、作業しない間は課金を停止したいです。
そのためには環境を全て終了する必要があるようです。
以下の画像の様に、環境詳細画面で「アクション」→「環境の終了」をクリックする。
公式ドキュメントはこちら
環境を再構築するにはアプリケーション一覧画面で「アクション」→「終了した環境の復元」をする。
なお、環境を終了してから6週間(42日)を超えると復元できなくなるとの事。(ドキュメントに記載が有る)
RDBに接続する
さて本題に入っていきます。
まずはLaravelアプリケーションにDBに接続する処理を作成してリポジトリにPushします。
トップページにDBからテキストを表示する処理と、DBのテキストを更新する処理を追加した。
ローカル環境で表示するとこんな感じ。
いちおうスキーマ定義はこんな感じ。
Schema::create('items', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); });
Beanstalk環境で確認するとDBに接続できなくてエラーになりました。
まだRDBを用意していないので当然ですね!🧐
RDSのインスタンスを作成します。
出来ました!🤙
Beanstalkの環境変数にRDSのホスト名やパスワードを設定する
マイグレーションする必要があるので、eb ssh
で環境に接続してphp artisan migrate
をします。
以下の様なエラーが発生しました。
データベースlaravel
が見つからないとの事🤔
Database name seems incorrect: You're using the default database name `laravel`. This database does not exist.
MySQL workbenchで接続して確認してみる。
一時的にRDSを外部から接続できる様に設定を変更する。
あれ?laravel
データベースあるな??🤔🤔
ということは原因は別か・・・。
RDSのログは見れないのか?
コンソールから閲覧できるっぽい。
ログファイルを選んでログの内容を閲覧してみる。
何も表示されねぇな・・・🤨
ネットワークのログは見れないのか?
VPCフローログを有効化すれば見れるらしい。
さっそく有効化してみた。
CloudWatchにログが保存されて、こんな感じで確認できる。
デフォルトのログの形式は以下の通り。
<version> <account-id> <interface-id> <srcaddr> <dstaddr> <srcport> <dstport> <protocol> <packets> <bytes> <start> <end> <action> <log-status>
ログを眺めてみたが、解決には至らず・・・💀
たぶんRDSへの接続がファイアウォールかなにかに拒否されている様な気がするのだが。
RDSのセキュリティグループを編集する
たまたま「VPCのDBインスタンスにアクセスするシナリオ」というドキュメントを見つけた。
ドンピシャこれだわ💡
RDSのセキュリティグループにBeanstalk環境からの接続を許可してやる必要があるみたい。
ちなみにセキュリティグループとはインスタンスに紐づくファイアウォールらしい。
インバウンドルールにBeanstalkのセキュリティグループからの接続を許可するルールを追加した。
Beanstalk(EC2)からRDSに接続できる様になってDBのマイグレーションが通る様になった!💯
画面も開けた!(DBからデータが読み込めた)
cronを使える様にする(Laravelのタスクスケジュールのトリガー)
実験のために、タスクスケジュールで毎分カウントアップする項目を追加した。
Beanstalkでcronのタスクを定義するには、ebextensionsとよばれる設定ファイルを記述する(ドキュメントはこちら)
この設定ファイルはアプリケーションがデプロイされる際に実行されるとの事。.ebextensions/cron-linux.config
を作成し以下の様に記述してみた。
webappユーザとして毎分タスクスケジュールを起動している。
files:
"/etc/cron.d/mycron":
mode: "000644"
owner: root
group: root
content: |
* * * * * webapp cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/mycron.bak"
何故かタスクがトリガーされない😒/var/log/cron
を確認すると以下のエラーが発生していた。
webappユーザのホームディレクトリが無いとユーザを切り替えられないらしい。
(CRON) ERROR chdir failed (/home/webapp): No such file or directory
また、もう1つ問題があって、環境変数が読み込まれていなくて、DB接続に失敗する😑
こちらによるとopt/elasticbeanstalk/support/envvars
を実行すれば環境変数が読み込めるとの事。
という訳で.ebextensions/cron-linux.config
は最終的に以下の様になりました。
環境変数を読み込んでタスクをトリガーするスクリプト/opt/ebextensions/trigger-task.sh
を作成して、cronからはsudo -u webapp
でユーザを切り替えつつ前述のスクリプトを起動する様にしてます。
files:
"/opt/ebextensions/trigger-task.sh":
mode: "000744"
owner: webapp
group: webapp
content: |
source /opt/elasticbeanstalk/support/envvars
cd /var/www/html
php artisan schedule:run >> /dev/null 2>&1
"/etc/cron.d/mycron":
mode: "000644"
owner: root
group: root
content: |
* * * * * root sudo -u webapp /opt/ebextensions/trigger-task.sh
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/mycron.bak"
cronによってトップページの数値がカウントアップされる様になった!😤
環境が消せないエラー
今日はこの辺で終わろうと思って、Beanstalk環境を停止したら正常に停止せず(ヘルスがSuspended
のまま)、以下の様なエラーが発生してました🆘
どうやら別のセキュリティグループから参照されているセキュリティグループは削除できないらしい。
Stack deletion failed: The following resource(s) failed to delete: [AWSEBSecurityGroup].
Deleting security group named: awseb-e-*-stack-AWSEBSecurityGroup-* failed Reason: resource sg-* has a dependent object (Service: AmazonEC2; Status Code: 400; Error Code: DependencyViolation; Request ID: *)
こちらに対策が記載されている。
暫定対処
暫定対処として、セキュリティグループを参照しているルールを削除して、eb terminate [環境名]
で環境を終了しました。
恒久対処
Beanstalkが自動的に作成したセキュリティグループ(awseb-e-XXXX-stack-AWSEBSecurityGroup-XXX
の様な名前が付与されているやつ)は環境を削除するときに自動的に削除されるっぽい。
で、そのセキュリティグループを別のセキュリティグループから参照していると環境削除時にエラーが出てしまうと。
恒久対処としては、自分で作成して付与したセキュリティグループなら削除されない様なので、別途セキュリティグループを作成して付与した。
所感
やってるうちに、他にもいろいろ試したい事が浮かんできたのでこの辺も少しずつ消化していきます!
- storageフォルダの権限の付け方
- RDSのバックアップ/リストア
- RDSの容量のオートスケール
- CodePipelineで、承認しないとデプロイされないようにする
- ビルド完了時のslack通知
- パブリックサブネット/プライベートサブネットの活用
Webエンジニアをやっています
UX/UIデザインからプログラミング、DB設計、SEO、インフラ構築など幅広く対応してます
PHP/PHPUnit/Laravel/Vue/Nuxt/Docker/Terraform
ご連絡はTwitterのDMまで。
「【Laravel & AWS】RDB(RDS)に接続する & cronを使える様にする【2日目】」への5件のフィードバック