--- title: Import Existing Resources weight: 200 --- 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`]({{}}) field enables importing external resources into Crossplane. Crossplane can import resources either [manually]({{}}) or [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 {{}}my-existing-network{{}}, create a new managed resource and use the {{}}my-existing-network{{}} in the annotation. ```yaml {label="annotation",copy-lines="none"} apiVersion: compute.gcp.crossplane.io/v1beta1 kind: Network metadata: annotations: crossplane.io/external-name: my-existing-network ``` The {{}}metadata.name{{}} field can be anything you want. For example, {{}}imported-network{{}}. {{< hint "note" >}} This name is the name of the Kubernetes object. It's not related to the resource name inside the Provider. {{< /hint >}} ```yaml {label="name",copy-lines="none"} apiVersion: compute.gcp.crossplane.io/v1beta1 kind: Network metadata: name: imported-network annotations: crossplane.io/external-name: my-existing-network ``` Leave the {{}}spec.forProvider{{}} 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 {{}}spec.forProvider{{}} 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 {label="fp",copy-lines="all"} 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]({{}}). Crossplane imports observe only resources but never changes or deletes the resources. {{}} 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 >}} ### Apply the Observe management policy Create a new managed resource matching the {{}}apiVersion{{}} and {{}}kind{{}} of the resource to import and add {{}}managementPolicies: ["Observe"]{{}} to the {{}}spec{{}} For example, to import a GCP SQL DatabaseInstance, create a new resource with the {{}}managementPolicies: ["Observe"]{{}} set. ```yaml {label="oo-policy",copy-lines="none"} apiVersion: sql.gcp.upbound.io/v1beta1 kind: DatabaseInstance spec: managementPolicies: ["Observe"] ``` ### Add the external-name annotation Add the {{}}crossplane.io/external-name{{}} annotation for the resource. This name must match the name inside the Provider. For example, for a GCP database named {{}}my-external-database{{}}, apply the {{}}crossplane.io/external-name{{}} annotation with the value {{}}my-external-database{{}}. ```yaml {label="oo-ex-name",copy-lines="none"} 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 {{}}name{{}} to use for the Kubernetes object. For example, name the Kubernetes object {{}}my-imported-database{{}}. ```yaml {label="oo-name",copy-lines="none"} 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 {{}}spec.forProvider{{}} field. For example, only import the GCP SQL database in the {{}}us-central1{{}} region. ```yaml {label="oo-region"} 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 {{}}status.atProvider{{}} fields with the values from the external resource. ```yaml {label="ooPopulated",copy-lines="none"} 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 ``` ## Control imported ObserveOnly resources Crossplane can take active control of observe only imported resources by changing the `managementPolicies` after import. Change the {{}}managementPolicies{{}} field of the managed resource to {{}}["*"]{{}}. Copy any required parameter values from {{}}status.atProvider{{}} and provide them in {{}}spec.forProvider{{}}. {{< hint "tip" >}} Manually copy the important `spec.atProvider` values to `spec.forProvider`. {{< /hint >}} ```yaml {label="fc"} 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.