[AWS] CodeDeploy+CodePipeline+GitHub push時にEC2にデプロイ

AWSに以下の環境を構築したので、備忘録として残しておこうと思います。


##目次
（１）IAMロールの作成 (CodeDeploy用、EC2用)
（２）EC2インスタンスの生成、各インストール、設定
（３）GitHubの設定
（４）CodeDeployの設定、CodeDeployでのデプロイ
（５）CodePipeLineの設定、GitHub（git push）でのデプロイ

##実施内容（イメージ）
<img width="464" alt="スクリーンショット 2017-04-04 18.15.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/114886/1e8d32a1-a714-1087-b85c-aa551fb46d1f.png">

"masterのEC2からGitHubにpushすると自動でslave1〜3のEC2にデプロイされる"という環境を構築します。
今回は、ELBやAuto Scalingは考慮しません。
また、slaveのEC2はイメージでは3つですが、1つで構築します。

##開発環境
EC2 (AmazonLinux)
Apache 2.2


| EC2 type | IP Address | EC2 Name|
| :------ |:------|:--------|
| master | 54.178.XXX.XXX |codeDeploy-master|
| slave | 13.112.YYY.YYY |codeDeploy-slave|

## （１） IAMロールの作成 (CodeDeploy用、EC2用)
・CodeDeploy用IAMロールの作成
【ロールの作成】
①IAM
②ロール
③新しいロールの作成
④ロール名の設定　ロール名：codeDeploy_Qiita
⑤Amazon EC2　選択
⑥AWSCodeDeployRole　選択
⑦ロールの作成

【信頼関係の編集】
作成された[codeDeploy_Qiita]をクリックして[信頼関係]　→　[信頼関係の編集]を選択
以下の様に変更

```javascript:信頼関係の編集
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "codedeploy.ap-northeast-1.amazonaws.com" //Tokyo
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

・EC2用IAMロールの作成
①IAM
②ロール
③新しいロールの作成
④ロール名の設定　ロール名：codeDeployEC2_Qiita
⑤Amazon EC2　選択
⑥AmazonS3ReadOnlyAccess　選択
⑦ロールの作成

## （２） EC2インスタンスの生成、各インストール
【EC2インタンスの生成】
詳しくは[こちら](http://qiita.com/hibriiiiidge/items/aebcd4184c7ab4c83bdf#ec2%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9amazon-linux%E3%81%AE%E4%BD%9C%E6%88%90)を参考に生成してください。

概要は下記です。
①Amazon マシンイメージ（AMI）の選択　AmazonLinux
②インスタンスタイプの選択 t2.micro(デフォルトのまま)
③インスタンスの詳細の設定　IAM ロールには先ほど作成した[codeDeployEC2_Qiita]を選択
④ストレージの追加　（デフォルトのまま）
⑤Add Tags (任意、ここでは[codeDeploy-master]と入力)
⑥セキュリティグループの設定　（SSHとHTTPを開放した設定）
⑦作成

【各インストール】
・apacheのインストール

```
[ec2-user@ip-10-0-1-239 ~]$ sudo yum -y install httpd

~インストール~

Complete!
[ec2-user@ip-10-0-1-239 ~]$ httpd -version #バージョン確認
Server version: Apache/2.2.31 (Unix)
[ec2-user@ip-10-0-1-239 ~]$ sudo /sbin/chkconfig httpd on #自動起動をonに変更
[ec2-user@ip-10-0-1-239 ~]$ sudo service httpd start #Apache起動
```

```
Starting httpd: httpd: apr_sockaddr_info_get() failed for ip-10-0-1-107
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
```
とエラーが出る場合は[こちら](http://qiita.com/hibriiiiidge/items/7483335bb3d2fef40214#apache22-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)をご参照ください。

・gitのインストール

```
[ec2-user@ip-10-0-1-239 ~]$ sudo yum -y install git
[ec2-user@ip-10-0-1-239 ~]$ git --version
git version 2.7.4
```

・AWS CLIのインストール

```
[ec2-user@ip-10-0-1-239 ~]$ sudo yum install -y aws-cli
[ec2-user@ip-10-0-1-239 ~]$ aws configure #AWS CLIの初期設定
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

Access Key IDとSecret Access Keyは[セキュリティ認証](https://console.aws.amazon.com/iam/home?#/security_credential)から確認できます。


・AWS CodeDeploy エージェントのインストール

```
[ec2-user@ip-10-0-1-239 ~]$ aws s3 cp s3://aws-codedeploy-ap-northeast-1/latest/install . --region ap-northeast-1
[ec2-user@ip-10-0-1-239 ~]$ chmod +x ./install
[ec2-user@ip-10-0-1-239 ~]$ sudo ./install auto
[ec2-user@ip-10-0-1-239 ~]$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 2953
```

## （３） GitHubの設定
・GitHub接続用のSSH公開鍵と秘密鍵の生成

```
[ec2-user@ip-10-0-1-239 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/ec2-user/.ssh/id_rsa.
Your public key has been saved in /home/ec2-user/.ssh/id_rsa.pub.
The key fingerprint is:
12:34:56:78:90:ab:cd:ef:gh:ij:kl:mn:op:qr:st:uv ec2-user@ip-10-0-1-239
The key's randomart image is:
+--[ RSA 2048]----+
|...              |
|.                |
|. o              |
|o+.              |
+-----------------+
[ec2-user@ip-10-0-1-239 ~]$ cd .ssh
[ec2-user@ip-10-0-1-239 .ssh]$ chmod 644 id_rsa.pub
[ec2-user@ip-10-0-1-239 .ssh]$ chmod 600 id_rsa
[ec2-user@ip-10-0-1-239 .ssh]$ cat id_rsa.pub
ssh-rsa XXXXXXXXXXXXXXX ec2-user@ip-10-0-1-239
```

`ssh-rsa XXXXXXXXXXXXXXX ec2-user@ip-10-0-1-239`をコピーする。

・[GitHub](https://github.com/)へssh接続

①[GitHub](https://github.com/)へアクセス
②右上のアイコンからSettingsを選択
③Personal settingsからSSH and GPG keys
④New SSH Key
⑤title：任意　
Key：先ほどコピーした"ssh-rsa XXXXXXXXXXXXXXX ec2-user@ip-10-0-1-239"をペイスト
⑥Add Key　

EC2へ戻り、GitHubへssh接続を実施

```
[ec2-user@ip-10-0-1-239 .ssh]$ cd
[ec2-user@ip-10-0-1-239 ~]$ vi .ssh/config #configファイルを新規作成

=========== configの中身を編集 ================
Host github.com
  HostName github.com
  IdentityFile /home/ec2-user/.ssh/id_rsa
  User git
==============================================

[ec2-user@ip-10-0-1-239 ~]$ chmod 600 .ssh/config
[ec2-user@ip-10-0-1-239 ~]$ ssh github.com #GitHubへssh接続
The authenticity of host 'github.com' can't be established.
RSA key fingerprint is 12:34:56:78:90:ab:cd:ef:gh:ij:kl:mn:op:qr:st:uv.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,XXX.XXX.XXX.XXX' (RSA) to the list of known hosts.
Hi {YOUR ACCOUNT}! You've successfully authenticated, but GitHub does not provide shell access.Connection to github.com closed.
```
GitHubへの接続OK

・GitHub上でリポジトリの作成及びクローン
①[Create a new repository](https://github.com/new)にアクセス
②Owner : YOUR_ACCOUNT
Repository name : codeDeployQiita
Description : 任意
③Public
④Create repository
作成されたリポジトリのURLをコピー
`https://github.com/YOUR_GIT_ACCOUNT/codeDeployQiita.git`

EC2へ戻り、リポジトリをクローンしたいディレクトリへ移動
今回は、`/var/www/html/codeDeployQiita`という構成

```
[ec2-user@ip-10-0-1-239 ~]$ cd /var/www/html/
[ec2-user@ip-10-0-1-239 ~]$ sudo git clone https://github.com/YOUR_ACCOUNT/codeDeployQiita.git
Cloning into 'codeDeployQiita'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
[ec2-user@ip-10-0-1-239 html]$ ls -la
合計 12
drwxr-xr-x 3 root root 4096  4月  5 10:08 .
drwxr-xr-x 6 root root 4096  4月  5 01:41 ..
drwxr-xr-x 3 root root 4096  4月  5 10:08 codeDeployQiita #クローンされていることを確認
[ec2-user@ip-10-0-1-239 html]$ sudo chown -R ec2-user:ec2-user codeDeployQiita
```

・ファイルの作成
codeDeployQiitaディレクトリの中に下記のファイル/ディレクトリを配置します。
  -index.html
  -appspec.yml
  -scripts/initialize.sh

```
[ec2-user@ip-10-0-1-239 html]$ cd codeDeployQiita
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ sudo vi appspec.yml

=========== appspec.ymlの中身を編集 ================
version: 0.0
os: linux
files:
    - source: /
      destination: /var/www/html/codeDeployQiita
permissions:
    - object: /var/www/html/codeDeployQiita
      pattern: "**"
      owner: apache
      group: apache
      mode: 755
      type:
        - file
hooks:
    BeforeInstall:
     - location: scripts/initialize.sh
       runas: root
====================================================

[ec2-user@ip-10-0-1-239 codeDeployQiita]$ sudo vi index.html

=========== index.htmlの中身を編集 ================
<div>Hello, World</div>
==================================================

[ec2-user@ip-10-0-1-239 codeDeployQiita]$ sudo mkdir scripts
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ cd scripts
[ec2-user@ip-10-0-1-239 scripts]$ sudo vi initialize.sh

=========== initialize.shの中身を編集 ================
#!/bin/bash
yum -y install httpd
service httpd start
=====================================================

[ec2-user@ip-10-0-1-239 scripts]$ cd ..
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ git add .
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ git commit -m "1st commit"

#gitのアカウントの設置をしていなかったのでエラーが出ます...
*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'ec2-user@ip-10-0-1-239.(none)')
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ git config --global user.name YOUR_NAME
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ git config --global user.email YOUR_MAIL_ADDRESS
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ git commit -m "1st commit" #commit成功
[master (root-commit) 6295ce4] 1st commit
 4 files changed, 21 insertions(+)
 create mode 100644 appspec.yml
 create mode 100644 index.html
 create mode 100644 scripts/initialize.sh
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ git push origin master #GitHubへpush
Username for 'https://github.com':YOUR_GITHUB_ACCOUNT #GitHubのアカウントを入力
Password for 'https://YOUR_GIT_ACCOUNT@github.com': YOUR_GITHUB_PASSWORD　#GitHubのパスワードを入力
Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (7/7), 647 bytes | 0 bytes/s, done.
Total 7 (delta 0), reused 0 (delta 0)
To https://github.com/YOUR_GIT_ACCOUNT/codeDeployQiita.git
 * [new branch]      master -> master
[ec2-user@ip-10-0-1-239 codeDeployQiita]$ 
```

GitHubのcodeDeployQiitaリポジトリにアクセスしてファイル等がUPされているか確認

## （４）CodeDeployの設定、CodeDeployでのデプロイ

・slaveEC2を構築
（３）までで構築したEC2をイメージ（AMI）に取っても良いし、新しくEC2を立ち上げても良い
apache、gitはインストール必要はないが、**AWS CodeDeploy エージェントをslaveEC2にインストールして実行する**必要がある

【CodeDeployの設定】
①CodeDeployへアクセス　→　[カスタムデプロイ]を選択
![cd1.png](https://qiita-image-store.s3.amazonaws.com/0/114886/bb28f42f-6840-037c-b3da-040376bf70fe.png)

②[アプリケーションの作成]
![cd2.png](https://qiita-image-store.s3.amazonaws.com/0/114886/f776f0ac-15ac-4cfa-8318-10c5cb1cbfea.png)

| 入力項目 | 値 |
| :------ |:------|
| アプリケーション名 | codeDeployApp(任意) |
| デプロイグループ名 | codeDeployGrp(任意) |
| デプロイタイプ | インプレースデプロイ |
| インスタンスの追加 | キー：Name 値:codeDeploy_slave |
| サービスロールARN | CodeDeploy用のIAMロール |


③[アクションの選択]
![cd3.png](https://qiita-image-store.s3.amazonaws.com/0/114886/42e52c3d-fb5a-9329-e0a6-31274af88ba0.png)
[アクション]　→　[新しいリビジョンのデプロイ]

④デプロイの作成
![cd4.png](https://qiita-image-store.s3.amazonaws.com/0/114886/cf1b8379-aa54-4bef-dcf0-fabe631d1378.png)

| 入力項目 | 値 |
| :------ |:------:|
| リポジトリ名 | YOUR_GIT_ACCOUNT/codeDeployQiita |
| コミットID | XXXXXXXXXXXXXXXX(※) |

※コミットIDは`git log`コマンドで確認

```
[ec2-user@13 codeDeployQiita]$ git log

commit XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX　#コミットID
Author:YOUR_GIT_ACCOUNT <YOUR_MAIL_ADDRESS>
Date:   Thu Apr 5 02:19:33 2017 +0000

    1st commit
```
⑤[デプロイ]
![cd5.png](https://qiita-image-store.s3.amazonaws.com/0/114886/d085930c-75d8-a62f-465a-c828943dc530.png)

![cd6.png](https://qiita-image-store.s3.amazonaws.com/0/114886/d13b61b6-0d66-c446-8bc5-f703522069a0.png)
デプロイ完了

http://13.112.YYY.YYY/codeDeployQiita/ にアクセスして`Hello, World`が表示されていればCodeDeployからのデプロイは完了

## （５）CodePipeLineの設定、GitHub（git push）でのデプロイ
①CodePipeLineにアクセス
②パイプライン名：codeDeployQiita_github
③ソースプロバイダ:GitHub →　GitHubへ接続
④リポジトリ：YOUR_ACCOUNT_NAME/codeDeployQiita
ブランチ：master
⑤ビルドプロバイダ：ビルドなし
⑥デプロイプロバイダ：AWS Deploy
アプリケーション名：codeDeployApp
デプロイグループ：codeDeployGrp
⑦サービスロール　→　[ロールの作成]　IAM画面に遷移
⑧ IAMロール：新しいIAMロールの作成、　ロール名：AWS-CodePipeline-Service-Qiita （任意）
![cd13.png](https://qiita-image-store.s3.amazonaws.com/0/114886/e16534a2-f2cd-844f-9cb7-d9d7604f8b9c.png)
⑨作成すると前の画面に戻り、ロール名には⑧で作成したロールが自動で入力されている
![cd14.png](https://qiita-image-store.s3.amazonaws.com/0/114886/e0da25de-c3c4-4c52-ca6c-1d21bf41954a.png)
⑩レビュー　確認後、問題なければ作成


【検証】
`index.html`を編集して、`git add`・`git commit`・`git push`を実行する。
http://13.112.YYY.YYY/codeDeployQiita/ にアクセスして変更されていればCodePipelineからのデプロイ(pushをトリガーにしたデプロイ)は完了

以上です。

大変参考にさせていただきました。
[AWS CodeDeployの導入 & AWS CodePipeLineでgit pushの度にEC2に自動デプロイ & 結果をSlackに通知](http://qiita.com/na0AaooQ/items/61b69580df0aa7e4e875)
[GitHubユーザアカウントとGitHubリポジトリ作成 + AWS EC2からGitHubリポジトリへpushする手順例](http://qiita.com/na0AaooQ/items/61b69580df0aa7e4e875)