Crossplane

Crossplane 徹底解説 — クラウドネイティブなインフラストラクチャ管理の新標準

1. はじめに

1.1 Crossplane とは何か

Crossplane は、Kubernetes をコントロールプレーンとして活用し、あらゆるクラウドインフラストラクチャをKubernetes のカスタムリソース (CR) として宣言的に管理するためのオープンソースフレームワークである。CNCF (Cloud Native Computing Foundation) のインキュベーションプロジェクトとして2020年に採択され、その後2023年9月にGraduatedプロジェクトに昇格した。

従来の Infrastructure as Code (IaC) ツールである Terraform や Pulumi が「プロビジョニングツール」としての役割を担うのに対し、Crossplane は Kubernetes のコントロールループ(Reconciliation Loop)を活用した「継続的なインフラストラクチャ管理プラットフォーム」としての位置づけを持つ。これにより、インフラストラクチャの状態を常に監視し、宣言された望ましい状態(Desired State)と実際の状態(Actual State)の差分を検出して自動的に修復する仕組みを実現する。

1.2 Crossplane が解決する課題

現代のクラウドネイティブ環境において、インフラストラクチャ管理は以下のような課題を抱えている。

マルチクラウド管理の複雑性

企業は複数のクラウドプロバイダー(AWS、GCP、Azure など)を利用することが一般的になっている。各プロバイダーは独自の API、CLI、SDK を提供しており、それぞれの操作方法やリソースモデルを理解する必要がある。Crossplane はこれらの差異を Kubernetes API の背後に抽象化し、統一的なインターフェースを提供する。

インフラストラクチャとアプリケーションの管理の分断

従来の IaC ツールでは、インフラストラクチャの管理とアプリケーションのデプロイは別々のワークフローで行われることが多い。Crossplane は両方を Kubernetes マニフェストとして統一的に管理できるため、GitOps ワークフローとの親和性が非常に高い。

セルフサービスインフラストラクチャの実現困難

開発チームがインフラストラクチャを必要とする際、従来はプラットフォームチームやインフラチームへの依頼が必要であった。Crossplane の Composition 機能を活用することで、プラットフォームチームが安全で標準化された「インフラストラクチャの型(テンプレート)」を定義し、開発チームはそれを自由に利用できるセルフサービスモデルを構築できる。

ドリフト(構成のずれ)の検出と修復

Terraform などの IaC ツールでは、terraform apply を実行した後にクラウドコンソール等から手動で変更が加えられると、コードと実際の状態に乖離(ドリフト)が発生する。Crossplane は Kubernetes のコントロールループにより、このドリフトを継続的に検出し自動修復する。

1.3 Crossplane の歴史と背景

Crossplane は Upbound 社によって2018年に開発が開始された。Upbound 社の創業者である Bassam Tabbara は、かつて Rook(Kubernetes 上のストレージオーケストレーション)プロジェクトの創始者でもあり、Kubernetes のオペレーターパターンに深い知見を持っていた。

年月マイルストーン
2018年12月Crossplane プロジェクト開始、GitHub でオープンソースとして公開
2020年6月CNCF Sandbox プロジェクトとして採択
2021年9月CNCF Incubation プロジェクトに昇格
2022年Composition Functions の概念導入
2023年6月Crossplane v1.13 リリース(Composition Functions GA)
2023年9月CNCF Graduated プロジェクトに昇格
2024年Provider v1 の安定化、エコシステムの成熟
2025年Crossplane v1.17+ リリース、Composition Functions v2 の進化

1.4 Crossplane と他の IaC ツールとの比較

Crossplane を理解するために、主要な IaC ツールとの比較を行う。

特徴CrossplaneTerraformPulumiAWS CDK
宣言的管理○ (YAML)○ (HCL)△ (命令的+宣言的)× (命令的)
継続的リコンシリエーション×××
ドリフト自動修復× (手動 plan/apply)××
Kubernetes ネイティブ×××
GitOps 親和性×
抽象化レイヤー○ (Compositions)△ (Modules)○ (Components)○ (Constructs)
マルチクラウド対応× (AWS のみ)
ステート管理Kubernetes etcdtfstate ファイルPulumi Cloud/自前CloudFormation
学習コスト中〜高低〜中
コミュニティ成長中非常に大きい成長中中程度

Terraform との最大の違いは「ステート管理」と「継続的リコンシリエーション」にある。Terraform では tfstate ファイルを別途管理する必要があり、ステートのロックやバックエンドの設定が必要となる。一方、Crossplane は Kubernetes の etcd をステートストアとして活用するため、追加のステート管理インフラが不要である。また、Terraform は planapply のコマンドを手動(または CI/CD パイプライン経由)で実行する必要があるが、Crossplane はコントロールループにより自動的かつ継続的にリコンシリエーションを行う。

1.5 本記事の構成

本記事では、Crossplane の全体像を理解するために以下の構成で解説を進める。

  1. はじめに(本章)
  2. アーキテクチャの全体像
  3. コアコンポーネントの詳細
  4. Provider の仕組みと設定
  5. Managed Resources の管理
  6. Composition と XRD によるインフラストラクチャの抽象化
  7. Composition Functions による高度なロジック
  8. パッケージ管理
  9. RBAC とセキュリティ
  10. GitOps との統合
  11. 実践的なユースケースと設定例
  12. 運用とトラブルシューティング
  13. パフォーマンスとスケーラビリティ
  14. エコシステムと今後の展望
  15. まとめ

2. アーキテクチャの全体像

2.1 Crossplane のアーキテクチャ概要

Crossplane のアーキテクチャは、Kubernetes のエクステンションメカニズムを最大限に活用した設計となっている。その中心には以下の要素がある。

┌─────────────────────────────────────────────────────────────────┐
│                    Kubernetes Cluster                            │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │                Crossplane Core                            │  │
│  │  ┌─────────────┐  ┌──────────────┐  ┌───────────────┐   │  │
│  │  │ Composition │  │   Package    │  │    RBAC       │   │  │
│  │  │  Engine     │  │   Manager    │  │   Manager     │   │  │
│  │  └─────────────┘  └──────────────┘  └───────────────┘   │  │
│  └──────────────────────────────────────────────────────────┘  │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │                    Providers                              │  │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────┐ │  │
│  │  │ AWS      │  │ GCP      │  │ Azure    │  │ Helm    │ │  │
│  │  │ Provider │  │ Provider │  │ Provider │  │ Provider│ │  │
│  │  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬────┘ │  │
│  └───────┼──────────────┼──────────────┼─────────────┼──────┘  │
│          │              │              │             │          │
└──────────┼──────────────┼──────────────┼─────────────┼──────────┘
           │              │              │             │
           ▼              ▼              ▼             ▼
      ┌─────────┐   ┌─────────┐   ┌──────────┐  ┌──────────┐
      │  AWS    │   │  GCP    │   │  Azure   │  │ Helm     │
      │  API    │   │  API    │   │  API     │  │ Charts   │
      └─────────┘   └─────────┘   └──────────┘  └──────────┘

2.2 コントロールプレーンとしての Kubernetes

Crossplane が Kubernetes をコントロールプレーンとして採用している理由は複数存在する。

宣言的 API の活用

Kubernetes API サーバーは、リソースの望ましい状態(Desired State)を宣言的に記述し、それを API として公開する仕組みを提供する。Crossplane はこの仕組みを拡張し、クラウドリソースに対しても同様の宣言的管理を実現する。

Custom Resource Definition (CRD) によるスキーマ拡張

Kubernetes の CRD メカニズムにより、任意のリソース型を定義できる。Crossplane の各 Provider は、対象クラウドサービスのリソースに対応する CRD を登録する。例えば、AWS Provider をインストールすると、s3.aws.upbound.io/Bucketec2.aws.upbound.io/Instance などの CRD が自動的に登録される。

コントロールループ(Reconciliation Loop)

Kubernetes のコントローラーマネージャーは、各リソースに対して「observe → analyze → act」のループを繰り返し実行する。Crossplane のコントローラーは以下のサイクルを回す。

  ┌──────────┐
  │ Observe  │ ← 外部リソースの現在の状態を取得
  └────┬─────┘
       │
  ┌────▼─────┐
  │ Compare  │ ← Desired State と Actual State を比較
  └────┬─────┘
       │
  ┌────▼─────┐
  │  Act     │ ← 差分があれば API を呼び出して修正
  └────┬─────┘
       │
       └──────→ ループを繰り返す(デフォルト: 1分間隔)

etcd による状態管理

Kubernetes の etcd がステートストアとして機能するため、Terraform の tfstate のような外部ステート管理が不要となる。ただし、etcd のサイズ制限(デフォルト 2GB)に注意が必要であり、大量のリソースを管理する場合は etcd のチューニングが必要となる場合がある。

2.3 リソースモデルの階層構造

Crossplane のリソースモデルは、以下の3つの階層で構成される。

┌─────────────────────────────────────────────────────────┐
│                   Claim (XC)                             │
│  開発者が利用する高レベルの抽象化されたリソース           │
│  例: DatabaseClaim, KubernetesClusterClaim              │
│  → Namespace スコープ                                   │
└─────────────────────┬───────────────────────────────────┘
                      │ 参照
┌─────────────────────▼───────────────────────────────────┐
│             Composite Resource (XR)                      │
│  複数のManagedResourceを束ねる中間層                     │
│  例: XDatabase, XKubernetesCluster                      │
│  → Cluster スコープ                                     │
└─────────────────────┬───────────────────────────────────┘
                      │ 所有
┌─────────────────────▼───────────────────────────────────┐
│              Managed Resource (MR)                       │
│  外部クラウドリソースと1:1で対応する低レベルリソース      │
│  例: Bucket, Instance, VPC, Subnet                      │
│  → Cluster スコープ                                     │
└─────────────────────────────────────────────────────────┘

Claim (XC)

Claim はアプリケーション開発者が利用する最上位の抽象化レイヤーである。Namespace スコープで作成されるため、Kubernetes の名前空間ベースのマルチテナント設計と親和性が高い。

Composite Resource (XR)

XR は Composition の結果として生成される中間層のリソースである。Cluster スコープで存在し、1つ以上の Managed Resource を所有する。

Managed Resource (MR)

MR は外部のクラウドリソースと1対1で対応するリソースである。各 Provider が定義する CRD に基づいて作成される。

2.4 データフローの全体像

ユーザーが Claim を作成してから実際のクラウドリソースがプロビジョニングされるまでのデータフローを示す。

[ユーザー/GitOps]
      │
      │ kubectl apply -f claim.yaml
      ▼
[Kubernetes API Server]
      │
      │ Claim リソースが etcd に保存
      ▼
[Crossplane Composition Engine]
      │
      │ 1. Claim を検出
      │ 2. 対応する XRD/Composition を検索
      │ 3. Composition に基づいて XR を生成
      │ 4. XR に基づいて Managed Resources を生成
      ▼
[Provider Controller]
      │
      │ 1. Managed Resource を検出
      │ 2. 外部リソースの状態を確認(Observe)
      │ 3. 必要に応じてリソースを作成/更新(Create/Update)
      │ 4. ステータスを Managed Resource に反映
      ▼
[Cloud Provider API]
      │
      │ 実際のクラウドリソースが作成される
      ▼
[クラウドリソース]
  (S3バケット, RDSインスタンス, VPC 等)

2.5 ネットワーキングとセキュリティの観点

Crossplane のコントロールプレーンは Kubernetes クラスター内で動作するため、クラウドプロバイダーの API エンドポイントへの外向き通信が必要となる。セキュリティの観点から以下の点に注意が必要である。

  • 認証情報の管理: Provider が使用するクラウド認証情報は Kubernetes Secret として管理される。IRSA (IAM Roles for Service Accounts)、Workload Identity などの Pod Identity メカニズムの利用が推奨される
  • ネットワークポリシー: Provider Pod からクラウド API への通信のみを許可するネットワークポリシーの設定が望ましい
  • RBAC: Crossplane は独自の RBAC マネージャーを持ち、Composition 作成者とClaim 利用者の権限を分離できる

3. コアコンポーネントの詳細

3.1 Crossplane Pod の構成

Crossplane をインストールすると、以下の Pod が展開される。

$ kubectl get pods -n crossplane-system
NAME                                       READY   STATUS    RESTARTS   AGE
crossplane-7c9b4c6f5d-xxxxx               1/1     Running   0          5m
crossplane-rbac-manager-6d8f6b4c9-yyyyy   1/1     Running   0          5m

crossplane Pod

メインの Crossplane コントローラーであり、以下の機能を担当する。

  • Composition Engine: XRD、Composition、Claim、XR の管理
  • Package Manager: Provider、Configuration パッケージのインストールと管理
  • CRD の動的登録と管理

crossplane-rbac-manager Pod

Crossplane が定義するリソースに対する RBAC ポリシーを自動管理するコンポーネントである。新しい CRD が登録されると、自動的に適切な ClusterRole を生成する。

3.2 Composition Engine

Composition Engine は Crossplane の中核となるコンポーネントであり、以下の責務を持つ。

  1. XRD (CompositeResourceDefinition) の管理: XRD が作成されると、対応する CRD を動的に生成し、Kubernetes API サーバーに登録する
  2. Composition の選択: XR が作成されると、CompositionSelector や CompositionRef に基づいて適切な Composition を選択する
  3. リソースのレンダリング: 選択された Composition のテンプレートに基づいて Managed Resource を生成する
  4. ステータスの伝播: Managed Resource のステータスを XR、さらに Claim へと伝播させる

3.3 Package Manager

Package Manager は OCI (Open Container Initiative) レジストリからパッケージをダウンロードし、インストールする機能を提供する。Crossplane のパッケージは OCI イメージとして配布される。

パッケージの種類は以下の通り。

パッケージ種別説明
Providerクラウドプロバイダーの CRD とコントローラーprovider-aws, provider-gcp
ConfigurationXRD と Composition のセットplatform-ref-aws
FunctionComposition Functions の実装function-patch-and-transform

3.4 Managed Resource コントローラーのライフサイクル

各 Managed Resource コントローラーは、以下のライフサイクルステートを管理する。

                    ┌─────────────────┐
                    │    Created      │
                    │  (Pending)      │
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │   Provisioning  │
                    │  (Creating)     │
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
              ┌─────│    Available    │──────┐
              │     │   (Ready)      │      │
              │     └────────┬────────┘      │
              │              │               │
     ドリフト検出        更新要求         削除要求
              │              │               │
     ┌────────▼────────┐    │     ┌─────────▼────────┐
     │   Reconciling   │    │     │    Deleting       │
     │  (Syncing)      │    │     │                   │
     └────────┬────────┘    │     └─────────┬─────────┘
              │              │               │
              └──────────────┘     ┌─────────▼─────────┐
                                   │    Deleted         │
                                   └───────────────────┘

ステータス条件(Status Conditions)は以下の通りである。

  • Synced: 外部リソースとの同期状態を示す。True は同期済み、False はエラーが発生していることを示す
  • Ready: リソースが利用可能な状態かを示す。True はリソースが完全にプロビジョニングされ利用可能であることを示す
  • LastAsyncOperation: 非同期操作の結果を示す(一部の Provider で使用)

4. Provider の仕組みと設定

4.1 Provider の概要

Provider は Crossplane のプラグインシステムであり、特定のクラウドプロバイダーや外部サービスの API と通信するためのコントローラーと CRD のセットを提供する。各 Provider は OCI イメージとしてパッケージングされ、Crossplane の Package Manager によってインストールされる。

4.2 主要な Provider

Crossplane エコシステムには多数の Provider が存在する。以下に代表的なものを示す。

Provider対象CRD 数(概算)メンテナー
provider-aws-* (Upbound family)Amazon Web Services1000+Upbound
provider-gcp-* (Upbound family)Google Cloud Platform800+Upbound
provider-azure-* (Upbound family)Microsoft Azure900+Upbound
provider-kubernetesKubernetes クラスターN/A (動的)コミュニティ
provider-helmHelm チャートN/A (動的)コミュニティ
provider-terraformTerraform モジュールN/A (動的)Upbound
provider-sqlSQL データベース10+コミュニティ

Upbound 公式 Provider(Family Provider)

Upbound 社は、各クラウドプロバイダー向けに「Family Provider」というモジュール化された Provider セットを提供している。例えば AWS 向けには以下のような構成となる。

provider-family-aws          ← 基盤となる Provider(認証管理)
├── provider-aws-s3           ← S3 関連の CRD とコントローラー
├── provider-aws-ec2          ← EC2 関連の CRD とコントローラー
├── provider-aws-rds          ← RDS 関連の CRD とコントローラー
├── provider-aws-iam          ← IAM 関連の CRD とコントローラー
├── provider-aws-eks          ← EKS 関連の CRD とコントローラー
├── provider-aws-lambda       ← Lambda 関連の CRD とコントローラー
├── provider-aws-vpc          ← VPC 関連の CRD とコントローラー
└── ... (その他多数)

この設計により、必要なサービスの Provider のみをインストールできるため、CRD の数を抑えてクラスターへの負荷を軽減できる。

4.3 Provider のインストール

Provider のインストールは Provider リソースを作成することで行う。

# provider-aws-s3.yaml
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws-s3
spec:
  package: xpkg.upbound.io/upbound/provider-aws-s3:v1.14.0
  runtimeConfigRef:
    name: default

v1.14 以降では DeploymentRuntimeConfig を使用してProvider のランタイム設定をカスタマイズする。

# deployment-runtime-config.yaml
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
  name: aws-runtime-config
spec:
  deploymentTemplate:
    spec:
      replicas: 1
      selector: {}
      template:
        spec:
          containers:
            - name: package-runtime
              resources:
                limits:
                  memory: 512Mi
                  cpu: 500m
                requests:
                  memory: 256Mi
                  cpu: 250m
              env:
                - name: HTTPS_PROXY
                  value: "http://proxy.example.com:8080"
          serviceAccountName: provider-aws-sa
          nodeSelector:
            node-role: crossplane
          tolerations:
            - key: "dedicated"
              operator: "Equal"
              value: "crossplane"
              effect: "NoSchedule"

4.4 Provider の認証設定(ProviderConfig)

Provider がクラウド API にアクセスするための認証情報は ProviderConfig リソースで設定する。

AWS の認証設定例(アクセスキー方式)

apiVersion: v1
kind: Secret
metadata:
  name: aws-credentials
  namespace: crossplane-system
type: Opaque
stringData:
  credentials: |
    [default]
    aws_access_key_id = AKIAIOSFODNN7EXAMPLE
    aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
---
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: aws-credentials
      key: credentials

AWS の認証設定例(IRSA 方式 -- 推奨)

apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: IRSA

IRSA(IAM Roles for Service Accounts)を使用する場合は、以下の設定が前提となる。

  1. EKS クラスターで OIDC Provider が有効化されていること
  2. IAM ロールが作成され、適切な信頼ポリシーが設定されていること
  3. Provider の ServiceAccount に IAM ロールのアノテーションが付与されていること
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
  name: aws-irsa-config
spec:
  serviceAccountTemplate:
    metadata:
      annotations:
        eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/crossplane-provider-aws

GCP の認証設定例(Workload Identity 方式)

apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  projectID: my-gcp-project-id
  credentials:
    source: InjectedIdentity

Azure の認証設定例(Service Principal 方式)

apiVersion: v1
kind: Secret
metadata:
  name: azure-credentials
  namespace: crossplane-system
type: Opaque
stringData:
  credentials: |
    {
      "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "clientSecret": "your-client-secret",
      "subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
      "resourceManagerEndpointUrl": "https://management.azure.com/"
    }
---
apiVersion: azure.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: azure-credentials
      key: credentials

4.5 複数の ProviderConfig によるマルチアカウント管理

Crossplane は複数の ProviderConfig を定義することで、マルチアカウント・マルチリージョンの管理を実現できる。

# 本番環境用
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: aws-production
spec:
  credentials:
    source: IRSA
  assumeRoleChain:
    - roleARN: arn:aws:iam::111111111111:role/crossplane-production
---
# ステージング環境用
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: aws-staging
spec:
  credentials:
    source: IRSA
  assumeRoleChain:
    - roleARN: arn:aws:iam::222222222222:role/crossplane-staging
---
# 開発環境用
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: aws-development
spec:
  credentials:
    source: IRSA
  assumeRoleChain:
    - roleARN: arn:aws:iam::333333333333:role/crossplane-development

Managed Resource から ProviderConfig を参照する際は providerConfigRef を使用する。

apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
  name: my-production-bucket
spec:
  forProvider:
    region: ap-northeast-1
  providerConfigRef:
    name: aws-production  # 本番アカウントの認証情報を使用

5. Managed Resources の管理

5.1 Managed Resource の基本構造

Managed Resource は外部クラウドリソースと1対1で対応する Kubernetes カスタムリソースである。その基本的な構造は以下の通り。

apiVersion: <provider-group>/<version>
kind: <ResourceKind>
metadata:
  name: <resource-name>
  annotations:
    crossplane.io/external-name: "actual-cloud-resource-name"
spec:
  forProvider:
    region: ap-northeast-1
  providerConfigRef:
    name: default
  deletionPolicy: Delete  # Delete (デフォルト) or Orphan
  managementPolicies:
    - "*"  # デフォルト: すべての操作を管理
  writeConnectionSecretToRef:
    name: my-resource-connection
    namespace: crossplane-system
status:
  conditions:
    - type: Ready
      status: "True"
      reason: Available
    - type: Synced
      status: "True"
      reason: ReconcileSuccess
  atProvider:
    arn: "arn:aws:s3:::my-bucket-name"
    id: "my-bucket-name"

5.2 具体的な Managed Resource の例

S3 バケットの作成

apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
  name: my-application-bucket
  annotations:
    crossplane.io/external-name: "my-app-bucket-prod-2024"
spec:
  forProvider:
    region: ap-northeast-1
    tags:
      Environment: production
      Team: platform
      ManagedBy: crossplane
  providerConfigRef:
    name: aws-production
  deletionPolicy: Delete
---
apiVersion: s3.aws.upbound.io/v1beta1
kind: BucketVersioning
metadata:
  name: my-application-bucket-versioning
spec:
  forProvider:
    bucketRef:
      name: my-application-bucket
    versioningConfiguration:
      - status: Enabled
  providerConfigRef:
    name: aws-production
---
apiVersion: s3.aws.upbound.io/v1beta2
kind: BucketServerSideEncryptionConfiguration
metadata:
  name: my-application-bucket-encryption
spec:
  forProvider:
    bucketRef:
      name: my-application-bucket
    rule:
      - applyServerSideEncryptionByDefault:
          - sseAlgorithm: aws:kms
            kmsMasterKeyId: "arn:aws:kms:ap-northeast-1:123456789012:key/xxxxxxxx"
  providerConfigRef:
    name: aws-production

RDS PostgreSQL インスタンスの作成

apiVersion: rds.aws.upbound.io/v1beta2
kind: Instance
metadata:
  name: my-postgresql-instance
spec:
  forProvider:
    region: ap-northeast-1
    allocatedStorage: 100
    maxAllocatedStorage: 500
    engine: postgres
    engineVersion: "15.4"
    instanceClass: db.r6g.large
    dbName: myapplication
    username: admin
    autoGeneratePassword: true
    dbSubnetGroupNameRef:
      name: my-db-subnet-group
    vpcSecurityGroupIdRefs:
      - name: database-sg
    multiAz: true
    storageType: gp3
    storageEncrypted: true
    backupRetentionPeriod: 7
    deletionProtection: true
    tags:
      Environment: production
  providerConfigRef:
    name: aws-production
  writeConnectionSecretToRef:
    name: my-postgresql-connection
    namespace: crossplane-system
  deletionPolicy: Orphan

5.3 リソース間の参照(References)

Crossplane の Managed Resource 間では、リソースの参照(Reference)機能を使用して依存関係を表現できる。

apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
  name: my-vpc
spec:
  forProvider:
    region: ap-northeast-1
    cidrBlock: "10.0.0.0/16"
    enableDnsHostnames: true
    enableDnsSupport: true
---
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
metadata:
  name: private-subnet-1a
spec:
  forProvider:
    region: ap-northeast-1
    availabilityZone: ap-northeast-1a
    cidrBlock: "10.0.1.0/24"
    vpcIdRef:
      name: my-vpc  # 名前ベースの参照

参照の方式は以下の2種類がある。

方式フィールド名説明
名前参照*Ref (例: vpcIdRef)リソースの名前で参照
セレクタ参照*Selector (例: vpcIdSelector)ラベルセレクタで参照

5.4 削除ポリシーと管理ポリシー

削除ポリシー(DeletionPolicy)

  • Delete: Managed Resource が削除されると外部リソースも削除(デフォルト)
  • Orphan: Managed Resource が削除されても外部リソースは残る

管理ポリシー(ManagementPolicies)-- v1.14+

spec:
  managementPolicies:
    - "*"          # すべての操作を管理(デフォルト)
    # - Create     # リソースの作成のみ
    # - Update     # リソースの更新のみ
    # - Delete     # リソースの削除のみ
    # - Observe    # リソースの状態監視のみ

既存のクラウドリソースを Crossplane にインポートしたい場合は、Observe のみを指定することで読み取り専用のリソースとして管理できる。

apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
  name: existing-vpc
  annotations:
    crossplane.io/external-name: "vpc-0123456789abcdef0"
spec:
  forProvider:
    region: ap-northeast-1
  managementPolicies:
    - Observe
  providerConfigRef:
    name: aws-production

6. Composition と XRD によるインフラストラクチャの抽象化

6.1 Composition の概念

Composition は Crossplane の最も強力な機能の1つであり、複数の Managed Resource を1つの高レベルな抽象リソースとしてまとめる仕組みを提供する。これにより、プラットフォームチームが組織固有のインフラストラクチャ「ビルディングブロック」を定義し、開発チームはその詳細を知ることなくインフラストラクチャをセルフサービスで利用できるようになる。

┌─────────────────────────────────────────────────────────────┐
│ CompositeResourceDefinition (XRD)                           │
│ - API スキーマの定義                                        │
│ - Claim と XR のインターフェースを規定                       │
└─────────────────────────┬───────────────────────────────────┘
                          │
┌─────────────────────────▼───────────────────────────────────┐
│ Composition                                                  │
│ - XRD のパラメータから Managed Resources への                │
│   マッピングを定義                                           │
└─────────────────────────┬───────────────────────────────────┘
                          │
┌─────────────────────────▼───────────────────────────────────┐
│ Claim (XC) / Composite Resource (XR)                        │
│ - ユーザーが作成するリソースインスタンス                     │
└─────────────────────────────────────────────────────────────┘

6.2 CompositeResourceDefinition (XRD) の定義

XRD は Kubernetes の CRD を生成するための「メタ CRD」とも呼べるリソースである。

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xdatabases.platform.example.com
spec:
  group: platform.example.com
  names:
    kind: XDatabase
    plural: xdatabases
  claimNames:
    kind: Database
    plural: databases
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                parameters:
                  type: object
                  properties:
                    engine:
                      type: string
                      enum: [postgres, mysql]
                      default: postgres
                    size:
                      type: string
                      enum: [small, medium, large]
                      default: small
                    storageGB:
                      type: integer
                      minimum: 20
                      maximum: 10000
                      default: 50
                    region:
                      type: string
                      default: ap-northeast-1
                    highAvailability:
                      type: boolean
                      default: false
                  required: [engine, region]
              required: [parameters]
            status:
              type: object
              properties:
                endpoint:
                  type: string
                port:
                  type: integer

6.3 Composition の定義

Composition は XRD で定義されたパラメータを実際の Managed Resource にマッピングする。

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xdatabases.aws.platform.example.com
  labels:
    provider: aws
spec:
  compositeTypeRef:
    apiVersion: platform.example.com/v1alpha1
    kind: XDatabase
  mode: Resources
  patchSets:
    - name: common-parameters
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: spec.parameters.region
          toFieldPath: spec.forProvider.region
  resources:
    - name: rds-instance
      base:
        apiVersion: rds.aws.upbound.io/v1beta2
        kind: Instance
        spec:
          forProvider:
            autoGeneratePassword: true
            storageType: gp3
            storageEncrypted: true
      patches:
        - type: PatchSet
          patchSetName: common-parameters
        - type: FromCompositeFieldPath
          fromFieldPath: spec.parameters.engine
          toFieldPath: spec.forProvider.engine
        - type: FromCompositeFieldPath
          fromFieldPath: spec.parameters.size
          toFieldPath: spec.forProvider.instanceClass
          transforms:
            - type: map
              map:
                small: "db.t3.medium"
                medium: "db.r6g.large"
                large: "db.r6g.xlarge"
        - type: FromCompositeFieldPath
          fromFieldPath: spec.parameters.highAvailability
          toFieldPath: spec.forProvider.multiAz
        - type: ToCompositeFieldPath
          fromFieldPath: status.atProvider.endpoint
          toFieldPath: status.endpoint

6.4 Claim の作成

開発者は XRD で定義されたスキーマに従って Claim を作成する。

apiVersion: platform.example.com/v1alpha1
kind: Database
metadata:
  name: my-app-db
  namespace: team-alpha
spec:
  parameters:
    engine: postgres
    size: small
    storageGB: 50
    region: ap-northeast-1
    highAvailability: false
  compositionSelector:
    matchLabels:
      provider: aws
  writeConnectionSecretToRef:
    name: my-app-db-connection

6.5 Patch の種類と Transform

パッチタイプ方向説明
FromCompositeFieldPathXR -> MRXR のフィールドを MR にコピー
ToCompositeFieldPathMR -> XRMR のフィールドを XR にコピー
CombineFromCompositeXR -> MRXR の複数フィールドを結合して MR に設定
FromEnvironmentFieldPathEnv -> MREnvironment Config から MR にコピー

Transform の種類

# Map Transform
transforms:
  - type: map
    map:
      small: "db.t3.medium"
      medium: "db.r6g.large"

# Math Transform
transforms:
  - type: math
    math:
      type: Multiply
      multiply: 1024

# String Transform
transforms:
  - type: string
    string:
      type: Format
      fmt: "%s-db-subnet-group"

6.6 Environment Config

Environment Config は Composition 内で共有されるコンテキスト情報を提供する。

apiVersion: apiextensions.crossplane.io/v1alpha1
kind: EnvironmentConfig
metadata:
  name: production-ap-northeast-1
  labels:
    environment: production
    region: ap-northeast-1
data:
  vpcId: "vpc-0123456789abcdef0"
  kmsKeyArn: "arn:aws:kms:ap-northeast-1:123456789012:key/xxxx"
  accountId: "123456789012"

7. Composition Functions による高度なロジック

7.1 Composition Functions の概要

Composition Functions は Crossplane v1.14 で GA となった機能であり、Composition のリソース生成ロジックをプログラマブルに記述できる仕組みを提供する。条件分岐、ループ、外部データの参照などの複雑なロジックを実現できる。

7.2 Pipeline モードの Composition

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xdatabases.aws-pipeline.platform.example.com
spec:
  compositeTypeRef:
    apiVersion: platform.example.com/v1alpha1
    kind: XDatabase
  mode: Pipeline
  pipeline:
    - step: render-resources
      functionRef:
        name: function-patch-and-transform
      input:
        apiVersion: pt.fn.crossplane.io/v1beta1
        kind: Resources
        resources:
          - name: rds-instance
            base:
              apiVersion: rds.aws.upbound.io/v1beta2
              kind: Instance
              spec:
                forProvider:
                  engine: postgres
                  storageEncrypted: true
    - step: auto-ready
      functionRef:
        name: function-auto-ready

7.3 主要な Composition Functions

Function説明
function-patch-and-transform基本的なリソース生成とパッチ適用
function-go-templatingGo テンプレートによる動的リソース生成
function-kclKCL 言語による型安全な設定記述
function-auto-ready全子リソース Ready 時に XR を Ready に設定
function-extra-resourcesComposition 外のリソースを参照

Go テンプレートを使用した Composition の例

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xnetworks.aws-templated.platform.example.com
spec:
  compositeTypeRef:
    apiVersion: platform.example.com/v1alpha1
    kind: XNetwork
  mode: Pipeline
  pipeline:
    - step: render-network
      functionRef:
        name: function-go-templating
      input:
        apiVersion: gotemplating.fn.crossplane.io/v1beta1
        kind: GoTemplate
        source: Inline
        inline:
          template: |
            {{ $xr := .observed.composite.resource }}
            {{ $region := $xr.spec.parameters.region }}
            ---
            apiVersion: ec2.aws.upbound.io/v1beta1
            kind: VPC
            metadata:
              annotations:
                gotemplating.fn.crossplane.io/composition-resource-name: vpc
            spec:
              forProvider:
                region: {{ $region }}
                cidrBlock: {{ $xr.spec.parameters.vpcCidr }}
            {{ $azs := list "a" "c" "d" }}
            {{ range $i, $az := $azs }}
            ---
            apiVersion: ec2.aws.upbound.io/v1beta1
            kind: Subnet
            metadata:
              annotations:
                gotemplating.fn.crossplane.io/composition-resource-name: subnet-{{ $az }}
            spec:
              forProvider:
                region: {{ $region }}
                availabilityZone: {{ $region }}{{ $az }}
                cidrBlock: "10.0.{{ add $i 1 }}.0/24"
            {{ end }}
    - step: auto-ready
      functionRef:
        name: function-auto-ready

7.4 カスタム Composition Function の開発

Go 言語での Function 実装例:

package main

import (
    fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1"
    "github.com/crossplane/function-sdk-go"
    "github.com/crossplane/function-sdk-go/request"
    "github.com/crossplane/function-sdk-go/response"
)

type Function struct {
    fnv1beta1.UnimplementedFunctionRunnerServiceServer
}

func (f *Function) RunFunction(
    req *fnv1beta1.RunFunctionRequest,
) (*fnv1beta1.RunFunctionResponse, error) {
    rsp := response.To(req, response.DefaultTTL)
    xr, err := request.GetObservedCompositeResource(req)
    if err != nil {
        response.Fatal(rsp, err)
        return rsp, nil
    }
    // カスタムロジックをここに実装
    return rsp, nil
}

8. パッケージ管理

8.1 Configuration パッケージの作成

# crossplane.yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
  name: platform-database
spec:
  crossplane:
    version: ">=v1.14.0"
  dependsOn:
    - provider: xpkg.upbound.io/upbound/provider-aws-rds
      version: ">=v1.0.0"
    - function: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform
      version: ">=v0.5.0"

パッケージのビルドとプッシュ:

$ crossplane xpkg build --package-root=. --output=platform-database.xpkg
$ crossplane xpkg push --package-files=platform-database.xpkg \
    registry.example.com/platform/platform-database:v1.0.0

8.2 パッケージのインストール

apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
  name: platform-database
spec:
  package: registry.example.com/platform/platform-database:v1.0.0
  revisionActivationPolicy: Automatic
  revisionHistoryLimit: 3

9. RBAC とセキュリティ

9.1 プラットフォームチームと開発チームの権限分離

# プラットフォームチーム用
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: platform-admin
rules:
  - apiGroups: ["apiextensions.crossplane.io"]
    resources: ["compositeresourcedefinitions", "compositions"]
    verbs: ["*"]
  - apiGroups: ["pkg.crossplane.io"]
    resources: ["providers", "configurations", "functions"]
    verbs: ["*"]
---
# 開発チーム用
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer
  namespace: team-alpha
rules:
  - apiGroups: ["platform.example.com"]
    resources: ["databases"]
    verbs: ["*"]

9.2 認証情報の安全な管理

External Secrets Operator との統合により、クラウドのシークレットマネージャーから認証情報を自動取得できる。

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: aws-crossplane-credentials
  namespace: crossplane-system
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: aws-credentials
  data:
    - secretKey: access_key
      remoteRef:
        key: crossplane/aws-credentials
        property: access_key_id

10. GitOps との統合

10.1 ArgoCD との統合

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: crossplane-infrastructure
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/infrastructure.git
    targetRevision: main
    path: crossplane/claims
  destination:
    server: https://kubernetes.default.svc
    namespace: infrastructure
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - ServerSideApply=true

10.2 Git リポジトリの構成例

infrastructure/
├── crossplane/
│   ├── providers/
│   ├── functions/
│   ├── platform-apis/
│   │   ├── database/
│   │   │   ├── xrd.yaml
│   │   │   └── composition-aws.yaml
│   │   └── network/
│   ├── environment-configs/
│   └── claims/
│       ├── production/
│       ├── staging/
│       └── development/
└── apps/

10.3 プルリクエストベースのワークフロー

  1. 開発者が Claim を作成/変更する PR を作成
  2. CI パイプラインで crossplane beta validate によるスキーマ検証、crossplane beta render によるローカルレンダリング
  3. プラットフォームチームがレビュー
  4. マージ後、ArgoCD が自動 sync
  5. Crossplane が Composition に基づきリソースを作成

11. 実践的なユースケースと設定例

11.1 Web アプリケーション基盤の構築

3層アーキテクチャの Web アプリケーション基盤を Crossplane で構築する例。XRD でコンピュート、データベース、キャッシュの設定パラメータを定義し、Go テンプレートを使用した Composition でセキュリティグループ、RDS インスタンス、ElastiCache クラスターを条件付きで生成する。

11.2 EKS クラスターのプロビジョニング

IAM Role、EKS Cluster、NodeGroup、Addon を一括でプロビジョニングする Composition を定義し、開発チームは Claim でクラスター名、ノードプールの構成、アドオンの選択を指定するだけで EKS クラスターを構築できる。

11.3 マルチクラウドのオブジェクトストレージ

同一の XRD に対して AWS (S3) 向けと GCP (GCS) 向けの Composition を用意し、Claim の compositionSelector で provider ラベルを切り替えるだけでクラウドプロバイダーを選択できる。

12. 運用とトラブルシューティング

12.1 日常的な運用コマンド

kubectl get managed                         # 全 Managed Resource の状態確認
kubectl get databases.platform.example.com -A  # 全 Claim の状態確認
kubectl get providers                        # Provider の状態確認
kubectl get compositions                     # Composition の一覧
kubectl describe instance.rds.aws.upbound.io/my-db  # 詳細表示

12.2 よくある問題と対処法

症状原因対処法
Synced: FalseIAM 権限不足、パラメータ不正Provider ログの確認、ProviderConfig の検証
MR が作成されないComposition 選択の失敗XR の compositionRef を確認、Crossplane ログの確認
パッケージインストール失敗イメージプル失敗ネットワーク接続、レジストリ認証の確認
クラスター負荷増大CRD の肥大化Family Provider の活用、不要な Provider の削除

12.3 モニタリングとアラート

重要なメトリクス:

メトリクス説明アラート閾値の目安
controller_runtime_reconcile_errors_totalリコンシリエーションエラー数増加傾向
controller_runtime_reconcile_time_secondsリコンシリエーション所要時間p99 > 30秒
workqueue_depthコントローラーのワークキュー深度> 100

12.4 アップグレード戦略

# Crossplane のアップグレード
$ helm upgrade crossplane crossplane-stable/crossplane \
    --namespace crossplane-system --version 1.17.0

# Provider のアップグレード(段階的に)
$ kubectl patch provider provider-aws-s3 --type merge \
    -p '{"spec":{"package":"xpkg.upbound.io/upbound/provider-aws-s3:v1.15.0"}}'

13. パフォーマンスとスケーラビリティ

13.1 スケーラビリティの考慮事項

項目推奨値制約要因
Managed Resource 数~2,000/ProviderProvider のメモリ・CPU
CRD 数~500API Server のメモリ、etcd
Composition の深さ~50 リソースComposition Engine のパフォーマンス
Provider 数~20クラスターのリソース

13.2 パフォーマンスチューニング

apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
  name: high-performance-config
spec:
  deploymentTemplate:
    spec:
      template:
        spec:
          containers:
            - name: package-runtime
              resources:
                limits:
                  memory: 2Gi
                  cpu: "2"
              args:
                - --poll=5m
                - --max-reconcile-rate=50

13.3 大規模環境でのベストプラクティス

  1. Family Provider の活用で CRD 数を最小限に抑える
  2. 専用ノードに Crossplane と Provider の Pod を配置
  3. 頻繁に変更されないリソースにはリコンシリエーション間隔を延長
  4. 大量のリソースは複数の ProviderConfig に分割

14. エコシステムと今後の展望

14.1 Crossplane エコシステム

ツール用途
crossplane CLIコマンドラインツール
Upbound Cloudマネージド Crossplane コントロールプレーン
UpjetTerraform Provider から Crossplane Provider を自動生成
provider-terraform既存の Terraform モジュールを Crossplane から利用
provider-kubernetesKubernetes リソースを Crossplane で管理
provider-helmHelm チャートを Crossplane で管理

14.2 今後の展望

  1. Composition Functions の進化(より多くの言語サポート)
  2. Observability の強化(ネイティブなメトリクス、トレーシング)
  3. マルチクラスターサポート
  4. WebAssembly (Wasm) Functions
  5. ステートフルリソースの管理改善

15. まとめ

15.1 Crossplane の強み

  1. Kubernetes ネイティブ: 既存のエコシステム(RBAC、GitOps、モニタリング等)をそのまま活用
  2. 継続的リコンシリエーション: ドリフトを自動修復
  3. 抽象化レイヤー: Composition によるセルフサービスインフラを実現
  4. マルチクラウド対応: 同一 API で複数クラウドのリソースを管理
  5. エコシステム: Upjet による豊富な Provider カバレッジ

15.2 Crossplane の課題

  1. 学習曲線: Kubernetes + Crossplane 固有概念の理解が必要
  2. デバッグの困難さ: 複数レイヤーにまたがる問題の特定が困難
  3. CRD の肥大化: 多数の Provider で API Server への負荷が増大
  4. 成熟度: Terraform と比較するとコミュニティ規模で劣る

15.3 導入の判断基準

Crossplane が適している場合

  • Kubernetes を中心としたプラットフォーム基盤を構築している
  • マルチクラウド/マルチアカウント環境を統一的に管理したい
  • 開発チームにセルフサービスのインフラストラクチャを提供したい
  • GitOps ワークフローでインフラとアプリケーションを統合管理したい

Crossplane が適していない場合

  • Kubernetes を使用していない環境
  • 小規模なインフラストラクチャで Terraform で十分に管理できる
  • チームに Kubernetes の運用知識が不足している

15.4 推奨される導入アプローチ

  1. フェーズ 1: 評価: 開発環境で小規模なリソースを管理し動作を理解
  2. フェーズ 2: プラットフォーム API の設計: XRD と Composition を設計
  3. フェーズ 3: パイロット: ステージング環境で実際のアプリケーション基盤を管理
  4. フェーズ 4: 本番導入: GitOps と統合し本番環境のインフラを段階的に移行
  5. フェーズ 5: 拡張: Composition Functions、カスタム Provider の開発

本記事では、Crossplane のアーキテクチャ、コアコンポーネント、Provider の設定、Composition による抽象化、Composition Functions、パッケージ管理、セキュリティ、GitOps との統合、実践的なユースケース、運用・トラブルシューティング、パフォーマンスとスケーラビリティ、そしてエコシステムと今後の展望について包括的に解説した。

Crossplane は Kubernetes エコシステムの一部として急速に成熟しつつあり、クラウドネイティブなインフラストラクチャ管理の新たな標準となる可能性を秘めている。特に、プラットフォームエンジニアリングの文脈において、開発者体験の向上とインフラストラクチャのガバナンスを両立させるための強力なツールとして、今後ますますその重要性が増していくものと考えられる。