はじめに
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を作成以降は、次回にします。
参考記事




















