見出し画像

gitlabを使ったAWS CodePipelineでCodeDeployを使ったEC2にデプロイする

段々とタイトルからして難易度が高くなっていくというのは最早致し方ないのか何なのか。CodeDeployという仕組みを利用してmarkdownからhtmlに変換したものをEC2にuploadしていく


前回まででS3にデプロイできるようになっていると思うから、今回はデプロイステージだけ弄っていくんだけど、その前にちょっとソースコードを変更する。

ソースコードの変更

前回まで作成したsample.mdというのがあるはず


# サンプルドキュメント

これはMarkdownファイルのサンプルです。以下は簡単な箇条書きです。

## 箇条書き

- アイテム1
- アイテム2
- アイテム3

## コードブロック

```python
def greet(name):
    return f"Hello, {name}!"

print(greet("World"))
```

今回titleとかあった方がいいのでこのように変更した

---
title: サンプルドキュメント
---

これはMarkdownファイルのサンプルです。以下は簡単な箇条書きです。

## 箇条書き

- アイテム1
- アイテム2
- アイテム3

## コードブロック

```python
def greet(name):
    return f"Hello, {name}!"

print(greet("World"))
```

そしてbuildspec.ymlが以下のようになっていると思う(多分)

version: 0.2

phases:
  install:
    commands:
      - echo "Installing pandoc for Markdown to HTML conversion"
      - apt-get update && apt-get install -y pandoc  # pandocをインストール
  build:
    commands:
      - echo "Converting sample.md to HTML format"
      - pandoc sample.md -o sample.html  # MarkdownをHTMLに変換
      - echo "Displaying HTML content of sample.html:"
      - cat sample.html  # 標準出力にHTMLの内容を表示

artifacts:
  files:
    - sample.html  # デプロイしたいファイル

ここではEC2のapache2のdefaultの/var/www/html/index.html を置き換える事を最終ゴールとしたい。

その場合sample.htmlだとちょっと具合が悪いのでindex.html に変更したい。もちろん -o index.html としてもいいんだけどちょっとわかり辛くなるのでmarkdownのファイル自体の名前をindex.mdに変更する。

% git mv -f sample.md index.md

リポジトリにサンプルで作ったindex.htmlが既にあったのでこれを削除している

% git rm index.html

更に、buildspec.yml を以下のように変更する。もうcatとかは十分試したので不要だと思うので削除。あとapt-getからaptに謎に変更してるけどまあこれはどっちでもいいや。あとstandaloneを指定してたり等

version: 0.2

phases:
  install:
    commands:
      - echo "Installing pandoc for Markdown to HTML conversion"
      - apt update && apt install -y pandoc
  build:
    commands:
      - echo "Converting index.md to HTML format"
      - pandoc index.md -o index.html --standalone

artifacts:
  files:
    - index.html
    - appspec.yml
    - scripts/**

ここまでuploadし、現在のビルドシステムを使って正しく動作するか(S3にputされるか)確認しておくとよいと思われる。

EC2を1つ起動

さて、本題となるEC2へのデプロイの為にEC2を1つ用意する必要があるだろう。

ここではdebianを起動する。スペックは何でもいい。小さくていいんじゃないかな。httpを解放しておくと後で確認の際にセキュリティーグループを弄ったりしなくていいんじゃないでしょうか。

sshでログインし、パッケージをアップグレードしておく

# apt update; apt upgrade -y

CodeDeployAgentをダウンロード、install

CodeDeployを受け入れるためにはEC2に専用のエージェントを常駐する必要がある。以下のようにして行う

wget https://aws-codedeploy-eu-west-1.s3.eu-west-1.amazonaws.com/latest/codedeploy-agent_all.deb

で、dpkg -i でinstallする

# dpkg -i codedeploy-agent_all.deb
Selecting previously unselected package codedeploy-agent.
(Reading database ... 30655 files and directories currently installed.)
Preparing to unpack codedeploy-agent_all.deb ...
Unpacking codedeploy-agent (1.7.0-92) ...
dpkg: dependency problems prevent configuration of codedeploy-agent:
 codedeploy-agent depends on ruby2.0 | ruby2.1 | ruby2.2 | ruby2.3 | ruby2.4 | ruby2.5 | ruby2.6 | ruby2.7 | ruby3.0 | ruby3.1 | ruby3.2; however:
  Package ruby2.0 is not installed.
  Package ruby2.1 is not installed.
  Package ruby2.2 is not installed.
  Package ruby2.3 is not installed.
  Package ruby2.4 is not installed.
  Package ruby2.5 is not installed.
  Package ruby2.6 is not installed.
  Package ruby2.7 is not installed.
  Package ruby3.0 is not installed.
  Package ruby3.1 is not installed.
  Package ruby3.2 is not installed.

dpkg: error processing package codedeploy-agent (--install):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 codedeploy-agent

このようになるので

# apt install -f

すると

# apt install -f
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Correcting dependencies... Done
The following additional packages will be installed:
  fonts-lato javascript-common libjs-jquery libncurses6 libruby libruby3.1
  rake ruby ruby-net-telnet ruby-rubygems ruby-sdbm ruby-webrick ruby-xmlrpc
  ruby3.1 rubygems-integration unzip zip
Suggested packages:
  apache2 | lighttpd | httpd ri ruby-dev bundler
The following NEW packages will be installed:
  fonts-lato javascript-common libjs-jquery libncurses6 libruby libruby3.1
  rake ruby ruby-net-telnet ruby-rubygems ruby-sdbm ruby-webrick ruby-xmlrpc
  ruby3.1 rubygems-integration unzip zip
0 upgraded, 17 newly installed, 0 to remove and 0 not upgraded.
1 not fully installed or removed.
Need to get 9909 kB of archives.
After this operation, 47.0 MB of additional disk space will be used.
Do you want to continue? [Y/n]

このようになってinstallされる。まあこの辺はdpkgとかaptの話だし、まあ今回は割愛していいよね。

# systemctl start codedeploy-agent # エージェントを起動
# systemctl status codedeploy-agent # エージェントの現在のstatusを表示

とかやってみれば

# systemctl status codedeploy-agent
● codedeploy-agent.service - LSB: AWS CodeDeploy Host Agent
     Loaded: loaded (/etc/init.d/codedeploy-agent; generated)
     Active: active (running) since Tue 2024-11-05 06:12:55 UTC; 14s ago
       Docs: man:systemd-sysv-generator(8)
    Process: 10963 ExecStart=/etc/init.d/codedeploy-agent start (code=exited, s>
      Tasks: 2 (limit: 426)
     Memory: 51.8M
        CPU: 1.026s
     CGroup: /system.slice/codedeploy-agent.service
             ├─10969 "codedeploy-agent: master 10969"
             └─10971 "codedeploy-agent: booting child"

などactiveになってればok

apacheのinstallと確認

# apt install apache2

でinstallし、当該ipにアクセスする。すると

/var/www/html/index.html の内容が表示されるだろう

defaultページが表示されないと次には進めないぞ

従って、ここでのミッションはこの/var/www/html/index.htmlを書き換えていく事にある。

EC2ロールの変更

CodeDeployを受け入れるためにはEC2ロールにAmazonEC2RoleforAWSCodeDeployという権限が付いていないといけない。とはいえ、そういったロールも現在は定義されていないと思うので自分で作成する必要がある。「新しいIAMロールを作成」を押し

さらにジャンプ先の画面でロールを作成を押す。

ここからAWSのサービスを選択したままユースケースに

EC2を指定する。ここで

ここでAmazonEC2RoleforAWSCodeDeployを探し出してくる。適当な名前を付けて保存。ここではEC2-CodeDeploy-Role などした。そして

その名前を付けたロールを割り当てておく。ここまでEC2の事前準備

CodeDeployに与えるロールの設定

https://us-east-1.console.aws.amazon.com/iamv2/home?region=ap-northeast-1#/roles

deployに使ったroleで基本的にok。ここではAWSCodePipelineServiceRole-ap-northeast-1-test-deploy-to-s3 を使った

信頼関係を押すと上記のようなjsonが見えるが、これを変更する

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "codepipeline.amazonaws.com",
                    "codedeploy.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

つまり、

                "Service": [
                    "codepipeline.amazonaws.com",
                    "codedeploy.amazonaws.com"
                ]

これが重要なわけね。

CodeDeployの設定

まずアプリケーションの作成をする。アプリケーションとは要するに大枠でありその中にdeployグループってのが作られるんだけどまあとにかく1つやる場合でも大枠は必要ってことで…

https://ap-northeast-1.console.aws.amazon.com/codesuite/codedeploy/start?region=ap-northeast-1

アプリケーションの作成

例によって適当な名前を入れている

プラットフォームにはEC2/オンプレミスを設定

そうすると次はデプロイグループの作成を求められる。ここでは「test」とした

事前にロールの信頼関係を構築しているはずなので、先程のロールがここにポップアップされてくるはずだ

デプロイ先などの指定

デプロイ方法はdefault。EC2では適当にNameで名前を特定し、入力して指定。Name以外の指定方法もありえる。

インプレースを指定しておく、そして最後の

ロードバランシングの有効みを外す

appspec.ymlの作成とpush

ここまでで概ね準備が整っているのだけど、CodeDeployを使う為にはgitリポジトリに以下のようなファイルを作成+pushする必要がある

appspec.yml 

version: 0.0
os: linux
files:
  - source: index.html
    destination: /var/www/html/
hooks:
  AfterInstall:
    - location: scripts/restart_server.sh
      timeout: 300
      runas: root

続いてscripts/ ディレクトリを作成しその下にrestart_server.sh を作成する

scripts/restart_server.sh

#!/bin/bash
sudo systemctl restart apache2

さらに

hooks:
  BeforeInstall:
    - location: scripts/remove_existing_index.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/restart_server.sh
      timeout: 300
      runas: root

BeforeInstallとして以下を定義しておく

#!/bin/bash
rm -f /var/www/html/index.html

上書きするにあたってはこれが正解みたいなんだよねえ…

executableにしておく

chmod +x scripts/*

これらをcommit&pushするのであるが、ただし、ここで忘れてはならない点として、ここで指定するファイル群は全てartifactsに含める必要があるということでつまり、buildspec.ymlで指定する必要がある。

buildspec.yml 

version: 0.2

phases:
  install:
    commands:
      - echo "Installing pandoc for Markdown to HTML conversion"
      - apt update && apt install -y pandoc
  build:
    commands:
      - echo "Converting index.md to HTML format"
      - pandoc index.md -o index.html --metadata title="サンプルドキュメント" --metadata charset="utf-8"

artifacts:
  files:
    - index.html
    - appspec.yml
    - scripts/**  

以上のように更新し、これらをcommit&pushする

% git add .
% git commit 
% git push

コメントは適当に考えて

pipelineのデプロイステージ変更

ここからはawsコンソールでの作業、今のままではデプロイステージが単純にs3になったままなのでこれをCodeDeployへと変更する

さらにアプリケーション名デプロイグループを選択していく

保存した後、再度変更をリリースする

以下のスクリーンショットのように当該IPへアクセスした際、htmlが置き換わっていればok


トラブルシューティング

非常に設定項目、手順が多いため、トラブルが起きた場合は段階(ステージ)ごとに分けて考える必要がある。source、build、deployの3ステージを定義しているから、それぞれ成功してから先にすすめるようにすること。

CodeDeployの失敗に関しては、EC2で 以下のログを参照するのも役に立つはずだ

/var/log/aws/codedeploy-agent/codedeploy-agent.log

最初の方でうまく動作するまで、deployするときにtail -fを仕掛けておいてもいいと思う

このシステムを用いたlaravelのdeployもいずれ、やってみよう

いいなと思ったら応援しよう!