AWS はじめての継続的デリバリーパイプライン（CICD）やってみた


# はじめに
## 本稿の内容
**CI/CD** (Continuous Integration/Continuous Delivery)で開発できる環境を整備しよう！というToBeを掲げても、いきなり理想的なパイプラインを作るは難しいもの。

そこで、今回は個人のAWSアカウントを利用して**CI/CD**を実現するパイプラインの中でも、『最小構成』といえるような簡易なパイプラインの一例を実装してみました。

これを土台に実際に作り学習やイメージを膨らませたり、自分の必要なサービスの追加や更新を施したりして、ToBeとなる**CI/CD**構築のベースとしていければと思います。


## 参考
以下のAWS公式ハンズオンをベースとしています。この内容をベースにしつつGithubでなくCodeCommitを使うなど若干の変更を加えています。

[継続的デリバリーパイプラインを作成する](https://aws.amazon.com/jp/getting-started/hands-on/create-continuous-delivery-pipeline/)

## 前提
- AWSアカウントを持っていて、基本的な操作や設定方法等は知っている
- Gitアカウント/ツールの基本的なノウハウ、設定方法等は知っている
- その他若干の環境やツールの差異があっても適宜吸収できる！ググれる！

## 構成
以下の五部構成により図のような最低限の継続的デリバリー実装を行っていきます。

1. リポジトリのセットアップ（CodeCommit）

2. プラットフォームのセットアップ（BeansTalk）

3. ビルドプロジェクトのセットアップ（CodeBuild）

4. デリバリーパイプラインのセットアップ（CodePipeline）

5. 継続的デリバリーの実現
5. ![cicd_basic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600107/dac07513-0180-d9b2-ec61-080c4a8e3e34.png)


## コスト
個人の使い方にもよるので保証は一切できませんが、
**私の場合は**アカウント作成後12か月の無料枠内で0円で実施できたと思います。

Beantalkのマシン代やS3にログが吐かれたりパイプライン上でAPIが飛び交うので個々人で自分の利用の仕方の課金を調べてみてください。(課金要素の網羅もしかねるので悪しからず、自己責任で。) 
<br>

# ハンズオン手順
以下より実際に試したハンズオンの流れを記していきます。
全て東京リージョン上で実施しています。
特に明記しない設定についてはその当時のデフォルトのままです。
<br>

## 1. リポジトリのセットアップ
### 概要

**CodeCommit**上にリポジトリを整備していきます。
このリポジトリをのちのちパイプライン上でソースとして参照したり、変更を検知して自動デリバリーをキックしたりします。

なお、[AWSハンズオン](https://aws.amazon.com/jp/getting-started/hands-on/create-continuous-delivery-pipeline/module-one/)ではGithubを使っているのでGithubで実施したい方やCodeCommitでうまくいかない、認証ができないなどの人はそちらを参照してください。

### リポジトリ作成
**CodeCommit**のコンソールを開きます。

リポジトリ一覧が出力されるので[<span style="background-color:Orangered; color:white"> リポジトリを作成 </span>]ボタンを押します。

以下のリポジトリの設定を投入して[<span style="background-color:Orangered; color:white"> 作成 </span>]ボタンを押します。

| 項目 | 投入値 | 
| --- | --- |
|リポジトリ名 | Cicd_kangaezaru | 

### リポジトリのクローン
自分のローカルマシンへ作成したリポジトリをクローンしましょう。リポジトリの「URLのクローン」からHTTPのURLをコピーし、ローカルマシンで次のコマンドを打ちます。

`git clone https://~~~`

:::note info
CodeCommitのリポジトリをローカルでクローンするときは何かしら認証が必要になります。例えば、AWSのIAMユーザの画面から「認証情報」というタブを開くとCodeCommit用の認証情報を生成する項目があります。
:::

作られたローカルリポジトリに適当にファイルを追加していきます。ここでは以下のHello Worldを返すアプリのapp.jsをプッシュしてみます。
```Javascript:app.js
const express = require('express');
const app = express();
const port = 8080;

app.get('/', (req, res) => res.send('Hello World!'));

app.listen(port);
console.log(`App running on http://localhost:${port}`);
```
`git add app.js`

`git commit -m "change message"`

`git push`

<br>

### 検証
ローカルでコミットしプッシュしたファイルが、AWSのCodeCommitのコンソール上でも存在することを確認します。
<br>

## 2. プラットフォームのセットアップ
### 概要

**ElasticBeanstalk**でアプリをデプロイする環境を準備します。まず本節ではAWSのサンプルコードを表示させるWebサーバを構築します。のちのち自分で作ったapp.jsを動かしてHellow Worldを表示するWebサーバとします。

:::note info
Beanstalkは結構頻繁に画面のレイアウトが変わるような気がします。
:::

### Beanstalkの作成
**Beanstalk**のコンソールを開きます。

まず環境一覧が出力されるので[<span style="background-color:Orangered; color:white"> 新しい環境の作成 </span>]ボタンを押します。

『環境枠の選択』ではウェブサーバ環境を選択します。次のページで以下のような設定値を投入します。


| 項目 | 投入値 | 
| --- | --- |
|アプリケーション名 | Cicd_kangaezaru | 
|環境 | Cicd_kangaezaru-env |
|プラットフォーム | Node.js |
|アプリケーションコード | サンプルアプリケーション |

[<span style="background-color:Orangered; color:white"> 環境の作成 </span>]ボタンを押します。
しばらく環境が作成されるまで待ちます。

### 検証
環境が作成され一覧に表示されたら、Beanstalkで稼働するWebサーバへのURLリンクが生まれるので移動してみる。
Congratulationsといった表示がされるサンプルウェブページに行けることを確認します。

<br>

## 3. ビルドプロジェクトのセットアップ

### 概要
**CodeBuild**でビルドジョブのプロジェクトを作成します。各種ランタイムなどを設定し、ソースコードをコンパイルするための詳細を定義します。

### ビルドプロジェクトの作成
**CodeBuild**のコンソールを開きます。

プロジェクト一覧が出力されるので[<span style="background-color:Orangered; color:white"> ビルドプロジェクトを作成する </span>]ボタンを押します。

以下のような設定値を投入します。

| 項目 | 投入値 | 
| --- | --- |
|プロジェクト名 | Cicd_kangaezaru-build | 
|ソースプロバイダ | AWS CodeCommit |
|リポジトリ | Cicd_kangaezaru |
|環境イメージ | マネージド型イメージ |
|オペレーティングシステム | Amazon Linux 2 |
|ランタイム | Standard |
|イメージ | aws/codebuild/amazonlinux2-x86_64-standard:3.0 |
|環境タイプ | Linux |
|サービスロール | 新しいサービスロール |
|ロール名 | codebuild-cicd-build-service-role |

### ビルドスペックの設定
ビルドの各処理や環境変数などはbuildspec.ymlというファイルに記述して保存できます。
「ビルドコマンドの挿入」を選択し、「エディタに切り替え」をする。以下のコードに置き換えます。
```
version: 0.2
phases:
    build:
        commands:
            - npm i --save
artifacts:
    files:
        - '**/*'
```

[<span style="background-color:Orangered; color:white"> ビルドプロジェクトを作成する </span>]ボタンを押します。

<br>

### 検証
作成ボタン押下後、「次のプロジェクトが正常に作成されました: Cicd_kangaezaru-build」と出力されていることを確認します。
<br>

## 4. デリバリーパイプラインの作成

### 概要
**CodePipeline**で継続的デリバリーを実現するパイプラインを構築します。ここではCodeCommitのコードをソースとしてCodeBuildでビルドし、Beanstalkにデプロイする一連の流れをシームレスに自動化する。

### CodePipelineのセットアップ
**CodePipeline**のコンソールを開きます。

パイプライン一覧が出力されるので[<span style="background-color:Orangered; color:white"> パイプラインを作成する </span>]ボタンを押します。

以下のような設定値を投入します。

| 項目 | 投入値 | 
| --- | --- |
|パイプライン名 | Cicd_kangaezaru-line | 
|サービスロール | 新しいサービスロール |
|ロール名 | AWSCodePipelineServiceRole-cicd-line-service-role |

[<span style="background-color:Orangered; color:white"> 次に </span>]ボタンを押します。

**ソースステージ**を設定します。

| 項目 | 投入値 | 
| --- | --- |
|ソースプロバイダー | AWS CodeCommit | 
|リポジトリ名 | Cicd_kangaezaru |
|ブランチ名 | master |

[<span style="background-color:Orangered; color:white"> 次に </span>]ボタンを押します。

**ビルドステージ**を設定します。

| 項目 | 投入値 | 
| --- | --- |
|ソースプロバイダー | AWS CodeBuild | 
|リージョン | アジアパシフィック (東京) |
|プロジェクト名 | Cicd_kangaezaru-build |
|ブランチ名 | master |

[<span style="background-color:Orangered; color:white"> 次に </span>]ボタンを押します。

**デプロイステージ**を設定します。

| 項目 | 投入値 | 
| --- | --- |
|ソースプロバイダー | AWS Elastic Beanstalk | 
|リージョン | アジアパシフィック (東京) |
|アプリケーション名 | Cicd_kangaezaru |
|環境名 | Cicd_kangaezaru-env |

[<span style="background-color:Orangered; color:white"> 次に </span>]ボタンを押します。

レビューページでレビューして[<span style="background-color:Orangered; color:white"> パイプラインを作成 </span>]ボタンを押します。

### 検証
ソース、ビルド、デプロイの各ステージで実行が進められます。

しばらく待ってソースとビルドのステージが緑に変わりすが、デプロイでエラーが出ています。app.jsのみプッシュしている場合はもう一つファイルを追加する必要があり想定内の動作です。
<br>

## 5. 継続的改善とデリバリーの実現

### 概要
エラーが出ている部分を修正して再度パイプラインを実行し、自動デプロイを行います。これにより実際の開発時も修正をすぐに環境で確認し、継続的に改善と反映を繰り返していくことができます。

### 改善のアクション
エラーを解消するために以下のファイルを自分のマシンのローカルリポジトリで作成します。( AWSの本ハンズオンの[サンプル](https://github.com/aws-samples/aws-elastic-beanstalk-express-js-sample) より)

```Javascript:package.json
{
  "name": "aws-elastic-beanstalk-express-js-sample",
  "version": "1.0.0",
  "description": "Sample Node.js (Express) app for AWS Elastic Beanstalk",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/aws-samples/aws-elastic-beanstalk-express-js-sample.git"
  },
  "license": "MIT-0",
  "dependencies": {
    "express": "^4.17.1"
  }
}
```

ファイルをコミット・プッシュします。

`git add package.json`

`git commit -m "change message"`

`git push`

### 検証と継続的デリバリー
プッシュされると**CodePipeline**の作成したパイプラインが再度ソースステージから走り出します。
今度はデプロイステージまで成功しましたと出力されると思います。

デプロイステージの **AWS Elastic Beanstalk** のリンクをクリックします。Elastic Beanstalk 環境を一覧表示した新しいタブが開きます。
作成した環境の URL をクリックします。白い背景のウェブページと、最後に  コミットしたときのテキスト（Hello World等）が表示されます。

当然Hello Worldなどの文字を変更してコミット・プッシュすればテキストも変更されるので検証してみてください。

<br>

# おわりに
これで最小構成の継続的デリバリーのパイプラインができました。

これをベースに新たに他のサービスを組み合わせたり、他の言語での開発検証に置き換えたり、ユニットテストやインテグレーションテストのステージを追加したりして、理想のCI/CDを追い求めていきましょう！

不要であれば使い終わったリソースは削除してください([このページのクリーンアップ参照](https://aws.amazon.com/jp/getting-started/hands-on/create-continuous-delivery-pipeline/module-five/))。