Back to Crossplane

Import Existing Resources

content/v1.20/guides/import-existing-resources.md

1.19-archive8.6 KB
Original Source

If you have resources that are already provisioned in a Provider, you can import them as managed resources and let Crossplane manage them. A managed resource's [managementPolicies]({{<ref "../concepts/managed-resources#managementpolicies">}}) field enables importing external resources into Crossplane.

Crossplane can import resources either [manually]({{<ref "#import-resources-manually">}}) or [automatically]({{<ref "#import-resources-automatically">}}).

Import resources manually

Crossplane can discover and import existing Provider resources by matching the crossplane.io/external-name annotation in a managed resource.

To import an existing external resource in a Provider, create a new managed resource with the crossplane.io/external-name annotation. Set the annotation value to the name of the resource in the Provider.

For example, to import an existing GCP Network named {{<hover label="annotation" line="5">}}my-existing-network{{</hover>}}, create a new managed resource and use the {{<hover label="annotation" line="5">}}my-existing-network{{</hover>}} in the annotation.

yaml
apiVersion: compute.gcp.crossplane.io/v1beta1
kind: Network
metadata:
  annotations:
    crossplane.io/external-name: my-existing-network

The {{<hover label="name" line="5">}}metadata.name{{</hover>}} field can be anything you want. For example, {{<hover label="name" line="5">}}imported-network{{</hover>}}.

{{< hint "note" >}} This name is the name of the Kubernetes object. It's not related to the resource name inside the Provider. {{< /hint >}}

yaml
apiVersion: compute.gcp.crossplane.io/v1beta1
kind: Network
metadata:
  name: imported-network
  annotations:
    crossplane.io/external-name: my-existing-network

Leave the {{<hover label="fp" line="8">}}spec.forProvider{{</hover>}} field empty. Crossplane imports the settings and automatically applies them to the managed resource.

{{< hint "important" >}} If the managed resource has required fields in the {{<hover label="fp" line="8">}}spec.forProvider{{</hover>}} you must add it to the forProvider field.

The values of those fields must match what's inside the Provider or Crossplane overwrites the existing values. {{< /hint >}}

yaml
apiVersion: compute.gcp.crossplane.io/v1beta1
kind: Network
metadata:
  name: imported-network
  annotations:
    crossplane.io/external-name: my-existing-network
spec:
  forProvider: {}

Crossplane now controls and manages this imported resource. Any changes to the managed resource spec changes the external resource.

Import resources automatically

Automatically import external resources with an Observe [management policy]({{<ref "../concepts/managed-resources#managementpolicies">}}).

Crossplane imports observe only resources but never changes or deletes the resources.

{{<hint "important" >}} The managed resource managementPolicies option is a beta feature.

The Provider determines support for management policies. Refer to the Provider's documentation to see if the Provider supports management policies. {{< /hint >}}

<!-- vale off -->

Apply the Observe management policy

<!-- vale on -->

Create a new managed resource matching the {{<hover label="oo-policy" line="1">}}apiVersion{{</hover>}} and {{<hover label="oo-policy" line="2">}}kind{{</hover>}} of the resource to import and add {{<hover label="oo-policy" line="4">}}managementPolicies: ["Observe"]{{</hover>}} to the {{<hover label="oo-policy" line="3">}}spec{{</hover>}}

For example, to import a GCP SQL DatabaseInstance, create a new resource with the {{<hover label="oo-policy" line="4">}}managementPolicies: ["Observe"]{{</hover>}} set.

yaml
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
spec:
  managementPolicies: ["Observe"]

Add the external-name annotation

Add the {{<hover label="oo-ex-name" line="5">}}crossplane.io/external-name{{</hover>}} annotation for the resource. This name must match the name inside the Provider.

For example, for a GCP database named {{<hover label="oo-ex-name" line="5">}}my-external-database{{</hover>}}, apply the {{<hover label="oo-ex-name" line="5">}}crossplane.io/external-name{{</hover>}} annotation with the value {{<hover label="oo-ex-name" line="5">}}my-external-database{{</hover>}}.

yaml
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
metadata:
  annotations:
    crossplane.io/external-name: my-external-database
spec:
  managementPolicies: ["Observe"]

Create a Kubernetes object name

Create a {{<hover label="oo-name" line="4">}}name{{</hover>}} to use for the Kubernetes object.

For example, name the Kubernetes object {{<hover label="oo-name" line="4">}}my-imported-database{{</hover>}}.

yaml
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
metadata:
  name: my-imported-database
  annotations:
    crossplane.io/external-name: my-external-database
spec:
  managementPolicies: ["Observe"]

Identify a specific external resource

If more than one resource inside the Provider shares the same name, identify the specific resource with a unique {{<hover line="9" label="oo-region">}}spec.forProvider{{</hover>}} field.

For example, only import the GCP SQL database in the {{<hover line="10" label="oo-region">}}us-central1{{</hover>}} region.

yaml
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
metadata:
  name: my-imported-database
  annotations:
    crossplane.io/external-name: my-external-database
spec:
  managementPolicies: ["Observe"]
  forProvider:
    region: "us-central1"

Apply the managed resource

Apply the new managed resource. Crossplane syncs the status of the external resource in the cloud with the newly created managed resource.

View the discovered resource

Crossplane discovers the managed resource and populates the {{<hover label="ooPopulated" line="12">}}status.atProvider{{</hover>}} fields with the values from the external resource.

yaml
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
metadata:
  name: my-imported-database
  annotations:
    crossplane.io/external-name: my-external-database
spec:
  managementPolicies: ["Observe"]
  forProvider:
    region: us-central1
status:
  atProvider:
    connectionName: crossplane-playground:us-central1:my-external-database
    databaseVersion: POSTGRES_14
    deletionProtection: true
    firstIpAddress: 35.184.74.79
    id: my-external-database
    publicIpAddress: 35.184.74.79
    region: us-central1
    # Removed for brevity
    settings:
    - activationPolicy: ALWAYS
      availabilityType: REGIONAL
      diskSize: 100
      # Removed for brevity
      pricingPlan: PER_USE
      tier: db-custom-4-26624
      version: 4
  conditions:
  - lastTransitionTime: "2023-02-22T07:16:51Z"
    reason: Available
    status: "True"
    type: Ready
  - lastTransitionTime: "2023-02-22T07:16:51Z"
    reason: ReconcileSuccess
    status: "True"
    type: Synced
<!-- vale off -->

Control imported ObserveOnly resources

<!-- vale on -->

Crossplane can take active control of observe only imported resources by changing the managementPolicies after import.

Change the {{<hover label="fc" line="8">}}managementPolicies{{</hover>}} field of the managed resource to {{<hover label="fc" line="8">}}["*"]{{</hover>}}.

Copy any required parameter values from {{<hover label="fc" line="16">}}status.atProvider{{</hover>}} and provide them in {{<hover label="fc" line="9">}}spec.forProvider{{</hover>}}.

{{< hint "tip" >}} Manually copy the important status.atProvider values to spec.forProvider. {{< /hint >}}

yaml
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
metadata:
  name: my-imported-database
  annotations:
    crossplane.io/external-name: my-external-database
spec:
  managementPolicies: ["*"]
  forProvider:
    databaseVersion: POSTGRES_14
    region: us-central1
    settings:
    - diskSize: 100
      tier: db-custom-4-26624
status:
  atProvider:
    databaseVersion: POSTGRES_14
    region: us-central1
    # Removed for brevity
    settings:
    - diskSize: 100
      tier: db-custom-4-26624
      # Removed for brevity
  conditions:
    - lastTransitionTime: "2023-02-22T07:16:51Z"
      reason: Available
      status: "True"
      type: Ready
    - lastTransitionTime: "2023-02-22T11:16:45Z"
      reason: ReconcileSuccess
      status: "True"
      type: Synced

Crossplane now fully manages the imported resource. Crossplane applies any changes to the managed resource in the Provider's external resource.