CodeDeployを使ってEC2インスタンスにLaravelプロジェクトをデプロイする
AWSを有効活用するためCI/CD系をとりあえず試している中でCodeDeployの使い方は少しずつ分かってきたので、手順をまとめる。
- EC2インスタンスの起動
- CodeDeployエージェントのインストール
- Laravelプロジェクトの作成
- CodeDeployに必要なファイルを作成
- ソースコードをデプロイするためのS3バケットの準備
- CodeDeployのセットアップ
- アプリケーションのデプロイ
- Apacheの設定をLaravel向けにする
- 再デプロイ
- まとめ
EC2インスタンスの起動
まずはデプロイするサーバーとしてEC2インスタンスを起動します。
AWSマネジメントコンソールを開き、こちらの記事の「EC2インスタンスの作成」までを行ってください。
ただ、注意点としてステップ 3: インスタンスの詳細の設定で「AmazonEC2RoleforAWSCodeDeploy」ポリシーをもったIAMロールを設定するようにしてください。
なお、本記事ではEC2にKey=Name,Value=CodeDeployTrialというタグをつけたと仮定して進めていきます。
CodeDeployエージェントのインストール
次にCodeDeployを実行に必要なパッケージをEC2インスタンスにインストールします。
sshでEC2インスタンスに入ったら以下のコマンドを実行します。
sudo yum update -y sudo yum -y install ruby sudo yum install -y wget cd /home/ec2-user wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install chmod +x ./install sudo ./install auto
5つ目のwgetコマンドに渡しているURLはEC2がどのリージョンにあるかによって変わります。
詳しくは以下をご覧ください。
CodeDeploy リソースキットリファレンス - AWS CodeDeploy
以上のコマンドが正常に終了したらCodeDeployエージェントのインストールは完了です。
Laravelプロジェクトの作成
ローカルの開発マシンにlaravel newコマンドでLaravelプロジェクトを作成します。Composerを使いますのでもしインストールをされていない方は以下からダウンロードしてください。
https://getcomposer.org/download/
以下のコマンドを実行するとcode-deploy-tiralというディレクトリを作成されます。その中にLaravelに必要なパッケージが揃った状態になっています。
laravel new code-deploy-trial
CodeDeployに必要なファイルを作成
code-deploy-trialディレクトリに入ります。
cd code-deploy-trial
以下の構成になるようにファイル、ディレクトリを作ります。
scripts └ install_dependencies.sh └ start_server.sh └ stop_server.sh appspec.yml
code-deploy-trialディレクトリ直下にappspec.ymlとscriptsディレクトリ、scriptsディレクトリに.shファイルが3つです。
そして各ファイルは以下の内容になります。
appspec.yml
version: 0.0 os: linux files: - source: / destination: /var/www/html hooks: BeforeInstall: - location: scripts/install_dependencies.sh timeout: 300 runas: root ApplicationStart: - location: scripts/start_server.sh timeout: 300 runas: root ApplicationStop: - location: scripts/stop_server.sh timeout: 300 runas: root
install_dependencies.sh
#!/bin/bash yum install -y httpd amazon-linux-extras install php7.3
start_server.sh
#!/bin/bash systemctl start httpd.service
stop_server.sh
#!/bin/bash isExistApp=`pgrep httpd` if [[ -n $isExistApp ]]; then systemctl stop httpd fi
install_dependencies.shのyum installは-yオプションを付け忘れると後々デプロイを失敗することがあります。注意してください。
これで設定ファイルの準備ができました。
ソースコードをデプロイするためのS3バケットの準備
s3バケットを作ります。
code-deploy-trialというバケット名は既に使われていたのでcarametal-code-deploy-trialとしました。
aws s3 mb s3://carametal-code-deploy-trial
S3バケットにCodeDeploy用のポリシーを設定します。
bucket-policy.jsonというファイルを以下の内容で作成してください。
バケット名、使用しているIAMユーザーのID、EC2を作るときに設定したIAMロールのARNとなっている部分は皆さんの環境に合わせて入れ替えてください。
{ "Statement": [ { "Action": [ "s3:PutObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::バケット名/*", "Principal": { "AWS": [ "使用しているIAMユーザーのID" ] } }, { "Action": [ "s3:Get*", "s3:List*" ], "Effect": "Allow", "Resource": "arn:aws:s3:::バケット名/*", "Principal": { "AWS": [ "EC2を作るときに設定したIAMロールのARN" ] } } ] }
ちなみに使用しているIAMユーザーのIDは以下のコマンドでとれます。ちなみにIAMユーザーのARNを設定しても問題ありません。
aws sts get-caller-identity
EC2を作るときに設定したIAMロールのARNは以下のコマンドで取れます。
aws iam get-role --role-name CodeDeployTrialRole
bucket-policy.jsonの準備ができたらS3バケットにポリシーを紐づけします。
aws s3api put-bucket-policy --bucket carametal-code-deploy-trial --policy file://bucket-policy.json
これでS3バケットの準備は完了です。
CodeDeployのセットアップ
CodeDeployにデプロイするため必要な準備を行っていきます。
まずはCodeDeployで扱うアプリケーションを作成します。
今回はCodeDeployTrialという名前でアプリケーションを作成します。
aws deploy create-application --application-name CodeDeployTrial
デプロイグループを作成します。
「EC2に設定したNameタグの値」と「AWSCodeDeployRoleを持つIAMロールのARN」はみなさんの環境に応じて変更してください。
aws deploy create-deployment-group --application-name CodeDeployTrial \ --deployment-group-name CodeDeployTrialGroup \ --deployment-config-name CodeDeployDefault.OneAtATime \ --ec2-tag-filters Key=Name,Value=EC2に設定したNameタグの値,Type=KEY_AND_VALUE \ --service-role-arn AWSCodeDeployRoleを持つIAMロールのARN
アプリケーションのデプロイ
そしていよいよアプリ―ケーションのデプロイを行います。
まずはソースコードをS3にアップロードします。
aws deploy push \ --application-name CodeDeployTrial \ --s3-location s3://carametal-code-deploy-trial/code-deploy-trial.zip
※以下のコマンドを実行するとLaravelプロジェクトのすべてのファイルがs3にアップロードされます。本来.envファイルやvendorディレクトリなどはサーバーごとで別のものを用意するべきと言われています。注意してください
そしてEC2インスタンスへのデプロイです。
aws deploy create-deployment \ --application-name CodeDeployTrial\ --deployment-group-name CodeDeployTrialGroup \ --deployment-config-name CodeDeployDefault.OneAtATime \ --s3-location bucket=carametal-code-deploy-trial,bundleType=zip,key=code-deploy-trial.zip,eTag=s3オブジェクトのETag
s3オブジェクトのETagとなっている部分は以下のコマンドで取得できます。
aws s3api head-object --bucket carametal-code-deploy-trial --key code-deploy-trial.zip
これでデプロイの完了です。ただまだ終わりません。
Apacheの設定をLaravel向けにする
この状態でEC2インスタンスのIPアドレスにアクセスしてみてもApacheのテストページが表示されてしまいます。設定ファイルの内容を変更してLaravelに向けるようにします。
/etc/httpd/conf/httpd.confをテキストエディタで開いて編集します。
sudo vim /etc/httpd/conf/httpd.conf
DocumentRootを"/var/www/html"から"/var/www/html/public"に変更します。
# DocumentRoot "/var/www/html" DocumentRoot "/var/www/html/public"
これでIPへのアクセスがLaravelに向きます。
それともう一つ
コメントがたくさんあると思いますが、コメントを除くと以下のようになります。
これはドキュメントルート以外にアクセスするために必要な設定です。
<Directory "/var/www/html"> Options Indexes FollowSymLinks # AllowOverride None AllowOverride All Require all granted </Directory>
このままだとLogが書き込めなかったというエラーになるので以下を実行します。
/var/www/html配下のディレクトリとファイルがapacheの所有物になりLogへの書き込みが可能になります。
sudo chown -R apache:apache /var/www/html/*
ようやくEC2のIPアドレスへブラウザからアクセスするとLaravelのwelcomページが表示されます。
これでLaravelプロジェクトをEC2インスタンスにデプロイできました。が、もう少しだけ続きます。
再デプロイ
先ほどAllowOverrideを変更してドキュメントルート以外へのアクセスを有効にしましたが、まだ実際に動くコードがありません。
なのでコードを追加し、EC2インスタンスに再デプロイして確かめてみます。
Laravelプロジェクトのroutes/web.phpの末尾に以下を追加します。
Route::get('info', function() { phpinfo(); });
S3へのaws deploy pushとaws deploy create-deploymentを再度実行します。create-deploymentのeTagはpushするたびに更新されるので新しい値を入力してください。
まとめ
なんとかCodeDeployの初歩的な使い方は理解できたかなと思います。ただ、.envとかvendorとかもまとめてデプロイしちゃってるから実際に運用するには向いてない。もっというとCI/CDにはまだほど遠いので、次回はCodePipelineも使ってより実践的な手法を身に着けたい。