Azure DevOps パイプラインからプライベート Amazon EKS クラスターにワークロードをデプロイする - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Azure DevOps パイプラインからプライベート Amazon EKS クラスターにワークロードをデプロイする

Amazon Web Services、Mahendra Revanasiddappa

概要

このパターンは、Azure DevOps パイプラインからプライベート Amazon Elastic Kubernetes Service (Amazon EKS) クラスターに継続的インテグレーションおよび継続的デリバリー (CI/CD) を実装する方法を示しています。Amazon EKS クラスターのプライベート API サーバーエンドポイントに移行することにより、セキュリティ体制を強化している組織が直面する重大な課題に対処します。

パブリックエンドポイントは Kubernetes API サーバーをインターネットに直接公開するため、悪意のある攻撃者のターゲットとなりうる大きなアタックサーフェスが発生します。プライベートエンドポイントに切り替えると、クラスターのコントロールプレーンへのアクセスが顧客の仮想プライベートクラウド (VPC) 内に限定されます。

Amazon EKS クラスターをプライベート API エンドポイントに移行するとセキュリティが大幅に強化されますが、Azure DevOps などの外部 CI/CD プラットフォームに接続の課題が生じます。プライベートエンドポイントにアクセスできるのは、クラスターの VPC またはピアネットワーク内からのみです。したがって、 AWS プライベートネットワーク外で動作する標準の Microsoft がホストする Azure DevOps エージェントは、Kubernetes API サーバーに直接到達できません。これらのエージェントで実行されている kubectl や Helm などのツールに依存する一般的なデプロイワークフローは、クラスターへの接続を確立できないため、中断されます。

この問題を解決するために、このパターンでは、プライベート Amazon EKS クラスター内でセルフホスト型の Azure DevOps エージェントを使用して効率的なアプローチを説明します。このソリューションは、セキュリティ要件を維持しながら、優れたコスト最適化、運用効率、スケーラビリティを提供します。このアプローチは、特に、パフォーマンスやセキュリティを犠牲にすることなく、マルチクラウド DevOps プロセスを合理化しようとする企業にメリットをもたらします。

前提条件と制限

前提条件

  • アクティブ AWS アカウント。

  • AWS Command Line Interface (AWS CLI) バージョン 2.13.17 以降がインストールされています。

  • kubectl バージョン 1.25.1 以降がインストールされていること。

  • 名前空間、シークレット、デプロイを作成するアクセス権限を持つプライベート Amazon EKS クラスターバージョン 1.24 以降が作成されていること

  • インターネットへのアウトバウンド接続を持つ Amazon EKS クラスター内のワーカーノード。これは、ワーカーノードで動作している Azure DevOps エージェントを Azure DevOps エージェントプールに接続できるようにするものです。

  • GitHub アカウントが作成されていること

  • サービス接続を設定できるアクセス権を持つ Azure DevOps プロジェクト (Azure Pipelines と外部サービスまたはリモートサービス間の認証された接続) が作成されていること

  • 前のポイントで説明した Azure DevOps プロジェクト用にインストールされた AWS Toolkit for Azure DevOps バージョン 1.15 以降。インストール手順は、Visual Studio Marketplace の「AWS Toolkit for Azure DevOps」を参照してください。

制限事項

アーキテクチャ

このパターンでは、以下が作成されます。

  • Amazon ECR リポジトリ – Amazon Elastic Container Registry (Amazon ECR) リポジトリは、Azure DevOps エージェントとデプロイされたサンプルアプリケーションを使用して Docker イメージを保存します。

  • Azure DevOps エージェントプール – Azure DevOps セルフホスト型エージェントプールは、プライベート Amazon EKS クラスターで動作するエージェントを登録します。

  • IAM ロール - プライベート Amazon EKS クラスターで実行されているエージェントに必要なアクセスを提供する Azure サービス接続の AWS Identity and Access Management (IAM) ロール。

  • Azure DevOps サービス接続 – パイプラインジョブが AWS のサービスにアクセスするために必要なアクセスを提供する IAM ロールを使用する Azure DevOps アカウントのサービス接続。

次の図は、プライベート Amazon EKS クラスターにセルフホスト型の Azure DevOps エージェントをデプロイし、同じクラスターにサンプルアプリケーションをデプロイするアーキテクチャを示しています。

プライベート Amazon EKS クラスターへのセルフホスト型の Azure DevOps エージェントとサンプルアプリケーションのデプロイ。

この図表は、次のワークフローを示しています:

  1. セルフホスト型の Azure DevOps エージェントを Amazon EKS クラスター内のデプロイとしてデプロイします。

  2. Azure DevOps エージェントは、認証のための個人アクセストークン (PAT) を使用して Azure DevOps アカウントのエージェントプールに接続します。

  3. Azure Pipelines は、GitHub リポジトリのコードを使用して、デプロイするパイプラインを設定します。

  4. パイプラインは、パイプライン設定で設定されたエージェントプールからのエージェントで動作します。Azure DevOps エージェントは、Azure DevOps アカウントに常にポーリングすることにより、パイプラインのジョブ情報を取得します。

  5. Azure DevOps エージェントは、Docker イメージをパイプラインジョブの一部として構築し、そのイメージを Amazon ECR リポジトリにプッシュします。

  6. Azure DevOps エージェントは、webapp という名前空間のプライベート Amazon EKS クラスターにサンプルアプリケーションをデプロイします。

ツール

ツール

その他のツール

  • Docker は、オペレーティングシステムレベルの仮想化を使用してソフトウェアをコンテナで配信するサービスとしてのPlatform as a Service (PaaS) 製品のセットです。

  • kubectlは、Kubernetes クラスターに対してコマンドを実行するためのコマンドラインインターフェイスです。

コードリポジトリ

ベストプラクティス

エピック

タスク説明必要なスキル

Azure DevOps の組織 GUID を検索する。

Azure DevOps アカウントにサインインし、次の URL (https://dev.azure.com/{DevOps_Org_ID}/_apis/projectCollections?api-version=6.0) を使用して組織の GUID を検索します。この URL で、{DevOps_org_ID} は Azure DevOps の組織 ID に置き換えてください。

AWS DevOps

AWS アカウントで IdP を設定する。

Azure サービス接続 AWS アカウント 用に で ID プロバイダー (IdP) を設定するには、次の手順を実行します。

  1. にサインインし AWS マネジメントコンソール、https://console.aws.amazon.com/iam/ で IAM コンソールを開きます。

  2. 左側のペインで、[ID プロバイダ] を選択します。

  3. [Add Provider (プロバイダを追加] を選択します。

  4. [プロバイダーのタイプ] として [OpenID Connect] を選択します。

  5. [プロバイダーの URL] に、Azure DevOps の発行者 URL を入力します。Azure DevOps の各テナントには通常、https://vstoken.dev.azure.com/{OrganizationGUID} の形式を使用する一意の OrganizationGUID があります。{OrganizationGUID} は Azure DevOps の組織 ID に置き換えてください。

  6. [対象者] に、「api://AzureADTokenExchange」と入力します。これは Azure DevOps の固定値です。

  7. [Add Provider (プロバイダを追加] を選択します。

  8. 次のタスクで使用するために、新しく作成されたプロバイダーの ARN を書き留めておきます。

詳細については、OpenID Connect を使用して Azure DevOps AWS から にフェデレーションする方法」を参照してください。

AWS DevOps

AWS アカウントで IAM ポリシーを作成する。

Azure DevOps パイプラインで使用される IAM ロールに必要なアクセス権限を付与する IAM ポリシーを作成するには、次の手順を実行します。

  1. IAM コンソールの左側のペインで、[ポリシー] を選択します。

  2. [ポリシーを作成] を選択します。

  3. [アクセス許可を指定] には [ポリシーエディタ][JSON] を選択します。デフォルトの JSON ポリシーを次の JSON に置き換えます。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Action": [ "ecr:*", "eks:DescribeCluster", "eks:ListClusters" ], "Resource": "*" } ] }
  4. [次へ] を選択します。

  5. [ポリシー名] に IAM ポリシーの名前を入力します。このパターンでは、「ADO-policy」という名前を使用します。

  6. [Create policy] (ポリシーの作成) を選択します。

AWS DevOps

AWS アカウントで IAM ロールを作成する。

Azure サービス接続 AWS アカウント 用に で IAM ロールを設定するには、次の手順を実行します。

  1. IAM コンソールの左側のペインで [ロール] を選択します。

  2. [ロールの作成] を選択してください。

  3. [信頼されたエンティティタイプ] で、[ウェブアイデンティティ] を選択します。

  4. ドロップダウンリストから正しい IdP を選択します。IdP 名は vstoken.dev.azure.com/{OrganizationGUID} で始まります。

  5. [対象者] ドロップダウンリストで、api://AzureADTokenExchange を選択します。

  6. このロールを 1 つのサービス接続のみに制限するには、条件を追加します。[条件] [条件を追加] を選択し、[キー]vstoken.dev.azure.com/{OrganizationGUID}:sub を選択します。[条件][StringEquals] を選択します。[値] には sc://{OrganizationName}/{ProjectName}/{ServiceConnectionName} の形式を使用します。ServiceConnectionName には、aws-sc を使用します。このサービス接続は次のタスクで作成します。

  7. [次へ] を選択します。

  8. [許可を追加] には、前のタスクで作成したポリシーである [ADO-policy] を選択します。

  9. [次へ] を選択し、[ロール名] に「ado-role」と入力します。[信頼されたエンティティを選択] で、次の信頼ポリシーを使用します。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::{account_id}:oidc-provider/vstoken.dev.azure.com/{OrganizationGUID}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "vstoken.dev.azure.com/{OrganizationGUID}:aud": "api://AzureADTokenExchange", "vstoken.dev.azure.com/{OrganizationGUID}:sub": "sc://{OrganizationName}/{ProjectName}/{ServiceConnectionName}" } } } ] }

ポリシーで、次のプレースホルダーの情報を指定します。

  • {account_id} - AWS アカウント ID

  • {OrganizationGUID} – Azure DevOps の組織 GUID

  • {OrganizationName} – Azure DevOps の組織名

  • {ProjectName} – Azure DevOps のプロジェクト名

  • {ServiceConnectionName} – Azure DevOps のサービス接続名。aws-sc を使用します。このサービス接続は次のタスクで作成します。

AWS DevOps

Azure DevOps アカウントでサービス接続を作成する。

Azure サービス接続を設定するには、次の手順を実行します。

  1. Azure DevOps プロジェクトで、[プロジェクト設定][サービス接続] を選択します。

  2. [New service connection] を選択し、サービス接続のタイプを aws として選択し、[次へ] を選択します。

  3. [Role to Assume] に、IAM ロールの arn ado-role を入力します。ado-role は、前のタスク AWS アカウントで IAM ロールを作成するで作成しました。

  4. [OIDC を使用] チェックボックスをオンにします。

  5. [Service connection name] の場合、タスクプロパティに「aws-sc」と入力します。

  6. [保存] を選択します。

詳細は、Microsoft ドキュメントの「Create a service connection」を参照してください。

AWS DevOps

Amazon EKS 設定ファイルに IAM ロールを追加する。

IAM ロールには、Amazon EKS クラスターで必要なオペレーションを実行するためのアクセス権限が必要です。パイプラインロールであるため、IAM ロールでクラスター上のほぼすべてのタイプのリソースを管理できる必要があります。そのため、このロールには system:masters グループアクセス権限が適しています。

必要な設定を Kubernetes 内の aws-auth ConfigMap に追加するには、次のコードを使用します。

- groups: - system:masters rolearn: arn:aws:iam::{account_id}:role/ADO-role username: ADO-role

を AWS アカウント ID {account_id}に置き換えます。

詳細は、Amazon EKS ドキュメントの「Amazon EKS で IAM を使用する方法」を参照してください。

AWS DevOps
タスク説明必要なスキル

セルフホスト型エージェントプールを作成する。

Azure DevOps アカウントでセルフホスト型エージェントプールを設定するには、次の手順を実行します。

  1. Azure DevOps アカウント組織にサインインします。

  2. [Azure DevOps Organization] を選択します。

  3. お使いの Azure DevOps プロジェクトを選択します。

  4. [プロジェクト設定] を選択します。

  5. [Agent pools] を選択します。

  6. [Add pool] を選択します。

  7. [Self-hosted] を選択します。

  8. [Name] に「eks-agent」と入力します。

  9. [Grant access permission to all pipelines] のチェックボックスをオンにします。

  10. [作成] を選択します。

詳細については、Microsoft ドキュメントの「Create and manage agent pools」を参照してください。

タスク説明必要なスキル

Amazon ECR リポジトリを作成します。

Azure DevOps エージェントとサンプルアプリケーション (webapp) をプライベート Amazon EKS クラスターにデプロイするために使用される Docker イメージは、Amazon ECR リポジトリに保存する必要があります。Amazon ECR リポジトリを作成するには、次の手順に従います。

  1. https://console.aws.amazon.com/ecr/repositories で Amazon ECR コンソールを開きます。

  2. ナビゲーションバーから、リポジトリを作成する AWS リージョンを選択します。

  3. [リポジトリ] ページで、[プライベートリポジトリ] を選択し、次に [リポジトリの作成] を選択します。

  4. [リポジトリ名] に、「webapp」と入力します。このパターンのサンプルアプリケーションが機能するには、Amazon ECR リポジトリ名に webapp を使用する必要があります。リポジトリに別の名前を使用する場合は、「トラブルシューティング」を参照してください。

詳細は、Amazon ECR ドキュメントの「Creating an Amazon ECR private repository to store images」を参照してください。

AWS DevOps

Dockerfile を作成して Azure DevOps エージェントを構築する。

Dockerfile を作成して、Azure DevOps エージェントがインストールされている Docker イメージを構築します。次の内容を Dockerfile という名前のファイルに保存します。

FROM ubuntu:22.04 ENV TARGETARCH="linux-x64" RUN apt update && apt upgrade -y && apt install -y curl git jq libicu70 unzip wget RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" RUN unzip awscliv2.zip RUN ./aws/install RUN rm -rf aws awscliv2.zip RUN curl -sSL https://get.docker.com/ | sh RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash RUN mkdir -p azp WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh RUN useradd -m -d /home/agent agent RUN chown -R agent:agent /azp /home/agent RUN groupadd -f docker RUN usermod -aG docker agent USER agent ENTRYPOINT [ "./start.sh" ]
AWS DevOps

Azure DevOps エージェント用のスクリプトを作成する。

start.sh スクリプトを作成するには、次の手順を実行します。

  1. Microsoft ドキュメントの「Create and build the Dockerfile」の手順に移動し、ステップ 5 までスクロールします。次の内容を ~/azp-agent-in-docker/start.sh に保存します必ず Unix スタイル (LF) の行末を使用してください

  2. スクリプトの内容をコピーし、Dockerfile と同じディレクトリの start.sh という名前のファイルに保存します。

AWS DevOps

Azure DevOps エージェントを使用して Docker イメージを構築する。

Azure DevOps エージェントをインストールするための Docker イメージを作成するには、前に作成した Dockerfile を使用してイメージを構築します。Dockerfile を保存したのと同じディレクトリで、以下のコマンドを実行します。

aws ecr get-login-password --region region | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com docker build --platform linux/amd64 -t ado-agent:latest . docker tag ado-agent:latest aws_account_id.dkr.ecr.region.amazonaws.com/webapp:latest docker push aws_account_id.dkr.ecr.region.amazonaws.com/webapp:latest

aws_account_id と を AWS アカウント ID と region に置き換えます AWS リージョン。

AWS DevOps
タスク説明必要なスキル

Azure 個人アクセストークンを生成する。

プライベート Amazon EKS クラスターで動作するエージェントには、Azure DevOps アカウントで認証できるように個人アクセストークン (PAT) が必要です。PAT を生成するには、次の手順を実行します。

  1. Azure DevOps 組織で使用する予定のユーザーアカウントでサインインします (https://dev.azure.com/{Your_Organization})。

  1. ホームページから、ユーザー設定を開き、[Personal access tokens] を選択します。

  2. [New Token] を選択します。

  3. トークンの名前を入力します。

  4. [Show all scopes] を選択します。

  5. [Agent Pools] で、[Read & manage] のチェックボックスをオンにします。

  6. [作成] を選択します。

  7. プライベート Amazon EKS クラスターにシークレットを作成するには、次の設定を使用します。

apiVersion: v1 kind: Secret metadata: name: azdevops-pat namespace: default type: Opaque stringData: AZP_TOKEN: <PAT Token>
  1. 設定を ado-secret.yaml という名前のファイルに保存します。<PAT Token> は、先ほど作成した個人アクセストークンに置き換えます。シークレットを作成するには、次のコマンドを実行します。

kubectl create -f ado-secret.yaml

詳細は、Microsoft ドキュメントの「Register an agent using a personal access token (PAT)」を参照してください。

AWS DevOps

エージェントのデプロイに Kubernetes マニフェストファイルを使用する。

Azure DevOps エージェントをプライベート Amazon EKS クラスターにデプロイするには、次のマニフェストファイルをコピーし、agent-deployment.yaml として保存します。

apiVersion: apps/v1 kind: Deployment metadata: name: azure-pipelines-agent-eks labels: app: azure-pipelines-agent spec: replicas: 1 selector: matchLabels: app: azure-pipelines-agent template: metadata: labels: app: azure-pipelines-agent spec: containers: - name: docker image: docker:dind securityContext: privileged: true volumeMounts: - name: shared-workspace mountPath: /workspace - name: dind-storage mountPath: /var/lib/docker env: - name: DOCKER_TLS_CERTDIR value: "" - name: azure-pipelines-agent image: aws_account_id.dkr.ecr.region.amazonaws.com/webapp:latest env: - name: AZP_URL value: "<Azure account URL>" - name: AZP_POOL value: "eks-agent" - name: AZP_TOKEN valueFrom: secretKeyRef: name: azdevops-pat key: AZP_TOKEN - name: AZP_AGENT_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: DOCKER_HOST value: tcp://localhost:2375 volumeMounts: - mountPath: /workspace name: shared-workspace volumes: - name: dind-storage emptyDir: {} - name: shared-workspace emptyDir: {}

aws_account_id と を AWS アカウント ID と Azure DevOps アカウント URL <Azure account URL>に置き換えます。

AWS DevOps

エージェントをプライベート Amazon EKS クラスターにデプロイする。

Azure DevOps エージェントをプライベート Amazon EKS クラスターにデプロイするには、次のコマンドを実行します。

kubectl create -f agent-deployment.tf
AWS DevOps

エージェントが実行されていることを確認する

Azure DevOps エージェントが実行されていることを確認するには、次のコマンドを使用します。

kubectl get deploy azure-pipelines-agent-eks

次のような内容が出力されます。

NAME READY UP-TO-DATE AVAILABLE AGE azure-pipelines-agent-eks 1/1 1 1 58s

READY 列に 1/1 が表示されていることを確認します。

AWS DevOps

エージェントが Azure DevOps エージェントプールに登録されていることを確認する。

エージェントがプライベート Amazon EKS クラスターにデプロイされ、エージェントプール eks-agent に登録されていることを確認するには、次の手順を実行します。

  1. Azure DevOps 組織にサインインします (https://dev.azure.com/{Your_Organization})。

  2. [プロジェクト設定] を選択します。

  3. [Agent pools] を選択します。

  4. [eks-agent] プールを選択し、[Agents] タブを確認します。

[Status][Online] のエージェントが 1 つ表示されます。エージェントの名前は、azure-pipelines-agent-eks-* で始まっているはずです。

AWS DevOps
タスク説明必要なスキル

サンプルアプリケーションリポジトリを GitHub アカウントにフォークする。

次の AWS サンプルリポジトリを GitHub アカウントにフォークします。

https://github.com/aws-samples/deploy-kubernetes-resources-to-amazon-eks-using-azure-devops

AWS DevOps

パイプラインを作成する

Azure DevOps アカウントでパイプラインを作成するには、次の手順を実行します。

  1. Azure DevOps 組織で使用する予定のユーザーアカウントでサインインします (https://dev.azure.com/{Your_Organization})。

  2. プロジェクトとパイプラインコンソールに移動します。

  3. [New Pipeline] を選択します。

  4. [Where is your code] で、[GitHub] を選択します。

  5. パイプラインが GitHub アカウントに接続するために必要な認証情報を入力します。

  6. リポジトリ deploy-kubernetes-resources-to-amazon-eks-using-azure-devops を選択します。

  7. [Configure your pipeline] で、[Existing Azure Pipelines YAML file] を選択します。

  8. [Select an existing YAML file] で、[Branch] には [main][path] には [azure_pipelines.yaml] を選択します。

  9. [続行] をクリックしてください。

  10. [Review your pipeline YAML] で、awsRegionawsEKSClusterName の入力パラメータ値は実際の情報に置き換えてください。

pool: name: eks-agent #pool: self-hosted # If you are running self-hosted Azure DevOps Agents stages: # Refering the pipeline template, input parameter that are not specified will be added with defaults - template: ./pipeline_templates/main_template.yaml parameters: serviceConnectionName: aws-sc awsRegion: <your region> awsEKSClusterName: <name of your EKS cluster> projectName: webapp
  1. [RUN] を選択します。

AWS DevOps

サンプルアプリケーションがデプロイされていることを確認する。

パイプラインが完了したら、Amazon ECR リポジトリと Amazon EKS クラスターの両方をチェックして、サンプルアプリケーションのデプロイが成功したことを確認します。

Amazon ECR リポジトリのアーティファクトを検証するには、次の手順を実行します。

  1. webapp Amazon ECR リポジトリに移動します。

  2. 次の新しいアーティファクトがあることを確認します。

  • Docker イメージ – <date>.<build_number>-image

  • Helm チャート – <date>.<build_number>-helm

例えば、20250501.1-image20250501.1-helm です。

名前空間 webapp のプライベート Amazon EKS クラスターでのデプロイを確認するには、次のコマンドを実行します。

kubectl get deploy -n webapp

予想される出力は次のようになります。

NAME READY UP-TO-DATE AVAILABLE webapp 1/1 1 1

注: これが最初のパイプライン実行である場合は、サービス接続とエージェントプールの承認が必要となる場合があります。Azure DevOps パイプラインインターフェイスでアクセス許可リクエストを探し、承認して続行します。

AWS DevOps

トラブルシューティング

問題ソリューション

Amazon ECR リポジトリ名が webapp と一致しないとパイプラインが失敗する

サンプルアプリケーションでは、Amazon ECR リポジトリ名が azure_pipeline.ymlprojectName: webapp パラメータと一致することが想定されています。

この問題を解決するには、Amazon ECR リポジトリの名前を webapp に変更するか、以下を更新します。

  • フォークされた GitHub リポジトリの webapp ディレクトリの名前を Amazon ECR リポジトリ名と一致するように変更します。

  • Amazon ECR リポジトリ名と一致するように azure_pipeline.ymlprojectName パラメータを更新します。

エラー: Kubernetes クラスターに到達できません: サーバーがクライアントに認証情報の提供を要求しました

Azure パイプラインの「Helm チャートのプルとデプロイ」ステップでこのエラーが発生した場合、通常、Amazon EKS クラスターの aws-auth ConfigMap での誤った IAM ロール設定が根本原因です。

この問題を解決するには、以下を確認してください。

  • aws-auth ConfigMap の設定を確認します。

  • Amazon EKS クラスターの認証設定を確認します。Amazon EKS コンソール、[クラスターの詳細][アクセス設定]を開きます。[認証][EKS API と ConfigMap] ([EKS API] だけでなく) に設定されていることを確認します。

関連リソース

AWS ブログ

AWS のサービス ドキュメント

Microsoft ドキュメント