AWS CodeDeployとGitHubを連携してEC2に簡単自動デプロイ

# １．はじめに
以下を目的として本記事をまとめた。

・ツールや環境になじみのないユーザーにもわかりやすい言葉でまとめる。
・設定が多いので、なるべく詳細な内容を書き、覚書として使用する。

# ２．用語説明

## （１）デプロイとは
デプロイとは、ソフトウェアの分野で、開発したソフトウェアを利用できるように実際の運用環境に展開すること。

## （２）GitHubとは

GitHubとは、ソフトウェア開発プロジェクトのためのソースコード管理サービス。
弊社では、GitHubを使用して、ソースのバージョン管理を行っている。

## （３）AWSとは

AWSとは、Amazon Web Servicesの略で、WEB系の企業に対し、ITインフラのサービスを提供している。
弊社では、主にAWSを使って、インフラの管理を行っている。

### ①Amazon EC2とは

Amazon EC2とは、Amazon Elastic Compute Cloudの略で、仮想サーバを提供するウェブサービス。
以下は、EC2と略す。
[Amazon EC2](https://aws.amazon.com/jp/ec2/)

### ②AWS CodeDeployとは

AWS CodeDeployとは、AWSが提供する、EC2 インスタンスへのコード（GitHubか、Amazon S3にて管理）のデプロイを自動化するサービス。

以下は、CodeDeployと略す。

[AWS CodeDeploy](https://aws.amazon.com/jp/codedeploy/)

### ③IAM とは

IAM とは、AWS Identity and Access Managementの略で、ユーザーに対して AWS へのアクセスを制御する仕組み。

[IAM](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/introduction.html)

# ３．CodeDeployで簡単自動デプロイ
GitHubとの連携の前に、まずはCodeDeployを使ってEC2インスタンスに対する自動デプロイをしてみる。

## （１）準備

### ①IAMロールの作成
IAMコンソールの「ロール」から、「新しいロールの作成」ボタンをクリックする。

#### ・CodeDeploy

 手順              |               入力 |
|:-----------------|:------------------|
| ロール名の設定          |任意| 
| ロールタイプの選択      |AWSサービスロール＞Amazon EC2 |
| ポリシーのアタッチ             |AWSCodeDeployRole  | 

#### ・EC2

 手順              |               入力 |
|:-----------------|:------------------|
| ロール名の設定          |任意 | 
| ロールタイプの選択      |AWSサービスロール＞Amazon EC2 |
| ポリシーのアタッチ             |AmazonS3ReadOnlyAccess| 

※後述する、CodeDeploy用のagentをインストールするために必要

### ②EC2の設定

#### ・EC2インスタンスの作成

新規の場合は、EC2インスタンスを作成する際、先ほど作成した「AmazonS3ReadOnlyAccess」を割り当てればOK。
しかし、既存のEC2インスタンスにあとから「ロール」を追加するのは現時点では不可能とのこと。
今回は、以下の方法で問題を回避した。

・既存のEC2インスタンスのAMIを作成する
・新規でEC2インスタンスを作成する際、「AmazonS3ReadOnlyAccess」と「AMI」を割り当てる。

#### ・CodeDeploy用のagentをインストール

EC2インスタンスにログインし、以下のコマンドをたたけばOK。

インスール
```
$ sudo yum update
$ sudo yum install ruby
$ sudo yum install aws-cli
$ cd /home/ec2-user
$ aws s3 cp s3://aws-codedeploy-ap-northeast-1/latest/install . --region ap-northeast-1
$ chmod +x ./install
$ sudo ./install auto
```

インストールの確認
```
$ sudo service codedeploy-agent status
```

### ③appspec.ymlの作成
デプロイ内容を記載するymlファイルを作成し、デプロイしたいソースのルートに置く

設定内容

 項目            |               説明 |例
|:-----------------|:------------------|:------------------|
| version          |デプロイバージョン | |0.0
| os      |デプロイ先のEC2インスタンスのos |linux or windows |
| files:source            |デプロイ元のソースのパス。全ソースをデプロイする場合は「/」|/ |
| files:destination |ソースを配置する、デプロイ先のEC2インスタンスのパス|/home/release |
| hooks :ApplicationStart|デプロイ実行前に行いたい処理がある場合に、シェルのファイル名等設定する|location: scripts/codedeploy_start.sh|

例

```
version: 0.0
os: linux
files:
  - source: /
    destination: /home/release 
hooks:
  ApplicationStart:
    - location: scripts/codedeploy_start.sh
      timeout: 180
```
## （２）実行
AWSのコンソールに戻り、CodeDeployを実行する。

### ①新しいアプリケーションの作成

IAMコンソールの「AWS CodeDeploy」の「アプリケーション」から、「新しいアプリケーションの作成」ボタンをクリックし、以下を設定する。

設定内容

 項目            |               説明 |例
|:-----------------|:------------------|:------------------|
| アプリケーション名          |任意 | testapp
| デプロイグループ名      |任意|testdeploy |
| インスタンスの追加（タグの種類）            |デプロイ対象の特定方法|EC2 |
| インスタンスの追加（キー、値）|予めEC2に設定しているタグを選択する|key、value |
| デプロイ設定|デプロイする際の挙動を設定する|OneAtATime(1回に1個のインスタンスにデプロイ)|
| サービスロール ARN|作成した、CodeDeploy用のロールを設定する|arn:aws:iam::xxxxxxxxxxxxxx:role/AWS-CodeDeploy-Role|

### ①新しいデプロイの作成

以下を設定して、「今すぐデプロイ」ボタンをクリックする。

設定内容

 項目            |               説明 |例
|:-----------------|:------------------|:------------------|
| アプリケーション          |設定したアプリケーション名を選択する | testapp
| デプロイグループ      |設定したデプロイグループ名を選択する|testdeploy |
| リビジョンタイプ           |ソースを管理している場所|GitHub|
| リポジトリ名|GitHubのリポジトリ名| |
| コミットID|デプロイしたいコミットのID||
| デプロイ設定|デプロイする際の挙動を設定する|OneAtATime(1回に1個のインスタンスにデプロイ)|

### ③デプロイ結果の確認

「デプロイID」から、デプロイの「ステータス」を確認して「成功」と出るかどうか確認する。

ここまでで、コンソールから楽にデプロイできちゃう設定は完了！

# ４．GitHubと連携させてもっと簡単自動デプロイ

## （１）準備

### ①IAMユーザーの作成

AWS IAMコンソールの「ユーザー」から、「ユーザーの作成」ボタンをクリック
し、以下を設定して、GitHub用のユーザーを作成する

設定内容

#### ・詳細
 項目            |               説明 |例
|:-----------------|:------------------|:------------------|
| ユーザー名          |任意| GitHub
| アクセスの種類      |アクセスする媒体を選択する|プログラムによるアクセス|

#### ・アクセス権限

「既存のポリシーを直接アタッチします」を選択し、「ポリシーの作成」ボタンをクリック
「独自のポリシーを作成」を選択する。

 項目            |               説明 |例
|:-----------------|:------------------|:------------------|
| ポリシー名         |任意| CodeDeploy-Access 
| 説明      |任意||

ポリシードキュメント

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "codedeploy:GetDeploymentConfig",
            "Resource": "arn:aws:codedeploy:ap-northeast-1:aws_account:deploymentconfig:*"
        },
        {
            "Effect": "Allow",
            "Action": "codedeploy:RegisterApplicationRevision",
            "Resource": "arn:aws:codedeploy:ap-northeast-1:aws_account:application:application_name"
        },
        {
            "Effect": "Allow",
            "Action": "codedeploy:GetApplicationRevision",
            "Resource": "arn:aws:codedeploy:ap-northeast-1:aws_account:application:application_name"
        },
        {
            "Effect": "Allow",
            "Action": "codedeploy:CreateDeployment",
            "Resource": "arn:aws:codedeploy:ap-northeast-1:aws_account:deploymentgroup:application_name/deploygroup_name
        }
    ]
}

```
なお、以下の部分は変更が必要。

項目            |               説明 |例
|:-----------------|:------------------|:------------------|
| aws_account        |AWSのアカウント番号|12345678 
| application_name     |AWS CodeDeployで設定したアプリケーション名|testapp
| deploygroup_name     |AWS CodeDeployで設定したデプロイグループ名|testdeploy 

#### ・確認

「ユーザーの作成」ボタンをクリックして、ユーザーを作成する。
「Access Key ID」と「Secret Access key」は保存しておく。

### ②「AWS CodeDeploy」用のサービスを追加

GitHubの管理画面のデプロイ対象のリポジトリに移動する。

「Settings」＞「Installed integrations」にて「Add Services」ボタンをクリックし
「AWS CodeDeploy」を選択する。

設定内容

項目            |               説明 |例
|:-----------------|:------------------|:------------------|
| Application name         |AWS CodeDeployで設定したアプリケーション名|testapp
| Deployment group     |AWS CodeDeployで設定したデプロイグループ名|testdeploy 
| Aws access key     |GitHub用ユーザーのAccess Key ID| 
| Aws region      |AWSのリージョン|ap-northeast-1
| GitHub api url     |空欄でOK|
|  Aws secret access key      |GitHub用ユーザーのSecret Access key|
|  GitHub token     |空欄でOK|

#### ③GitHubのアクセストークンを取得
[Personal access tokens](https://github.com/settings/tokens)を表示し、Generate a personal access token を選択し、以下のように設定する。

項目            |               説明 |例
|:-----------------|:------------------|:------------------|
|Token description         |任意|AutoDeploy
| Select scopes     |権限の範囲|repo_deployment 

#### ④「GitHub Auto-Deployment」 サービスを追加

GitHubの管理画面のデプロイ対象のリポジトリに戻り、

「Settings」＞「Installed integrations」にて「Add Services」ボタンをクリックし
「GitHub Auto-Deployment」を選択する。

項目            |               説明 |例
|:-----------------|:------------------|:------------------|
|GitHub token         |GitHubのアクセストークンを設定する|
| Environments    |AWS CodeDeployで設定したデプロイグループ名|testdeploy 

##（２） Git push でデプロイ実行

準備は完了したので、後はデプロイしたいソースをcommitしてpushするだけでデプロイ完了！

# ５．参考
[GitHubへのpush時にCodeDeployを使ってEC2にアプリケーションをデプロイする](http://qiita.com/toshihirock/items/4ab08afcab2a0e7628a8)
[EC2デプロイのためにCodeDeployを導入する](http://qiita.com/yukofeb/items/e077fc8755416c904032)

# ６．おわりに
## （１）メリット
・設定が多く、準備に戸惑ったものの、設定さえしてしまえばgit pushのみでデプロイ
ができるので非常に便利である。
・デプロイ作業をチームメンバーと共有する必要性がないので、迅速に開発が進められる。
・デプロイのログを記録でき、いつでもAWSのコンソールから確認ができる。

## （２）デメリット
・設定が多いので準備に多少時間を要する。
・git push してデプロイできるブランチはデフォルトブランチに限られるので
そういった制約がなければより良い。

メリット、デメリットあるものの、自分にはメリットのほうが大きいと感じた。
今後も、AWSで機能が追加された際には色々と試してみたい。