[アップデート] EC2 Image Builderが新しくコンテナイメージをサポートしました #reinvent

こんにちは。サービスグループの武田です。昨年のre:Invent 2019で発表された、EC2のイメージ作成を自動化するサービスEC2 Image Builderが、新しくコンテナイメージをサポートするようになりました。
2020.12.19

こんにちは。サービスグループの武田です。

昨年のre:Invent 2019で発表された、EC2のイメージ作成を自動化するサービスEC2 Image Builderが、新しくコンテナイメージをサポートするようになりました。コンテナジャーニー歓喜!

さっそくコンテナイメージをビルドするパイプラインを作成してみましたのでお届けします。

まずはリポジトリの作成から

パイプラインを作成する前に、ビルドしたコンテナイメージを保存するリポジトリを用意します。今回は次の手順でECRにリポジトリを作成しました。

ECRにアクセスします。

プライベートリポジトリとし、名前はtest-image-builderとします。

イメージスキャンは有効にしておきます。最後に[リポジトリを作成]をクリックします。

リポジトリが作成できました。

パイプラインを作成する

続いてパイプラインを作成していきましょう。基本的にはウィザードのとおりで問題ないのですが、一部修正の必要な箇所がありましたので、そこだけ注意が必要です。

まずはEC2 Image Builderのページにアクセスをし、[イメージパイプラインを作成する]ボタンをクリックします。

いくつかのステップに分かれていますね。ステップ1ではパイプラインの設定をしていきます。パイプライン名はtest-image-pipelineとし、説明はテストとしました。

ビルドスケジュールおよび更新設定を指定できます。これは利用するシチュエーションに合わせて調整が必要な箇所となりますが、今回は日本時間で月曜日の2時にスケジュールしました。更新設定はシンプルに更新をチェックしないようにしました。

ステップ2ではイメージレシピを選択していきます。どのようなイメージを作成するのかを設定する箇所で、既存のレシピを使い回すか、新しく作成します。今回がはじめてですので、新しいレシピを作成します。イメージ出力はもちろんコンテナイメージを選択します。

レシピ名はtest-recipeとし、バージョンは0.0.1としました。特に深い理由はありません。

続いてソースイメージの選択です。DockerfileのFROMに指定するものというとわかりやすいでしょうか。ここではECRでホストされているイメージ、Docker Hubでホストされているイメージ、そしてその他の管理されているイメージの3つから選べるようになっています。今回はイメージのFROMでよく使われているUbuntuにしました。画面上では、まず管理対象イメージを選択するを選択し、OSはUbuntuを選択します。

イメージのオリジンではクイックスタート(Amazon 管理)を選択し、イメージ名はUbuntu 20 x86_latest。そして自動バージョニングオプションは利用可能な最新のOSバージョンを使用するを選択しました。バージョンについては依存関係などを理由に簡単に上げられないケースもありますので、実運用する際にはバージョンを固定した方が安心でしょうか。

次にイメージに含めるコンポーネントを選択します。事前に用意されているものを入れることもできますし、カスタムコンポーネントを作成しておきそれを入れることもできます。今回はビルドコンポーネントとしてAWS CLI v2Python3を選択しました。

ビルド後に、テストに使用するテストコンポーネントを選択します。いくつか提供されていますが、今回はsimple-boot-test-linuxを選択しました。

Dockerfileを指定します。デフォルトのDefine Dockerfile templateは中身真っ白で最初とまどいますが、慌てずUse exampleを指定しましょう。何やらテンプレートっぽい内容が表示されますが、これで問題ありません。どうやらビルド時に、ここまで指定したコンポーネントなどにsedで置換されるしくみのようです。

ビルドしたイメージを保存するリポジトリを指定します。最初に作成したtest-image-builderを入力します。

ステップ3ではインフラストラクチャ、つまりイメージをビルドする環境の指定をします。ページ上部に説明がありますが、Image Builderのパイプラインが実行されるとアカウント内でEC2インスタンスが起動され、そこでビルドが行われます。そのEC2インスタンスにアタッチするロールなどの指定をするというわけです。今のところロールなどは一切ないため、サービスデフォルトを指定しました。後で分かることですが、どうやらこのウィザードで作成されたロールには 権限が足りない ようです。そのため後でロールに権限を追加します。

ステップ4はディストリビューション、つまりイメージの配信先の設定です。ここでもサービスデフォルトを指定しました。

最後に確認画面が表示され、内容に問題がなければ[パイプラインを作成する]をクリックしましょう。

無事に作成できました。アクションから手動でパイプラインを実行できるのですが、このままでは失敗します。先にロールの権限を修正しましょう。

IAMのページを開き、EC2InstanceProfileForImageBuilderロールの詳細を開きます。

ポリシー名は任意で、新しいインラインポリシーをアタッチします。s3:*はログの出力先としてS3を設定できるので、ログを出力する場合に必要となりました(出力しないなら不要)。実際はPutObjectだけで十分なのでしょうか。またECRにプッシュしますので、その権限も必要です。これも精査はしていないのですが、経験上いくつか権限が必要なはずですので、ecr:*でまるっと付与しています。最後に先ほど定義したコンテナレシピを取得する権限も追加する必要がありました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "ecr:*",
                "imagebuilder:GetContainerRecipe"
            ],
            "Resource": "*"
        }
    ]
}

準備ができました。パイプラインを手動で実行すると環境が構築されます。

EC2のページを見てみると、インスタンスが作られていることも確認できます。

無事にビルドに成功しました(失敗がたくさんあるのは、まぁ察してください)。

ECRを見てみると、ビルドしたイメージがプッシュされていました!

まとめ

これまでEC2のAMIを自動作成するサービスとしてImage Builderがありましたが、コンテナイメージもサポートされたことでより用途が広がりそうですね!コンテナイメージのCI/CD環境を作ろうか検討していた方はぜひImage Builderを利用してみてはいかがでしょうか。