保守業務を中心に携わってきた人間がAWSのCI/CDサービスについて学んでみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333262/93f37826-32f2-87ad-cb2f-1e9ce9e344cc.png)


# はじめに

AWSの知見を深めるために保守作業を中心に業務へ携わってきた人間が、
今更ですがCodeシリーズの学習をするために書いた記事です。

Codeシリーズで提供されている機能の概要的な部分が中心となっています。
（内容は、2024年11月時点の情報で学習した内容となります。）

既にご存知の方はぜひ一緒に復習、これから学習する方は一緒に理解を深めていければと思います！

# 改めて・・CI/CD、Codeシリーズとは？

まずCI/CDとは、Continuous Integration/Continuous Delivery & Deploymentの略で、日本語では継続的インテグレーション/継続的デリバリー&デプロイと呼ばれます。 CI/CDを一言で言えば、一定の品質を保証しながら、素早くアプリケーションをデプロイする自動化の手法です。
CI/CDは以下のようなイメージになると考えています。

【CI/CDのイメージ図】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333262/04008c6e-35c6-efa7-407c-c76f12842ee0.png)



リポジトリサービスでアプリケーションのコードを管理し、継続的インテグレーション（CI）でコードのマージ～テストまでを自動化、継続的デリバリー（CD）で各環境でデプロイを自動化という流れになるようです。

Codeシリーズは、AWSでCI/CD環境を構築するために提供されているサービスになります。
CI/CD環境をAWSのCodeシリーズで構築する場合は、以下サービスを利用することで実現可能となります。

①CodeCommit（リポジトリサービス。コード、バージョン管理を行う）
②CodePipeline（CI/CDサービス。コードのビルド、テスト、デプロイのプロセスを自動化）
③CodeBuild（ビルドサービス。ソフトウェアのビルド、テスト、パッケージングを自動化）
④CodeDeploy（デプロイサービス。複数環境などのデプロイを自動化）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333262/1d59fbe7-d440-a1e6-434b-4b843ccd6630.png)



# **AWS Codeシリーズ**

## **CodePipeline**

AWS CodePipeline は、ソフトウェアのリリースプロセスを自動化するためのフルマネージド型のCI/CDサービスです。
CodePipelineを使用することで、コードのビルド、テスト、デプロイのプロセスを自動化し、ソフトウェア開発のライフサイクル全体を効率化することができます。

|特徴|概要|
| ---- | ---- |
|CI/CD自動化| CodePipelineは、コードの変更がリポジトリにプッシュされるたびに、ビルド、テスト、デプロイの各ステージを自動的にトリガーすることができます。これにより、手動での操作を減らし、迅速なフィードバックとリリースを実現します。
|マルチステージパイプライン|CodePipelineは、複数のステージ（例えば、ビルド、テスト、デプロイなど）を定義して、コードを一連のプロセスで処理します。各ステージは独立しており、異なるアクション（ビルド、デプロイ、テストなど）を実行できます。|
|ロールバック機能|デプロイが失敗した場合や問題が発生した場合、CodePipelineは自動的に前の安定したバージョンへロールバックできます。これにより、デプロイ後の障害によるダウンタイムを最小限に抑えることができます。|

【コンポーネント】
ソースステージ：
最初のステージで、ソースコードが格納されているリポジトリ（AWS CodeCommit、GitHub、S3など）から最新のコードを取得します。このステージでのコードの変更をトリガーにして、パイプラインが実行されます。

ビルドステージ：
CodeBuildなどのビルドツールを使って、ソースコードをコンパイル、パッケージ化、テストなどを行います。ビルドが完了すると、アーティファクト（ビルド成果物）が生成され、次のステージへ渡されます。

テストステージ：
ビルドが完了した後、ユニットテストや統合テスト、UIテストなどを実行します。テスト結果が問題なければ、次のデプロイメントステージへ進みます。

デプロイステージ：
最終的にアプリケーションをターゲット環境（AWS EC2、ECS、Lambda、オンプレミスなど）にデプロイします。CodeDeployを使ってEC2インスタンスにデプロイしたり、ECSクラスターにコンテナをデプロイしたりします。

承認ステージ：
特定のパイプラインステージで手動承認を挟むことができます。例えば、テストを通過した後に、ステージを管理者の手動承認を待って次に進める設定が可能です。


各サービスで実行されるプロセスをCodePipelineで自動化できることは便利だと思っていますが、まずは各Codeシリーズの理解が先ですね…（単体で利用するサービスではないので）


## **CodeCommit**
AWS CodeCommitは、プライベート Git リポジトリをホストする、安全で高度にスケーラブルなマネージド型のソース管理サービスです。

|特徴|概要|
| ---- | ---- |
|Git互換|CodeCommitはGitをベースにしており、Gitクライアントを使用してリポジトリを操作可能<br>Gitのコマンドを使って、リモートリポジトリとやり取りが可能|
| セキュリティ | CodeCommitはIAMと統合されており、細かなアクセス制御が可能<br>データの暗号化、アクセスログを監視も可能

CodeCommitはGitHubやGitLab、Bitbucketなどの他のGitホスティングサービスと同様にGitベースのリポジトリを提供しますが、AWSインフラに統合されているため、CodeCommitを選択することでインフラ全体を一元的に管理することができます。

【新規サービス終了】

2024年7月25日にCodeCommitの新規利用が終了しています。
既にサービスを利用しているユーザーはこれまで通り利用できますが
今後、アップデートされる予定はありません。

:::note warn
> 慎重に検討を重ねた結果、 2024 年 7 月 25 日をもちまして、 AWS CodeCommit について、新規のお客様向けのアクセスを閉じることを決定いたしました。
> AWS CodeCommit を既にお使いのお客様は、これまで通りサービスをご利用いただくことが可能です。
AWS は AWS CodeCommit のセキュリティ、可用性、パフォーマンスの改善に引き続き投資を行ってまいりますが、新機能の導入は予定しておりません。

[AWS CodeCommit リポジトリを他の Git プロバイダーに移行する方法](https://aws.amazon.com/jp/blogs/news/how-to-migrate-your-aws-codecommit-repository-to-another-git-provider/#:~:text=%E6%85%8E%E9%87%8D%E3%81%AB%E6%A4%9C%E8%A8%8E%E3%82%92%E9%87%8D%E3%81%AD,%E3%82%92%E6%B1%BA%E5%AE%9A%E3%81%84%E3%81%9F%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82)
:::

サービスの終了時期は未定ですが、代替サービスを検討する必要はあると考えています。
GitHubやGitLabなどが代替サービスと考えられるので、CodeCommitの運用からどのような変化があるのか、別の記事で更新したいと思います。

## **CodeBuild**
AWS CodeBuildは、フルマネージド型のビルドサービスで、ソフトウェアのビルド、テスト、およびパッケージングを自動化します。CodeBuildを使用すると、インフラの管理やサーバーのセットアップなしで、ソースコードをコンパイルし、テストを実行して、最終的なアーティファクト（成果物）を生成することができます。

|特徴|概要|
| ---- | ---- |
|スケーラビリティ|複数のビルドを同時に実行でき、プロジェクトの規模に関係なくスケールします。複数のビルドジョブを並行して処理するため、ビルド時間を短縮できます。高いスケーラビリティを持っており、必要に応じて自動的にリソースをスケールアップ/スケールダウンします。|
|豊富なビルド環境| CodeBuildは、公式のビルド環境（Dockerイメージ）を提供しており、さまざまなプログラミング言語やフレームワークに対応しています。例えば、Java、Node.js、Python、Go、.NET、Ruby、Dockerなどのビルドがサポートされています。また、独自のDockerイメージを使用して、カスタムビルド環境を作成することもできます。|

### buildspec.yml
 これはビルドの各ステップ（インストール、ビルド、テスト、アーティファクトの生成など）を記述するファイルです。CodeBuildは、このファイルに基づいてビルドを実行します。
yaml形式、以下のような構成で記述されています。


```yaml
# [必須]buildspec のバージョンを表します(0.2が推奨値)
 version: 0.2
# [任意]コマンドを実行する Linux ユーザーを指定可能
run-as: Linux-user-name
# [任意]環境変数の設定
env:
 # OSごとにサポートされているシェルを選択
  shell: shell-tag
 # カスタム環境変数を定義する
  variables:
    key: "value"
    key: "value"
 # パラメータストアに保存された環境変数を利用する場合に設定
  parameter-store:
    key: "value"
    key: "value"
 # 環境変数をエクスポートする場合に設定
  exported-variables:
    - variable
    - variable
 # シークレットマネージャーに保存された環境変数を利用する場合に設定
  secrets-manager:
    key: secret-id:json-key:version-stage:version-id
 # Git 認証情報ヘルパー使用して Git 認証情報を提供する場合に設定
  git-credential-helper: no | yes
# [任意]プロキシサーバーでビルドを実行する際に設定
proxy:
 # アーティファクトをアップロードする際に設定（デフォルトはno）
  upload-artifacts: no | yes
 # Cloudwatchログを作成する際に設定（デフォルトno）
  logs: no | yes
```
```yaml
# [必須]CodeBuild 実行されるコマンドを定義する
phases:
  # [任意]ビルド中にパッケージをインストールする場合に設定（下記項目でオプションを設定）
  install:
  # コマンドを実行する Linux ユーザーを指定する場合に設定
    run-as: Linux-user-name
  # ビルドが失敗した場合のアクションを指定する
  #（ABORT:ビルド中止、CONTINUE:次のフェーズに移行）
    on-failure: ABORT | CONTINUE
  # ランタイムバージョンを指定する場合に設定
  # (指定しない場合は、デフォルトのランタイムバージョンが設定される)
    runtime-versions:
      runtime: version
      runtime: version
  # インストール時に実行されるコマンドを記述する
    commands:
      - command
      - command
  # 下記に指定したコマンドは、commands:で指定したコマンド完了後に実行される
    finally:
      - command
      - command

# [任意]ビルド前に実行するコマンドがある場合に設定する
  pre_build:
    run-as: Linux-user-name
    on-failure: ABORT | CONTINUE
    commands:
      - command
      - command
    finally:
      - command
      - command
# ビルド中に実行するコマンドがある場合に設定する   
  build:
    run-as: Linux-user-name
    on-failure: ABORT | CONTINUE
    commands:
      - command
      - command
    finally:
      - command
      - command
# ビルド後に実行するコマンドがある場合に設定する    
  post_build:
    run-as: Linux-user-name
    on-failure: ABORT | CONTINUE
    commands:
      - command
      - command
    finally:
      - command
      - command
```
```yaml
# ビルドの実行結果を出力する際に設定する
reports:
 # レポートの送信先のレポートグループを指定
  report-group-name-or-arn:
   # ディレクトリを指定
    files:
      - location
      - location
    base-directory: location
    discard-paths: no | yes
    # レポートファイル形式を設定
    file-format: report-format
# ビルドアーティファクト（成果物）に関する設定
artifacts:
  files:
    - location
    - location
  name: artifact-name
  discard-paths: no | yes
  base-directory: location
  exclude-paths: excluded paths
  enable-symlinks: no | yes
  s3-prefix: prefix
  secondary-artifacts:
    artifactIdentifier:
      files:
        - location
        - location
      name: secondary-artifact-name
      discard-paths: no | yes
      base-directory: location
    artifactIdentifier:
      files:
        - location
        - location
      discard-paths: no | yes
      base-directory: location
# キャッシュをS3にアップロードする際に設定
cache:
  paths:
    - path
    - path
```

buildspec.ymlは多くのオプション項目が用意されていますが、すべてを設定する必要はないため、公式ドキュメントを確認しつつ、必要な項目のみ記述します。

[CodeBuildのビルド仕様リファレンス](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html#build-spec-ref-syntax)


オプション項目は多いですが、用意されたアプリケーションをビルドする単純な作業であればbuildspec.ymlは簡単に記述できると思いました。また定常的に必要ない、短時間しか利用しないアプリケーションであればEventBridgeなど他のサービスをトリガーにして必要な時にビルドして実行するなど色々と工夫ができると感じました。


## **CodeDeploy**
アプリケーションを複数のコンピュータやインスタンスに自動的にデプロイするためのフルマネージドサービスです。主に、AWSのEC2インスタンスやオンプレミスのサーバーにアプリケーションを効率的にデプロイするために使用されます。

|特徴|概要|
| ---- | ---- |
|自動デプロイ|アプリケーションのデプロイ作業を自動化します。これにより、手動でのデプロイ作業を減らし、ヒューマンエラーを防止|
|拡張性とスケーラビリティ|インスタンスの数に関係なく、スケーラブルなデプロイを提供します。数千台のEC2インスタンスやコンテナに対しても、効率的にデプロイを実行|
|カスタムデプロイフック|デプロイ中に実行するカスタムスクリプト（フック）を設定できます。たとえば、アプリケーションがデプロイされる前後で何か処理を行いたい場合、デプロイフックを利用することで柔軟な制御が可能|

【プラットフォーム】
CodeDeploy は、下記３つのプラットフォームに対してデプロイが可能です。

- EC2インスタンス
- Lambda
- ECS


【デプロイタイプ】
CodeDeploy は、２つのデプロイタイプが提供されています。

①インプレイスデプロイ: 既存のインスタンス上で新しいバージョンをデプロイする方法。新しいコードをインスタンスに置き換える形でデプロイされます

:::note warn
注意点
- LambdaとECSでは、インプレイスデプロイを利用できない。
- 構成にもよるが既存のインスタンスにデプロイを行うため、少なからずダウンタイムが発生する。
:::

②Blue/Green deployment: アプリケーションの新バージョン（Green）をデプロイする前に、古いバージョン（Blue）と切り替え可能な新しい環境を準備します。これにより、ダウンタイムを最小限に抑え、迅速にロールバックできるメリットがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333262/0187ab59-a1ce-8122-bd8b-cd89906a360e.png)


ECSを例にデプロイの流れは下記のようになります。

1. 新しいバージョンのデプロイ：
CodeDeployを使用して、Green環境に新しいアプリケーションバージョンをデプロイ
（テスト用のターゲットグループにデプロイするため、通常ユーザーは接続できない）
1. テストと検証：
Green環境でアプリケーションが正常に動作するか確認。
必要に応じて負荷テストやユーザーテストを行う。
1. トラフィックの切り替え：
Green環境が問題なく動作していることが確認できたら、トラフィックをBlue環境からGreen環境へ切り替え。これにより、新しいバージョンが本番環境として稼働する。
1. Blue環境の撤去：
新しいバージョンが安定して稼働していることを確認した後、Blue環境を削除するか、次回のデプロイ時に再利用することも可能

対象とプラットフォーム、運用している構成によってデプロイタイプが異なってくることは理解できていますが今回触れていないデプロイ戦略は、選択によって意図しないダウンタイム等が発生してしまうため、少し深堀が必要な内容と感じました。

選択するオプションによってデプロイされるタイミングが異なってくるためフロー図などにして整理していきたいと思います。

# まとめ
今回はCodeシリーズの機能について、概要的な部分にしか触れていません。特にCodeDeployは、ターゲットとなるサービスによって選択できるデプロイ設定が異なっています。

運用していくシステムの仕様などを考慮して組み合わせのパターンを考えていくため、単純にドキュメントなぞるだけの知識量では、選択していくのが難しいと思っています。（オプション等も多いので…）

次回以降の記事では、１つのサービスに絞って深堀をしたいと考えています。

参考
[CodeCommitとは](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/welcome.html)
[CodeDeployとは](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/welcome.html#welcome-deployment-overview)
[CodePipelineとは](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/welcome.html)
[CodeBuildとは](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/welcome.html)

# 弊社では一緒に働く仲間を募集中です！

現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております！

募集内容等詳細は、是非採用サイトをご確認ください。

https://engineer.po-holdings.co.jp/