Porterの基本概念とCNABとの関係性

**Porter**は、クラウドネイティブなアプリケーションのインストーラーを作成するためのツールであり、Cloud Native Application Bundle (CNAB) 仕様の実装です ([What is Porter? – Porter](https://porter.sh/docs/introduction/what-is-porter/#:~:text=Porter%20is%20an%20implementation%20of,how%20the%20sausage%20is%20made))。CNABはアプリケーション本体だけでなく、そのインフラや構成までも含めて一括でパッケージ化・デプロイするための標準仕様です。PorterはこのCNAB仕様に沿って**バンドル**(bundle)と呼ばれるインストーラーを作成し、アプリケーションのインストールロジックを一つにまとめて他チームや顧客に受け渡すことができます ([What is Porter? – Porter](https://porter.sh/docs/introduction/what-is-porter/#:~:text=Porter%20is%20an%20implementation%20of,how%20the%20sausage%20is%20made))。このバンドルには、アプリケーションのデプロイに必要なスクリプトや設定、CLIツール（例: `kubectl` や Terraform など）をすべて含めることができ、利用者は複雑な内部手順を知らなくても**`porter install` コマンド一つで環境構築が可能**になります ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=1,passing%20in%20the%20database%20credentials))。例えば、WordPressをKubernetes上にデプロイしAzureのマネージドMySQLに接続するようなケースでも、Porterのバンドル内にHelmチャートやデータベース設定スクリプト、HelmおよびAzure CLIなど必要なものを全て含めておけば、利用者はKubernetesクラスターの認証情報さえ用意すれば`porter install`だけでインストールできるようになります ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=1,passing%20in%20the%20database%20credentials))。Porterの利用者はアプリケーション固有の詳細を意識せずに**一貫したデプロイ体験**を得られるのがポイントです ([What is Porter? – Porter](https://porter.sh/docs/introduction/what-is-porter/#:~:text=Porter%20is%20an%20implementation%20of,how%20the%20sausage%20is%20made)) ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=1,passing%20in%20the%20database%20credentials))。

PorterはCNAB仕様に忠実で、現在策定済みのサブ仕様（Core、Claims、Registry など）をすべてサポートしています ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=Does%20Porter%20fully%20implement%20the,CNAB%20specification))。セキュリティ関連など一部ドラフト段階の仕様は未対応ですが、Porter自身が新機能を先行実装してCNAB拡張を実証する **リファレンス実装** の役割も担っています ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=Can%20I%20use%20Porter%20bundles,with%20other%20CNAB%20tools)) ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=Porter%20is%20at%20the%20leading,specifications%20or%20a%20custom%20extension))。そのためPorterで作成したバンドルは、（仮に他のCNAB準拠ツールがあれば）基本的に他ツールでも実行可能であり、逆に他ツールで作られたCNABバンドルもPorterで実行できます ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=Can%20I%20use%20Porter%20bundles,with%20other%20CNAB%20tools))。（ただしPorter固有の拡張、例えば未策定の依存関係機能などを使っている場合、他ツールでは対応していない可能性があります ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=At%20the%20time%20of%20writing%2C,bundles%20created%20by%20another%20tool))。）Porter自体はCloud Native Computing Foundation (CNCF)のサンドボックスプロジェクトとしてホストされており、クラウドベンダーに依存しないオープンなツールです。なお、PorterはTerraformやAnsibleといった構成管理ツールそのものを置き換えるものではなく、それら**既存ツールをひとまとめにパッケージングして配布可能にする**レイヤーを提供するものです ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=Porter%20is%20an%20implementation%20of,gapped%20networks))。例えば、PorterではTerraformのバイナリとそのスクリプトをバンドルに含めOCIレジストリ経由で配布したり、あるいはオフライン環境ではUSBメモリ経由で受け渡す、といったことが可能になります ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=Porter%20is%20an%20implementation%20of,gapped%20networks))。このようにPorterはCNAB仕様に準拠した**汎用インストーラー作成ツール**として、クラウドネイティブアプリケーションの安全で再現可能なデプロイを支援します。

# Mixinsの概要と利用方法

**Mixin（ミックスイン）**はPorterにおける拡張コンポーネントで、Porterと外部ツール・プラットフォームとの橋渡しをする「アダプター」の役割を果たします ([Mixins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-mixins/#:~:text=Mixins%20are%20adapters%20between%20the,steps%20in%20the%20Porter%20manifest))。Porterのバンドルは、インストールやアップグレードなどの各アクションにおいて様々な手順を実行できますが、各手順の実装はmixinを通じて行われます。言い換えれば、mixinは**Porterのバンドルに組み込む個々のツール操作**（例えばHelmでチャートをインストールする、Azure CLIでリソースを作成する、Terraformを実行する、など）を実現するプラグインのようなものです ([Mixins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-mixins/#:~:text=Mixins%20are%20adapters%20between%20the,steps%20in%20the%20Porter%20manifest))。mixinはPorter本体と対話し、必要なCLIバイナリや設定ファイルをバンドル（インボケーションイメージ）に含める方法を知っており、またPorter manifest内（`porter.yaml`）で指定された各ステップの実行方法も理解しています ([Mixins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-mixins/#:~:text=Mixins%20are%20adapters%20between%20the,steps%20in%20the%20Porter%20manifest))。例えばKubernetesクラスタにマニフェストを適用する`kubernetes` mixinは内部で`kubectl`コマンドを実行し、Helmチャートをデプロイする`helm3` mixinは内部で`helm`コマンドを呼び出す、といった具合です。

Porterには数多くの公式・コミュニティ製mixinsが用意されており、デフォルトで同梱されているのは基本的なコマンド実行用の`exec` mixinのみです ([Mixins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-mixins/#:~:text=There%20are%20many%20mixins%20,220%20is%20installed%20by%20default))。他のmixin（例えば`kubernetes`や`helm3`など）を使用する場合、**事前にそのmixinをPorterにインストールする必要があります** ([Porter Buildtime Architecture – Porter](https://porter.sh/architecture-buildtime/#:~:text=Mixins%20must%20be%20installed%20to,porter%2Fmixins%2Fkubernetes))。Porter CLIにはmixin管理用のコマンドが用意されており、利用可能なmixinの検索やインストールが可能です（例：`porter mixins search helm` や `porter mixins install helm3`） ([Porter Buildtime Architecture – Porter](https://porter.sh/architecture-buildtime/#:~:text=match%20at%20L330%20Mixins%20must,porter%2Fmixins%2Fkubernetes))。実際にバンドルを作成する際は、`porter.yaml`のトップレベルに`mixins`セクションを設けてバンドルで使うmixinを列挙します。その上で各アクション（`install`, `upgrade`, `uninstall`など）のステップとしてmixinの機能を記述します。以下にHelmとAzureを使う例を示します。

```yaml
mixins:
- helm3
- az

install:
- helm3:
    description: "Helmチャートのインストール"
    name: myapp
    chart: myrepo/mychart
    version: 1.2.3
    set:
      image.tag: "v1.2.3"
- az:
    description: "Azureリソースの構成"
    script: |
      az group create -n ${RESOURCE_GROUP} -l japaneast
      az mysql server create ... 
```

上記の例では、まず`mixins`でHelm用の`helm3`とAzure CLI用の`az`ミックスインを宣言しています。`install`アクション内では、`helm3`ミックスインのステップでHelmチャートをデプロイし、続いて`az`ミックスインでAzure CLIのスクリプトを実行しています。それぞれのmixinはPorterによって**ビルド時に必要なバイナリ（helmやaz CLI）をインボケーションイメージに含める**よう指示され ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=The%20Kubernetes%20Mixin%20provides%20bundle,command%20line%20tool)) ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=Rather%20than%20trying%20to%20rebuild,being%20installed))、実行時には指定されたコマンドを実行してくれます。なお、mixinによってはPorter manifest内で追加の設定が可能です。例えば`helm3`ミックスインでは、あらかじめHelmリポジトリを登録するURLを指定できます ([Porter Manifest – Porter](https://porter.sh/docs/bundle/manifest/#images#:~:text=mixins%3A%20,https%3A%2F%2Fcharts.bitnami.com%2Fbitnami))。

mixinを利用する際には、Porterをバンドルのビルド実行環境とするマシン（開発PCやCI環境など）に該当mixinをインストールしておく必要があります ([Porter Buildtime Architecture – Porter](https://porter.sh/architecture-buildtime/#:~:text=Mixins%20must%20be%20installed%20to,porter%2Fmixins%2Fkubernetes))。インストール済みのmixinは`porter mixins list`で確認でき、実体は`~/.porter/mixins/`以下に保存されます ([Porter Buildtime Architecture – Porter](https://porter.sh/architecture-buildtime/#:~:text=match%20at%20L330%20Mixins%20must,porter%2Fmixins%2Fkubernetes))。Porter CLIはビルド時にそのディレクトリからmixinを呼び出し、各ステップの処理内容に応じてDockerfileの生成や実行コマンドの挿入を行います。以上が既存mixinの概要と使い方です。

## Mixinsの開発（カスタムmixinの作成）

Porterはユーザーが**独自のmixin**を開発・追加することも可能です ([Mixins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-mixins/#:~:text=Mixins%20make%20Porter%20special,use%20them%2C%20create%20your%20own))。コミュニティではTerraformやDocker Compose、Google Cloud (`gcloud`)など様々なmixinが作成されています ([Porter Buildtime Architecture – Porter](https://porter.sh/architecture-buildtime/#:~:text=,compose%20mixin))。独自mixinを作成することで、Porterがサポートしていないツールやカスタムなデプロイ手順を組み込むことができます。Porter CLIには`porter mixins create <名前>`というサブコマンドが用意されており、mixin開発用のひな形プロジェクトを生成できます ([Porter Buildtime Architecture – Porter](https://porter.sh/architecture-buildtime/#:~:text=,porter%20mixins%20feed%20generate))。生成されるコードには、Porterと連携するために必要なインターフェース（**ビルド時**にDockerfileのフラグメントを提供する処理や、**実行時**にインストール/アップグレード等のアクションごとに実行する処理）が含まれる構造になっています。開発者はそれを土台に、自分の目的に合わせたコマンド呼び出しやファイル配置ロジックを実装します。例えば、新しいクラウドサービス用のmixinを作る場合、そのサービスのCLIをインボケーションイメージにインストールする処理と、`install`時に適切なCLIコマンドを実行する処理を実装することになります。

作成したmixinはコンパイルして実行バイナリを配布するほか、Porterのmixinフィードに登録して`porter mixins search`で検索可能にすることもできます。mixin自体もCNABバンドルの形式でパッケージ化・配布でき、バージョン管理や信頼性の確保が行われます（Porterの観点では、**mixinも一種のCNABバンドル**として動作します）。このようにPorterはエコシステムを拡張する柔軟な仕組みを提供しており、エンジニアは必要に応じて独自のmixinを開発し組み込むことで、どんな環境構築手順でもCNABバンドル化できるようになります。

# Pluginsの概要と利用方法

**Plugin（プラグイン）**は、Porterクライアント自体の機能を拡張・置換するコンポーネントです ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=The%20Porter%20client%20is%20extensible,client%2C%20reimplementing%20Porter%E2%80%99s%20default%20functionality))。先述のmixinがバンドルの実行内容（デプロイ手順）を拡張するものだったのに対し、pluginは**Porterの内部動作を差し替える**ための仕組みです ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=Plugins%20are%20very%20different%20from,binary%20may%20contain%20multiple%20implementations))。Porterはバンドルやインストール情報を保存したり、シークレット（機密情報）やクレデンシャルを保管・参照したりしますが、これらのデフォルト実装をpluginによって差し替えることができます ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=The%20Porter%20client%20is%20extensible,client%2C%20reimplementing%20Porter%E2%80%99s%20default%20functionality))。例えば、Porterはインストールの履歴データやCredential/ParameterのセットをデフォルトではローカルのMongoDB（Dockerコンテナ上の簡易インスタンス）に保存しますが ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=For%20example%2C%20Porter%20saves%20installation,offering%20from%20your%20cloud%20provider))、本番環境では代わりにクラウド上のマネージドMongoDBサービスや社内のデータベースを使いたい、という場合があります。そのような場合にPorterは**Storageプラグイン**という種類のpluginを用意しており、デフォルトの`mongodb-docker`プラグイン（ローカルDockerボリューム上のMongoDBに保存）を、`mongodb`プラグイン（任意のMongoDB接続先に保存）に差し替えることで対応できます ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=Storage%20plugins%20let%20you%20save,use%20the%20mongodb%20storage%20plugin))。実際Porter本体には開発・テスト用途向けの`mongodb-docker`ストレージプラグインと、本番向けの`mongodb`ストレージプラグインが同梱されています ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=For%20example%2C%20Porter%20saves%20installation,offering%20from%20your%20cloud%20provider))。後者を利用する際はPorterの設定で接続文字列を指定することで、Porterのすべてのデータ（インストール履歴やバンドル情報など）が指定したMongoDBサーバーに保存されるようになります ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=For%20example%2C%20Porter%20saves%20installation,offering%20from%20your%20cloud%20provider))。

同様に、シークレットや機密情報の取り扱いをカスタマイズする**Secretsプラグイン**も用意されています。デフォルトではPorterはホストマシン上の環境変数やファイル、コマンド出力などからシークレットを取得する`host`プラグインを使用します ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=Secrets%20plugins%20allow%20you%20to,or%20the%20%20231))。`host`プラグインは手軽ですが、Porterがバンドル実行中に生成したシークレットを保存する仕組みがないため、本番用途には不向きです ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=Secrets%20plugins%20allow%20you%20to,or%20the%20%20231))。そこで例えばAzureのKey Vaultをシークレット管理に使いたい場合は、Porterの**Azureプラグイン**（Azure Key Vault連携用のSecretsプラグイン）を導入しPorter設定で有効化します ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=secrets%20plugin%20is%20the%20host,or%20the%20%20231)) ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=A%20secrets%20plugin%20can%20implement,secrets%20from%20Azure%20Key%20Vault))。これにより、バンドルから参照する機密情報の解決や、インストール中に生成されたパスワードなどの出力の安全な保存を、Azure Key Vault上で行えるようになります。Porterには他にもHashiCorp Vault用の`hashicorp`プラグインや、KubernetesのSecretsリソースと連携するプラグインなどが存在します ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=secrets%20plugin%20is%20the%20host,or%20the%20%20231)) ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=,236))。

Porterのpluginには今述べた**Storage**と**Secrets**の2種類のほか、細かな用途向けにいくつか種類があります（例えば認証情報の解決専用や、Porterの動作ログ出力先を変えるもの等）。ただ、いずれも「Porterの標準動作を別の実装に差し替える」という点は共通しています ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=The%20Porter%20client%20is%20extensible,client%2C%20reimplementing%20Porter%E2%80%99s%20default%20functionality)) ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=Plugins%20are%20very%20different%20from,binary%20may%20contain%20multiple%20implementations))。使用できるpluginはPorter CLIの`porter plugins search`で検索可能で、インストールは`porter plugins install <名前>`で行います ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=,porter%20plugins%20search))。インストール後は`porter plugins list`で一覧を確認でき、`porter plugins install`時に自動的に必要なバイナリが`~/.porter/plugins/`以下に配置されます ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=,porter%20plugins%20search))。もっとも、pluginをインストールしただけでは動作は変わりません。実際にPorterに使わせるには、Porterの設定ファイル（デフォルトは`~/.porter/config.toml`）でどのプラグインを利用するか指定する必要があります ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20verbosity,the%20storage%20configuration%20to%20use))。例えばAzureプラグインをSecretsプラグインとして使う場合、`default-secrets-plugin = "azure.keyvault"` のように設定します ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20verbosity,the%20storage%20configuration%20to%20use))。設定を反映した上でPorterコマンド（例えば`porter install`）を実行すると、資格情報の解決や機密データの保存処理がAzure Key Vault経由に差し替わっていることが確認できます。なおPorter Operator（後述）を使う場合にも、後述のPorterConfigリソースに同様の設定を行うことでプラグインを有効化できます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20verbosity,the%20storage%20configuration%20to%20use))。

## Pluginsの開発（カスタムpluginの作成）

Porterのpluginもまた独自に開発することが可能です。Porterはプラグインの種類ごとにGo言語のインターフェース（例えばストレージ用なら `plugins.StorageProtocol`）を定義しており ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=plugin)) ([Plugin Types – Porter](https://porter.sh/plugins/types/#:~:text=A%20secrets%20plugin%20can%20implement,secrets%20from%20Azure%20Key%20Vault))、新しいプラグインはこれらのインターフェースを実装する形で作成します。たとえば社内の特殊なデータベースにPorterの状態を保存したい場合、Storageプラグインを自作してそのデータベースへの読み書き処理を実装できます ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=testing,offering%20from%20your%20cloud%20provider))。Porterのプラグイン機構では一つのバイナリに複数種類の実装を含めることも可能になっており ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=Plugins%20are%20very%20different%20from,binary%20may%20contain%20multiple%20implementations))、工夫次第で様々な拡張が行えます。実際、Porter公式の`azure`プラグインは**Secretsプラグイン**（Azure Key Vaultを使用）としての側面と、Porterの**Credentialプラグイン**（Azure CLIを用いてログイン情報を取得する認証プロバイダ）としての側面を一つのプラグインで実装しています。独自プラグインを開発した場合、適切にコンパイルして配布すればPorter CLIから`porter plugins install`で追加できるようになります。加えて、Porterのプラグイン検索リスト（先述の`porter plugins search`で参照されるリスト）にエントリを加えれば、他のユーザーにも利用してもらいやすくなるでしょう。

まとめると、**mixinsはPorterのバンドル内容（インストール処理そのもの）を拡張し、pluginsはPorterクライアントの動作を拡張・カスタマイズする**ものです ([Plugins – Porter](https://porter.sh/docs/introduction/concepts-and-components/intro-plugins/#:~:text=Plugins%20are%20very%20different%20from,binary%20may%20contain%20multiple%20implementations))。Porterはこれら双方の拡張機構を備えることで、非常に幅広いユースケースに対応可能な柔軟性を実現しています。

# HelmとKubernetesとの連携

PorterはKubernetes環境やHelmチャートとも密接に連携することができます。前述の通り、Porter自体がKubernetes上のアプリケーション（および関連インフラ）を扱うための仕組みとしてCNABを採用しており、内部でHelmや`kubectl`等のツールを呼び出すことが可能です。ここではPorterによるHelmとKubernetesとの具体的な連携方法について説明します。

## Helmとの連携（Helmミックスイン）

Kubernetes上のアプリケーションを扱う際にHelmチャートを使うケースは一般的です。Porterでは**Helmミックスイン**（`helm3`）を使用することで、バンドル内の手順としてHelmチャートのインストールやアップグレードを行えます。HelmミックスインはPorterのアクションに応じて内部で対応する`helm`コマンドを実行します。具体的には、`install`アクションでは`helm install`, `upgrade`アクションでは`helm upgrade`, バンドルの`uninstall`（削除）時には`helm uninstall`を呼び出す実装になっています（旧v2用の`helm`ミックスインも存在しますが、現在はHelm v3用の`helm3`ミックスインが主流です）。

Porter YAMLで`helm3`ミックスインを使うには、事前に`porter mixins install helm3`でミックスインをインストールした上で、manifestに以下のような記述を行います。

```yaml
mixins:
- helm3

install:
- helm3:
    description: "Helmによるデプロイ"
    name: sample-app
    chart: myrepo/sample-app-chart
    version: 0.3.1
    set:
      replicaCount: 3
```

上記では`install`ステップでHelmチャート`sample-app-chart`をリリース名`sample-app`としてデプロイする設定になっています。`set`オプションでHelmのvaluesを上書き指定することもできます。`helm3`ミックスインを含むバンドルをビルドすると、Porterは自動的にインボケーションイメージ内に対応するHelm CLIバイナリ（`helm`コマンド）をダウンロードして配置します ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=The%20Kubernetes%20Mixin%20provides%20bundle,command%20line%20tool)) ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=Rather%20than%20trying%20to%20rebuild,being%20installed))。そのため、エンドユーザーが`porter install`でバンドルを実行する際には、実行環境にHelmを別途用意する必要はありません。Porterはバンドル内でHelmを実行し、チャートのインストール結果をCNABの規約に沿って出力（例えば、結果として得られるKubernetesリソースの情報をPorterのoutputs機能で取得する等）できます。Helmリポジトリの追加が必要な場合も、前述のようにPorter manifest内でリポジトリURLを宣言しておくことでビルド時に`helm repo add`を実行させることが可能です ([Porter Manifest – Porter](https://porter.sh/docs/bundle/manifest/#images#:~:text=mixins%3A%20,https%3A%2F%2Fcharts.bitnami.com%2Fbitnami))。

このように、PorterのHelmミックスインを使えばHelmチャートを他の手順（データベース準備や構成など）とまとめて一つのCNABバンドルに梱包でき、Helm単体では実現しづらい**複合的なデプロイ処理**を一括して配布・実行できます。

## Kubernetesとの連携（Kubernetesミックスインとクレデンシャル管理）

PorterはHelm以外にも**直接Kubernetesリソースを適用/削除する機能**を提供しています。具体的には、**Kubernetesミックスイン**（`kubernetes`）を使用すると、Kubernetesマニフェスト（YAML）をバンドル内に含め、それをapply/deleteする処理をバンドルに組み込めます ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=The%20Kubernetes%20Mixin%20provides%20bundle,command%20line%20tool))。Kubernetesミックスインは内部的に`kubectl`コマンドを利用しており、Porterのアクションに応じて`kubectl apply`や`kubectl delete`を実行します ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=The%20Kubernetes%20Mixin%20provides%20bundle,command%20line%20tool))。たとえば、デプロイ対象のマニフェストを事前にバンドルのCNABディレクトリ内に配置しておき、Porter manifestで以下のように指定します。

```yaml
mixins:
- kubernetes

install:
- kubernetes:
    description: "K8sマニフェスト適用"
    manifest: "manifests/app.yaml"
```

上記の設定でバンドルをビルドすると、kubernetesミックスインはDockerfileに`kubectl`のインストールコマンドを追加し ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=Rather%20than%20trying%20to%20rebuild,being%20installed))、実行時には`manifests/app.yaml`（インボケーションイメージ内に含めたKubernetesマニフェスト）を`kubectl apply`で適用します。`upgrade`アクション時には変更差分を再適用し、`uninstall`アクション時には対応するリソースを`kubectl delete`で削除します ([Kubernetes Mixin – Porter](https://porter.sh/design/kubernetes-mixin/#:~:text=The%20Kubernetes%20Mixin%20provides%20bundle,command%20line%20tool))。これにより、Kubernetesのネイティブなリソース操作もPorterバンドルに含めることができます。

PorterがKubernetesクラスタに対して操作を行う際は、当然ながらそのクラスタの認証情報（kubeconfigなど）が必要になります。Porterでは**Credential**機能を使って、こうした外部クラスターの認証情報をバンドル実行時に提供します。具体的には、Porter manifestでバンドルが必要とするクレデンシャルとして`kubeconfig`を定義し、ユーザーは`porter install`時に自分のクラスタ用のkubeconfigパスをPorterに教えるか、Credential Set経由で渡します ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=1,passing%20in%20the%20database%20credentials))。Porterは実行時にそのクレデンシャルをインボケーションイメージ内にマウントし、`KUBECONFIG`環境変数などを通じてmixin（例えばkubernetesミックスインやhelmミックスイン）に認証情報を引き渡します。これにより、バンドル内の`kubectl`や`helm`コマンドは適切に認証された状態でクラスタにアクセスできます。先のWordPressの例では、利用者は**KubernetesクラスターのクレデンシャルをPorterに提供するだけで**、Porterバンドルが内部でMySQLサービスのプロビジョニングからHelmによるWordPressチャートのインストールまで自動的に実行してくれるわけです ([FAQ – Porter](https://porter.sh/docs/faq/#:~:text=1,passing%20in%20the%20database%20credentials))。

まとめると、PorterはHelmや`kubectl`といったKubernetesエコシステムのツールと統合するためにmixinを提供しており、それらを駆使することで**インフラストラクチャとアプリケーションのセットアップを一体化**できます。さらにPorterのCredential機構と組み合わせることで、Kubernetesの認証情報管理もセキュアに行いながら、マルチクラウド・ハイブリッドな環境へのデプロイを統一的な手順で実現できます。

# Porter Operatorのカスタムリソース

PorterはCLIツールとしてローカル環境でバンドルの作成・実行ができますが、Kubernetes上でこれらを自動化・管理するための**Porter Operator**も提供されています。Porter OperatorはKubernetesのカスタムリソース定義（CRD）を利用してPorterの動作をネイティブに統合するもので、GitOps的なワークフローでPorterのバンドルを継続的に適用するようなシナリオに適しています ([Porter Operator v1.0.0 is here! – Porter](https://porter.sh/blog/operator-v1-is-here/#:~:text=The%20Porter%20Operator%20gives%20you,pipeline%20with%20support%20for%20GitOps))。Operatorを導入すると、Kubernetes上でPorter専用のリソース（CR）を作成・変更・削除するだけで、対応するPorterの操作（インストール、アップグレード、アンインストールなど）が自動的に実行されます ([Porter Operator QuickStart – Porter](https://porter.sh/docs/operator/quickstart/#:~:text=The%20Operator%20uses%20the%20concept,deleted%2C%20the%20installation%20is%20uninstalled))。ここではPorter Operatorが提供する主要なカスタムリソースについて、その役割と仕様を解説します。

**※ 注意:** Porter Operatorの各カスタムリソースは、Kubernetesのメタデータとしての`metadata.name`や`metadata.namespace`とは別に、**Porter独自の名前（name）や名前空間（namespace）をspec内に持ちます** ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=The%20Porter%20Operator%20provides%20custom,the%20name%20and%20labels%20fields))。たとえばCR自体のネームスペース（メタデータ）はKubernetes上の配置に使われますが、spec内の`namespace`フィールドはPorterが管理するインストール名空間（Porterの論理的なグルーピング）を意味します。これらは互いに連動しない独立した概念である点に留意してください ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=The%20Porter%20Operator%20provides%20custom,the%20name%20and%20labels%20fields))。

## Installation カスタムリソース

**Installation**リソースはPorter Operatorの中核となるカスタムリソースで、**「あるPorterバンドルを、この名前と設定でインストールしたい」という所望状態**をKubernetes上に表現するものです ([Porter Operator QuickStart – Porter](https://porter.sh/docs/operator/quickstart/#:~:text=The%20Operator%20uses%20the%20concept,deleted%2C%20the%20installation%20is%20uninstalled))。オペレーターはInstallationリソース（正確にはKubernetes上のカスタムリソース`Installation.getporter.org/v1`）を監視し、そのspecが示す内容とPorter内に記録された現在状態を比較して差分があればPorterを使った処理を実行します ([Porter Operator QuickStart – Porter](https://porter.sh/docs/operator/quickstart/#:~:text=The%20Operator%20uses%20the%20concept,deleted%2C%20the%20installation%20is%20uninstalled))。具体的には、(1) 新しいInstallationリソースが作成された場合、そのバンドルがまだインストールされていなければ`porter install`が実行され、(2) 既存のInstallationリソースのspecが変更（例えばバンドルバージョンやパラメータの変更）された場合には`porter upgrade`が実行され、(3) Installationリソースが削除された場合には対応する`porter uninstall`が実行されます ([Porter Operator QuickStart – Porter](https://porter.sh/docs/operator/quickstart/#:~:text=The%20Operator%20uses%20the%20concept,deleted%2C%20the%20installation%20is%20uninstalled))。このようにInstallationリソースはPorterにおける**インストール対象のDesired State（望ましい状態）**をKubernetesリソースとして定義するものです。

Installationリソースの仕様（specフィールド）はPorter CLIで扱うインストール設定とほぼ同一です ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=The%20Installation%20spec%20is%20the,removing%20the%20status%20section))。実際、CLIで`porter installation show NAME -o yaml`で出力されるインストール記録（Installationオブジェクト）のうち、`status`セクションを除いた部分をそのままInstallation CRのspecに利用できます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=The%20Installation%20spec%20is%20the,removing%20the%20status%20section))。主要なフィールドとしては以下があります ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=Field%20Required%20Description%20schemaType%20false,where%20the%20bundle%20is%20published)) ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=bundle,in%20the%20associated%20parameter%20sets))。

- **`schemaVersion`**: Porter Installation仕様のバージョン（通常 `1.0.2`）。
- **`name`**: Porter上でのインストール名（各InstallationはPorter内で一意の名前を持ちます） ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=schemaVersion%20true%20The%20version%20of,where%20the%20bundle%20is%20published))。
- **`namespace`**: Porter内の名前空間。省略時はグローバル（空）ですが、チームや環境ごとにPorterのインストールを区分けしたい場合に使用します ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=name%20true%20The%20name%20of,The%20bundle%20repository%20digest))。
- **`bundle`**: インストールすべきバンドルの参照情報 ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=labels%20false%20A%20set%20of,list%20of%20credential%20set%20names))。OCIレジストリ上のバンドルを指し、`repository`（必須）および`version` / `tag` / `digest`のいずれか一つで特定します ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=labels%20false%20A%20set%20of,list%20of%20credential%20set%20names)) ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=,fields%3A%20digest%2C%20version%2C%20or%20tag))。複数指定された場合は**digest > version > tag**の優先順位で解釈されます ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=Either%20the%20bundle%20digest%2C%20version%2C,falling%20back%20to%20tag%20last))。
- **`parameters`**: （オプション）バンドル実行時に渡すパラメータのマップ。キーはパラメータ名、値はその値です ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=convention%20of%20defaulting%20the%20bundle,in%20the%20associated%20parameter%20sets))。ここに指定した値はParameterSetで提供される値より優先されます。
- **`credentialSets`**: （オプション）使用するCredentialSetリソース名のリスト ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=parameterSets%3A%20,level%3A%2011))。複数指定可能で、バンドル実行時に統合されます。
- **`parameterSets`**: （オプション）使用するParameterSetリソース名のリスト ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=parameterSets%3A%20,level%3A%2011))。複数指定可能で、上から順にマージされます。
- **`labels`**: （オプション）任意のキー値ラベルを付与可能。Porter内のInstallationオブジェクトにラベルとして保存され、検索などに利用できます。
- **`uninstalled`**: （オプション）デフォルトfalse。trueに設定すると、そのInstallationが**アンインストールされるべき**状態であることを示します ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=namespace%20false%20The%20namespace%20in,The%20bundle%20repository%20digest))。（通常はCR削除でアンインストールしますが、このフィールドを使うことでCR自体は残したままリソースだけ削除する、といった運用も可能です。）

以上が主なフィールドです。Installation CRを作成後、オペレーターが内部的に起動するPorterエージェント（KubernetesのJobとして動作）によってインストール処理が遂行され、結果はInstallation CRの`status`フィールドに反映されます。`status`には直近のアクション（install/upgrade/...）や実行結果（成功/失敗）等が記録され、`porter installations show <NAME>`コマンドで確認することもできます。

## CredentialSet カスタムリソース

**CredentialSet**リソースは、Porterの**クレデンシャルセット**をKubernetes上で管理するためのカスタムリソースです。Porterのバンドルはデプロイ時にクラウドの認証情報やSSH鍵、データベースパスワードなど様々な**機密情報（クレデンシャル）**を必要とする場合があります。それらを事前に束ねて名前を付けたものがCredential Setです。通常、Porter CLIではユーザーのローカル環境（例えば`~/.porter/credentials/`フォルダ内）にCredential SetをYAMLで保存しますが、Porter Operatorを使う場合はそれをKubernetesのリソースとして定義できます。

CredentialSet CRのspecも基本的にはPorter CLIのCredential Setフォーマットと同じです ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20the%20glossary%20for%20more,information%20about%20the%20CredentialSet%20resource))。`schemaVersion`やPorter上の`name`、`namespace`（Porter用）を指定し、その中でどのクレデンシャル名に対してどのソースを割り当てるかを列挙します ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=apiVersion%3A%20getporter,me%20credentials)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=credentials%20true%20List%20of%20credential,The%20name%20of%20the%20secret))。たとえば以下のような内容です。

```yaml
apiVersion: getporter.org/v1
kind: CredentialSet
metadata:
  name: my-creds
spec:
  schemaVersion: 1.0.1
  name: my-creds                # Porter上でのクレデンシャルセット名
  namespace: team1              # Porter上の名前空間
  credentials:
    - name: kubeconfig          # バンドルで定義されたクレデンシャルの名前
      source:
        secret: cluster-creds   # KubernetesのSecret名
    - name: db_password
      source:
        secret: db-secret
```

上記では、バンドル側で要求される`kubeconfig`というクレデンシャルに対して、KubernetesのSecretリソース`cluster-creds`（ユーザーのkubeconfigを事前に登録したもの）を提供し、`db_password`には`db-secret`から取得することを示しています。現時点でCredentialSetで使えるソース種別はKubernetesのSecretのみです ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=credentials%20true%20List%20of%20credential,The%20name%20of%20the%20secret))（将来的に他のソースも検討されています）。Operator実行時には、Porterエージェントが該当のSecretを参照し中身を自動でマウントすることで、バンドル内でそのクレデンシャルが利用可能になります。CredentialSetもInstallationと同様に`agentConfig`フィールドを持ち、特定のAgentConfig（後述）を参照してPorterエージェントの動作をカスタマイズ可能です ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20agentConfig,The%20name%20of%20the%20secret))。

Installation CRのspecで`credentialSets: ["my-creds"]`のように参照することで、複数のクレデンシャルをまとめて提供できる仕組みになっています ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=parameterSets%3A%20,level%3A%2011))。これにより、機密情報を直接Installationに書かずKubernetesのSecretに安全に保管した上で、Porter Operatorがそれらを束ねて扱えるようになります。

## ParameterSet カスタムリソース

**ParameterSet**リソースは、Porterの**パラメータセット**をKubernetes上で管理するためのカスタムリソースです。CredentialSetが機密情報（バンドルが要求するクレデンシャル）を扱うのに対し、ParameterSetはバンドルに渡す各種パラメータ（環境設定値やオプション）を事前定義しておくためのものです。例えば、あるバンドルが`memory_size`や`enable_feature_x`といったパラメータを受け取る場合、それらの値を集めてセットにしておき、Installation実行時にまとめて指定できます。

ParameterSet CRのspecもPorter CLIのParameter Set形式と同様です ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20the%20glossary%20for%20more,information%20about%20the%20ParameterSet%20resource))。`schemaVersion`やPorter上の`name`（Parameter Set名）等を指定し、`parameters`フィールドで各パラメータ名とその値ソースを列挙します ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=apiVersion%3A%20getporter,secret)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=parameters%20true%20List%20of%20parameter,secret%20that%20holds%20the%20parameter))。例を示します。

```yaml
apiVersion: getporter.org/v1
kind: ParameterSet
metadata:
  name: my-params
spec:
  schemaVersion: 1.0.1
  name: my-params
  namespace: team1
  parameters:
    - name: environment
      source:
        value: "staging"
    - name: admin_password
      source:
        secret: "app-admin-secret"
```

この例では、バンドルが要求する`environment`パラメータにはリテラル値"staging"を割り当て、`admin_password`パラメータにはKubernetesのSecret`app-admin-secret`から取得するよう指定しています。Parameterのソースとしてはプレーンな値(`value`)とSecret参照(`secret`)を指定でき、Secretを使うことで機密性の高いパラメータも安全に提供できます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=parameters%20true%20List%20of%20parameter,secret%20that%20holds%20the%20parameter))。ParameterSetもInstallationから`parameterSets: ["my-params"]`のように参照指定することで、実行時に適用されます ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=parameterSets%3A%20,level%3A%2011))（複数指定した場合はリスト順にマージされ、同じパラメータ名が重複した場合は後勝ちになります）。なおInstallation spec内で直接指定した`parameters`フィールドは、ParameterSet経由の値よりも優先されます ([Porter Installation File Format 1.0.2 – Porter](https://porter.sh/docs/references/file-formats/installation/#:~:text=convention%20of%20defaulting%20the%20bundle,in%20the%20associated%20parameter%20sets))。これによりデフォルト値セットを用意しつつ、一部の実行でだけ特定パラメータを上書きするといった運用も可能です。

## AgentConfig カスタムリソース

**AgentConfig**リソースは、Porter Operatorが内部で起動する**Porterエージェント（Agent）**の挙動をカスタマイズするための設定用リソースです。Porter Operatorは実際のインストール・アップグレード処理を行う際、Kubernetes上で`porter-agent`というコンテナイメージをジョブ（Job）として起動します ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=apiVersion%3A%20getporter,agent%20volumeSize%3A%2064Mi))。このエージェントコンテナ内でPorter CLIが実行され、指定のバンドル処理が行われます。デフォルトではOperatorに組み込みの標準設定が使われますが、AgentConfigリソースを用意しInstallationやCredentialSet、ParameterSetから参照することで、以下のような点を変更できます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=porterRepository%20false%20ghcr.io%2Fgetporter%2Fporter,pod%2Fjob%20for%20the%20installation%20image)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=serviceAccount%20true%20,is%20canary%20or%20latest%2C%20otherwise))。

- 使用するPorterエージェントイメージのリポジトリやバージョン（`porterRepository`, `porterVersion`） ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=porterRepository%20false%20ghcr.io%2Fgetporter%2Fporter,pod%2Fjob%20for%20the%20installation%20image))。デフォルトはOperator対応バージョンのPorterがホストされた`ghcr.io/getporter/porter-agent`イメージです。最新機能を試すために`canary`版を指定したり、独自にビルドしたエージェントイメージを指定できます。
- エージェントPodを実行する際のKubernetesサービスアカウント（`serviceAccount`） ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=porterVersion%20false%20varies%20The%20tag,share%20data%20between%20the%20Porter))。デフォルトではOperatorインストール時に`porter-agent`というServiceAccountと適切なRoleが作られますが、必要に応じて変更可能です。
- バンドルの実行に用いる作業ディスク容量（`volumeSize`） ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Must%20exist%20in%20the%20same,pull%20the%20Porter%20Agent%20image))。Porterエージェントとバンドルのインボケーションイメージがデータ共有するための一時ボリュームサイズで、デフォルト64MiBです。大きなファイルを扱う場合は増やせます。
- エージェントイメージのPullポリシーや、ジョブ失敗時の再試行回数上限（`pullPolicy`, `retryLimit`）など ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=porterRepository%20false%20ghcr.io%2Fgetporter%2Fporter,pod%2Fjob%20for%20the%20installation%20image)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=files%20used%20by%20the%20bundle,to%20install%20before%20bundle%20runs))。
- Porterエージェント起動時にインストールしておくべきPorterプラグイン設定（`pluginConfigFile`） ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=installationServiceAccount%3A%20installation,0))。たとえばエージェント上でAzureやHashicorp Vaultのプラグインを有効化してからバンドルを実行したい場合に、この設定で有効化します。

AgentConfigリソースを作成するとき、最低限`serviceAccount`だけは既存のものを指定する必要があります ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=has%20been%20tested%20with%20the,including%20credentials%2C%20parameters%20and%20outputs))（Operatorの名前空間で`porter-agent`というServiceAccountがデフォルト作成されますので通常それを指定）。それ以外は省略すればデフォルト値が適用されます。作成したAgentConfigリソースは、InstallationやCredentialSet、ParameterSetのspec内で`agentConfig: <AgentConfig名>`と参照できます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=In%20addition%20to%20the%20normal,the%20following%20fields%20are%20supported)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20agentConfig,The%20name%20of%20the%20secret)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20agentConfig,secret%20that%20holds%20the%20parameter))。たとえば特定のInstallationだけエージェントイメージを別バージョンにしたい場合、そのInstallation specに対応するAgentConfigを関連付ければOKです。こうした柔軟な設定により、Operator利用時でもPorterエージェントの挙動を細かく調整できます。

## PorterConfig カスタムリソース

**PorterConfig**リソースは、Porterのクライアント設定（configファイルの内容）をKubernetes上で管理するためのカスタムリソースです。Porter CLIでは`~/.porter/config.toml`で様々な設定（デフォルト出力の冗長度、利用するプラグインの指定、デフォルト名空間やストレージ設定など）を行えますが、Porter Operator環境下でも同様の設定をCRとして提供できます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20the%20glossary%20for%20more,information%20about%20the%20PorterConfig%20resource)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20verbosity,the%20storage%20configuration%20to%20use))。PorterConfigリソースのspecフィールドはPorterの設定ファイルの各オプションに対応しており、camelCaseではなくハイフン区切りの名前になっている以外は同じ項目です ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20the%20glossary%20for%20more,information%20about%20the%20PorterConfig%20resource))。主な設定項目には以下があります。

- **`verbosity`**: Porter実行ログの冗長レベル（例: `debug`にすると詳細なデバッグログを出力） ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=Field%20Required%20Default%20Description%20verbosity,the%20storage%20configuration%20to%20use))。
- **`default-storage`**: デフォルトで使用するストレージ設定の名前 ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20Porter%20Feature%20Flags%20for,A%20list%20of%20named))。通常Operatorでは`in-cluster-mongodb`というMongoDB（Operator同梱のデータベース）設定が使われます。
- **`storage`**: 利用可能なストレージ設定の一覧 ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=defined%20without%20the%20namespace%20set,name%20of%20the%20storage%20plugin)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20Porter%20Feature%20Flags%20for,A%20list%20of%20named))。例えば上記`in-cluster-mongodb`の接続情報（MongoDBプラグイン＋接続URL）などを含めます。
- **`default-secrets`**: デフォルトで使用するシークレット管理設定の名前 ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20Porter%20Feature%20Flags%20for,A%20list%20of%20named))。デフォルト空（未設定）の場合、`default-secrets-plugin`で指定されたプラグインが使われます。
- **`default-secrets-plugin`**: Secretsプラグインの種類デフォルト ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=default,list%20of%20named%20secrets%20configurations))。Operatorでは初期状態で`kubernetes.secrets`（KubernetesのSecretリソースを用いるプラグイン）が指定されています。
- **`default-storage-plugin`**: Storageプラグインの種類デフォルト ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20Porter%20Feature%20Flags%20for,A%20list%20of%20named))。Operator初期状態では`mongodb`が指定されています。
- **`secrets`**: 利用可能なシークレット管理設定の一覧（複数の外部Vaultを設定して名前で切り替えられるようにする場合など） ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=See%20Porter%20Feature%20Flags%20for,A%20list%20of%20named))。
- **`experimental`**: Porterの実験的機能フラグ群（現在は未使用か限定的）。

PorterConfigリソースを作成すると、Operatorはその設定を参照してPorterエージェント起動時に適用します。たとえば独自のMongoDBストレージを使うようにPorterConfigで設定すれば、エージェントはインストール結果などをそちらのDBに保存します。またAzureやVault等のプラグインを使う場合も、このPorterConfigにプラグイン設定を記述します。なお、一つのクラスターにPorterConfigは一つで十分です（名前空間ごとに分ける必要は基本ありません）。Porter Operatorをデプロイした直後は既定の設定が内蔵されていますが、必要に応じてPorterConfigを作成・調整するとよいでしょう。

## その他のリソース: AgentAction

上記の主要リソースのほかに、Porter Operatorには**AgentAction**というカスタムリソースも存在します ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=AgentAction))。AgentActionリソースは、Porterエージェントに対して**任意のPorterコマンドを実行させる**ための仕組みです。通常、Installationリソースを介してPorterにインストールやアップグレードをさせますが、さらに自由度の高い用途（例えばデバッグ目的で`porter installation apply`を直接実行するとか、Porterに特殊なカスタムアクションを実行させる等）のためにAgentActionを作成できます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=args%3A%20%5B,yaml%3A%20c2NoZW1hVmVyc2lvbjogMS4wLjAKbmFtZXNwYWNlOiBvcGVyYXRvc%20gpuYW1lOiBoZWxsbwpidW5kbGU6CiAgcmVwb3NpdG9yeTogZ2hjci5pby9nZXRwb3J0ZXIvdGVzdC9wb%203J0ZXItaGVsbG8KICB2ZXJzaW9uOiAwLjIuMApwYXJhbWV0ZXJzOgogIG5hbWU6IGxsYW1hcyAK))。AgentActionのspecにはPorterコマンドの引数列（例: `args: ["installation", "apply", "mybundle.yaml"]`）やエージェント上に配置すべきファイル（base64エンコードで指定）などを記述し、リソースを作成するとそれに基づいてエージェントJobが一度きり実行されます ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=args%3A%20%5B,yaml%3A%20c2NoZW1hVmVyc2lvbjogMS4wLjAKbmFtZXNwYWNlOiBvcGVyYXRvc%20gpuYW1lOiBoZWxsbwpidW5kbGU6CiAgcmVwb3NpdG9yeTogZ2hjci5pby9nZXRwb3J0ZXIvdGVzdC9wb%203J0ZXItaGVsbG8KICB2ZXJzaW9uOiAwLjIuMApwYXJhbWV0ZXJzOgogIG5hbWU6IGxsYW1hcyAK)) ([Porter Operator Resources – Porter](https://porter.sh/docs/operator/file-formats/#:~:text=image,Additional%20volumes))。ただしこのリソースは高度な用途向けであり、一般的なインストール管理には通常直接使用しません。

以上、Porter Operatorの主要なカスタムリソースであるInstallation、CredentialSet、ParameterSet、AgentConfig、PorterConfig（および特殊用途のAgentAction）について概要を説明しました。Porter Operatorを導入すると、これらリソースを組み合わせることでKubernetesクラスター上でPorterのCI/CD的な運用が可能になります。例えば、GitリポジトリにInstallationやCredentialSetのYAMLを配置し、それをArgo CDやFluxなどで適用すれば、コード変更に応じてPorterによるバンドル適用が自動で行われる、といった**GitOpsワークフロー**も実現できます。Porter OperatorはKubernetesの宣言的管理の恩恵をPorterに持ち込み、インフラとアプリケーションのライフサイクル管理を一段と統一された形で提供してくれるでしょう ([Porter Operator v1.0.0 is here! – Porter](https://porter.sh/blog/operator-v1-is-here/#:~:text=The%20Porter%20Operator%20gives%20you,pipeline%20with%20support%20for%20GitOps))。