AWS Codeサービス群を利用してCI/CD環境を作成してみた

# はじめに
　この記事は [アイレット株式会社 22新卒 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/iret-22) 17日目の記事になります。
私は、4月に文系未経験でアイレットに入社したばかりのひよっこエンジニアです。
記事を投稿するのも初めてなので、暖かい目で見ていただけるとありがたいです。

# 背景
　2023年3月7日に改訂されるAWS Certified DevOps Engineer - Professional資格取得への学習の一部として“AWS Hands-on for Beginners"の[AWS Code サービス群を活用して、CI/CD のための構成を構築しよう！](https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-cicd-2022-reg-event.html?trk=aws_introduction_page)に取り組んだので、その内容を記事にまとめました。

# CI/CDとは何か
　CI/CDとは継続的インテグレーション(Continuous Integration) / 継続的デリバリー(Continuous Delivery)の略であり、特定の技術を指すものではなく、ソフトウェアの変更を常にテストし、自動で本番環境に適用できるような状態にしておく開発手法のことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/aaac37fd-5e56-9c86-bb78-ddadf8caa114.png)
※[こちら](https://www.sbbit.jp/article/cont1/81640)の記事の説明と図がわかりやすかったので参考にさせて頂きました。
## 登場人物(AWSサービス)
　今回のハンズオンで登場するAWSサービスについて簡単に説明します
### AWS CodeCommit
* フルマネージド型のソース管理サービスで、ソースコードをアップロードするリポジトリ
### AWS CodeBuild
* ソースコードをコンパイル・テスト実行し、デプロイ可能なソフトウェアパッケージを作成できるフルマネージド型のビルドサービス
### AWS CodeDeploy
* 様々なコンピューティングリソース(EC2,Lambda,オンプレ環境など)に対してデプロイを行う
### AWS CodePipeline
* フルマネージド型の継続的デリバリーサービス
* CodeCommit, CodeBuild, CodeDeployの3つのサービス群をパイプライン化して、ソースコードの変更をトリガーにビルド、デプロイといった一連の流れを自動的に実行する
### Cloud9
* ブラウザのみでコードを記述、実行、デバッグ可能なクラウドベースの統合開発環境(IDE)
### Amazon EC2
* 皆さんおなじみの仮想サーバサービス
### Amazon S3
* 皆さんおなじみのオブジェクトストレージサービス
## ハンズオン

### 構成図
![スクリーンショット 2022-12-13 1.16.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/c27a721b-689b-73e4-4be1-aceb1526eafb.png)

## S3
### 1. S3バケット作成
　AmazonS3>バケット>"バケットを作成"にてS3バケットを作成
※バケット名以外はデフォルト設定にて作成
![スクリーンショット 2022-12-13 1.11.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/413a7847-6559-fed7-168f-ccf6bf29df03.png)

## EC2
### 1.EC2インスタンスを起動する
　OSはAmazonLinux2を設定し、あまり良くないですがVPCなどはデフォルトのものを設定しました
![スクリーンショット 2022-12-13 7.03.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/bfb41a5a-ce54-421c-9283-9a7081410947.png)
　こちらもあまり良くないですが、セキュリティグループはSSHとHTTPを0.0.0.0で設定しました
![スクリーンショット 2022-12-13 7.02.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/5d729b8a-6ed1-7779-1e02-47bb938592d8.png)

### 2.インスタンスの環境を設定する
　セッションマネージャーにて、対象のインスタンスに接続し、下記コマンド実行する
```
sudo yum update -y
sudo yum install httpd -y
sudo systemctl start httpd.service
sudo systemctl enable httpd.service
```
### 3.code deployエージェントインストール
　手順2と同様に下記コマンドを実行し、デプロイ作業を行うCode Deployエージェントをインストールする
```
sudo yum install ruby
sudo yum install wget
cd /home/ec2-user
wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent status
```
[参考サイトURL](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html)
### 4.IAMロールを作成しアタッチ
　IAM>ロール>ロールを作成にてロール作成し、ポリシーはAmazonS3FullAccessに設定する
![スクリーンショット 2022-12-13 6.55.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/7c742060-be39-a489-053e-1f6f7ac25c49.png)


## AWS CodeCommit
### リポジトリの作成


デベロッパー用ツール>CodeCommit>リポジトリ>リポジトリを作成にてリポジトリを作成する

## Cloud9
### 1.Environment作成
AWS Cloud9>Environments>Create environmentにてEnvironmentを作成する
![スクリーンショット 2022-12-13 1.21.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/42f39be5-618d-3a6e-554e-a3777601795d.png)

### 2.認証情報ヘルパーなどを設定する
AWS Cloud9>Environments>Open in Cloud9に移動し、認証ヘルパー設定・ユーザ-ネーム・メールアドレスを設定するコマンド実行
![7C370D0E-FAE6-4460-B150-F9A9007F3697.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/8c8c61cc-85b2-b18b-8e12-c6e808ad514b.png)
実行コマンド
```
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true
git config --global user.name "ユーザーネーム"
git config --global user.email "メールアドレス"
```
※[参考サイト](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-https-unixes.html)

### 3.リポジトリのクローンを作成
Codecommit>リポジトリ>対象のリポジトリを選択し、HTTPS欄に記載のコマンドをコピーする。Cloud9に移動し、上記でコピーしたコマンド実行
![F54FA57D-4DE3-4B45-B06B-B195A8A4DE51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/ad510cb8-f4aa-77b8-fd95-3cf8bc9a53a9.png)

### 4.index.htmlファイルをCloud9にアップロード
index.htmlファイルをドラッグし、Cloud9にアップロードする。
index.htmlファイル
```
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>S3 Static Web Hosting</title>
</head>
<body>
  Hello, AWS World!!
</body>
</html>
```
### 5.CodeCommitへ変更をプッシュする
Cloud9にて、下記コマンド実行
```
cd h4b-hands-on/
git add -A
git commit -m "init."
git push origin master
```

## CodeBuild
### 1.ビルドを作成する
　デベロッパー用ツール>CodeBuild>ビルドプロジェクトより下記の通りビルドプロジェクトを作成
![スクリーンショット 2022-12-13 7.15.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/ac8cdd25-0667-ad7a-37b4-c5e5b913e187.png)

### 2. IAMロールにポリシーを追加
　作成されたcodebuild-h4b-hands-on-service-roleロールにAWSCodeDeployDeployerAccessポリシーを追加する
![スクリーンショット 2022-12-13 10.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/4056c35b-13fd-cd78-c557-162ae31ab8bc.png)


### 3.buildspec.ymlを設定
　Cloud9にbuildspec.ymlファイルをアップロード、またsrcフォルダを作成しindex.htmlファイルの配置を変更
※それぞれのフォルダはh4b-hands-onリポジトリの下に配置
![スクリーンショット 2022-12-13 7.19.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/fbfe28fa-5b88-42ff-d495-a605345733c3.png)

buildspec.ymlファイル
```
version: 0.2
phases:
  build:
    commands:
      - aws deploy push --application-name h4b-app --s3-location s3://h4b-hands-on/h4b-hands-on.zip --source src
artifacts:
  files:
    - '**/*'
  base-directory: src
```


## CodeDeploy
### 1.IAMロールの作成
　CodeDeployロールを作成し、ポリシーはAWSCodeDeployRoleに設定
![スクリーンショット 2022-12-13 10.41.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/2ac106aa-3a0c-dab3-863a-1eb74a68163d.png)

### 2.アプリケーションの作成
　デベロッパー用ツール>CodeDeploy>アプリケーション>アプリケーションの作成にてアプリケーションを作成する
![スクリーンショット 2022-12-13 10.32.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/75d23e1b-d99b-c248-e7a5-793b9283e315.png)

### 3.デプロイグループの作成
デベロッパー用ツール
　CodeDeploy>アプリケーション>手順2で作成したアプリケーション>デプロイグループの作成にて作成する。
サービスロールにて手順1で作成した、IAMロールを指定し、タググループにてEC2インスタンスを指定して作成。
![スクリーンショット 2022-12-13 10.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/7e0ead06-1814-3719-369e-ccb914272cf8.png)
![スクリーンショット 2022-12-13 10.36.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/0de92157-f423-5c97-dc1c-4a00c9381b76.png)

### 4.appspec.yml作成と配置
　appspec.ymlファイルはsrcフォルダの下に配置する
![スクリーンショット 2022-12-13 10.52.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/d2c6841e-4c3a-18bf-17a5-ad3eab7ca0a0.png)
appspec.ymlファイル
```
version: 0.0
os: linux
files:
  - source: index.html
    destination: /var/www/html/
```
### 5.CodeCommitリポジトリにプッシュする
Cloud9にて下記コマンドを実行し、CodeCommitリポジトリにプッシュする
```
git add -A
git commit -m "fix"
git push origin master  
```
### 6.ビルドする
デベロッパー用ツール>CodeBuild>ビルドプロジェクトにて作成したビルドプロジェクトのラジオボタンにチェックを入れ、ビルドを開始を押出
![50B10C24-2FFD-4D5E-938F-A55CCCF0AFB4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/7d339559-7d6e-2424-1c57-368f7038cd1c.png)
　全てのステータスが成功になり、ビルドが完了
![スクリーンショット 2022-12-13 11.03.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/762193b5-e81c-a6d8-17d9-93ab60aaf215.png)
### 7.アプリケーションをデプロイする
　デベロッパー用ツール>CodeDeploy>アプリケーションにて作成したアプリケーションのラジオボタンにチェックを入れ、アプリケーションをデプロイするを押出
![D0B6263F-32FF-49B7-8665-7DE03006957D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/8258e3ba-9e0c-8830-eea4-0cf91f137063.png)
　デプロイの作成画面に推移するので、下記画像の部分のみ入力しデプロイの作成を押出。
リビジョンは作成したS3のアーティファクトを選択する。
![スクリーンショット 2022-12-13 11.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/31669f5e-a15b-530a-3fe7-8b5aec9cffd0.png)
　下記画像の通り、ステータスが成功となりデプロイが完了する
![スクリーンショット 2022-12-13 11.12.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/ac2d1245-a6b3-f748-473c-834c010ff03f.png)
### 8.結果を確認する
　ここまでの作業で、Cloud9で設定したアプリケーションがEC2にデプロイされているはずなのでEC2のパブリックIPで検索し結果を確認する。
アプリケーションデプロイ前
![スクリーンショット 2022-12-12 23.27.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/54f108ad-34eb-01d6-9d67-24955fe1bd2c.png)
アプリケーションデプロイ後
![スクリーンショット 2022-12-13 0.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/4f5ce02e-39e0-3bf4-fa4c-a1fd96dc9641.png)
　Cloud9のindex.htmlの内容が表示されることが確認できたため、正常にデプロイできていることがわかる。

## CodePipeline
### 1.パイプラインを作成する
　デベロッパー用ツール>CodePipeline>パイプライン>"新規のパイプラインを作成する"にてパイプラインを作成
 ![スクリーンショット 2022-12-13 0.22.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/78e8caae-03cc-fe8d-af94-06078e2f9b40.png)
　ソースプロバイダーにはCodeCommitを指定し、リポジトリ名とブランチ名を入力
![スクリーンショット 2022-12-13 0.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/3d65cc90-1d1d-40bf-2da1-d04763522cb8.png)
　ビルドプロバイダーにはCodeBuildを設定
![スクリーンショット 2022-12-13 0.25.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/dd98db64-0681-49b7-ca77-c8858f615271.png)
　デプロイプロバイダーにはCodeDeployを設定し、アプリケーションとデプロイグループもそれぞれ設定する
![スクリーンショット 2022-12-13 0.25.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/cc05b971-7b2c-d198-18f5-51534f0bf595.png)
　ステップ5にて、記載した内容を確認し、問題なければ"作成"を押出

### 2.ソースコードを修正してみる
　実際にCloud9にてindex.htmlの内容を修正し、CodeCommitへプッシュしてみる

index.html(body)修正前
```
<body>
  Hello, AWS World!! 
</body>
```
index.html(body)修正後
```
<body>
  Hello, Advent Calendar 2022!! 
</body>
```
ソースコード修正後、Cloud9にて下記コマンド実行しプッシュ
```
git add -A
git commit -m "fix"
git push origin master  
```
　すると。。自動でCodeCommitが変更を検知し、ビルド作業が実行され始めました
![スクリーンショット 2022-12-13 0.55.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/504de22a-0750-b0c8-a08e-8aa9ff0f613e.png)

　ビルド作業が完了すると、自動でデプロイ作業に移ります
![スクリーンショット 2022-12-13 0.57.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/5d2a13b7-21bf-19f9-44f5-4061c1ac5adf.png)
　デプロイ作業も完了し、一連の動作が全て完了されました
![スクリーンショット 2022-12-13 0.58.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/30bde97b-9d5c-7f29-b954-0de07ad0b341.png)

### 3.サイト内容の変更を確認する
　EC2インスタンスのパブリックIPで検索すると、無事に変更が反映されていました！
![スクリーンショット 2022-12-13 0.59.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953840/403fb2a1-3e7e-a204-a914-1446d4dc25af.png)

## さいごに
　今回、CI/CD環境を初めて作成しましたが、変更後のビルドやデプロイが自動で行われると、導入にリソースを割かれることが減り、より開発に注力できると感じました。
また、buildspec.ymlやappspec.ymlなどを自分で設定することで、よりそれぞれの役割や意味などの理解が深まりました。
今回はAWS認定資格取得への学習の一部としてハンズオンに取り組みました、
やはり書籍や過去問での学習方法もいいですが、余裕のある方はハンズオンなどで実際に作成・設定してみることでより体系的に理解できると感じました。