【初心者】CodeCommit, CodeDeploy, CodePipeline を使ってみる

# 1. 目的
- devops関係の復習をしている。code系のサービスの知識が乏しいため、基礎的なハンズオンから始めて勉強する。

# 2. やったこと
- AWS公式チュートリアル[「チュートリアル: シンプルなパイプラインを作成する (CodeCommit リポジトリ)」](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/tutorials-simple-codecommit.html) を実施する。
- Developers.IOの記事[「CodeCommitからEC2にデプロイするシンプルなパイプラインを作ってみた」](https://dev.classmethod.jp/articles/pipeline-to-deploy-from-codecommit-to-ec2/)に、上記公式チュートリアルの詳細な解説があり、それも見ながら実施する。
- チュートリアル内容は以下の通り。
    - CodeCommitにリポジトリを作成し、デプロイしたいアプリケーション(※httpdを起動してindex.htmlを置くだけ…)をアップロードする。
    - アプリケーションのデプロイ先となるEC2インスタンス(1個)を作成する。
    - CodeDeployに「アプリケーション」を作成し、デプロイ先やデプロイ方法の設定を行う。
    - CodePipelineに、ソースをCodeCommitのリポジトリ、デプロイをCodeDeployのアプリケーションとして「パイプライン」を作成する。
    - 「パイプライン」を初回実行し、デプロイしたWEBサイトが表示されることを確認する。
    - CodeCommitのリポジトリ内容(index.html)を更新する。CodeCommitの更新をトリガにパイプラインが再実行され、WEBサイトのコンテンツが更新されることを確認する。

# 3. 構成図

![codecommit図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/42b97fbc-deeb-6955-72bf-847ab51cd53d.png)



# 4. 手順
- 基本的にチュートリアルの手順通りに実施するが、詰まった点などを補足する。

## 事前準備
- 「[Setup for HTTPS users using Git credentials](https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-gc.html)」 に従い、CodeCommitにhttps経由でアクセスする環境を整備する。
- 「AWSCodeCommitPowerUser」権限を持つIAMユーザを作成する。
- 上記権限を持つIAMユーザの管理画面にて、「AWS CodeCommit の HTTPS Git 認証情報」の「認証情報の生成」を実施する。CodeCommitに接続するためのUsername/Passwordのセットが生成される。

## Step 1: Create a CodeCommit repository

- CodeCommitの管理画面にて、新規レポジトリを作成する。

![codecommit01b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/f49e8c7b-4114-9a52-028d-9f1426b243c4.png)


- 作業用インスタンスにgitをインストールし、ローカルリポジトリのセットアップを行う。git clone 実行時に、事前に作成した「AWS CodeCommit の HTTPS Git 認証情報」が必要になる。

```
[ec2-user@ip-10-0-0-130 ~]$ sudo yum install git
[ec2-user@ip-10-0-0-130 tmp]$ git --version
git version 2.32.0
[ec2-user@ip-10-0-0-130 tmp]$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/mksamba-XXXX
Cloning into 'mksamba-XXXX'...
Username for 'https://git-codecommit.ap-northeast-1.amazonaws.com': [username]
Password for 'https://xxxxxx@git-codecommit.ap-northeast-1.amazonaws.com': [password]
warning: You appear to have cloned an empty repository.
```

## Step 2: Add sample code to your CodeCommit repository

- SampleApp_Linux.zip を保存して解凍する。

```
[ec2-user@ip-10-0-0-130 mksamba-XXXX]$ wget https://docs.aws.amazon.com/codepipeline/latest/userguide/samples/SampleApp_Linux.zip
[ec2-user@ip-10-0-0-130 mksamba-XXXX]$ unzip SampleApp_Linux.zip
[ec2-user@ip-10-0-0-130 mksamba-XXXX]$ rm SampleApp_Linux.zip
[ec2-user@ip-10-0-0-130 mksamba-XXXX]$ ls
appspec.yml  index.html  LICENSE.txt  scripts
```

- リポジトリにファイルをアップロードする。

```
[ec2-user@ip-10-0-0-130 mksamba-XXXX]$ git add -A
[ec2-user@ip-10-0-0-130 mksamba-XXXX]$ git commit -m "Add sample application files"
[ec2-user@ip-10-0-0-130 mksamba-XXXX]$ git push
```

- appspec.yml (CodeDeployによるデプロイ内容を規定するファイル)の意味についてざっくり理解しておく。各行の意味は、[「CodeDeploy Spec ファイルのリファレンス」](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file.html)を参照。

```
version: 0.0    # 現在0.0で固定
os: linux   # EC2インスタンスが対象の場合、OS指定が必要
files:　　# リポジトリ内のindex.htmlを対象EC2の/var/www/htmlへコピー
  - source: /index.html
    destination: /var/www/html/
hooks:　　
  BeforeInstall:  # インストールの前に実行
    - location: scripts/install_dependencies　# スクリプトの中身は httpd のインストール
      timeout: 300
      runas: root
    - location: scripts/start_server　# スクリプトの中身は httpd の start
      timeout: 300
      runas: root
  ApplicationStop:　# デプロイ完了後、次回のデプロイの最初に実施
    - location: scripts/stop_server   # スクリプトの中身は httpd の stop
      timeout: 300
      runas: root
```

## Step 3: Create an Amazon EC2 Linux instance and install the CodeDeploy agent

- アプリケーションをデプロイするターゲットとなるEC2インスタンスの作成、設定を行う。
- IAMポリシー(AmazonEC2RoleforAWSCodeDeploy, AmazonSSMManagedInstanceCore)を含むIAMロールを作成する。
- Amazon Linux 2 のインスタンスを作成し、上記のIAMロールを設定する。また、タグとして「Key: Name」、「Value: mksamba-MyCodePipelineDemo」を設定する。(デプロイ先としての指定にタグを用いるため)

## Step 4: Create an application in CodeDeploy 

- CodeDeployにアプリケーションを作成する。
- 「信頼されたエンティティ」として「CodeDeploy」を指定したIAMロールを作成する。
- マネージメントコンソールの「CodeDeploy > アプリケーション > アプリケーションの作成」にて、アプリケーションを作成する。

![codecommit02a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/17719aec-9bdc-b1a2-f6e4-9436505225d5.png)


- 続けてデプロイグループを作成する。
    - サービスロールとして、先の手順で作成したIAMロールを指定。
    - デプロイタイプとして「インプレース」(1台のデプロイ先のEC2インスタンスにそのまま上書きデプロイしていく)を選択。
    - 環境設定(デプロイ先)として、EC2インスタンスを選択し、タグ「Key: Name」、「Value: mksamba-MyCodePipelineDemo」を指定。
    - デプロイ設定として、デフォルトの「CodeDeployDefault.AllAtOnce」を選択。選択肢毎の挙動は「[EC2/オンプレミスコンピューティングプラットフォームの事前定義されたデプロイ設定](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/deployment-configurations.html)」を参照。
    - AWS Systems Manager を使用したエージェント設定にて、「今すぐ更新し、更新をスケジュール」を選択する。これによりCodeDeploy Agentのインストール、更新が行われる。
    - Load balancerにて、「ロードバランシングを有効にする」のチェックを外す。

![codecommit03a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/c6a88ec9-50b8-3820-3365-c442312b0112.png)
![codecommit04a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/52cba1cc-5ea4-19b5-0ed1-239bc211168e.png)
![codecommit05a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/5813b45f-4de9-6102-8155-67f1a2e2ff6e.png)

## Step 5: Create your first pipeline in CodePipeline
 
- マネージメントコンソールの 「CodePipeline - パイプライン - 新規のパイプラインを作成する」にて、パイプラインを作成する。
    - 新しいサービスロールを作成する。
    - ソースとして、あらかじめ作成したCodeCommitのリポジトリを指定する。
    - ビルドステージは今回はないのでスキップにする。(index.htmlを配置するだけのアプリケーションなので)
    - デプロイとして、あらかじめ作成したCodeDeployのアプリケーション/デプロイグループを指定する。

![codecommit06a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/6e8cee83-b76c-d9ba-e75b-deb6c527b8aa.png)
![codecommit07a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/366e9812-fc6d-f441-8a7e-50e23c26e7da.png)
![codecommit08a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/dd4cb864-1b37-e476-d40e-106c9b826bbd.png)
![codecommit09a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/d047e472-d3d4-804a-007d-c13a4d337077.png)


- パイプラインを作成後、初回実行される。(ソースのCodeCommitのリポジトリの内容をCodeDeployでEC2インスタンスへ展開)

![codecommit10a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/eb60d7d7-8852-70d3-bee8-794c2adbec79.png)


- デプロイ先のEC2インスタンスのEIPにhttpアクセスすると、無事デプロイしたコンテンツが表示される。

![codecommit11a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/8cfb5547-25e7-7b55-1e44-ffa85c28202f.png)

## Step 6: Modify code in your CodeCommit repository

- 作業用インスタンスのローカルリポジトリでindex.htmlファイルを更新し、アップロードする。

```
[ec2-user@ip-10-0-0-130 mksamba-qiita-XXXX]$ vi index.html  (中身を更新)
[ec2-user@ip-10-0-0-130 mksamba-qiita-XXXX]$ git commit -am "Updated sample application files"
[ec2-user@ip-10-0-0-130 mksamba-qiita-XXXX]$ git push
```
- CodeCommitのリポジトリの変更により、CloudWatch EventsによりCodePipelineのパイプラインが再実行される。完了後、EC2インスタンスにhttpアクセスすると、コンテンツが更新されていることが確認できる。

![codecommit12a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/1b23501d-d9bd-80c4-4166-3391e99073d8.png)

# 6. 所感

- 処理の流れが理解できて、ド初心者にはちょうどよいチュートリアルだった。コンテナへのデプロイなど、もう少し複雑な内容にチャレンジしたい。