LoginSignup
17
15

More than 3 years have passed since last update.

AWS(EC2)への自動デプロイをDeployerからGitHub Actionsに移行する

Last updated at Posted at 2021-04-15

初心者が実務で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

以下のような感じで設定できればOK。

3. 自分のマシンからSSH接続確認

踏み台サーバーの設定

踏み台サーバーのプロキシの設定をする。

$ cd /.ssh
$ vi config

でconfigファイルにプロキシの設定を追加。追加する設定内容は管理者確認する。

.ssh/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リポジトリに設定

settingDeployKeysAdd 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環境の設定
DEVELOP_ACCESS_KEY:作ったIAMのアクセスキー
DEVELOP_SECRET_ACCESS_KEY:作ったIAMのシークレットキー
DEVELOP_HOST_NAME:サーバIP
DEVELOP_SECURITY_GROUP:セキュリティグループID
DEVELOP_PRIVATE_KEY:サーバの秘密鍵(.pubじゃない方)
production環境の設定
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したドキュメントが入るように設定していくというもの。

/home/ユーザー名の状態を確認
$ 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の設定に以下を追加した。(もともとはコメントアウトで別の値が入っていた)

Dockerfileに追記
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so

8. GitHub Actions Workflowの設定 & deployテスト

Workflowファイルを作成してプロジェクトと同じディレクトリに入れる。(今回は管理者から共有)
内容としてはmain(stag)ブランチが更新されると自動的にjobsが走るというもの。

deploy_develop.ymlの雰囲気(の一部)
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。

以上で作業完了です。お疲れさまでした〜

17
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15