zaki work log

作業ログやら生活ログやらなんやら

[Ansible Builder / AWS] CodeCommit + CodeBuild 環境でEEの自動ビルドとECRへpush (起動は手動)

プライベートではGitHub Actions使ったEEの自動ビルドを1年前に試したけど、業務だとCodeCommit環境を使ってたりするので、せっかくなのでAWSのサービスを使ったビルド環境を試してみた。

初めに軽く検索した感じだと、CodeBuildではコンテナで処理がされるという情報を見かけたので、コンテナビルドはどうするのかと思ったけど、普通にCodeBuild内でコンテナビルドも動くようだ。

やりたいことは以下。

  • EEのソースはCodeCommitのものを使用
  • Ansible Builderをインストール
  • Red Hat RegistryからEEとRunnerのベースイメージをpull
  • イメージビルド
  • ビルドが完了したらECRへpush

これをCodeBuildを使って処理する。

CodeCommit

ポイントはビルドの定義を行うbuildspec.ymlファイル。
ほかは基本的には特記事項なし。

Buildspec

buildspec.ymlファイルを作成。
中身はこんな感じ。 この中身に従ってCodeBuildが動作する。 GitHub Actionsにおける.github/workflows/main.ymlみたいな位置づけのファイル。

rh_account,rh_username,rh_passwordについては、あとでSecret Managerで使うキー文字列。

version: 0.2

env:
  secrets-manager:
    USERNAME: rh_account:rh_username
    PASSWORD: rh_account:rh_password

phases:
  pre_build:
    commands:
    - pip install ansible-builder
    - docker login registry.redhat.io -u ${USERNAME} -p ${PASSWORD}
    - aws ecr get-login-password --region ap-northeast-1 | docker login ********.***.ecr.ap-northeast-1.amazonaws.com --username AWS --password-stdin

  build:
    commands:
    - echo "build image"
    - ansible-builder build -t ********.***.ecr.ap-northeast-1.amazonaws.com/sample-repository:develop

  post_build:
    commands:
    - echo "push image to ecr"
    - docker push ********.***.ecr.ap-northeast-1.amazonaws.com/sample-repository:develop

execution-environment.yml

お題はterraformを実行できるEEを作る。 今のところ必要がないので定義ファイルはver1のまま。

version: 1
build_arg_defaults:
  EE_BASE_IMAGE: registry.redhat.io/ansible-automation-platform/ee-minimal-rhel8:2.16.5-1
  EE_BUILDER_IMAGE: registry.redhat.io/ansible-automation-platform/ansible-builder-rhel8:1.2.0-75

ansible_config: 'ansible.cfg'

dependencies:
  galaxy: requirements.yml
  python: requirements.txt
  system: bindep.txt

additional_build_steps:
  prepend:
    - RUN microdnf install -y yum-utils
    - RUN yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
    - RUN dnf -y install terraform

requirements.yml

---
collections:
- community.general

bindep.txt

git

CodeBuild

プロジェクトを作成

プロジェクト名に任意の名前を指定。
ソースプロバイダに「AWS CodeCommit」を指定、リポジトリとブランチを入力する。
(ちなみにGitHubなど外部のリポジトリも選択可能)

環境はデフォルトでOK (というかデフォルト以外の選択を試していない)
「追加設定」をクリックし、必要に応じてパラメタとして使用する環境変数を設定する。
今回は、registry.redhat.ioにログインするための認証情報を外部からセットするため、環境変数でなくSecret Managerを使用する予定。これも環境変数のところで「タイプ」から「Secret Manager」を選択することで使用できる。
Secret Manager側が未設定なので、とりあえず今は何も設定せずに進める。(あとから編集可能)
ほかにはビルドするマシンサイズ(CPU/メモリ)を選択することもできる。デフォルトはRAM3GB/2vCPUs

Buildspecは「buildspecファイルを使用する」を選択。

他はデフォルトで「ビルドプロジェクトを作成する」を押下。

作成完了したら、「サービスロール」の文字列を確認しておく。
(次のSecret Managerからのアクセス許可で使用する)

Secret Managerの作成とアクセス権の設定

registry.redhat.ioにログインするための認証情報を作成する。

「新しいシークレットを保存する」から、「その他のシークレットのタイプ」を選択。
key/value形式のデータを登録できるので、ユーザー名とパスワードそれぞれキーと値を入力。

「暗号化キー」はデフォルトのまま「次」押下。

シークレットの設定で名称を入力し、「リソースのアクセス許可」で、CodeBuildからのアクセスを許可する編集を行う。
「許可を編集」を押下し、"Statement"へ以下を入力する。

{
    "Version":"2012-10-17",
    "Statement": [ {
        "Effect" : "Allow",
        "Principal" : {
            "AWS" : "CodeBuildのサービスロールのARN"
        },
        "Action" : "secretsmanager:GetSecretValue",
        "Resource" : "*"
    } ]
}

「次」で進んだ先はデフォルトでOKなので、そのまま「保存」でSecretを作成する。

※ ちなみに環境変数だと機密情報が「見えてしまう」のでSecret Managerを使おう、という文脈のはずだけど、他のIAMユーザーでもAWSのマネジメントコンソールからSecret Managerに保存している値はどうも参照できるっぽいので、個人に割り当てられてるパスワード情報とかは…どうすればいいんだ?

CodeBuildでSecret Manager値参照の設定

プロジェクトの編集の、環境の追加設定以下にある環境変数パートで、以下入力

名前 タイプ
RH_ACCOUNT (任意) シークレットの名前 (上の例だとrh_account) Secret Manager

これを入力して「プロジェクトを更新する」押下で保存。

CodeBuildからECRのアクセス権の設定

ビルドしたイメージをpushするために、CodeBuildの処理内からECRへのアクセス権を設定する。
具体的にはaws ecr get-login-passwordを使えるようにする設定。 (無いとno identity-based policy allows the ecr:GetAuthorizationToken actionエラー)

まず作成したCodeBuildのプロジェクトのサービスロール(リンクになってる)をクリックし、サービスロールのページへ移動する。

サービスロールの設定では「許可ポリシー」が(デフォルトのポリシーと、↑でセットしたSecret Managerの)2つセットされてるはずで、ここでさらに「許可を追加」->「ポリシーをアタッチ」押下。

検索欄にcontainerregistryを入力して出てくるAmazonEC2ContainerRegistryPowerUserをチェックして「許可を追加」する。

これで準備OK

ビルド

CodeBuildのプロジェクトに戻り、「ビルドを開始」を押下。

問題がなければansible-builderのインストール、各コンテナレジストリへのログイン、ビルドが行われ、最後にイメージをECRへpushするところまで処理される。

ECRでもpushされたイメージを確認できる。

まとめ

現状まだ処理の起動はボタンぽちが必要だけど、それまでAnsible Builderを用意して、コードをGitから持ってきて、ビルドのコマンドラインを入力・tagを設定してpushという手順だったのが、ボタン押下1アクションで全部終わるのはだいぶラクチン。しかもローカルPCでやるより断然速い。(スペックの問題)

Gitのpushやtagの作成に反応させるにはCodeBuildの設定にはなさそうだったので、おそらくCodePipelineを使うと思う。これもそのうちやってみる。

ちなみに一番ハマったのはSecret Managerからの値の取得だった。キーの関係がよくわからず試行錯誤。。


ところで1年前に書いたGitHub ActionsのEEイメージビルド、これも4月16日だったんだねぇ(16日中の公開は間に合わなかったけど笑)

zaki-hmkc.hatenablog.com

参考

docs.aws.amazon.com

docs.aws.amazon.com

docs.aws.amazon.com

dev.classmethod.jp

qiita.com