OCI DevOps実践Vol1 OCIR・ビルド/デプロイパイプラインでCI/CD構築

目次

1. この記事について — OCIRとビルド/デプロイパイプラインでアプリCI/CDを構築する

OCI DevOps(Build/Deploy)・OCIR・Artifact RegistryとAWS CodePipeline/CodeBuild/CodeDeploy/ECR/CodeArtifactの対応マップ
fig01: OCI DevOps(Build/Deploy)・OCIR・Artifact RegistryとAWS CodePipeline/CodeBuild/CodeDeploy/ECR/CodeArtifactの対応マップ

OCI DevOpsは、単体で見ればAWSのCodePipeline・CodeBuild・CodeDeployに近い役割を持つCI/CDサービスです。しかし、コンテナイメージを保管するOCIR(Oracle Cloud Infrastructure Registry)や、汎用アーティファクトを管理するArtifact Registryと組み合わせて初めて、コードの変更からコンテナイメージのビルド、デプロイまでを一気通貫で自動化するパイプラインとして機能します。本記事は、この一連の流れを実際に構築し、動く状態まで持っていくことを通じて、OCIにおけるCI/CD実践の勘所を掴んでもらうことを目的としています。

これまでの「OCI入門」シリーズや「OCI Terraform実践」シリーズでは、コンソール操作またはTerraformでリソースを1回作成して終わり、という構成が中心でした。しかし実務のアプリケーション開発では、リソースを1回作って終わりではなく、コードの変更が継続的に発生し、そのたびにビルド・デプロイを繰り返すことになります。本記事が扱うOCI DevOpsは、この「継続的な変更をどう自動化するか」という、これまでのシリーズでは扱ってこなかった観点に焦点を当てる記事です。

AWS実務者向け対応マップの要点

  • OCI DevOps(ビルド/デプロイパイプライン) ↔ AWS CodePipeline/CodeBuild/CodeDeploy: パイプライン定義・ビルド実行・デプロイ実行という役割分担が近い構成です
  • OCIR ↔ ECR: いずれもマネージド型コンテナレジストリで、docker push/docker pullの操作感も近いサービスです
  • Artifact Registry ↔ CodeArtifact: コンテナイメージ以外の汎用アーティファクト(ビルド成果物)を管理する位置づけが対応します
  • instance group deployment ↔ CodeDeploy(EC2): computeインスタンス群への段階的デプロイという概念が対応します
  • これらの対応関係は、§3〜§5の実装および§3-1・§5-1の対比整理の中で、コンソール操作レベルの具体例とあわせて改めて確認します
課金の見える化の要点

  • OCI DevOps・OCIR・Artifact Registryは、いずれもAlways Free対象リソースの一覧に掲載されていません(詳細は§2-4)
  • ビルドパイプライン実行中は、ビルドランナーの既定シェイプ(2 OCPU/8GBメモリ)分のコンピュート課金が、ビルド実行時間に応じて発生します
  • 本記事は、Pay As You Go(従量課金)へ昇格済みのテナンシを前提として進めます(§2-1で詳述)
  • 課金はビルド実行中の時間分のみが対象で、待機中(アイドル時)には発生しません(§2-4で試算)

前作「OCI Functions & API Gatewayサーバーレス実践 Vol1」では、OCIR(コンテナレジストリ)やCI/CDパイプラインの詳細を、今後公開予定のOCI DevOps関連記事に委譲すると予告していました。本記事は、その予告を回収する位置づけの記事です。

本記事の§3以降では、実際にOCIRリポジトリを作成してコンテナイメージをpushするところから始め、ビルドパイプライン・デプロイパイプラインを順に構築し、最終的にコードの変更が自動的にアプリケーションへ反映される状態まで一気通貫で確認します。§1・§2では、その実装に入る前提として、本記事のゴール・読者像・料金の考え方を先に整理します。

1-1. 本記事のゴール

本記事は、「OCI DevOps実践」シリーズの第1弾として、アプリケーションのソースコードをOCIRへのコンテナイメージpushからOCI DevOpsのビルドパイプライン・デプロイパイプラインへとつなげ、実際にアプリケーションが動作する状態まで構築することをゴールとしています。

具体的には、コンテナイメージのpushをトリガーとしてビルドパイプラインが起動し、ビルド済みの成果物をデプロイパイプラインが反映するという、コード変更からアプリケーション更新までの一連の流れを、1つのテナンシ上で動かせる状態を目指します。

多くのハンズオン記事は、OCIRへのイメージpushや、DevOpsパイプラインの作成といった個々の操作を単発で扱って終わりますが、実務でのCI/CDは、複数のパイプラインステージが連鎖して初めて意味を持ちます。本記事がOCIR・ビルドパイプライン・デプロイパイプラインをあえて1本の記事としてまとめているのは、この「連鎖させて初めて見える設計判断」を体験してもらうためです。たとえば、ビルドパイプラインのトリガー条件とデプロイパイプラインの起動条件をどう連携させるか、ビルドランナーのシェイプ選定がビルド時間と課金にどう影響するかといった、単体のドキュメントだけでは気づきにくいポイントも扱います。

本記事を読み終えると、次の状態になっていることを目指しています。

  • OCIRにコンテナイメージをpushし、そのpushをトリガーとしてOCI DevOpsのビルドパイプラインを起動できる
  • ビルドパイプラインの成果物を、デプロイパイプライン経由でアプリケーション実行環境に反映できる
  • ビルドランナーのシェイプ選定が課金にどう影響するかを、公式価格表に基づいて具体的な数値で説明できる
  • AWSのCodePipeline/CodeBuild/CodeDeployの実務経験を踏まえて、OCIでの対応実装における本質的な違いを説明できる

本記事は、あくまで「OCIR起点のCI/CDパイプライン」に焦点を絞っており、次の範囲についてはあえて深掘りせず、既存記事・今後公開予定の記事に委譲します。いずれも本記事の§3以降(同一記事内)で扱う範囲ではなく、別記事に委譲する範囲である点をご留意ください。

  • OKEクラスターの構築手順: 「OCI入門」シリーズVol6を参照してください。本記事では、既存のOKEクラスターへデプロイする側の実装のみを扱います
  • インフラのTerraformによるIaC化: 「OCI Terraform実践 Vol1」を参照してください。本記事のDevOpsプロジェクト・パイプライン自体はコンソール操作で構築し、Terraform化は扱いません
  • FunctionsのfnCLIによるデプロイ: 「OCI Functions & API Gatewayサーバーレス実践 Vol1」を参照してください。本記事が扱うOCI DevOpsのビルド/デプロイパイプラインとは別系統のデプロイ手段です
  • Vaultの詳細な使い方: 「OCIセキュリティ実践 Vol1」を参照してください。本記事のパイプラインでは、Auth Tokenのような機密情報をVaultで一元管理する構成までは踏み込みません

これらの委譲は、本記事のスコープを「OCIRを起点としたビルド/デプロイパイプラインの結線」に絞り込むための判断です。個々の周辺技術の説明に紙幅を割くよりも、パイプラインを連鎖させたときに初めて見えてくる設計判断(トリガー条件・成果物の受け渡し・ビルドランナーのシェイプ選定)に焦点を当てることを優先しています。

裏を返せば、上記4つの周辺技術について、コンソール上の操作自体は本記事の随所で必要最小限触れることになりますが、それぞれの設計思想や発展的な使い方の解説は、既刊または今後公開予定の記事側の役割として明確に切り分けています。

1-2. 読者像

本記事は、AWSでCodePipeline・CodeBuild・CodeDeployを使ったCI/CDパイプラインの構築・運用経験があり、OCIでの対応実装を実務レベルで知りたいエンジニアを主な読者として想定しています。具体的には、マルチクラウド戦略の一環で自社システムの一部をOCIに移行する検討をしているエンジニア、あるいは顧客からOCI上でのCI/CD構成の提案を求められたインフラ/クラウドエンジニアなどを想定しています。

いずれのケースでも、「AWSでできていたCI/CDが、OCIでも同じようにできるのか」という素朴な疑問が出発点になることが多く、本記事はその疑問に実装レベルで答えることを目指しています。マルチクラウド戦略においては、機能の有無だけでなく、パイプラインの構成要素がどこまで1対1で対応するのか、対応しない部分はどこかを正確に把握することが、移行判断の質を左右します。

特に、次のような疑問を持つ方に向けて、本記事は具体的な答えを用意しています。

  • OCI DevOpsのビルドパイプラインは、AWS CodeBuildと同じ感覚で使えるのか
  • OCIRへのイメージpushは、AWS ECRへのpushとどこまで操作感が近いのか
  • ビルドランナーのシェイプ(OCPU/メモリ)選定は、料金にどう影響するのか
  • 純粋なAlways Freeテナンシだけで、この記事の内容を最後まで実践できるのか

AWSでの経験と、本記事を通じて得られる理解の対応関係を整理すると、次のようになります。

AWSでの経験本記事で得られる理解
CodePipelineでのステージ構成・トリガー設定経験OCI DevOpsのビルドパイプライン・デプロイパイプラインという2分割構成と、Trigger Deploymentステージによる連結の考え方が分かる(§4・§5)
CodeBuildのbuildspec.yml運用経験build_spec.yamlの記法と、ビルドランナーのシェイプ選定が課金にどう影響するかが分かる(§2-4・§4)
ECRへのdocker pushの運用経験OCIRへのAuth Token認証によるpushフローと、AWSとの操作感の違いが分かる(§3)

本記事が主な対象としない読者像も明確にしておきます。OCIのコンソール操作そのものをこれから学びたい場合は、本記事より先に「OCI入門」シリーズを読むことをお勧めします。また、Kubernetesの基本概念(Pod・Deployment・Serviceなど)を一から学びたい場合は、本記事よりも先にKubernetes自体の入門教材を参照する方が目的に合っています。本記事は、あくまで「OCIRとOCI DevOpsのパイプラインをどう結線するか」という、CI/CDの実装面に焦点を当てています。

なお、本記事は「OCI入門」シリーズでコンパートメント・IAMポリシーの基礎を扱い済みであることを前提としています。基礎自体の再説は行わず、本記事に固有の範囲のみを扱います。加えて、デプロイ先として利用する実行環境(§5で選定)についても、その構築手順自体は既刊記事に委譲し、本記事では「既にデプロイ先が用意されている」状態からパイプラインを組み立てる実装のみを扱います。

これは、AWSでVPC・EKSクラスターの構築を別チーム(インフラチーム)が担当し、アプリケーションチームがCodePipeline/CodeBuild/CodeDeployのパイプライン設計に専念する、という役割分担に慣れた読者にとっては、むしろ馴染みのある前提かもしれません。本記事は、この「土台は既にある」という前提に立ったうえで、アプリケーションチームが担う領域に焦点を絞っています。

逆に言えば、OCIRやOCI DevOpsのいずれも本記事が初めての利用であっても問題ありません。これらのサービス固有の概念(OCIRのタグ運用、ビルドパイプラインのステージ構成など)は、本記事の各章で必要な範囲を都度説明します。一方で、コンテナ化そのものの基礎(Dockerfileの書き方など)や、Kubernetesの基本概念については、本記事では前提知識として扱い、個別の解説は行いません。

インフラIaC・OKEクラスター・アプリCI-CDの3レイヤー棲み分け図
fig02: 3レイヤー棲み分け対応図(インフラIaC=OCI Terraform実践Vol1/クラスター=getting-started Vol6/アプリCI-CD=本記事)

1-3. なぜ今これを書くか

本記事を今書く理由は、大きく3つあります。

1つ目は、シリーズとしての継続性です。前作「OCI Functions & API Gatewayサーバーレス実践 Vol1」は、§2でOCIRを使ったFunctionsのコンテナイメージ管理に触れつつも、OCIR(コンテナレジストリ)やCI/CDパイプラインの詳細は今後公開予定のOCI DevOps関連記事に委譲すると明記していました。個々のサービスの記事の中でCI/CDパイプラインの詳細まで扱うと、記事のスコープが際限なく広がってしまうため、当時はあえて踏み込まずに済ませていた領域です。本記事は、この委譲予告を実際に回収し、OCIRを起点としたCI/CDパイプラインという独立したテーマとして正面から扱う記事として位置づけています。

2つ目は、インフラ・クラスター・アプリケーションという3つのレイヤーの棲み分けを整理する必要があったことです。fig02が示す通り、インフラのTerraformによるIaC化は「OCI Terraform実践 Vol1」が、Kubernetesクラスターの構築は「OCI入門」シリーズVol6(OKE)が、それぞれ既に扱っています。この2つの記事は、いずれも「土台を作る」記事であり、その土台の上で実際にアプリケーションを継続的に更新し続けるための仕組みは、まだどの記事でも扱われていませんでした。本記事は、この2つのレイヤーの上に載る「アプリケーションのCI/CD」というレイヤーを担当し、3レイヤーの棲み分けを完成させる記事です。レイヤーごとに記事を分けることで、読者は自分が今取り組んでいる課題がどのレイヤーに属するのかを意識しながら、必要な記事だけを選んで参照できるようになります。

3つ目は、料金の正確性です。「OCI入門」シリーズや「OCI Terraform実践」シリーズの多くは、Always Free対象リソースの範囲内で「0円完結」を謳ってきましたが、OCI DevOps・OCIR・Artifact Registryはいずれもこの対象外です。この事実に気づかないまま、従来シリーズと同じ感覚でハンズオンを進めてしまうと、ビルドを何度も試行錯誤するうちに、想定していなかった課金が積み重なっていた、という事態になりかねません。本記事では、こうした従来シリーズの「0円完結」という表現をあえて使わず、ビルドランナーの課金がどの程度の規模になるのかを、公式価格表に基づいて具体的に試算します(§2-4)。少額とはいえ課金が発生する前提を最初に明示しておくことで、読者が安心して手を動かせる状態を作ることを重視しています。

この3つの軸——シリーズの継続性・レイヤーの棲み分け・料金の正確性——を、本記事の位置づけとして整理すると、次のようになります。

観点前作・関連記事の扱い本記事の扱い
CI/CDパイプラインの詳細「OCI Functions & API Gatewayサーバーレス実践 Vol1」は委譲にとどめた本記事で正面から扱う
インフラのコード化「OCI Terraform実践 Vol1」が担当対象外・既刊に委譲
クラスターの構築「OCI入門」シリーズVol6(OKE)が担当対象外・既刊に委譲(§5でデプロイ先として利用)
料金の表現従来シリーズはAlways Free枠内で「0円完結」Always Free対象外を前提に「少額課金の見える化」(§2-4)

次の§2では、ここまで整理したゴール・読者像・委譲事項を踏まえたうえで、本記事のハンズオンを進めるための前提環境と技術スタック、そして本記事の核心である料金試算を整理します。§3以降では、OCIRリポジトリの作成からビルドパイプライン・デプロイパイプラインの構築、動作確認までを実装レベルで扱います。

この章(§1)のポイント

  • 本記事は、OCIR・ビルドパイプライン・デプロイパイプラインを連鎖させ、コード変更からアプリケーション更新までのCI/CDをE2Eで構築します
  • 前作「OCI Functions & API Gatewayサーバーレス実践 Vol1」が予告した「OCI DevOps関連記事への委譲」を、本記事で回収します
  • OCI DevOps・OCIR・Artifact RegistryはAlways Free対象外のため、本記事では「0円完結」ではなく「少額課金の見える化」という文脈で料金を扱います(詳細は§2-4)

前作「OCI Terraform実践 Vol1」を読む(インフラIaC化編)


2. 前提・環境・準備

OCI DevOpsパイプライン環境構成図
fig03: 前提環境の全体構成(OCIR/Artifact Registry/DevOpsプロジェクト/ビルドパイプライン/デプロイパイプラインの関係)

2-1. 前提環境

本記事の実践には、次の前提が必要です。

  • Pay As You Go(従量課金)へ昇格済みのOCIテナンシ(理由は後述)
  • DevOps・OCIR・Artifact Registryの各サービスを操作できるIAMポリシーが設定されたユーザーまたはグループ
  • コンテナイメージをビルドするための、ローカル端末のdocker(またはPodman)環境
  • gitクライアント(DevOpsのコードリポジトリ、または外部リポジトリとの連携に使用)

これらの前提を、チェックリストの形で整理すると次の通りです。

前提項目確認方法
OCIテナンシがPAYGへ昇格済みコンソールの「請求書とコスト管理」でPay As You Goと表示される
IAMポリシー(DevOps/OCIR/Artifact Registry操作権限)が設定済み各サービスのコンソールメニューにアクセスできる
ローカル端末にdocker(またはPodman)がインストール済みdocker versionが実行できる
gitクライアントがインストール済みgit --versionが実行できる

【★必達・憶測禁止】Free Tierテナンシ(未昇格)の状態でOCI DevOpsのビルドを実行できるかどうかは、2026年8月時点でOracleの公式ドキュメントに明記が見当たりません。一方、OCI DevOps・OCIR・Artifact Registryはいずれも、後述のAlways Free対象リソース一覧に掲載されていません。本記事では、この点を踏まえ、「PAYG(従量課金)へ昇格済みのテナンシ」を前提として進めます。「無料でできます」という断定的な表現は、公式な裏付けが得られていないため、本記事では使用しません。

コンパートメント設計の考え方

本記事では、OCIR・DevOpsプロジェクト・ビルド/デプロイパイプラインといったCI/CD関連リソースを、既刊「OCI Terraform実践 Vol1」や「OCI入門」シリーズVol6(OKE)で使用してきたコンパートメントと同一のコンパートメントにまとめる構成を前提とします。本番運用では、CI/CDリソースを専用のコンパートメントに分離し、IAMポリシーで権限を最小化する構成が一般的ですが、本記事はVol1として構成をシンプルに保ち、コンパートメント分離の設計は今後のテーマとして切り出しています。

これは、AWSで開発用AWSアカウントとCI/CD用AWSアカウントを分離するマルチアカウント構成に慣れた読者にとっては、やや大雑把に見えるかもしれません。本記事では、まずOCIR→ビルド→デプロイの結線を最短で確認することを優先し、権限分離の設計判断は次のステップとして切り出しています。

AWS実務者向けのIAMポリシー対比

OCI DevOpsのビルド/デプロイパイプラインが、OCIRや対象クラスターなど他のOCIリソースにアクセスするための権限モデルは、AWSでCodeBuild/CodeDeployのサービスロールを設計してきた読者にとって、次のように対応づけて理解できます。

観点AWS(CodeBuild/CodeDeploy)OCI(DevOps)
実行主体への権限付与IAMロール(サービスロール)をパイプライン/ビルドプロジェクトにアタッチdynamic groupでパイプラインリソース自身にIDを持たせ、ポリシーで権限付与
ポリシーの記述単位JSON形式のIAMポリシードキュメントテナンシ共通の平文ポリシー構文(Allow group ... to ... in compartment ...)
権限の対象範囲ARNベースでリソースを個別指定コンパートメント単位でリソース種別(family)ごとに指定するのが一般的

権限の与え方の思想自体は近いものの、OCIではポリシー文がテナンシ共通の1つの構文で記述される点、dynamic groupという「リソース自身にIDを与える」概念を経由する点が、AWSのIAMロールとの実務上の違いです。

OCIRへのコンテナイメージpush準備

DevOpsのビルドパイプラインでは、ビルド成果物であるコンテナイメージをOCIRへpushする流れになります。事前準備として、OCIのユーザー設定画面で「Auth Token」を発行し、次のようにdockerコマンドでOCIRにログインしておく必要があります。

docker login <リージョンキー>.ocir.io -u <テナンシ名前空間>/<ユーザー名> -p <Auth Token>

リージョンキーは、東京リージョンの場合はnrtです。Auth Tokenは、発行時のみ表示される値であり、後から再表示できません。発行直後に安全な場所へ控えておく必要があります。紛失した場合は、古いAuth Tokenを取り消し、新規に発行し直すことで対応します。

DevOpsプロジェクト・コードリポジトリへのIAMポリシー

開発者がコンソールやCLIからDevOpsプロジェクト・ビルドパイプライン・コードリポジトリを作成・管理するには、次のようなポリシーが必要です。

Allow group <開発者グループ名> to manage devops-family in compartment <対象コンパートメント名>

ビルドパイプラインがOCIRへイメージをpushしたり、Artifact Registryへ成果物を発行したりするには、ビルドパイプライン自身にIDを持たせるdynamic groupと、そのdynamic groupに対する権限付与ポリシーが必要です。

ALL {resource.type = 'devopsbuildpipeline', resource.compartment.id = '<DevOpsプロジェクトのコンパートメントocid>'}
Allow dynamic-group <上記dynamic group名> to manage repos in compartment <対象コンパートメント名>
Allow dynamic-group <上記dynamic group名> to use ons-topics in compartment <対象コンパートメント名>

このポリシーは、AWSでCodeBuildのサービスロールにECRへのpush権限(IAMロールポリシー)を付与してきた読者にとっては、権限の与え方の思想自体は近いものの、OCIではdynamic groupという「リソース自身にIDを与える」仕組みを介する点が異なります。

本記事で使用するリソース命名規則

本記事の§3以降で作成するリソースは、次の命名規則に統一します。

リソース種別命名例
OCIRリポジトリoci-devops-vol1-app
DevOpsプロジェクトoci-devops-vol1-project
ビルドパイプラインoci-devops-vol1-build
デプロイパイプラインoci-devops-vol1-deploy

2-2. 使用技術スタック

本記事で使用するサービス・ツールの基盤とバージョンは、次の通りです(2026年8月時点の公式ドキュメント準拠)。

サービス/ツール基盤/仕様本記事での役割
OCI DevOpsマネージド型CI/CDサービス。ビルドパイプライン・デプロイパイプライン・コードリポジトリで構成ビルド・デプロイの自動化
OCIRマネージド型コンテナレジストリビルド済みコンテナイメージの保管
Artifact Registry汎用アーティファクト(ビルド成果物)管理サービスデプロイ用マニフェスト等の保管(用途に応じて)
ビルドランナーOracle Linux 8ベースのマネージド型ビルド実行基盤ビルドパイプラインのステージ実行

OL7ビルドランナーの終了(2026-08-28)とOL8移行

OCI DevOpsのビルドランナーは、従来Oracle Linux 7(OL7)ベースのイメージも選択できましたが、Oracleの公式アナウンス(Service Change Announcements)によれば、2026年8月28日をもってOL7ベースのビルドランナーは新規作成・実行ができなくなります。移行遅延によるビルド起動の待ち時間増加を避けるため、Oracleは2025年10月12日までにOracle Linux 8(OL8)への移行を推奨していました。本記事の執筆時点(2026年8月)はこの推奨移行期限を過ぎているため、本記事は最初からOL8ランナー前提でパイプラインを構築します。OL8は、DevOpsのビルドステージが提供するベースコンテナイメージとして公式に案内されており、Gradle・Maven・Podman・Terraform・OCI CLIなど、主要なビルドツールがプリインストールされています。

【落とし穴】既存のパイプライン定義がOL7ランナーを明示的に指定している場合、2026年8月28日以降はビルドが起動できなくなります。本記事のハンズオンで新規に作成するビルドステージは、OL8ランナーを明示的に選択してください。

OL7からOL8への移行に伴い、ビルドランナー上のコンテナエンジンもDockerからPodmanへ置き換わっています(OL7ランナーでは引き続きDockerが利用可能ですが、2026年8月28日のサポート終了とともに使えなくなります)。本記事の§3では、動作確認のため手元の端末でdockerコマンドを使いますが、§4でビルドパイプライン上のビルドステージを構成する際は、podmanコマンドを使う点に注意してください。ビルドしたイメージは、いずれのコマンドで作成してもOCI準拠のコンテナイメージ形式であるため、OCIRへのpush・pull自体には支障ありません。

OCIRとArtifact Registryの使い分け

本記事では、コンテナイメージの保管にOCIRのみを使用し、Artifact Registryは扱いません。Artifact Registryは、Helmチャートや言語パッケージ(npm/Maven等)、汎用ファイルといった、コンテナイメージ以外の成果物を管理する用途を主な守備範囲としています。本記事のハンズオンはコンテナイメージのCI/CDに焦点を絞っているため、Artifact Registryの利用は本記事のスコープには含みません。両サービスの使い分けの詳細は、§3-1で改めて整理します。

2-3. ゴール状態の定義

本記事における「動作している状態」とは、次の一連の流れが実際に動作し、期待した結果を得られる状態を指します。

  • 開発者がアプリケーションのコンテナイメージをOCIRへpushすると、そのpushをトリガーとしてビルドパイプラインが起動する
  • ビルドパイプラインが正常に完了すると、その成果物をデプロイパイプラインがアプリケーション実行環境(§5で選定するデプロイ先)へ反映する
  • デプロイ後のアプリケーションに対してリクエストを送信し、更新が反映されていることを確認できる

この一連の流れは、AWSでCodePipelineを組んだ経験がある読者であれば、「ソースステージ(pushの検知)→ビルドステージ→デプロイステージ」という馴染みのある流れとして理解できるはずです。OCI DevOpsでは、ビルドパイプラインとデプロイパイプラインが別リソースとして分かれており、両者を「Trigger Deployment」ステージで明示的に連結する点が、AWSの単一パイプライン内でステージを並べる構成との違いです。この連結の具体的な設定方法は§4-2・§5-4で扱います。

この状態を、それぞれ次の観点から確認できることをもって「動作している」と判定します。

フェーズ確認項目確認方法
イメージpushOCIRへのpushが成功するOCIRコンソールでイメージタグが確認できる
ビルドビルドパイプラインがトリガーされ完了するビルドパイプラインのログで成功ステータスを確認する
デプロイデプロイパイプラインが成果物を反映するデプロイパイプラインのログで成功ステータスを確認する
動作確認更新後のアプリケーションが期待通り応答するアプリケーションへのリクエストで更新内容を確認する

この一連の流れを、本記事の§3以降で実際に構築しながら確認していきます。

2-4. 料金試算 — 少額課金の見える化

Always Free対象外という前提

【重要・落とし穴】OCIのAlways Free対象リソース一覧(2026年8月時点の公式ドキュメントで確認)には、OCI DevOps・OCIR・Artifact Registryのいずれも含まれていません。したがって、これら3サービスは、純粋なAlways Freeテナンシのみでは実演できず、Pay As You Go(従量課金)への移行を前提とした環境が必要です。従来の「OCI入門」シリーズや「OCI Terraform実践」シリーズが謳ってきた「0円完結」という表現は、本記事では使用しません。

Always Free対象可否の内訳(2026年8月時点)

サービスAlways Free対象備考
OCI DevOps対象外サービス自体に固有の課金SKUはなく、ビルドランナーのコンピュート使用分が課金対象
OCIR対象外専用SKUなし。保管されるイメージはObject Storage相当の課金体系
Artifact Registry対象外OCIRと同様、専用の無料枠は確認できていない

「OCI入門」シリーズや「OCI Terraform実践」シリーズを完走してきた読者にとっては、Always Free枠だけで完結しないサービスに触れるのは本記事が初めてになるかもしれません。ただし、後述の試算が示す通り、課金額自体は月額で数十円〜百数十円程度の少額にとどまるため、過度に身構える必要はありません。重要なのは、「0円で完結する」という思い込みのまま検証を進めず、あらかじめ課金が発生する前提でクレジットカード登録・PAYGへの昇格を済ませておくことです。

ビルドランナー課金の試算

OCI DevOpsの公式ドキュメントでは、ビルドパイプラインの実行について「ビルド実行中に使用したコンピュートシェイプ(OCPUとメモリ)分が課金される」旨が明記されています。ビルドランナーの既定シェイプは、迅速に起動できるクイックスタートオプションとして2 OCPU/8GBメモリが用意されており、これをカスタマイズ(OCPU数・メモリ量の変更)できます。

本記事では、この既定シェイプ(2 OCPU/8GBメモリ)を採用した場合の課金を、Oracleの公式価格表(標準x86コンピュート「Compute – Standard – E4」の現行料金、2026年8月時点)に基づいて試算します。ビルドランナー固有の課金SKUはドキュメント上に個別の記載がなく、標準コンピュートの従量課金がそのまま適用されると案内されているため、この標準料金を基準とした試算です。

項目単価
OCPU$0.025 / OCPU時間
メモリ$0.0015 / GB時間

既定シェイプ(2 OCPU/8GBメモリ)を1時間稼働させた場合の単価は、次の計算になります。

2 OCPU × $0.025/OCPU時間 = $0.05
8 GB × $0.0015/GB時間 = $0.012
合計 = $0.062 / 時間

課金は「ビルド実行中」の時間分のみが対象で、待機中(アイドル時)には発生しません。たとえば、1回のビルドが10分(1/6時間)で完了する場合、1回あたりの課金はおよそ$0.0103です。本記事のハンズオン規模を想定し、動作確認のために1日1回・月20回程度ビルドを実行すると仮定すると、月間の課金はおよそ$0.21となります。これはあくまで、公式単価と仮定のビルド時間・実行回数に基づく試算例であり、実際のビルド時間はアプリケーションの内容によって変動します。

ビルド時間や実行頻度が変わった場合の目安として、いくつかのパターンを試算すると次のようになります。いずれも既定シェイプ(2 OCPU/8GBメモリ、$0.062/時間)を前提とした計算例です。

1回あたりのビルド時間月間実行回数月間課金の目安
5分20回約$0.10
10分20回約$0.21
10分100回(1日3〜4回程度)約$1.03
30分20回約$0.62

いずれの試算も、本記事のハンズオン規模であれば月額で数十円〜百数十円程度に収まる計算です。AWS CodeBuildも同様にビルド実行中のコンピュート時間に応じた従量課金モデルを採用しており、「実行時間に比例して課金される」という課金構造自体はAWS実務者にとって馴染みのある考え方のはずです。

なお、OCIRに保管するコンテナイメージ自体にも、ストレージ課金が発生します。OCIRの保管領域はObject Storage(Standard)相当の課金体系(2026年8月時点の公式価格表でGigabyte当たり$0.0255/月)が適用されると案内されており、本記事で扱うような数十〜数百MB規模のサンプルアプリイメージであれば、ビルドランナーのコンピュート課金と比べて無視できる程度の金額にとどまります。

この章(§2)のポイント

  • OCI DevOps・OCIR・Artifact Registryは、いずれもAlways Free対象外のため、PAYG昇格済みテナンシを前提とします
  • OL7ビルドランナーは2026年8月28日に終了するため、本記事は最初からOL8ランナー前提で構築します
  • ビルドランナー既定シェイプ(2 OCPU/8GBメモリ)の課金は、公式標準コンピュート単価換算でおよそ$0.062/時間、ビルド実行時間分のみが対象です
  • 本記事のハンズオン規模であれば、月間の課金額は数十円〜百数十円程度に収まる見込みです

前提環境の整理はここまでです。PAYG昇格済みテナンシ・IAMポリシー・OL8ビルドランナー・料金試算という4つの観点を押さえたことで、§3以降で実際にリソースを作成していく準備が整いました。次の§3では、CI/CDパイプラインの起点となるOCIRリポジトリの作成から着手します。


3. OCIRリポジトリ作成〜コンテナイメージのpush

3-1. OCIR・Artifact RegistryとAWS ECR・CodeArtifactの役割対比

本節から、実際に手を動かしてOCI DevOpsのCI/CDパイプラインを構築していきます。まず最初に必要なのは、ビルドしたコンテナイメージの置き場所です。OCIでは、この役割をOCIR(OCI Registry、コンソール上の表記はContainer Registry)とArtifact Registryという2つのサービスが分担しています。

OCIのサービス役割AWSの対応サービス
OCIR(Container Registry)Dockerイメージ・OCI準拠イメージ専用のレジストリAmazon ECR
Artifact RegistryHelmチャート・言語パッケージ(npm/Maven等)・汎用ファイルのレジストリAWS CodeArtifact

AWSではECRとCodeArtifactが別サービスとして提供されているのと同様に、OCIでもコンテナイメージ専用のOCIRと、それ以外の成果物を扱うArtifact Registryが分かれています。本記事はコンテナイメージのCI/CDが主題のため、以降はOCIRのみを扱い、Artifact Registryは扱いません(Helmチャートのデプロイなど、Artifact Registryが必要になる発展的な構成は本記事のスコープ外とします)。

3-2. リポジトリの作成

OCIコンソールの「Developer Services」→「Containers」→「Container Registry」から、リポジトリを作成します。

  1. 対象リージョン(東京: ap-tokyo-1、または大阪: ap-osaka-1)を選択
  2. 「Create repository」をクリック
  3. コンパートメントを選択(OCI Terraform実践Vol1・Vol1〜6で使用してきたコンパートメントと同じものを指定すると、リソースの管理がひとまとまりになります)
  4. リポジトリ名を入力(例: oci-devops-practice/sample-app。スラッシュ区切りで名前空間のようにグルーピングできます)
  5. アクセス設定を「Private」に指定

アクセス設定は必ず「Private」を選択してください。「Public」にすると、認証なしで誰でもイメージをpullできる状態になります。学習目的であっても、意図せず機微な情報を含むイメージを公開してしまうリスクを避けるため、本記事では一貫してPrivateリポジトリを前提とします。

なお、OCIRはリポジトリを事前作成しなくても、初回のdocker push・podman push時に自動作成される仕様です。ただし自動作成時のアクセス設定は「Private」が既定であるものの、意図せぬ名前でリポジトリが乱立しやすいため、本記事ではコンソールから明示的に作成する手順を採ります。

3-3. Authトークンの発行とログイン

OCIRへのpush/pullには、OCIのユーザー名とAuthトークンを使ったBasic認証形式のログインが必要です。

  1. OCIコンソール右上のプロフィールアイコン→「User settings」を開く
  2. 左メニューの「Auth Tokens」→「Generate token」
  3. トークンの説明(例: ocir-devops-practice)を入力して発行
  4. 表示されたトークン文字列を控える(この画面を閉じると二度と表示されないため、必ずこの時点でコピーしてください)

ログインコマンドは次の形式です。ホスト名はリージョンごとに異なり、東京リージョン(ap-tokyo-1)はnrt.ocir.io、大阪リージョン(ap-osaka-1)はkix.ocir.ioを使用します。

docker login nrt.ocir.io -u '<テナンシのオブジェクトストレージ名前空間>/<ユーザー名>'

OCI入門シリーズVol2で解説したIdentity Domainsを使い、Default Domain以外のドメインにユーザーを作成している場合は、ユーザー名部分を<テナンシの名前空間>/<ドメイン名>/<ユーザー名>の形式にする必要があります。パスワードの入力を求められたら、3-3の手順4で控えたAuthトークンを貼り付けます。OCIのアカウントパスワードそのものではない点に注意してください。

3-4. サンプルアプリのビルドと初回push

本記事では、以降の章で繰り返しビルド・デプロイの動作確認に使う題材として、バージョン文字列を返すだけの最小限のNode.js製HTTPサーバーを使います。

FROM node:20-alpine
WORKDIR /app
COPY server.js .
ENV APP_VERSION=v1
EXPOSE 8080
CMD ["node", "server.js"]
const http = require("http");
const version = process.env.APP_VERSION || "unknown";

http
  .createServer((req, res) => {
 res.writeHead(200, { "Content-Type": "text/plain" });
 res.end(`hello from oci-devops-practice ${version}\n`);
  })
  .listen(8080);

まずは自動化する前に、手元の端末でビルドとpushを一度手動で完走させておきます。DevOpsパイプラインを組んでから初めてpushを試すと、パイプライン側の設定ミスとイメージ自体の問題の切り分けが難しくなるためです。

docker build -t nrt.ocir.io/<テナンシの名前空間>/oci-devops-practice/sample-app:manual-check .
docker push nrt.ocir.io/<テナンシの名前空間>/oci-devops-practice/sample-app:manual-check

pushが成功したら、OCIコンソールのリポジトリ詳細画面でイメージが登録されていることを確認してください。

タグ運用の落とし穴 — :latest固定は避ける

  • ここで:manual-checkという固定タグを使ったのは動作確認のためです。§4以降でパイプラインを自動化する際は、ビルドのたびに一意なタグ(コミットハッシュやビルド実行IDに基づくタグ)を採番します。
  • :latestのような固定タグのまま自動デプロイを組むと、Kubernetes側でimagePullPolicyの設定次第では新しいイメージがpullされず、コード変更をpushしてもPodの中身が更新されないという事故につながります。§6のE2E確認で実際にこの挙動を確認します。

4. DevOpsプロジェクト作成・ビルドパイプライン構築

OCI DevOpsビルドパイプラインの構成図(コードリポジトリpush→トリガー→Managed Buildステージ→Deliver Artifactsステージ→OCIR)
fig04: ビルドパイプラインの構成(コードリポジトリへのpushがトリガーとなり、ビルド・OCIRへの登録までを自動実行する)

4-1. DevOpsプロジェクトの作成とコードリポジトリの接続

OCIコンソールの「Developer Services」→「DevOps」→「Projects」から、新しいDevOpsプロジェクトを作成します。コンパートメントは§3と同じものを指定してください。

コードリポジトリには、OCIが提供するマネージドGitリポジトリである「OCI Code Repository」を使います。DevOpsプロジェクト作成時に「Code Repository」を追加し、空のリポジトリとして作成するか、既存のGitHub/GitLabリポジトリを外部接続として登録するかを選べます。外部接続にはOAuthまたはパーソナルアクセストークンの登録が別途必要になるため、本記事では追加の外部連携設定が不要なOCI Code Repositoryを使い、§3-4のサンプルアプリのソース一式をこのリポジトリにpushしておきます。

続いて、このコードリポジトリへのpushをきっかけにビルドパイプラインを起動する「トリガー」を作成します。DevOpsプロジェクトの「Triggers」画面から、対象リポジトリと対象ブランチ(例: main)、イベント種別(Push)を指定してトリガーを作成し、後述のビルドパイプラインに紐づけます。

ビルド・デプロイ双方に必要なIAM設定

  • まずダイナミックグループを作成し、DevOpsプロジェクト配下のリソースにマッチするルールを登録します。
  • ALL {resource.type = 'devopsbuildpipeline', resource.compartment.id = 'compartmentOCID'}
  • ALL {resource.type = 'devopsdeploypipeline', resource.compartment.id = 'compartmentOCID'}
  • ALL {resource.type = 'devopsrepository', resource.compartment.id = 'compartmentOCID'}
  • ポリシーは、OCIRへのpushに必要なAllow dynamic-group DevOpsDynamicGroup to use repos in compartment <compartment_name>を最低限追加します。デプロイ側(OKEへの反映)に必要なポリシーは§5-2でまとめて追加します。

4-2. ビルドパイプラインとManaged Buildステージ

DevOpsプロジェクトの「Build Pipelines」から新しいビルドパイプラインを作成し、次の2つのステージを追加します。

  1. Managed Buildステージ: 4-1で作成したコードリポジトリをビルドソースとして指定し、リポジトリ直下に配置するbuild_spec.yaml(4-3で作成)を実行します。
  2. Deliver Artifactsステージ: Managed Buildステージが生成したイメージを、DevOpsのArtifact(OCIRリポジトリへの参照)に登録します(4-4で設定)。

Managed Buildステージの作成時、ビルドランナーのランタイムを選択する項目があります。必ずOracle Linux 8(OL8)ベースのランナーを選択してください。Oracle Linux 7(OL7)ベースのビルドランナーは2026年8月28日でサポートが終了し、それ以降は新規のビルド作成・実行自体ができなくなります。ビルドランナーの既定シェイプは2 OCPU/8GBで、これは追加のプロビジョニング待ち時間が発生しない標準構成です。カスタムシェイプ(OCPU/メモリを個別指定)も選択できますが、起動までの時間が既定シェイプより長くなる点に留意してください。

OL7→OL8移行で変わる点 — DockerではなくPodman

  • OL8ベースのビルドランナーでは、コンテナエンジンがDockerからPodmanに置き換わっています(OL7ランナーではDockerが引き続き利用可能ですが、2026-08-28のサポート終了とともに使えなくなります)。
  • build_spec.yaml内のビルドコマンドは、docker buildではなくpodman buildを使う必要があります。3-4で手元の端末で使ったdockerコマンドは、ビルドランナー上ではそのままでは使えない点に注意してください。
  • Podmanでビルドしたイメージも、OCI DevOpsのoutputArtifact上は引き続きDOCKER_IMAGEという種別名で扱われます(OCI準拠のコンテナイメージ形式であればビルドツールを問わない設計です)。

4-3. build_spec.yamlの作成

コードリポジトリのルートに、次のbuild_spec.yamlを配置します。ビルドランナーはビルドパイプラインのリソースプリンシパルで事前認証済みのため、OCIRへのログインに個別のAuthトークンを渡す必要はありません。

version: 0.1
component: build
timeoutInSeconds: 3000
shell: bash
env:
  exportedVariables:
 - IMAGE_TAG
steps:
  - type: Command
 name: "イメージタグの決定"
 command: |
export IMAGE_TAG=$(echo ${OCI_BUILD_RUN_ID} | rev | cut -c 1-10 | rev)
  - type: Command
 name: "イメージのビルド"
 command: |
podman build -t sample-app:${IMAGE_TAG} .
  - type: Command
 name: "OCIRタグの付与とpush"
 command: |
podman tag sample-app:${IMAGE_TAG} nrt.ocir.io/${TENANCY_NAMESPACE}/oci-devops-practice/sample-app:${IMAGE_TAG}
podman push nrt.ocir.io/${TENANCY_NAMESPACE}/oci-devops-practice/sample-app:${IMAGE_TAG}

outputArtifacts:
  - name: sample-app-image
 type: DOCKER_IMAGE
 location: nrt.ocir.io/${TENANCY_NAMESPACE}/oci-devops-practice/sample-app:${IMAGE_TAG}

3-4の手動pushでは固定タグ(:manual-check)を使いましたが、ここでは${OCI_BUILD_RUN_ID}(そのビルド実行ごとに一意な値を持つ実行ID)からタグを生成しています。ビルドのたびに異なるタグが付くため、後述する§5のデプロイ時にKubernetes側が確実に新しいイメージをpullできるようになります。TENANCY_NAMESPACEは、ビルドパイプラインの環境変数としてテナンシのオブジェクトストレージ名前空間をあらかじめ登録しておいてください。env.exportedVariablesに宣言したIMAGE_TAGは、Deliver Artifactsのパス置換とTrigger Deployment経由のデプロイパイプラインへ引き継がれます。ステップ間の値の受け渡しはbuild_spec.yamlのexportedVariables機構が担うため、従来のbuild.envファイル経由での受け渡しは不要です。

4-4. Deliver Artifactsステージ — OCIRへの登録

DevOpsプロジェクトの「Artifacts」から、種別「OCIR (Container Repository)」のArtifactリソースを作成し、3-2で作成したOCIRリポジトリを参照させます。パスはnrt.ocir.io/<テナンシの名前空間>/oci-devops-practice/sample-app:${IMAGE_TAG}${IMAGE_TAG}プレースホルダ込みで登録し、「Replace parameters」をYesにします。続いてビルドパイプラインのDeliver Artifactsステージで、build_spec.yamlのoutputArtifactsに定義した名前(sample-app-image)と、このArtifactリソースを紐づけます。

ここまでで、コードリポジトリへのpushをトリガーに、ビルド・イメージタグ付け・OCIRへのpushまでが自動化されました。

ビルド実行1回あたりの課金イメージ(§2-4との整合)

  • DevOpsのビルド実行は、ビルドランナーのシェイプ(既定2 OCPU/8GB)に応じたコンピュート課金として計上されます。標準x86シェイプのOCPU時間単価・メモリGB時間単価を当てはめると、10分程度のビルドであれば1回あたり1円に満たない少額に収まる計算です。
  • §2-4で整理したとおり、DevOps・OCIR・Artifact RegistryはいずれもAlways Free対象外のサービスです。「0円完結」ではなく、少額課金が積み重なる前提で運用してください。

5. デプロイパイプライン構築 — OKEへの継続的デプロイ

OCI DevOpsデプロイパイプラインの構成図(Trigger Deploymentステージ→デプロイパイプライン→Deploy-OKEステージ→OKEクラスターへのマニフェスト適用)
fig05: デプロイパイプラインの構成(ビルドパイプライン完了後にTrigger DeploymentステージからOKEへの反映まで自動連結する)

5-1. デプロイ先の選定 — OKEかcomputeか、ここで確定する

デプロイ先の候補としては、OKE(getting-started Vol6)とcomputeインスタンスグループ(getting-started Vol4)の2つが考えられます。本記事では、デプロイ先をOKE(Vol6で構築したクラスター)に確定します。

OCI入門シリーズ Vol6(OKE編)を先に読む

判断根拠は次の2点です。第一に、本シリーズは「インフラIaC(OCI Terraform実践Vol1)・クラスター(getting-started Vol6)・アプリCI/CD(本記事)」という3レイヤーの棲み分けを掲げており、既存のクラスター層の上にアプリCI/CD層を重ねる構成のほうが、このシリーズ構想を素直に体現できます。第二に、Kubernetesのserver-side applyによるロールアウトは、AWSでもEKS+CodeDeploy(Kubernetes)やArgo CD的な運用へ移行するチームが増えている流れと親和性が高く、実務での再利用価値が大きいと判断しました。

なお、AWSのCodeDeploy(EC2/オンプレミス)に、より直接的に対応するのはOCI DevOpsのcomputeインスタンスグループへのデプロイです。getting-started Vol4で構築したAlways Free A1インスタンスを対象に、ローリングデプロイを組む構成も技術的には可能ですが、本記事のハンズオンの範囲には含めません。EC2ベースの運用に近い形でOCI DevOpsを試したい場合の選択肢として、頭の片隅に置いておいてください。

5-2. Kubernetesクラスター環境の登録とIAM設定

DevOpsプロジェクトの「Environments」から、種別「Kubernetes cluster」の環境リソースを作成し、Vol6で作成したOKEクラスター(my-oke-cluster)を参照させます。

デプロイ用に、ダイナミックグループへのポリシーを追加します。

OKEデプロイに追加で必要なポリシー

  • Allow dynamic-group DevOpsDynamicGroup to manage cluster in compartment <compartment_name>
  • Allow dynamic-group DevOpsDynamicGroup to read all-artifacts in compartment <compartment_name>
  • 4-1で追加したビルド用のポリシーと合わせて、同じダイナミックグループに両方のポリシーが付与されている状態にしてください。

5-3. Kubernetesマニフェストのアーティファクト化

続いて、デプロイ対象のKubernetesマニフェストをDevOpsのArtifactとして登録します。DevOpsプロジェクトの「Artifacts」から種別「Kubernetes Manifest」のArtifactリソースを作成し、次の内容をインラインで登録します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  namespace: devops-practice
spec:
  replicas: 2
  selector:
 matchLabels:
app: sample-app
  template:
 metadata:
labels:
  app: sample-app
 spec:
containers:
  - name: sample-app
 image: nrt.ocir.io/<テナンシの名前空間>/oci-devops-practice/sample-app:${IMAGE_TAG}
 ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: sample-app
  namespace: devops-practice
spec:
  type: ClusterIP
  selector:
 app: sample-app
  ports:
 - port: 80
targetPort: 8080

${IMAGE_TAG}はbuild_spec.yamlのexportedVariablesで宣言した変数名に一致するプレースホルダで、Trigger Deployment経由で引き継がれデプロイ実行時に直近ビルドの実タグへ自動置換されます(置換対象はexportedVariables/パイプラインパラメータ名に一致する${…}のみです。Artifact名では置換されません)。

事前にkubectl create namespace devops-practiceで専用のNamespaceを作成しておいてください。Vol6のハンズオンで使った既定Namespaceと分離することで、本記事のリソースをまとめて後片付けしやすくなります。

マニフェストの制約

  • Deploy – OKEステージに渡すKubernetesマニフェストには、Jobリソースを含められません。バッチ処理やマイグレーションジョブをCI/CDに組み込みたい場合は、別のステージ種別(Run OKE Jobなど)を検討する必要があります。

5-4. Deploy – OKEステージの作成とTrigger Deploymentによる自動連結

DevOpsプロジェクトの「Deploy Pipelines」から新しいデプロイパイプラインを作成し、「Deploy – OKE」ステージを追加します。5-2で登録したクラスター環境と、5-3で登録したKubernetesマニフェストのArtifactを選択します。バリデーションに失敗した場合の自動ロールバックも、このステージの設定でオンにできます。

最後に、§4-2で作成したビルドパイプラインの末尾に「Trigger Deployment」ステージを追加し、このデプロイパイプラインを指定します。これで、コードリポジトリへのpushを起点として、ビルド・OCIR登録・OKEデプロイまでが1本のパイプラインとして自動連結されました。

ここまでで完成した自動化の流れ

  • コードリポジトリ(mainブランチ)へのpush → トリガー起動
  • ビルドパイプライン: Managed Build(podman build)→ Deliver Artifacts(OCIRへpush)→ Trigger Deployment
  • デプロイパイプライン: Deploy – OKE(パラメータ置換で最新イメージを反映しserver-side apply)

6. 動作確認(E2E: コード変更→ビルド→デプロイ→動作確認)

6-1. 初回実行の確認

§3-4で用意したサンプルアプリのソース一式を、§4-1で作成したコードリポジトリのmainブランチにpushします。

git push origin main

pushが完了すると、DevOpsプロジェクトの「Build Pipelines」画面でビルド実行が自動的に開始されます。ビルド実行の詳細画面で各ステージのログを確認しながら、Managed Buildステージ→Deliver Artifactsステージ→Trigger Deploymentステージの順に進むことを確認してください。Trigger Deploymentステージの完了後は、「Deploy Pipelines」画面で対応するデプロイ実行が開始されます。

デプロイ実行が成功したら、kubectlでPodの起動状況を確認します。

kubectl get pods -n devops-practice
kubectl get deployment sample-app -n devops-practice -o jsonpath='{.spec.template.spec.containers[0].image}'

2つ目のコマンドで表示されるイメージのタグが、DevOpsコンソール上でDeliver Artifactsステージが登録したタグと一致していれば、パラメータ置換が正しく機能している証拠です。ClusterIP Serviceとして公開しているため、動作確認にはロードバランサーを別途プロビジョニングせず、ポートフォワードで済ませます(不要な課金対象リソースを増やさないための工夫です)。

kubectl port-forward svc/sample-app -n devops-practice 8080:80
curl http://localhost:8080/

hello from oci-devops-practice v1のようなレスポンスが返ってくれば、初回のE2Eは成功です。

6-2. コード変更→自動ビルド→自動デプロイの実演

続いて、CI/CDパイプラインの本領である「コードを変更してpushするだけで、ビルドからデプロイまでが自動で流れる」挙動を実演します。§3-4のDockerfileにあるAPP_VERSIONv2に書き換え、コミットしてpushします。

ENV APP_VERSION=v2
git add Dockerfile
git commit -m "bump version to v2"
git push origin main

6-1と同じ手順でビルド・デプロイの実行状況を確認します。デプロイパイプラインの完了後、ロールアウトの状況を確認します。

kubectl rollout status deployment/sample-app -n devops-practice

ロールアウトが完了したら、再度port-forwardして応答を確認します。

kubectl port-forward svc/sample-app -n devops-practice 8080:80
curl http://localhost:8080/

レスポンスがhello from oci-devops-practice v2に変わっていれば、コード変更からデプロイまでの一連の自動化が成立していることを確認できたことになります。

うまく反映されないときの落とし穴

  • Podの中身が更新されない: §3-4で触れたタグ運用の問題です。build_spec.yamlのタグ生成が固定文字列になっていないか、Deploy – OKEステージが参照しているArtifactが最新のビルド結果を指しているかを確認してください。
  • ビルドがそもそも起動しない: §4-1で作成したトリガーの対象ブランチ・イベント種別と、実際にpushしたブランチ名が一致しているかを確認してください。
  • Deploy – OKEステージが失敗する: §5-2のIAMポリシーが不足している可能性が高いパターンです。manage clusterread all-artifactsの両方がダイナミックグループに付与されているか、コンパートメントの指定範囲が正しいかを見直してください。

7. クリーンアップ

7-1. 削除順序

放置すると少額課金が積み重なり続けるため、検証後は忘れずに片付けます。次の順序で削除すると、依存関係によるエラーを避けられます。

  1. kubectl delete namespace devops-practiceでDeployment・Serviceを一括削除
  2. デプロイパイプライン(Deploy – OKEステージ)を削除
  3. Kubernetesクラスター環境(Environments)を削除
  4. ビルドパイプライン(Managed Build・Deliver Artifacts・Trigger Deploymentの各ステージ)を削除
  5. トリガーを削除
  6. DevOpsプロジェクトを削除(4・5の削除が完了していないと、プロジェクト自体の削除に失敗します)
  7. OCIRのリポジトリ、またはリポジトリ内の不要なイメージタグを削除(3-2・4-3で作成したoci-devops-practice/sample-app)
  8. User settingsのAuth Tokensから、3-3で発行したトークンを削除
削除に失敗する場合の主な原因

  • デプロイパイプラインがKubernetesクラスター環境を参照したままの状態で、環境側を先に削除しようとしている(手順2→3の順序を守ってください)
  • ビルドパイプラインにトリガーが紐づいたまま、プロジェクトを削除しようとしている(手順4・5の完了後に手順6へ進んでください)

Vol6で構築したOKEクラスター自体、およびVol4で構築したAlways Free A1インスタンスは、本記事のスコープ外(既存クラスター・既存インスタンスを前提とする委譲事項)のため削除しません。他の実践シリーズの検証環境としても引き続き利用するため、削除する場合は各記事の内容を踏まえたうえで判断してください。

7-2. 課金停止の確認

OCIコンソールの「Cost Analysis」または請求ダッシュボードから、DevOps・Container Registry関連の直近の課金項目を確認し、新規のビルド実行やストレージ使用が発生していないことを確認してください。7-1の手順をすべて完了していれば、以降の継続課金は発生しません。


8. まとめ・次回予告

本記事で確立した内容

  • OCIRリポジトリの作成とAuthトークンによるログイン、手動pushでの事前動作確認
  • OL8(Podman)ベースのビルドランナーを前提としたManaged Buildステージとbuild_spec.yamlの構成
  • Deliver Artifactsステージによる、ビルド成果物のOCIRへの自動登録
  • Deploy – OKEステージとパラメータ置換によるKubernetesマニフェストへの最新イメージ反映
  • Trigger Deploymentステージによる、ビルドパイプラインとデプロイパイプラインの自動連結
  • コード変更→自動ビルド→自動デプロイのE2E動作確認と、削除順序に沿ったクリーンアップ

本記事では、OCI Terraform実践Vol1が担うインフラのコード化層、getting-started Vol6が担うクラスター層の上に、アプリケーションのCI/CD層を積み重ねる形で、3レイヤーの棲み分けを一通り完成させました。AWSでCodePipeline・CodeBuild・CodeDeploy・ECRを組み合わせた経験があれば、OCI DevOps・OCIRの構成要素はほぼ1対1で対応づけて理解できたはずです。一方で、Trigger Deploymentステージによるビルド・デプロイパイプラインの自動連結や、Kubernetesマニフェスト内でのパラメータ置換は、OCI DevOps固有の設計として押さえておく価値があります。

次回は、ここまで積み上げてきたOCIの検証環境全体を対象に、「OCIコスト管理・ガバナンス実践」を扱う予定です。Budgets(予算アラート)・Cost Analysis(コスト分析)・コンパートメント単位のクォータ・タグ付けによるコスト配賦といった、複数のコンパートメントにまたがる検証環境を運用するうえで欠かせないFinOps・組織統制の実践を取り上げます。本記事までのハンズオンで作成したコンパートメント群も、その回で棚卸しの題材として活用する見込みです。