[AWS]新卒1年目がAWS codepipelineでCI/CDを構築してみた1

この記事は[ディップ Advent Calendar 2023](#)の20日目の投稿です。

## 目次
- [はじめに](#はじめに)
- [導入背景](#導入背景)
- [やりたいこと](#やりたいこと)
- [今回作成するアーキテクチャ図](#今回作成するアーキテクチャ図)
- [ハンズオン](#ハンズオン)
    - [ALBの作成](#:point_up:ALBの作成)
    - [ECRの作成](#:point_up:ECRの作成)
    - [ECSの作成](#:point_up:ECSの作成)
    - codepipelineの作成（後編）
- [成果物の確認](#成果物の確認)
- [最後に](#最後に)
- [参考](#参考)


# はじめに
はじめまして！
この記事は、新卒１年目でAWS未経験者の私が自動デプロイの仕組みを構築した備忘録になります。
最後まで読めばAWS未経験者でも自動デプロイを構築できるようなハンズオン形式で進めてまいります。

:::note warn
こちらは前編です。
ECSでコンテナを立ち上げるまでを説明しております。
CodePipelineの構築は後編で説明いたします。
:::

# 導入背景

配属されてから新規サービスの開発を担当することになり、自動デプロイの構築に挑戦することになりました。

今までAWSを触ったことがないので、まずは各サービスの調査から始めましたが、
そもそもクラウドの知識がなかったため記事を読んでも、どんな機能なのか想像するのが難しく、詰まっていました。
そんな時、AWS公式のハンズオン資料を見つけました。
この通りに進めれば、構築できそうなくらい詳細に書かれていたのですが、
詰まってしまう箇所もあったので、より優しいハンズオンで紹介できたらと思います。

# やりたいこと

Githubのリポジトリでmainブランチに変更をプッシュしたら、自動でデプロイが走るようにする

# 今回作成するアーキテクチャ図
![アーキテクチャ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/bb7af217-a0be-80f2-b8d4-9290fd2e1eab.png)

最後に見返すと、イメージがつきやすいと思います。

## 用意するもの・事前準備

- AWSアカウント
- Githubリポジトリ（デプロイしたいリポジトリ）
- aws cliコマンドのインストール

# ハンズオン

## :point_up:ALBの作成

まず最初にロードバランサーを作成していきます。

検索バーにEC2と入力し、表示されたEC2を選択しましょう。
![EC2を検索](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/957522c4-6214-43f6-303b-015b8fae64b2.png)

EC2のページが開けたら、サイドバーからロードバランサーを選択します。
画像のような表示になったら、右上の<b>「ロードバランサーの作成」</b>ボタンをクリックします。
![スクリーンショット 2023-12-19 1.00.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/17188a3d-fe12-85fb-4023-b3a91c7d94c2.png)

アプリケーションロードバランサーを選択します。
![アプリケーションロードバランサーの選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/f572fd5c-cf15-16fd-88c3-dc2ff926b458.png)

下記の画像のように設定していきます。
![ロードバランサーの設定1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/c58fa1e9-c82b-9a21-8b35-92d8968db64f.png)
今回、vpcとセキュリティグループはデフォルトで用意されているものを使用します。
また、アベイラビリティゾーンは２つ用意しておきましょう。
![ロードバランサーの設定2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/559b98ad-789a-1593-a008-eaf42108afc1.png)

次に、ターゲットグループを設定するため、新しいターゲットグループを作成します。

![新しいターゲットグループを作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/1f2eb83a-a763-27ae-54c0-1a9640f74312.png)
下記の画像のような設定をしていきます・
![ターゲットグループの設定1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/f99e5b1a-eb7a-00fe-e491-567a821f3555.png)
![ターゲットグループの設定2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/ec067141-2b7c-79f6-beeb-17ff44b507d3.png)
![ターゲットグループの設定3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/646cc4f8-fac9-1db6-0801-cc459d609dca.png)

これらの設定ができたら、「作成」ボタンをクリックし、ターゲットグループの作成完了です。

ALBの設定に戻り、作成したターゲットグループを選択します。
![ALBの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/a546c35d-f9f3-0252-f154-adec2e546666.png)
これらの設定ができたら、「作成」ボタンをクリックし、ALBの作成完了です。

## :point_up:ECRの作成

次にECRを作成していきます。
ECRはElastic Container Resitstryの略で、Dockerのイメージを置いておくためのリポジトリです。
ECRに移動しリポジトリを作成していきます。

検索バーにElastic Containerくらいまで入力すると、Elastic Container Resitstoryと表示されるのでクリックします。
![検索バーECR](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/5d244e92-3f5e-f2dc-76b1-58bc4a451155.png)

サイドバーの<b>Repository</b>を選択し、<b>リポジトリを作成</b>をクリックします。
![ECRリポジトリの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/001cd86a-fff9-5bc0-1008-cb1e0e52e505.png)

任意のリポジトリ名を入力後、他の設定は特にせず、スクロールし<b>リポジトリを作成</b>ボタンをクリックしましょう。
![スクリーンショット 2023-12-19 15.19.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/dac69ed5-2afb-c141-0e67-615f9870eb18.png)
これでECRリポジトリの作成は完了です。

## 作成したECRにDockerイメージを保存する

次に、作成したECRリポジトリにDockerイメージをプッシュします。

ここからはローカルでの作業になります。</b>
### :writing_hand: 1. Dockerfileが置いてあるディレクトリに移動する

### :writing_hand:2.Dockerイメージにタグをつけて、ビルドする

以下のコマンドを実行します。
リポジトリ名とタグ名は任意なので、識別できる名前を設定しましょう。
```
docker build . -t <リポジトリ名>:<タグ名>
```

私はphpのDockerfileがあったため、以下のように実行しました。
```
docker build . -t php:php
```

以下のコマンドを実行して、作成されたイメージを確認することができます。
```
docker images
```
リポジトリ名がphp、タグ名がphpのイメージが作成されているのがわかります。
![作成されたイメージの確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/ae2c97df-68a8-006e-a50b-22cae34c4f03.png)

### :writing_hand: 3. DockerイメージをECRにプッシュする

1. ECRレジストリに認証を通す

:::note warn
aws configureの設定がまだの方は、
[こちらの記事](https://qiita.com/sakuchi/items/90886663f7adf3941472)に設定方法をまとめてくださっているので、ご確認ください
:::

ECRにプッシュするためには、ECRに認証を通す必要があります。
1回認証を通すと、12時間は有効になります。

以下のコマンドを実行して、認証を通しましょう。
<アカウントID>の部分はご自身のIDに変えてください。
```
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com
```
成功すると「Login succeed」と表示されます。

:::note
アカウントIDは、右上の「アカウント名」をクリック→「アカウント」をクリックすると確認できます。
![アカウントIDの確認方法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/382876b6-82e8-0447-1b06-2012dae9dec9.png)
:::

2.dockerイメージにつけたタグを変更する

先ほどdockerイメージのビルド時につけたリポジトリ名とタグ名をECR用に変更します。
リポジトリ名には、作成したECRリポジトリのURIを設定する必要があります。
以下のコマンドを実行して、リポジトリ名とタグ名を変更しましょう。
```
docker tag 変更前のリポジトリ名:変更前のタグ名 作成したECRリポジトリのURI:変更後のタグ名
```

「作成したECRリポジトリのURI」の部分は、
画像の箇所にあるECRリポジトリのURIをコピーして貼り付けてください。
![ECRリポジトリのURI](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/2fb76730-50a3-0e8e-8b3b-3854d5450e24.png)

私は、phpリポジトリにphpタグをつけてDockerイメージをビルドしたので、
以下のように変更しました。
```
docker tag php:php xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/test-ecr:php  
```

3.ECRリポジトリにプッシュする

最後に、ECRリポジトリにイメージをプッシュします。
以下のコマンドを実行しましょう。
`docker push <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/ECRリポジトリ:タグ`

私の場合は、以下のように実行しました。
```
docker push xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/test-ecr:php
```

AWSコンソールのECRリポジトリを確認し、画像のようにイメージがプッシュされていることが確認できれば成功です。
![スクリーンショット 2023-12-19 22.07.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/7e42590a-4f6c-3758-20a0-39cfd2ce697d.png)

## :point_up:ECSの作成

次にECSを作成していきます。
ECSはElastic Container Serviceの略で、ECRに格納したDockerイメージからコンテナを立ち上げて、アプリケーションを簡単にデプロイ、スケーリングすることができます。

### :writing_hand:クラスターの作成

今まで通り、検索バーでECSと入力し、<b>Elastic Container Service</b>を選択します。
サイドバーから<b>クラスター</b>を選択し、<b>クラスターの作成</b>ボタンをクリックします。
![クラスターの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/51af8ac7-f243-d79c-1771-a6c7e50825b7.png)

任意のクラスター名を入力し、インフラストラクチャはAWS Fargateを選択してください。
他は特に設定せずに、作成ボタンをクリックします。
![ECSの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/692dcd63-99a4-56be-e2e5-e6beae5b6696.png)
クラスターの作成には少し時間がかかります。

### :writing_hand:タスク定義の作成

次に、ECSにコンテナを立ち上げる際に使用するタスク定義を作成します。
タスク定義はDockerでいうdocker-compose.ymlに近い役割をしています。

ECSページのサイドバーから「タスク定義」を選択し、「新しいタスク定義の作成」ボタンをクリックします。
![新しいタスク定義の作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/450692e0-7206-ab7c-9f18-62b4cc646248.png)

下記の画像のように設定していきます。
![タスク定義の命名](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/606bdf6d-1856-3d92-5c5c-b2176a4ea836.png)

![タスク定義の設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/a28de380-0b01-4da2-4f28-54e4556d2d0b.png)

コンテナの設定では、コンテナの名前とDockerイメージを選択します。
![スクリーンショット 2023-12-19 22.32.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/e30b8ee7-fb8e-4163-2ec3-631438b3845d.png)

:::note
イメージURIには先ほどプッシュしたイメージのURIを入力します。
![スクリーンショット 2023-12-19 22.35.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/6a267223-995e-ebf8-fd3b-70c2d22c0205.png)
:::

「コンテナを追加」ボタンをクリックすると、複数コンテナを立ち上げることができます。
![コンテナを追加](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/f26f4552-a168-3674-01dc-0ec63be9a926.png)

それ以外は特に設定せず、「作成」ボタンをクリックします。
これでタスク定義の作成は完了です。

### :writing_hand:サービスの作成

次にクラスター内にサービスを作成していきます。
作成したクラスターをクリックします。
![作成したクラスターに移動](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/48ecf32e-fa76-2fb8-7c14-f6f6d81fb8e2.png)

「作成」ボタンをクリックします。
![サービスの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/7b9e4ec0-81e8-1296-f1da-818e403804c1.png)

下記の画像のように設定していきます。
![サービスの設定1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/8964c257-c650-389f-bbc5-b536da322d27.png)

ファミリーには、先ほど作成したタスク定義を設定します。
また、任意のサービス名を設定してください。
![サービスの設定2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/4f19d9b7-ce26-f0d2-3d66-bc9789aab0a5.png)

デプロイオプションを開き、「ブルー・グリーンデプロイ(AWS CodeDeployを使用)」を選択してください。
また、サービスロールを指定する必要があります。
（後ほど、CodeDeployの設定を行います。）
![サービスの設定3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/85e690a5-2f0e-d2cc-73f8-d764afeb3600.png)

---
:cold_sweat:いったん、サービスロールの作成作業:cold_sweat:

ここでサービスロールを作成する必要があるため、新しいタブを開きます。
コンソールでIAMを開きます。
サイドバーのロールを選択し、「ロールを作成」ボタンをクリックします。
![サービスロールの作成1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/dca1f57a-c319-eceb-6389-45067c0583be.png)
下記の画像のように設定します。
![サービスロールの作成2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/5ba46485-8200-d742-1d15-f32a475a755f.png)
ポリシーの許可は特に変更せず、次へで進みます。
![サービスロールの作成3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/27382390-cb74-536d-304f-35ff251c7beb.png)
サービスロールに任意の名前を設定し、「ロールを作成」ボタンをクリックしましょう。
![サービスロールの作成4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/4d35b198-43f1-736c-20fb-4e19c6965522.png)

これで、サービスロールの作成は完了です。

---
ALBの作成に戻ってきました。。。！:cold_sweat:

CodeDeployのサービスロールに、作成したサービスロールを設定しましょう。
![サービスの設定4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/7e75c6af-c655-22e6-b78b-fb793120cf48.png)


「service connectをオンにする」にチェックを入れます
![サービスの設定5](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/a1c01683-cfa3-ae74-f41b-44e4662dbd58.png)

ネットワーキングの設定は、デフォルトのVPCやセキュリティグループを使うため特に設定は変えていません。
![サービスの設定6](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/a9fa07db-b4e9-cfb7-7036-fb1ef1e0ded0.png)

ロードバランシングの設定は、Application Load Balancerを選択します。
![サービスの設定7](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/b49caacf-400a-813c-29c1-c9595d8b97bc.png)
「既存のロードバランサーを使用」をチェックし、作成したALBを指定します。
![サービスの設定8](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/3950229f-b1e5-9d64-4193-7b6bb85eb25d.png)
ターゲットグループ1には、「既存のターゲットグループを使用」をチェックし、作成したターゲットグループを指定します。
ターゲットグループ2には、「新しいターゲットグループの作成」をチェックし、任意のターゲットグループ名を設定します。
![サービスの設定9](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/094dff55-f645-c249-40fe-f280270dda65.png)

:::note
なぜターゲットグループが２つ必要なのか？
CodeDeployのブルー・グリーンデプロイでは、
新しいバージョンを「グリーン」のサーバーにデプロイし、古いバージョンを「ブルー」のサーバーに維持しておきます。グリーンで問題が起きた時、すぐにブルーに切り戻しができるような仕組みになっています。そのためブルー・グリーンは常に稼働できる必要があり、それぞれにターゲットグループを設定しておく必要があります。
:::

それ以外の設定は特に変えずに、「作成」ボタンをクリックします。
ここまででサービスの作成が完了しました。

## 成果物の確認

ここまでで、ECSのコンテナを立ち上げることができました。
作成したALBのDNSにアクセスすると、ブラウザで確認することができます。。。！
![ブラウザでの確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619984/777ba6bc-8bb9-3058-587a-25cbed4038b5.png)

手動でのデプロイができたということですね！

## 最後に

ここまでで、ECSコンテナを立ち上げることができたので、手動デプロイはできている状態になります。
次の後編では、Githubリポジトリのmainブランチに変更があったらデプロイを開始するような自動デプロイの仕組みを作成していきます。


## 参考

参考にさせていただきました！:bow_tone1:

https://techtionary.jp/3507/

https://dev.classmethod.jp/articles/beginner-series-to-check-how-t-create-docker-image-and-push-to-amazon-ecr/