CIをDroneからCodeBuildに移行したい

## はじめに
    
ディップアドベントカレンダー19日目の投稿です。
    
## やりたかったこと
Droneが担っていたCI部分（テスト→ビルド→GitHubのリリースタグ作成）を他ツールに移行できるか検証しました。
そこで引っかかった点を記録していきます。
実装はこれからなので、実装も完了したらまた記事にしたいと思います。

## サービスの構成
kintoneにレコード登録されたデータをバッチ実行で定期的にDBに登録する、APIとバッチの保守運用をしています。
以下のような構成になっています。
- アプリケーション: Go
- CI: Drone → これを移行したい
- CD: Jenkins
- インフラ: EC2

## なんで移行したいのか？
Droneが使えなくなってしまったからです。😢
DroneではホストのDockerのバージョン問題で、Go1.20以上のバージョンに上げることができなくなっていました。

公式Issueに記載あり

https://github.com/docker-library/golang/issues/467

            
Droneの不具合により、バージョンアップも厳しい状況でした。

ということで、移行を検討することになりました。

## Droneが担っていたこと

以下を行っていました。
- テスト
- ビルド
- GitHubのリリースタグ作成
- リリースにバイナリファイルをAssetsとして追加

## 候補を出してみる
工数を考えて、前例があると嬉しい。という前提で候補出しをしました。

- jenkins：CDをjenkinsから移行したいという話が出ていたので、除外
- GitHub Actions：前例あり
    - 調べた感じ、Droneが担っていたことは全部できそう
    - 軽い処理向き
- CodeBuild（Codeシリーズ）：前例あり
    - リリースにバイナリファイルをAssetsとして追加できるのか？
    - ghrコマンドを使ってリリースにファイルを追加しているが、buildspec.ymlでも同じようにできるのか？

すると、CodeBuildでDroneと同じ状態を実現できるかが不明瞭であることが分かったため、検証してみることに。

## CodeBuildでGitHubのリリースにファイルを追加してみる
### 流れ
- CodeBuildのビルドプロジェクトを作成する
  - ブランチのpushをトリガーに起動するよう設定する
![スクリーンショット 2024-12-18 16.53.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616730/500278de-4ecd-31b1-cb06-00e299c0bbf6.png)

- 検証用リポジトリを作成する
- GitHubと連携する
- secrets managerに環境変数を格納する
![スクリーンショット 2024-12-18 16.40.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616730/d678a78c-497a-31d6-c7c4-af9d944313e8.png)
- 環境変数を設定する
  - 値にシークレット名を入れる（タイプはSecrets Managerを選択）
![スクリーンショット 2024-12-20 11.19.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616730/2a117ff8-47bd-7fae-28ca-81b52674d7ea.png)

- IAMロールにポリシーを割り当てる
  - ビルドプロジェクトからサービスロールを開き、secrets managerへの読み取り権限を追加する
- buildspec.ymlを作成する
  - buildspec.ymlの例 ↓      
    - ```yaml
        version: 0.2
        
        env:
        # CodeBuildで設定した環境変数を指定
        secrets-manager:
        GITHUB_TOKEN: dev/rhp/ci/poc
        variables:
        # タグ名
        VERSION: "v1.0.0"
        # リポジトリ指定
        REPOSITORY: "リポジトリ名"
        
        phases:
        install:
        commands:
        # ghrコマンドをインストール
        - curl -L -o ghr.tar.gz https://github.com/tcnksm/ghr/releases/download/v0.17.0/ghr_v0.17.0_linux_amd64.tar.gz
        - tar -xzf ghr.tar.gz
        - mv ghr_v0.17.0_linux_amd64/ghr /usr/local/bin/
        - chmod +x /usr/local/bin/ghr
        
        post_build:
        commands:
        # タグ設定
        - export TAG=$VERSION
        - export GITHUB_API=https://GHEのドメイン/api/v3/
        # ghrコマンド実行
        - ghr -username ユーザ名 -repository $REPOSITORY -token $GITHUB_TOKEN -commitish dev -delete -prerelease -debug $TAG ./dist
        ```

## うまくいかない🤔

実行すると、CodeBuildで401が返ってきたため、権限周りを疑いながら調べてみました。
```
Failed to get draft release: get release tag: invalid status: 401 Unauthorized GET https://リポジトリ/releases?page=1&per_page=100: 401 Bad credentials []
```

- GitHubパーソナルアクセストークンの権限が足りない？
    - 必要な権限はつけたが、うまくいかず

- サービスロールに権限を付与できてない？
    - 必要な権限を付与したが、うまくいかず

- 環境変数の設定の仕方が違う？ → これが原因

    - secrets managerにトークンを保存したときに、キー/値の形式で入れていた
    ![スクリーンショット 2024-12-18 16.40.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616730/d678a78c-497a-31d6-c7c4-af9d944313e8.png)
    - トークンの値を貼り付けるだけで良かった

https://stackoverflow.com/questions/71905312/401-bad-credentials-when-try-to-hook-code-pipeline-with-github


凡ミスが原因でした...。調査を手伝ってくださった先輩に感謝です。
というわけで、リリースに同じリポジトリ内のファイルを添付することに成功しました。

![スクリーンショット 2024-12-18 17.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616730/33a2d103-7323-fcbb-010d-1bab390271f8.png)   
Droneと同様のことがCodeBuildでもできそうです。

## 結論
CodeBuildでうまくいくことがわかったので、GitHub Actionsに比べて比較的大きい処理に向いているCodeBuildに決定しました。
調査はここまでとして、これから実装していこうと思います。

## 学び
一からビルドプロジェクト作成してsecrets managerに環境変数を入れて…は初めてだったので、勉強になりました。

**secrets managerにトークンを保存するときは登録のデフォルトがキー/値型なので必要に応じてプレーンテキストにする**

これを忘れないようにしたいと思います。

AWSの勉強はまだまだですがこれからも学んでいきます。

ここまで読んでくださってありがとうございました。