EC2 Image Builder で CloudBeaver の AMI を作成する

こんにちは。インサイトテクノロジーの松尾です！

以前の投稿で、EC2起動時のユーザーデータを使用してCloudBeaverを簡単に起動する方法を紹介しました。

https://qiita.com/takumats/items/76bb1db8a0ffccc2aad1

ただ、毎回、起動時に指定するのも面倒なので、EC2 Image Builderを使ってAMIを作成する方法を紹介します。

※以前の投稿の方法でEC2を起動した後にそれをAMIにして保存すればいいだけとも言えなくもないですが、本投稿ではEC2 Image Builderを使ってみたかったのであえてEC2 Image Builderを使っています。

## EC2 Image Builderとは

AMIを作るためのCI(一連のスクリプトを自動化したもの)のサービスのようなイメージです。

https://docs.aws.amazon.com/imagebuilder/latest/userguide/what-is-image-builder.html

今まで、イメージ作成を手作業でやっていたようなケースでは、Image Builderに任せることで、自動化できる(楽をできる)ようなケースも出てくるのではないでしょうか。一方、すでにAMI作成をCIなどで実施してるような場合には、そこまで恩恵はないかもしれませんが、開発チームの状況によってはCI側にあるよりはAWSサービスでなるべく構築しておきたいというケースもあるでしょう。

では早速やってみましょう。

## コンポーネントを作成

EC2 Image Builderでは、コンポーネントを組み合わせてレシピを作成し、パイプラインでレシピを実行してイメージを作成するフローとなります。コンポーネントはもともと準備されているものもありますが、独自のソフトウェアインストールなどは定義する必要があります。自社のアプリなどであれば、インストールイメージをS3からダウンロードしてインストーラを実行する、といった手順を記載したコンポーネントを作成することになります。

CloudBeaverの場合には公開されているイメージを使用しますので、以前にユーザーデータの定義でEC2を起動したときと同様の以下の内容をコンポーネントで定義すればよさそうです。

```bash
dnf -y install docker
systemctl enable --now docker
mkdir /opt/cloudbeaver
docker run -d --name=cloudbeaver -p 18080:8978 -v /opt/cloudbeaver:/opt/cloudbeaver/workspace --restart always dbeaver/cloudbeaver:latest
```

EC2 Image Builderのメニューでコンポーネントを選択し、コンポーネントの作成を起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/990638cf-c8ad-ca6e-c20d-93656398ee1e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/d5751d85-4676-9c56-0fe6-fe056538b135.png)

コンポーネントはymlで定義します。例を使用する、を選択すると、サンプルエディタに反映されるので、それを修正すればよさそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/d83aa0c1-a00c-0c2b-f372-0270af16ed70.png)

buildフェーズのcommandsにインストールで実施したい作業ステップを記載すればよさそうです。
validateとtestもきちんと何かを書くべきでしょうが、ここはこのまま放置しておきましょう。

## レシピの作成とパイプラインの実行

レシピをあらかじめ作成してからパイプラインを実行することもできますが、ここではパイプライン実行時に作成することとします。

Image Builderのメニューからイメージパイプラインを選択し、イメージパイプラインの作成を起動します。適当な名前を選択し、スケジュールは手動を選択して次へ進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/749fdc88-1d62-2dd3-74b3-faed3bdb52b3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/c42e6bbc-6228-2845-205f-e7e77fd34ede.png)

新しいレシピを作成する、を選択します。ベースのイメージにはAmazon Linux 2023の最新イメージを使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/efc34446-6e1e-3456-3f19-c5ea5ddebad6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/eb38c2d1-04be-42d2-5bb1-4fa32703f0a4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/9d8e1e6a-4636-113b-92bf-b3c6ebe3b34b.png)

コンポーネントはすでに用意されているOSの更新と、先ほど作成したCloudBeaverインストールを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/d9252b26-7bb3-67f3-d72c-5a2b77cfbeb6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/c239ecb8-5489-991d-f843-1526b2bc1479.png)

2つのコンポーネントが選択された状態となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/3a5c4443-39cd-873d-6fa2-067d2d63fe3c.png)

テストコンポーネントはスキップし、ストレージオプションも変更せず、次へ進みます。

イメージ作成プロセスの定義、インフラストラクチャ設定を定義する、ディストリビューション設定を定義する、はデフォルトから変更せずそのまま次へ進み、最後の確認で、パイプラインを作成する、を実行します。

パイプラインがエラーなく作成できたら、実行しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/c322a2b1-15ed-0c07-f679-ded29a2c8319.png)

イメージ作成の状況はCloudWatch Logsへ出力されるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/d1254828-2013-c34a-0ffe-c63014035b5f.png)

そして、最後まで終わったころにはAMIも作成されておりました。

そして、そのAMIからEC2を起動すると、期待通り、CloudBeaverが起動することを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/939b9343-00fc-33c6-e68b-dca17c375edb.png)

## おわりに

以前EC2起動時のユーザーデータを使用してCloudBeaverを起動したものを、今回はEC2 Image Builderを使用してAMIを作成してみました。数コマンドからなるものであればEC2起動時に指定する方がお手軽かもしれませんが、より複雑な処理を指定する必要がある場合にはユーザーデータでは限界がありそうです。また、内容によってはAMIにしておいた方が再利用性も高いでしょう。

今回は非常にシンプルなコンポーネントを定義しただけですが、EC2 Image Builderではより複雑な処理もできますので、今後活用していきたいと思います。