はじめに
EC2にAuto Scaling設定を行い、Cl/CD (GitHub + CodePipeline + CodeDeploy + AMIの自動更新) を導入することで、自動デプロイを実現しましたので、手順をまとめます。
また、CodeDeploy後、最新のソースを反映したEC2のAMIを作成し、Auto Scaling の起動テンプレートにAMIを反映する
Lambdaを作成し、Codepipelineのステージに加えることでAMIの反映も自動化させました。
構築図
事前構築
- vpcやsubnetなど、ネットワーク層作成
- EC2やelbは、作成しても、作成していなくてもよいです。
- 今回は、分かりやすいように、EC2にNginxを入れるだけのシンプルなサーバーにします。
- 既に作成のEC2でもよいです。nginxでなくてもよいです。
- 今回は、分かりやすいように、EC2にNginxを入れるだけのシンプルなサーバーにします。
EC2 nginxをインストール
// ssh接続
% ssh -i xxxx.pem ec2-user@パブリックIP(またはDNS)
// nginxをインストール
$ sudo amazon-linux-extras install nginx1
// nginxを起動
$ sudo systemctl start nginx
// 自動起動設定
$ sudo systemctl enable nginx
$ cd /usr/share/nginx/html
$ ls
404.html 50x.html icons index.html nginx-logo.png poweredby.png
EC2のパブリックIPでブラウザからアクセスすると、ウェブサイトが見れます。
IAMロールを作成
IAMロールは、CodeDeployにアタッチする用とEC2にアタッチする用2つ作成します。
CodeDeploy作成時に使用するIAMロール作成
CodeDeploy作成時に、このRoleを選択します。
EC2にアタッチする用のIAMロール作成
AmazonS3FullAccess
は、Codepipelineで、S3へlogをアップする際に必要になりますので、EC2にアタッチします。
IAMロール作成後、EC2にアタッチしましょう。
EC2にCodeDeployのagentをインストールし、AMI作成
下記記事を参考に、EC2にCodeDeployのagentをインストールします。
$ cd
$ sudo yum install -y ruby
$ sudo yum install -y wget
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
パッケージ wget-1.14-18.amzn2.1.x86_64 はインストール済みか最新バージョンです
何もしません
$ wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto
$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 3246
sudo service codedeploy-agent status
以下のコマンドに関しては、EC2が東京リージョンに存在する場合のURLになります。
wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
リージョンのURLはこちらを参照してください
起動テンプレートを作成
起動テンプレートを作成前に、NginxをインストールしたEC2のAMIを取ります。
起動テンプレートを作成します。
-
サブネットは
起動テンプレートの設定に含めない
を選択します。 -
セキュリティーグループは、既存のものを選択します。
-
ネットワークインターフェイスを追加します。
他は、デフォルトのままにして、起動テンプレートを作成します。
Auto Scalingグループを作成
- Auto Scalingグループ名:
nginx
- 起動テンプレート:
nginx
- バージョン:
Latest
- VPCとSubnetを選択します。
- ロードバランサーとターゲットグループを作成していない場合、ここで作成します。
- ヘルスチェックのタイプで
ELB
をチェックしておりません.
一旦チェックせずに、AutoScalingを起動します。成功した場合に限り、チェックをつけてもよいです。 - グループサイズとスケーリングポリシーは、適当に決めました。
- 今回、通知はしません。
- タグも追加しません。
これで、1つインスタンスが起動するはずです。
ブラウザからelbのDNS名(nginx-elb-アカウントID.ap-northeast-1.elb.amazonaws.com)で
アクセスすると、nginxのデフォルトが表示されるか確認しましょう。
ブラウザで表示されない場合、EC2とELBのセキュリティーグループを確認しましょう。
ターゲットグループの修正
ターゲットグループはデフォルトだと、登録解除の遅延
は300秒になっており、CodeDeployの速度に影響が出るため、10秒に変更します。
また、同じ理由で、ヘルスチェックの正常と非正常のしきい値
を5回から最低の2回にしました。
これで、CodeDeploy時のデプロイ速度が格段に早くなります。
こちらの記事を参考にしました。
負荷をかけて Auto Scaling の動作確認
検証作業なので、スキップしてもよいです。
Auto Scalingのグループサイズの最大容量を3し、
yesコマンドで負荷をかけた後、EC2インスタンスが3になっているか確認してみましょう。
terminalのタブを2つ用意し、2つのタブどちらもEC2にSSH接続します。
片方は以下のコマンドを実行します。
$ yes dev/null &
もう片方のterminalは、EC2インスタンスが3になっていることを確認した後、killコマンドで停止しましょう。
$ top
// yesコマンドのPIDを確認します。
$ kill
その後、EC2がスケールインし、EC2インスタンスが1になっているか確認します。
# GitHubにappspec.ymlをアップ
元々Githubのリポジトリにあるものは、index.htmlのみです。
```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<p>CodeDeploy success!!</p>
</body>
</html>
このリポジトリにappspec.yml
を加えます。
appspec.yml
は、CodeDeployの指示書になります。
今回は以下の記述をします。
version: 0.0
os: linux
files:
- source: /
destination: /usr/share/nginx/html
file_exists_behavior: OVERWRITE
permissions:
- object: /usr/share/nginx/html
pattern: '**'
owner: ec2-user
group: nginx
mode: 644
type:
- file
- object: /usr/share/nginx/html
pattern: '**'
owner: ec2-user
group: nginx
mode: 755
type:
- directory
例えば、EC2で Laravel + apacheの場合、以下のappspec.ymlになりました。
version: 0.0
os: linux
files:
- source: /
destination: /usr/share/nginx/html
file_exists_behavior: OVERWRITE
permissions:
- object: /usr/share/nginx/html
pattern: "**"
owner: ec2-user
group: apache
except: [/usr/share/nginx/html/storage]
type:
- file
mode: 644
- object: /usr/share/nginx/html
pattern: "**"
owner: ec2-user
group: apache
except: [/usr/share/nginx/html/storage]
type:
- directory
ode: 755
- object: /usr/share/nginx/html/storage
pattern: "**"
owner: ec2-user
group: apache
type:
- file
mode: 775
- object: /usr/share/nginx/html/storage
pattern: "**"
owner: ec2-user
group: apache
type:
- directory
mode: 775
-
source
は、デプロイするリポジトリのパスを指定します。 -
destination
は、リビジョン(GitHubのソース)をサーバーにデプロイする際の、サーバーのパスを指定します。 -
file_exists_behavior: OVERWRITE
は、デプロイ先のソースを上書きします。
デプロイ対象がEC2の場合、リビジョンをデプロイする以前から存在していたファイルをCodeDeployのリビジョン対象にしたいことがあります。しかしそのままだとalready exists.とエラーを吐いてデプロイが失敗しますが、この記述によって上書きされ、エラーを回避できます。
詳細はこちらの記事をみてください
appspec.ymlをアップすると、GitHubのリポジトリは以下の構成になります。シンプルですね。
CodeDeployを設定
アプリケーションの作成
CodeDeployのアプリケーションの作成をクリックします。
アプリケーション名を記入し、プラットフォームは、EC2を選択します。
デプロイグループの作成
- デプロイグループ名:
nginx
- サービスロール:
CodeDeployRole
(IAMロール作成で作成したRoleです。) - デプロイタイプ:
インプレース
- 環境設定:
Amazon EC2 Auto Scaling グループ
をチェックし、nignx
を選択します - デプロイ設定:
CodeDeployDefault.OneAtTime
- 1つずつEC2にデプロイします。
- Load balancer:
ロードバランシングを有効にする
をチェックします。
デプロイの作成
- デプロイグループ:
先程作成したデプロイグループ名
- リビジョンタイプ:
Github
デプロイ成功後、EC2にSSH接続してみます。
$ cd /usr/share/nginx/html
//デプロイ前
$ ls -la
-rw-r--r-- 1 root root 3665 7月 12 01:09 404.html
-rw-r--r-- 1 root root 3708 7月 12 01:09 50x.html
drwxr-xr-x 2 root root 27 8月 24 15:20 icons
-rw-r--r-- 1 root root 3520 7月 12 01:09 index.html
-rw-r--r-- 1 root root 368 7月 12 01:09 nginx-logo.png
lrwxrwxrwx 1 root root 14 8月 24 15:20 poweredby.png -> nginx-logo.png
//デプロイ後
$ ls -la
-rw-r--r-- 1 root root 3665 7月 12 01:09 404.html
-rw-r--r-- 1 root root 3708 7月 12 01:09 50x.html
-rw-r--r-- 1 ec2-user nginx 353 8月 25 14:09 appspec.yml
drwxr-xr-x 2 root root 27 8月 24 15:20 icons
-rw-r--r-- 1 ec2-user nginx 168 8月 25 14:09 index.html
-rw-r--r-- 1 root root 368 7月 12 01:09 nginx-logo.png
lrwxrwxrwx 1 root root 14 8月 24 15:20 poweredby.png -> nginx-logo.png
index.html
が反映され、appspec.yml
が追加されていることが分かります。
ブラウザからelbのDNS名(nginx-elb-アカウントID.ap-northeast-1.elb.amazonaws.com)で
アクセスすると、nginxのデフォルトではなくなり、index.htmlが反映されていますね。
ブラウザで表示されない場合、EC2とELBのセキュリティーグループを確認しましょう。
長くなったため、CodePipelineを作成
以降は、次回にします。
参考記事