🐼

Self-hosted Agentを使ってAzure PipelineからプライベートEC2経由でECRにイメージを登録する

2023/03/16に公開

※Zenn初投稿になります

はじめに

Azure Pipelineを利用してコードのビルド・デプロイを行う場合、1つ以上のエージェントが必要になります。

MSドキュメントにはエージェントが以下の3種類あると記載されています。

  • Microsoft によってホストされるエージェント
  • セルフホステッド エージェント(以下SHAgent)
  • Azure Virtual Machine Scale Set エージェント(セルフホステッド エージェントベース)

それらのうち、SHAgentを利用するとAWSのプライベートサブネット上にあるEC2をAzure Pipelineのビルド・デプロイの実行先として登録することができます。

今回は、Azure PipelineからAWSのEC2経由で制限されたECRリポジトリに対して、コンテナイメージをPushする構成を検証してみました。


参考リンク

今回検証する上では以下の記事がかなり参考になりました。


前提条件

以下の作業は事前に完了している前提とします。

  • PAT作成済み(Agent登録時に利用)
  • Azure DevOps Organization作成
  • Azure DevOps プロジェクト作成
  • Azure Reposリポジトリ作成
  • Azure Pipeline用コード作成(GitHub)
  • EC2(Amazon Linux 2)・NATGW構築
  • EC2へのgit/dockerのインストール
  • ECRリポジトリ作成
  • ECRポリシー設定


構成図

MSドキュメントにも記載がある通り、Azure PipelineとSHAgent間の通信はSHAgentからポーリング接続を行うようになっているため、EC2にはAzure PipelineへのOutbound通信が許可されている必要があります。
そのため、以下のようにEC2の前段にNATGatewayを配置し、インターネットに出れる構成にします。


実施内容

概要

作業内容としては以下の流れで実施します。

  1. エージェントプール作成
  2. SHAgentインストールコマンド確認
  3. EC2ログイン、SHAgentインストール・実行
  4. エージェント登録確認
  5. パイプライン作成
  6. パイプライン実行
  7. イメージPush確認(ECRリポジトリ)


エージェントプール作成

まずはAzure DevOps Organizationsのコンソールにログインして、左下の[Organization settings]から設定画面に遷移します。


左側メニューのPipelinesに[Agent pools]項目があるので、そこからエージェントプール一覧を表示し、右上の[Add pool]ボタンから新しいエージェントプールの作成を行います。


エージェントプール作成画面では、プールタイプを[Self-hosted]、プール名にわかりやすい名前を入力して、作成ボタンを押下すると、新しいエージェントプールが作られます。
permissinosはpipelinesへの権限のみチェックを付けておきます。


作成したエージェントプールをクリックしてAgentsタブを押下すると、プールに登録されているAgentが確認できます。
※事前検証で設定済みだったので、画面は登録後のものです


SHAgentインストールコマンド確認

作成したエージェントプール画面の右上の[New agent]ボタンを押下します。


agentをインストールするコマンドが表示されるため、インストール先のOS等によって適切なものを確認します。
今回はAmazon Linuxにインストールするので、Linuxのコマンドを確認してメモしておきます。
agentファイルだけダウンロードリンクになっているので、コマンド実行前にEC2側でダウンロードが必要になります。


実際に実行したコマンドは以下になります。
※config.shだけ対話入力が必要なので注意が必要です。

$ whoami; date
$ cd ~
$ wget https://vstsagentpackage.azureedge.net/agent/2.217.2/vsts-agent-linux-x64-2.217.2.tar.gz -P ~/Downloads/
$ ls -l ~/Downloads/
$ mkdir myagent && cd myagent
$ tar zxvf ~/Downloads/vsts-agent-linux-x64-2.217.2.tar.gz
$ ./config.sh
$ ./run.sh


EC2ログイン、SHAgentインストール・実行

Session Manager経由でAWSマネジメントコンソールからEC2にログインして、agentインストールコマンドを順番に実行していきます。


config.shを実行すると対話形式で7回入力する必要があります。
入力内容は以下になります。

    1. 入力 (Y/N) Team Explorer Everywhereの使用許諾契約を今すぐ受け入れるか? → Y
    1. サーバーURLを入力 → https://dev.azure.com/xxxxxxxx
    1. 認証方法を入力 → PAT
    1. PAT情報を入力 → xxxxxxxxxxxxxxxxxxxxxxxxxxxx ※後述
    1. 追加するエージェントプールを入力 → [先ほど作成したエージェントプール名]
    1. 追加するエージェント名を入力 → linux-agent
    1. 作業ディレクトリを入力(デフォルトは_work) → _work ※未入力でEnterでも可


config.shの設定が完了したら、run.shを実行します。
run.shが実行されるとAzure DevOpsとの通信が確立されて、Azure側のエージェントプールに先ほど登録したエージェント名が表示されます。
※最初のほうにも記載しましたが、SHAgentはポーリング接続でJobの実行を確認するため、常時起動させる場合はバックグラウンドで動くように設定しておく必要があります。


※PATについて

PATとはPersonal Access Tokenの略で、エージェント登録コマンドを実行しているユーザーが、Azure DevOpsのユーザーであることを保証するためのトークンになります。
PATの作成方法は他の方が記事にされていると思うので、そちらを確認して作成してください。


エージェント登録確認

EC2側でリッスン状態になった後、Azure DevOpsコンソールからエージェントプールを見ると、先ほど登録した内容でエージェントが登録されたことが確認できます。


パイプライン作成

エージェントの登録が確認出来たら次はAzure Pipelineから、以下の流れでパイプラインの作成を行っていきます。
※途中、既にパイプライン作成済みのAzure Reposのリポジトリを選択している関係で最後のyamlファイル名に[-1]がついてますが、リポジトリに同名ファイルがなければ[-1]無しの[azure-pipelines.yml]というファイル名になると思います。


Azure Pipelineの画面から[New pipeline]ボタンを押下します。


ソースコードが格納されているGitリポジトリを指定します。


対象のリポジトリ名を選択します。


pipelineでビルドデプロイする環境を選択します。
今回はDockerfileを使用してイメージをECRにPushするので、一番上のDockerを選択します。


Dockerfileはソースコードに含まれているファイルを指定します。


パイプラインの実行はまだしないので、Saveボタンを押下します。


パイプラインを作成するとリポジトリにazure-pipeline.ymlファイルが追加されることになるので、コミット先のブランチを指定して保存します。


パイプライン保存後、自動作成されるazure-piplnies.ymlを以下のように修正します。
こちらにソースコード置いてます

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
  branches:
    include:
      - main

stages:
- template: templates/build.yml


※実行する前に:パイプライン環境変数設定

本記事では、ビルド・デプロイ時に指定するAWSリージョン名とECRリポジトリ名をパイプラインの環境変数に設定するように構成しているので、実行前にコンソールから登録しておきます。


※実行する前に:ECRにPushするIAMユーザー情報登録

Azire PipelineからECRリポジトリにPushする場合、Push操作を行うIAMユーザーの情報を事前に登録することが可能です。
Azure DevOpsコンソールの[Project Settings]からサービス接続の項目を選択し、[New service connection]ボタンから新しく接続情報を追加します。


IAMユーザーのアクセスキーとシークレットアクセスキーの入力は必須ですが、オプションとしてAssume Roleにも対応しているようでした。


サービス名まで入力できたら[Save]ボタンを押下して、サービスを作成します。


templates/build.ymlファイル内で以下のように指定して、登録したIAMユーザーの認証情報をJobパラメータとして渡すことが可能です。


パイプライン実行

Azure DevOpsのコンソールから作成したパイプラインを開いて、[Run pipeline]ボタンを押下してパイプラインを実行します。


しばらく待っているとJobが正常終了することが確認できました。


SHAgent側でもJobの実行と結果が出力されていました。


イメージPush確認(ECRリポジトリ)

ECRリポジトリを見ると、イメージが登録されていることが確認できました。


ECRリポジトリは特定のIPかVPCEndpointID以外からのアクセスを拒否するように設定済みのため、SHAgentをインストールしたプライベートサブネット上のEC2からデプロイされたとみて間違いなさそうです。


おわりに

前にGitLab Runnerを構築してECR/ECSにビルド&デプロイする検証(URL)をしていたので、Azure Pipelineのyamlファイルのイメージはすんなり理解できました。

普段はAWSメインでAzureを使うことはないのですが、たまたま機会があったので自分の備忘として書いてみました。
Azure側の理解ができていないところもあるので、もし説明や設定内容が間違っていたらご指摘いただけると助かります。

この記事がどなたかの参考になれば幸いです。

GitHubで編集を提案

Discussion