Blog

AWS CodePipelineを使用してWordPressへデプロイしてみる

この記事は、ニフティグループ Advent Calendar 2023 7日目の記事です。

こんにちわ!NIFTY engineering運用チームのいかりがわです!

今回はWordPressのテーマをGitHub管理できるようにし、EC2に自動でデプロイするようにしたので、その手法をまとめていきたいと思います。

背景

私たちが運用しているNIFTY engineeringでは、何らかの変更があったときはFileManagerというWordPressのファイル管理用プラグインを使って手動で変更を加えていました。

しかし、これでは手動での変更反映になり、以下のような問題が起こります。

  • 人為的なミスが発生する可能性が高まる
    • 設定や手順のミス、環境の不整合などが起きやすくなります。
  • 一貫性が保てない
    • NIFTY engineeringでは、本番環境、開発環境の2つの環境を用意しています。 運用上では開発環境で確認後、本番環境にデプロイするようにしていますが、緊急時の対応などは急いで対応するため、本番のみに反映しがちになります。

ニフティのプロジェクトでは基本的にCI/CDパイプラインが整備されています。

NIFTY engineeringもCI/CDのパイプラインを使用して変更を容易にしていきたいと考えており、AWS CodePipelineによる自動デプロイのインフラを作っていこうと考えました。

手法

私たちは、GitHub ActionsからAWS CodeCommitへソースコードをコピーして、CodePipelineを使用するようにしました。

また、WordPressのテーマをEC2に自動デプロイする手法を採用しました。

具体的な流れは以下の通りです。

  1. まず、DeveloperがソースコードをGitHubリポジトリにプッシュします。
  2. GitHub Actionsはリポジトリの変更を監視し、変更があったらトリガーします。
  3. 変更があると、GitHub ActionsはCodeCommitにソースコードをコピーします。
  4. CodeCommit内のコードが変更されると、CodePipelineがトリガーします。
  5. CodePipelineのデプロイフェーズにてAWS CodeDeployが実行されます。
  6. CodeDeployにて、EC2の特定のディレクトリに変更をデプロイします。

これで、GitHubでのソースコードの管理が容易になり、自動デプロイによる効率的な運用が可能となります。

構成図

構成図は以下のようになっています。構成図内の処理の順番は手法の手順に沿っています。

TerraformでAWSのリソースを作る

では実際にCI/CDインフラを作ってみたいと思います。

まず、AWSのリソースをTerraformで作っていきます。

ちなみにここではTerraformのプロバイダ設定やバージョンの定義は割愛して、リソースの定義のみにしています。

また、EC2インスタンスはすでに起動していることを想定します。

CodeCommit

CodeCommitのリポジトリを作成します。リポジトリ名を指定するだけです。

CodeDeploy

aws_iam_role、aws_iam_role_policy_attachmentを使用し、CodeDeployで使用するIAMロールを作成します。

指定したポリシーはマネージドポリシーのAWSCodeDeployRoleです。

また、aws_codedeploy_appを使用して、CodeDeployのリソースを作成し、aws_codedeploy_deployment_groupにて、CodeDeployで使用するデプロイメントグループを作成します。

以下のようにec2_tag_setでNameタグを指定することで、その名前と一致するEC2インスタンスを指定することができます。 これにより、CodeDeployがEC2へデプロイできるようになります。

CodePipeline

aws_iam_role、aws_iam_policy、aws_iam_role_policy_attachmentを使用して、CodePipeline用IAMロールを作成しています。

また、aws_iam_policyではpolicies/codepipeline_policy.jsonというファイルを参照しており、そこにポリシーの設定が記述されています。(後述)

aws_codepipelineを使用し、CodePipelineのリソースを定義していきます。

stageを使用することで、CodePipeline内の各フェーズを定義することができます。

今回は上で定義したCodeCommitとCodeDeployのリソースを紐付け、フェーズとして定義していきます。

CodePipeline用IAMロール

AWS公式のユーザーガイドを参考に作成しています。

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/security-iam.html

policies/codepipeline_policy.json

CodePipeline用S3バケット

CodePipelineでは各フェーズ間のデータの受け渡しに使用されます。

今回の例だと、CodeCommitからCodeDeployへソースコードを受け渡すために使用されます。

EventBridge

これまでの定義で一通りのリソースは定義されました。しかし、これでは何をもってCodePipelineが実行され、デプロイが走るのかが定義されていません。

ここでEventBridgeを定義し、CodeCommitのリポジトリでソースコードが変更されたときにCodePipelineがトリガーされるようにしていきます。

IAMロールはCodePipelineと同様のやり方で定義しています。

EventBridgeはCodePipelineを実行することができれば良いので、StartPipelineExecutionというポリシーのみ定義しています。

イベントパターン

イベントパターンの定義は別ファイルで定義しています。

CodeCommitリポジトリでソースコードが変更されたときにトリガーされるようにしています。

events/events_trigger_rule.tpl.json

IAM

最後にIAMユーザーです。

GitHubからCodeCommitへソースコードをプッシュできるようにするために作成します。

作成したIAMユーザーはGitHubリポジトリのシークレットに紐づけて使用します。

Terraformでの反映

applyして、AWSの環境にリソースを追加します。

無事反映されました!例としてCodePipelineの画面です。

SSHキーの登録

ローカル環境にて、ssh-keygenコマンドを実行します。

保存先とパスフレーズの入力を求められるので任意の保存先、パスフレーズを入力します。

指定した保存先にid_rsaとid_rsa.pubが出力されました。

id_rsaをGitHubへ、id_rsa.pubをIAMユーザーへそれぞれ登録していきます。

IAMユーザーにSSH公開キーを登録

id_rsa.pubを開いて、中身をIAMユーザーに登録します。

コンソールからIAMユーザーのページへ遷移し、Terraformで作成したIAMユーザーを探します。

IAMユーザーを選択し、セキュリティ認証情報へ遷移します。

すると、AWS CodeCommitのSSH公開キーという項目があるので、SSH公開キーのアップロードを選択します。

そして、先ほど作成したid_rsa.pubの内容をコピペします。

すると、SSHキーIDが表示されるようになるので、これをコピーしておきます。(GitHubに登録します)

IAMユーザーの設定は完了です。

GitHubに非公開キーとIAMユーザーのIDを登録

続いてGitHub Actionsに必要なシークレットを登録していきます。

必要なシークレットは以下のようになっています。

  • CODECOMMIT_SSH_USERNAME
    • IAMユーザーのSSHキーID
  • CODECOMMIT_SSH_PRIVATE_KEY
    • id_pubの中身

GitHubリポジトリのページより、Settingsへ遷移します。

そして、左メニューからSecrets and variablesより、Actionsの項目を選択します。

ここからRepository secretsを登録できるので、New repository secretsで変数を登録していきます。

これでSSHキーの登録は完了です。

GitHub Actions

続いてGitHub Actionsを作っていきます。

簡単にディレクトリ構成を紹介します。

対象のリポジトリは以下のようなディレクトリ構成をしています。

  • .github/workflows/mirror_codecommit.yaml
    • 実行されるGitHub Actionsの設定ファイル
  • .github/workflows/scripts/mirror.sh
    • 上記GitHub Actionsにて、実行されるシェルスクリプト
    • このシェルスクリプトでCodeCommitへのコピーを行います
  • appspec.yml
    • CodeDeployで使用されるデプロイの手順を定義する設定ファイル
  • myTheme/
    • WordPressに配置されるディレクトリ
    • デプロイ対象となる

mirror_codecommit.yaml

GitHub Actionsの設定ファイルを作成していきます。

ここではmainブランチへのプッシュを検知し、ソースコードをCodeCommitリポジトリにミラーリングするジョブを定義しています。

後述のシェルスクリプトを使用してCodeCommitにプッシュが行われます。

SSHキーは先ほど登録したシークレットから取得されます。

mirror.sh

続いて、GitHub Actionsから実行されるシェルスクリプトです。

あらかじめGitHub Actions上で登録された環境変数を読み取り、SSHキーなどのプッシュに必要な情報を取得します。

その情報を使用して、指定のCodeCommitのリポジトリにコードをプッシュしています。

appspec.yml

最後にappspec.ymlです。こちらはCodeDeployで使用されるデプロイの手順を定義する設定ファイルとなっています。

filesを使用して、デプロイ元のファイルと、デプロイ先EC2インスタンスのディレクトリを指定します。

今回の例だと、myTheme配下にテーマを配置しているので、こちらをデプロイするようにしています。

また、以下の設定を追加することで、ファイルが存在する場合は上書きするように設定しました。

これで、全ての設定が完了しました!

動かしてみる

全ての設定が完了したので、実際にリポジトリにプッシュして、GitHub ActionsやCodePipelineが動作することを確認してみます。

変更を反映していつものようにリポジトリにプッシュしてみます。

すると、GitHub Actionsが動き出しました!

CodeCommitにミラーリングされています! (リポジトリ名などが違いますがそこはご愛嬌…)

CodePipelineもこんな感じで実行されています!

これで一通りのデプロイまでの流れを試すことができました。

まとめ

今回はCodePipelineを使ってWordPressのテーマをデプロイしてみました。

これでNIFTY engineeringの変更が容易になり、より快適なブログライフを送ることができるようになりました!

WordPressのGitHub管理やCI/CDは悩ましいところが多いのでぜひ参考にしてみてください!

明日は、@kanishionoriさんの「今すぐ1on1をやった方がいい3つの理由」です。お楽しみに!

ニフティでは、
さまざまなプロダクトへ挑戦する
エンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトより
お気軽にご連絡ください!

ニフティに興味をお持ちの方は
キャリア登録をぜひお願いいたします!

connpassでニフティグループに
参加いただくと
イベントの
お知らせが届きます!