AWS CodeDeployとCodePipelineを触ってみた


きっかけ

前回記事でAWS Copilotを触ってみて色々便利だったので、Copilot Pipelineにも手を出してみようと思いました。
が、そもそもCodePipelineを触ったことがなかったので、まずこちらを触ってみることにしました。

目標構成

ローカルで編集したindex.htmlファイルをGitHubにプッシュするだけで、自動でEC2内のindex.htmlファイルを更新し即座に公開内容に反映したい。

準備

EC2インスタンスの作成

CodeDeployで使うEC2インスタンスを作成しておきます。以下のものが必要になります。

  • 以下の条件のVPC

    • インターネットゲートウェイがアタッチされている
    • 送信先:0.0.0.0/0ターゲット:上記のインターネットゲートウェイのルートがルートテーブルに設定されている
  • 以下の条件のロール

    • 一般的なユースケース EC2に、AWSCodeDeployRoleポリシーとAmazonS3FullAccessポリシーが付与されたロール
    • ユースケースがCodeDeployのロール
  • 以下の条件のEC2インスタンス

    • 作成したVPCとサブネットの付与
    • 作成したAWSCodeDeployRoleポリシーとAmazonS3FullAccessポリシーが紐づいているEC2ロールの付与
    • キーがNameのタグの付与(値は任意)
    • セキュリティーグループにタイプ:HTTP(ソースは初期値の0.0.0.0/0, ::/0のまま)の追加

CodeDeployエージェントをEC2インスタンスにインストール

作成したEC2インスタンスにCodeDeployエージェントをインストールします。

$ ssh -i 『EC2作成時に指定したpemファイル』 ec2-user@『EC2のIPv4パブリックIP』  # 作成したEC2インスタンスにSSH接続
$ sudo yum update
$ sudo yum install ruby
$ sudo yum install 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

上記のインストールの詳細はAmazon Linux 用または RHEL 用の CodeDeploy エージェントをインストールします。 - AWS CodeDeployを確認してください。

6行目の$ wget https://〜の行はリージョンによってURLが変わってきます。
変更する必要がある箇所は以下の赤文字の箇所です。
$ wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install
リージョン毎の入れるべき値はCodeDeploy リソースキットのリファレンス - AWS CodeDeployを確認してください。

必要なファイルをGitHubに上げる

AWSの公式サンプルファイルがGitHubに上がっているので今回はこれを利用します。
サンプルは以下のような構成になっています。

.
├── LICENSE.txt
├── appspec.yml    # CodeDeployに必須のファイルで、デプロイ時に実行する内容が書かれている
├── index.html     # 今回の更新対象のファイル
└── scripts        # デプロイ時に呼び出されるスクリプトが格納されている
    ├── install_dependencies
    ├── start_server
    └── stop_server

appspec.ymlの中身は以下のような形で、どのタイミングで何を実行するか指示するファイルです。
appspec.ymlには以下のルールがあります。

  • CodeDeployに必須のファイル
  • appspec.ymlのファイル名は固定
  • appspec.ymlを格納する場所は同期させるフォルダのルート

詳しくは以下のサイトを確認してください。

version: 0.0
os: linux
files:
  - source: /index.html             # 同期させる元
    destination: /var/www/html/     # 同期させる先(今回はEC2インスタンスの中身)
hooks:
  BeforeInstall:                    # 上記のファイルセクションで指定した場所にファイルをコピーする前
    - location: scripts/install_dependencies    # 必須項目。実行したいスクリプトの場所を指定
      timeout: 300                              # オプション。スクリプト実行時のタイムアウトを秒で指定
      runas: root                               # オプション。スクリプトの実行ユーザーを指定
    - location: scripts/start_server
      timeout: 300
      runas: root
  ApplicationStop:                  # アプリケーションのリビジョンが開始する直前
    - location: scripts/stop_server
      timeout: 300
      runas: root

スクリプトファイルはシンプルにこのような形です。(3ファイルまとめて)

### install_dependencies ###
#!/bin/bash
yum install -y httpd

### start_server ###
#!/bin/bash
service httpd start

### stop_server ###
#!/bin/bash
isExistApp=`pgrep httpd`
if [[ -n  $isExistApp ]]; then
    service httpd stop        
fi

AWS CodeDeployの設定

AWSマネジメントコンソールからCodeDeployの設定を行います。

  1. AWS マネジメントコンソールからCodeDeployに飛ぶ
  2. 左のメニューからアプリケーションをクリックし、アプリケーション画面右上のアプリケーションの作成をクリックする
  3. アプリケーションの作成画面で、以下を入力・選択しアプリケーションの作成をクリックする

    • アプリケーション名:任意の名前を入力
    • コンピューティングプラットフォーム:EC2/オンプレミスを選択
  4. アプリケーションを作成して遷移した画面下部のデプロイグループエリア右上のデプロイグループの作成をクリックする

  5. デプロイグループの作成画面で、以下を入力・選択しデプロイグループの作成をクリックする

    • デプロイグループ名:任意の名前を入力
    • サービスロール:本記事の始めに作成した、ユースケースがCodeDeployのロールを指定
    • 環境設定:Amazon EC2 インスタンスにチェックを入れ、EC2に設定したタグを指定
    • Load balancer:ロードバランシングを有効にするのチェックを外す

CodeDeployの動作確認

CodeDeployの設定が終わったら動作確認をしてみます。

  1. デプロイグループが作成できたら、その画面の右上のデプロイの作成をクリックする
  2. Create deployment画面で、以下を選択・入力しデプロイの作成をクリックする
    • デプロイグループ:作成したデプロイグループを指定(自動で指定されているはず)
    • リビジョンタイプ:アプリケーションは GitHub に格納されていますを選択
    • GitHub トークン名:検索入力欄にアカウントのエイリアスを入力しGitHubに接続をクリックする(未接続の場合のみ)
    • リポジトリ名:GitHubの『アカウント名』/『リポジトリ名』を入力(「/」前後にスペースは入れない)
    • コミットID:GitHubのCodeタブのコミット数リンク→最新コミット右のコピーボタンでコピーした値

  
デプロイの作成を行うとデプロイが開始され、デプロイのステータスが表示されます。
デプロイ処理中は進行中ステータスで、終わるまで時間がかかるのでステータスが成功になるまで少し待ちます。
表示されている画面一番下のデプロイのライフサイクルイベントの一覧のイベント列のView eventsをクリックするとappspec.ymlのhooksで出てきたイベントの実行結果が確認できます。

EC2のファイルの確認

デプロイが成功したので、EC2の/var/www/html/(appspec.ymlのdestinationで指定した場所)を確認するとindex.htmlが格納されています。

$ ssh -i 『EC2作成時に指定したpemファイル』 ec2-user@『EC2のIPv4パブリックIP』
$ cd /var/www/html/
$ ls
index.html    # ファイルが格納されている!

ブラウザでの確認

EC2のIPv4パブリック IPの値をブラウザに貼り付けてアクセスすることで、index.htmlの内容を確認出来ます。

これでCodeDeployは動かせるようになりました
ただ毎回コミットIDを調べてデプロイを作成するのは手間なので、GitHubにプッシュしたらEC2インスタンスにアップされるまでを自動で行えるようCodePipelineで設定します。

AWS CodePipelineの設定

AWSマネジメントコンソールからCodePipelineの設定を行います。

  1. AWS マネジメントコンソールからCodePipelineに飛ぶ
  2. パイプラインの一覧画面の右上のパイプラインを作成するをクリックする
  3. パイプラインの設定を選択する画面で、以下を入力し次へをクリックする
    • パイプライン名:任意の名前を入力
  4. ソースステージを追加する画面で、以下を選択・入力し次へをクリックする

    • ソースプロバイダー:GitHub
    • GitHubに接続するをクリック
    • リポジトリ名:GitHubの『アカウント名』/『リポジトリ名』を入力(「/」前後にスペースは入れない)
    • ブランチ:対象のブランチを選択
  5. ビルドステージを追加する画面で、AWS CodeBuildを指定できます。
    が、今回は使わないのでビルドステージをスキップをクリックする

  6. デプロイステージを追加する画面で、以下を選択して次へをクリックする

    • デプロイプロバイダー:AWS CodeDeployを選択
    • アプリケーション名:CodeDeployで作成したものを選択
    • デプロイグループ :CodeDeployで作成したものを選択
    • レビュー画面で、内容を確認してパイプラインを作成するをクリックする

CodePipelineの設定が終わると、自動でGitHubからファイルを取得してデプロイが行われます。
ローカルのindex.htmlファイルを適当に編集してGitHubにプッシュし、ブラウザで確認してみましょう。
ばっちりローカルでの変更がブラウザで反映されている! ...はず。

まとめ

サービス名の頭のAWSとAmazonはどう違うのだろう..

We're hiring!

AIチャットボットを開発しています。
ご興味ある方は Wantedlyページ からお気軽にご連絡ください!

参考

Amazon Linux 用または RHEL 用の CodeDeploy エージェントをインストールします。 - AWS CodeDeploy
CodeDeploy リソースキットのリファレンス - AWS CodeDeploy
CodeDeploy AppSpec File リファレンス - AWS CodeDeploy
AppSpec の「hooks」セクション - AWS CodeDeploy
aws-samples / aws-codedeploy-samples - GitHub
AWS CodeDeploy の AppSpec を読み解く | Developers.IO
【はじめてのCI/CD】AWSでやってみるDevOps最初の一歩、CodeDeploy、CodePipelineを使った自動デプロイのハンズオン - Youtube