超ミニマムなチュートリアルを通してCodeDeployを理解する2(AutoScaling編) 

前回記事の続きです。

[超ミニマムなチュートリアルを通してCodeDeployを理解する。](https://qiita.com/Kept1994/items/fa3516fa8fe326b4ac3b)

本記事で取り上げた通り、CodeDeployによるデプロイは以下の要領で行われます。

* `appspec.yml`とデプロイしたいファイルをzip化してS3に格納しておく。
* CodeDeployではデプロイ先と対象のファイルや設定を指定する。

今回は、ロードバランサ配下のAutoScalingGroup（ASG）のインスタンスを対象として`index.html`をデプロイすることを試してみます。

# 1. ASGを用意する。

別記事にまとめたので参考としてください。
→ [独自VPCでEC2のAutoScalingくらい秒で組めるようになりたい](https://qiita.com/Kept1994/items/0a72cec68761084a12e4)

ただし、注意すべき変更箇所があります。
前回のCodeDeployの記事のStepにも含めましたが、デプロイさせるインスタンスにはCodeDeployのAgentが導入されている必要があります。
起動設定の中の高度な詳細から以下のシェルを起動時に実行してもらうようにしましょう。

この設定をしない状態（＝Agentが入っていない状態）で後述のデプロイのコマンドを叩くと長い間「進行中」となった後にエラー終了します。

```shell:高度な詳細
#!/bin/sh

sudo yum update -y
sudo yum install ruby -y
sudo yum install wget -y
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
sudo yum install httpd -y
sudo service httpd start
sudo chkconfig httpd on
```

ここではAgent導入とApacheの導入・起動を設定しております。
（なお、このAgent導入方法はAmazonLinuxが対象です。AmazonLinux2は少し記述が違います。この辺りは公式記載あり)

インスタンスが立ち上がったらどれか1つにsshで入って確認をしましょう。

__1. Agentの確認__
以下のコマンドでAgentが入っているかを確認します。

```
$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 14295
```

__2. httpdの確認__
ブラウザから直接インスタンスのIPにアクセスするor動いてるプロセスを確認する。

```
$ ps ax | grep httpd
14371 ?        Ss     0:00 /usr/sbin/httpd
14374 ?        S      0:00 /usr/sbin/httpd
14375 ?        S      0:00 /usr/sbin/httpd
14376 ?        S      0:00 /usr/sbin/httpd
14377 ?        S      0:00 /usr/sbin/httpd
14378 ?        S      0:00 /usr/sbin/httpd
14379 ?        S      0:00 /usr/sbin/httpd
14380 ?        S      0:00 /usr/sbin/httpd
14382 ?        S      0:00 /usr/sbin/httpd
14492 pts/0    S+     0:00 grep --color=auto httpd
```

__3. ロードバランサとのリンクの確認__
ロードバランサのDNS名をブラウザからアクセスしてApacheのデフォルトの画面が表示されればOKです。

これで、ELB ＋ AutoScaingの準備は完了です。index.htmlをデプロイしていきましょう。
なお、今回は説明のために`CodeDeployASG`という名のAutoScalingGroupを用意しました。
前回と同様に2台のインスタンス構成です。

# 2. デプロイするファイルを用意する。

ローカルでやることは[超ミニマムなチュートリアルを通してCodeDeployを理解する。](https://qiita.com/Kept1994/items/fa3516fa8fe326b4ac3b)の記事と同じです。
実行済みの場合はスキップしてOKです。

* AWS CLIを入れるorアップデートする。
* デプロイ対象のindex.htmlを作成する。
* CodeDeployのデプロイ設定を記述したappspec.ymlを作成する。

# 3. S3バケットを準備する。

[超ミニマムなチュートリアルを通してCodeDeployを理解する。](https://qiita.com/Kept1994/items/fa3516fa8fe326b4ac3b)の記事と同じです。
実行済みの場合はスキップしてOKです。

# 4. ASGへのデプロイ

ここからが本題です。

現在、testCodeDeployディレクトリの中身は以下のようになっているはずです。

```shell
$ ls
appspec.yml index.html
```

## アプリケーションの作成

まずは、アプリケーションを作成します。ここでは`TestASG`とします。

```shell
$ aws deploy create-application --application-name TestASG
{
    "applicationId": "f33128d3-81bd-49f7-9b97-28f635995xxx"
}
```

## リビジョンの紐付け

デプロイ対象をzip化して、まるごと先ほど作成したS3バケットへ放り込みます。（1つのコマンドでできる。）
ここではファイル名を`testCodeDeploy.zip`とします。
ただし、この操作は、前回記事のS3バケットにすでに用意してある場合は`zip化`と`put-object`の操作はいらなくなり、`register-application-revision`のみ行えば大丈夫です。

```shell:S3が空の場合
$ aws deploy push \
--application-name Test \
--s3-location s3://testcodedeploy/testCodeDeploy.zip \
--ignore-hidden-files
To deploy with this revision, run:
aws deploy create-deployment --application-name Test --s3-location bucket=testcodedeploy,key=testCodeDeploy.zip,bundleType=zip,eTag=2dbc9aab3836f21317a9eed7a36f1xxx --deployment-group-name <deployment-group-name> --deployment-config-name <deployment-config-name> --description <description>
```

```shell:S3に既にzipがある場合
$ aws deploy register-application-revision \
--application-name TestASG \
--s3-location bucket=testcodedeploy,key=testCodeDeploy.zip,bundleType=zip
```

特に何も返値はないので不安な気持ちになりますがあってます。大丈夫。

## デプロイメントグループの作成

次は、デプロイメントグループの作成です。ここでは`TestASGGroup`と命名します。前回は`--ec2-tag-filters`でデプロイ対象のインスタンスを名指しで指定したのに対し、今回は`--auto-scaling-groups`で指定します。
`service-role-arn`には、AWSがデフォルトで提供しているロール`CodeDeployServiceRole`を使用します。

```shell
$ aws deploy create-deployment-group \
--application-name TestASG \
--auto-scaling-groups CodeDeployASG \
--deployment-group-name TestASGGroup \
--deployment-config-name CodeDeployDefault.OneAtATime \
--service-role-arn arn:aws:iam::xxxxxxxxxxxx:role/CodeDeployServiceRole
{
    "deploymentGroupId": "91350391-950f-497b-87c4-95abd8454xxx"
}
```

## デプロイ実行

いよいよデプロイです。

```shell
$ aws deploy create-deployment \
--application-name TestASG \
--deployment-config-name CodeDeployDefault.OneAtATime \
--deployment-group-name TestASGGroup \
--s3-location bucket=testcodedeploy,bundleType=zip,key=testCodeDeploy.zip 
{
    "deploymentId": "d-QHW602861"
}
```

これで実際に対象のEC2の`/var/www/html`下に`index.html`が置かれているはずです。
先ほどアクセスしたEC2のIPアドレスにブラウザからアクセスしてみましょう。`Hello World！`が表示されれば成功です。

実際にCodeDeployコンソールからデプロイメントを見てみると成功となっているでしょう。
インスタンスの終了とかがあるので時間がかかるかと想像していましたが、デプロイは10秒ほどで完了しました。

# デプロイ方式の種類

* CodeDeployDefault.AllAtOnce
  * 一度に全てのインスタンスへデプロイ。
* CodeDeployDefault.HalfAtATime
  * 一度に半分ずつデプロイ。
* CodeDeployDefault.OneAtATime
  * 一度に1つずつデプロイ。

詳しくは公式を参考に→https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/deployment-configurations.html

# 今後試したいこと

* [x]  EC2へのデプロイ
* [x]  AutoScalingGroupへのデプロイ
* [x]  lambdaへのデプロイ
* [ ]  CodeBuild等との一連の連携
* [ ]  appspec.ymlのhooksの利用