AWS CI/CD勉強メモ②:CodeBuildでDockerイメージをビルド


## やること

Cloud9でデータを用意して
CodeCommitの`リポジトリ`にpushして
CodeBuildの`ビルドプロジェクト`でビルドしてDockerイメージを作成して
ECR(Amazon Elastic Container Registry)の`リポジトリ`にDockerイメージをpushする。
動作確認は、Cloud9でDockerコンテナを実行する




## 構成

今回つくる構成

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/6eac0a74-3618-2e57-9294-b98334a2bd81.png)



## 参考

- [CodeBuildでDockerイメージのマルチステージビルド](https://cloudpack.media/42538)
- [【備忘録】CodeBuildで aws ecr get-login コマンド実行時にエラーが発生する](https://qiita.com/NaokiIshimura/items/e73898244d784d7fbce7)

![line.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/2e44c99e-a953-7542-63b3-986ecadaca08.png)

では、やっていく

## 1.ECRの作成

ECR リポジトリを作成します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/350fbc03-1ab1-0970-2abf-0acfef4e2da9.png)





リポジトリ`multistage-ecr`を作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/ac7ac2fe-a021-f8d3-4734-a6d0458b4e89.png)



## 2.CodeCommitの作成

CodeCommit リポジトリを作成する

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/9e571764-70cb-8a5e-9ca8-a5ccbb0628fe.png)




リポジトリ`multistage-ecr`を作成する

![101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/41250ca6-8dbd-fd30-5ae2-6115159d6cb4.png)



## 3.ビルド用リソースの作成

githubからサンプルを取得し、
Cloud9上でデータを更新し、
CodeCommitリポジトリにpushする

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/7628041a-1296-8fe6-b388-8e2297dd4eda.png)



Cloud9を作る（作り方は省略）

[ここ](https://cloudpack.media/42538)からサンプル取得

```bash:Cloud9-Terminal
$ https://github.com/cloudfish7/multi-stage-build-for-codebuild.git
```

CodeCommitリポジトリをクローン

```bash:Cloud9-Terminal
$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/multistage-test
$ cp ../multi-stage-build-for-codebuild/* ./ -r
```



ファイル構造

```bash:Cloud9-Terminal
$ pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'
/home/ec2-user/environment/multistage-test
|--buildspec.yml
|--Dockerfile
|--pom.xml
|--src
|  |--buildspec.yml
|  |--Dockerfile
|  |--hoge
|  |  |--Main.java
|  |--pom.xml
```

取得したサンプルデータの `buildspec.yml` を編集

- 更新箇所
    - {REPO_NAME}, {tag}, {account_id} を実際の値に更新する
    - 1行目を `version: 0.1` -> `version: 0.2` にする

```yaml:buildspec.yml
version: 0.1
 
phases:
  pre_build:
    commands:
      - $(aws ecr get-login --region ap-northeast-1 --no-include-email)
  build:
    commands:
      - docker build -t {REPO_NAME}:{tag} .
      - docker tag {REPO_NAME}:{tag} {account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/{REPO_NAME}:{tag}
      - docker push {account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/{REPO_NAME}:{tag}
  post_build:
    commands:
```


codecommit のリポジトリにpushする

```bash:Cloud9-Terminal
$ git add .
$ git commit -m "update"
$ git push origin master
```

## 4.CodeBuildの作成

ビルドプロジェクト `multistage-build` を作成し、実行する
→ ECR リポジトリにDockerイメージが格納される


![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/05e632c6-37af-63ab-fa47-2f64b0de81d7.png)



#### 4-1.ビルドプロジェクト作成

![100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/cb1480f9-5f6c-04e1-7add-f80b6a7472d1.png)


|項目|値|備考|
|---|---|---|
|プロジェクト名| multistage-build||
|ソースプロパイダ| AWS CodeCommit||
|リポジトリ| multistage-test||
|リファレンスタイプ| ブランチ||
|ブランチ| master||
|環境イメージ| マネージド型イメージ||
|オペレーティングシステム| Ubuntu||
|ランタイム| Standard||
|イメージ| aws/codebuild/standard:4.0||
|環境タイプ| Linux||
|サービスロール| 新しいサービスロール||
|ロール名| codebuild-nultistage-build-service-role| 自動作成|
|ビルド仕様| buildspecファイルを使用する||


#### 4-2.ECRアクセス権を追加

IAMロールにECRアクセスのポリシー追加
`AmazonEC2ContainerRegistryPowerUse` を追加

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/4a2435f9-8d09-3306-8464-02b4abd29a26.png" width="350">


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/3eff0ce0-8db4-2887-233b-8b7e15d67999.png)




#### 4-3.ビルド実行

CodeBuildを実行
成功すると、ECRにイメージがプッシュされてる

ここまでできれば一応成功

![CodeBuildビルドプロジェクト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/2e44c99e-a953-7542-63b3-986ecadaca08.png)

## 動作確認

ビルドしたDockerイメージをCloud9上に持ってきて、Dockerコンテナ実行できることを確認する

![動作確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/f76860f9-0b1d-4f8e-c76c-82b8a9bea556.png)


Dockerコンテナを実行

```bash:Cloud9-Terminal
$ aws ecr get-login --no-include-email --region ap-northeast-1
# -> 出力された長いコマンドをコピーして実行 -> Login Succeeded とでれば成功
```

ECR リポジトリからDockerイメージ取得

```bash:Cloud9-Terminal
$ docker pull xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/multistage-ecr:latest
```

Dockerイメージがある

```bash:Cloud9-Terminal
$ docker images
REPOSITORY                                                         TAG                 IMAGE ID            CREATED             SIZE
xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/multistage-ecr   latest              5bf8c20529d6        14 minutes ago      81.4MB
```


```bash:Cloud9-Terminal
$ docker run xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/multistage-ecr:latest
# Dockerコンテナ実行できたか確認
$ docker ps -ls
CONTAINER ID        IMAGE                                                                     COMMAND             CREATED             STATUS                      PORTS               NAMES               SIZE
c53e6c6ef9e6        xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/multistage-ecr:latest   "/bin/sh"           11 seconds ago      Exited (0) 11 seconds ago                       hopeful_mendel      0B (virtual 81.4MB)
```