初心者が実務でEC2へのデプロイをDeployerからGitHub Actionsに移行した時の手順まとめ的なメモです。
背景と目的
- 今回対象のプロジェクトは
Deployer
を使用して本番環境およびテスト環境にdeployを実行している。 - この場合、デプロイを行う人がローカルでコマンドを手動で実行することになる。
- これをGitHub Actionsを導入して「main(stag)ブランチが更新されたら自動でdeployされる」という状態に持っていく。
やること
- 踏み台サーバー経由でAWS EC2に接続できるようにする
- GitHub Actionsの自動デプロイの設定を行う
- Apacheのドキュメントルートの設定を行う
- SSL/TSLの自動更新設定を確認する
具体的な手順
AWSにIAMユーザーとしてログイン
まずはAWSのマネジメントコンソールにログインするところから。
アカウントID(の入ったURL)
とユーザー名
とパスワード
を管理者に共有してもらい、ログインする。
ログインしたら自分でパスワードの変更を行うこと。
右上のナビゲーションバーでユーザー名を選択して[セキュリティ資格情報]
を選択すれば変更できる。
1. セキュリティグループの設定
セキュリティグループのインバウンドルールを変更する。これは今回のデプロイの設定とは関係ないが、もともと踏み台サーバーのIPアドレスの登録設定が最適になかったことによる作業である。
EC2のダッシュボードから[セキュリティグループ]
を選択し、対象のグループ名を選択する。
次にインバウンドルールのタブから[インバウンドルールを編集]
→[ルールを追加]
の順に選択して、SSHのインバウンドルールを設定する。(踏み台サーバーのIPアドレスと名称)
2. IAMユーザーの作成
GitHub Actionsに割り当てるアタッチポリシーを割り当てる。
IAM
→ユーザー
→ユーザーを追加
の順に選択していき..
「物件名-github-actions-deploy」のような名前のIAMユーザーを作成してアクセス権限を割り当てる。
AmazonVPCFullAccess
AmazonEC2ContainerServiceRole
3. 自分のマシンからSSH接続確認
踏み台サーバーの設定
踏み台サーバーのプロキシの設定をする。
$ cd /.ssh
$ vi config
でconfigファイルにプロキシの設定を追加。追加する設定内容は管理者確認する。
### xxx(プロジェクト名) ########################################
Host <テスト環境のHost名>
HostName <サーバーのIP>
User <ユーザー名>
Port 22
IdentityFile ~/.ssh/<ローカルで作成した秘密鍵のファイル名>
ProxyCommand ssh -W %h:%p -p <プロキシのパスワード> <プロキシの名前>
Host <本番環境のHost名>
HostName <サーバーのIP>
User <ユーザー名>
Port 22
IdentityFile ~/.ssh/<ローカルで作成した秘密鍵のファイル名>
ProxyCommand ssh -W %h:%p -p <プロキシのパスワード> <プロキシの名前>
#####################################################
鍵を作成して公開鍵を管理者に共有する
自分のマシンでキーペアを作成する。
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_rsa): /Users/username/.ssh/xxx-develop
作成したら、
$ vi xxx-develop.pub
で公開鍵を開いてコピーし、管理者に登録してもらう。
登録されれば$ ssh Host名
でssh接続できるようになる。
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
なお上記はテスト環境での作業なので本番環境も同様に行っていく。
その際は⌘+Dで左右にターミナルを分割して作業すると良い。
4. そのままsshでEC2のクレデンシャルセット
SSHで接続した状態で、$ aws configure
を実行し、クレデンシャルをセットする。
$ aws configure
AWS Access Key ID [None]: アクセスキーを貼り付け
AWS Secret Access Key [None]: シークレットアクセスキーを貼り付け
Default region name [None]: リージョン名(ap-northeast-1とか)
Default output format [None]:特になし(入力不要)
これで与えられた権限にて作業ができるようになる。
5. GitHubリポジトリに設定する
①作業する前にイメージ(AMI)を作成する
現在の状態のインスタンスのバックアップとして、AMIを作成する。
(これは先にやっても良い)
インスタンス
→アクション
→イメージを作成
の順に選択。
イメージ名は今回は「プロジェクト名ボリュームのサイズ日付(20210401等)」の命名規則とする。
イメージの説明はイメージ名と同じものを貼り付けでOK。
イメージ作成時にダウンタイム(インスタンスが停止)が通常1〜2分程度発生するので留意。
本番環境でボリュームが大きいインスタンスを扱う時は、上長に確認すること。
②サーバで鍵を作成する
今回は~/.ssh/github/id_rsa.pub
という鍵がもともとあったが、
無い場合は$ ssh-keygen -t rsa
でキーペアを作成する。
③作った公開鍵をサーバの authorized_keys
に追記
$ vi authorized_keys
~/.ssh/authorized_key
を開いて、サーバーの公開鍵id_rsa.pub
の中身を追記する。
すでに別案件等の記述がある場合はその下に追記する。
④作った公開鍵をGitHubリポジトリに設定
setting
→ DeployKeys
→ Add deploy key
で公開鍵を設定する。
もしリポジトリに対する権限がなくて作業出来ない場合は、管理者に情報を送って設定してもらう。
TitleはわかりやすいものでOK。
⑤SSH接続テスト
サーバーでSSH接続できるかテスト。
$ ssh -T git@github.com
Hi 〇〇! You've successfully authenticated, but GitHub does not provide shell access.
こんな感じになれば接続成功。
⑥GitHubリポジトリにActions secretsを設定
リポジトリのSettings
タブのSecrets
を選択。ここのNameとValueを登録する。
下記の左側をNameに、右側をValueにひとつずつ設定していく。
・設定するNameとValue
USER_NAME:ユーザー名
DEVELOP_ACCESS_KEY:作ったIAMのアクセスキー
DEVELOP_SECRET_ACCESS_KEY:作ったIAMのシークレットキー
DEVELOP_HOST_NAME:サーバIP
DEVELOP_SECURITY_GROUP:セキュリティグループID
DEVELOP_PRIVATE_KEY:サーバの秘密鍵(.pubじゃない方)
PRODUCTION_ACCESS_KEY:作ったIAMのアクセスキー
PRODUCTION_SECRET_ACCESS_KEY:作ったIAMのシークレットキー
PRODUCTION_HOST_NAME:サーバIP
PRODUCTION_SECURITY_GROUP:セキュリティグループID
PRODUCTION_PRIVATE_KEY:サーバの秘密鍵(.pubじゃない方)
上記はそのまま続けて入力すればOK。
この時、改行や空白の違いで動かなくなり、どれが間違っているかもわからなくなるので慎重に作業すること。
サーバーの秘密鍵は-----BEGIN RSA PRIVATE KEY-----
や-----END RSA PRIVATE KEY-----
も含めてコピーして貼り付けることを忘れずに。(-の数が合ってるかも確認すると良い)
・Actions Secretsの完成イメージ
6. EC2に新しいドキュメントルート作成
現状のEC2のサーバー内の構成を確認し、projdir
というディレクトリを新規で追加する。
これからの作業は、そこにGitHubからpullしたドキュメントが入るように設定していくというもの。
$ cd /home/ユーザー名/
$ ls -la
lrwxrwxrwx 1 ユーザー名 ユーザー名 18 x月 xx xxxx public_html -> deploy/pro/current
現状はpublic_html
に対するdeploy/pro/current
というシンボリックリンクがある。
(deployerで自動デプロイを設定している)
ここで、projdir
というディレクトリを新規で作成する。
$ mkdir projdir
7. ローカルで階層を変える(番外)
これは今回のGitHub Actionsとは関係ない工程だが、dockerをリポジトリに含めていなかったため、ローカル環境でもprojdir
を作成して配下にアプリケーションデータたちを置き、dockerディレクトリとdocker-compose.ymlファイルもgitに含めるように変更する。
ディレクトリの構成を変えるときにgitの追跡が失われないように留意すること。
(必要に応じて再度$ git clone
した方が良いかも..)
Xdebugの設定変更(番外)
なおこれも今回のdeployとは関係ないが、このときDockerfileのXdebugの設定に以下を追加した。(もともとはコメントアウトで別の値が入っていた)
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so
8. GitHub Actions Workflowの設定 & deployテスト
Workflowファイルを作成してプロジェクトと同じディレクトリに入れる。(今回は管理者から共有)
内容としてはmain(stag)ブランチが更新されると自動的にjobsが走るというもの。
name: StagingDeploy
on:
push:
branches: [stag]
env:
ENV_FILE: .env.dev
RSYNC_SOURCE: /projdir/
RSYNC_TARGET: /home/ユーザー名/〇〇/develop/public_html
jobs:
deploy_staging:
if: github.ref == 'refs/heads/stag'
runs-on: ubuntu-latest
steps:
..
~後略~
実行されてdeployが完了した時の図
完了すると、先ほどサーバーで作成したproj
ディレクトリにドキュメントが入っているのが確認できる。
9. virtualhostのconfファイルの編集
バックアップ作成
まずはディレクトリに移動して既存のdefault_vhost.confファイルのバックアップを作成する。
$ cd /etc/httpd/conf.d/extra
$ sudo cp default_vhost.conf default_vhost.conf.bk0401
ドキュメントルート変更
viエディタで編集する。
$ sudo vi default_vhost.conf
DocumentRoot /home/ユーザー名/public_html/public ←これを
DocumentRoot /home/ユーザー名/public_html ←これに修正する
<Directory>
の部分も同様に修正する。
構文テスト
default_vhost.conf
を修正したら、Apacheの構文のテストを行う。
$ httpd -t
AH00526: Syntax error on line 32 of /etc/httpd/conf.d/extra/default_vhost.conf:
SSLCertificateFile: file '/etc/letsencrypt/live/ドメイン名/fullchain.pem' does not exist or is empty
構文エラーとなるので確認。
$ cd /etc/letsencrypt/live/
-bash: cd: /etc/letsencrypt/live/: Permission denied
live
ディレクトリのパーミッションが原因で構文エラーとなっているので、
パーミッションの設定を変更する。
$ cd /etc/letsencrypt
$ sudo chmod 755 archive/
$ sudo chmod 755 live/
この状態で再度テストして、OKなら再起動。
$ httpd -t
Syntax OK
$ sudo systemctl reload httpd
なおテスト環境では次のシンボリック設定を先に行っても良いが、本番環境では今回のように
構文テスト→NG→パーミッション変更→confファイル変更→シンボリック設定
の順序としないとダウンタイム(アクセスできない状態)が発生することになるので留意。
10. ドキュメントルートにシンボリックリンク貼る
/home/ユーザー名
に移動し、ドキュメントディレクトリ名をpublic_html
からpublic_html_bk
にリネーム。
$ cd /home/ユーザー名
$ sudo mv public_html public_html_bk
再度public_html
という名前で/home/ユーザー名/projdir/public
に対するシンボリックリンクを新たに作成する。
$ ln -s /home/ユーザー名/projdir/public /home/ユーザー名/public_html
$ ln -s
コマンドは、第一引数が本体(リンクの参照先)で、第二引数が作成するリンクである。
結果として以下のように変更される。
drwxrwsr-x 3 ユーザー名 ユーザー名 17 xxx deploy
drwxrwxr-x 2 ユーザー名 ユーザー名 4096 xxx logs
drwxrwsr-x 13 ユーザー名 ユーザー名 4096 xxx projdir
lrwxrwxrwx 1 ユーザー名 ユーザー名 18 xxx public_html -> deploy/pro/current
drwxrwsr-x 3 ユーザー名 ユーザー名 17 xxx deploy
drwxrwxr-x 2 ユーザー名 ユーザー名 4096 xxx logs
drwxrwsr-x 13 ユーザー名 ユーザー名 4096 xxx projdir
lrwxrwxrwx 1 ユーザー名 ユーザー名 29 xxx public_html -> /home/ユーザー名/projdir/public
lrwxrwxrwx 1 ユーザー名 ユーザー名 18 xxx public_html_bk -> deploy/pro/current
11. SSL/TLS自動更新の確認
今回はコマンドラインからの手動更新ではなくCertbotとCronを使った自動更新を設定しており、
ドキュメントルートを変更したため設定の確認を行っていく。
CertbotはLet’s EncryptからSSL/TSL証明書を発行や更新の申請をするための無料ツールである。
①Certbotコマンドのパスを確認
$ which certbot (なければcertbot-auto)
/usr/bin/certbot
②dry-run(テスト)を実行する
コマンドの場所が分かったのでrenew
コマンド(証明書更新)をテストする。
$ sudo /usr/bin/certbot renew --dry-run --post-hook "systemctl restart httpd"
--dry-run
オプションはファイルに影響を及ぼさずにテスト実行をするオプション。
また--post-hook
は更新実行後に行われる処理を記述できるオプションである。(--deploy-hook
でも良いかも)
コマンドを実行すると、
..
Challenge failed for domain ドメイン名
..
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
となる。ドメイン名やDNSのAレコード、IPアドレスが正しいか確認してくださいとのこと。
③ドメインのconfファイルを編集する
これは今回ドキュメントルートを変更したことによるためで、
/letsencript/renewalディレクトリにあるドメインのconfファイルを編集していく。
$ sudo vi /etc/letsencrypt/renewal/ドメイン名.conf
webroot_path = /home/ユーザー名/public_html, ←ここと
[[webroot_map]]
ドメイン名 = /home/ユーザー名/public_html ←ここを、正しいドキュメントルートに修正
④再度dry-runを実行する
$ sudo /usr/bin/certbot renew --dry-run --post-hook "systemctl restart httpd"
今度は無事に成功。
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/ドメイン名/fullchain.pem (success)
⑤Cronの状態を確認
$ sudo systemctl status crond
これで、
Active: active (running)
となっていればOK。
以上で作業完了です。お疲れさまでした〜