プライベートでは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日中の公開は間に合わなかったけど笑)